Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes
Pull gfs2 fixes from Steven Whitehouse: "Out of these five patches, the one for ensuring that the number of revokes is not exceeded, and the one for checking the glock is not already held in gfs2_getxattr are the two most important. The latter can be triggered by selinux. The other three patches are very small and fix mostly fairly trivial issues" * git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes: GFS2: Check for glock already held in gfs2_getxattr GFS2: alloc_workqueue() doesn't return an ERR_PTR GFS2: don't overrun reserved revokes GFS2: WQ_NON_REENTRANT is meaningless and going away GFS2: Fix typo in gfs2_create_inode()
This commit is contained in:
commit
d6a5e06cd1
4 changed files with 23 additions and 11 deletions
|
@ -1838,14 +1838,14 @@ int __init gfs2_glock_init(void)
|
|||
|
||||
glock_workqueue = alloc_workqueue("glock_workqueue", WQ_MEM_RECLAIM |
|
||||
WQ_HIGHPRI | WQ_FREEZABLE, 0);
|
||||
if (IS_ERR(glock_workqueue))
|
||||
return PTR_ERR(glock_workqueue);
|
||||
if (!glock_workqueue)
|
||||
return -ENOMEM;
|
||||
gfs2_delete_workqueue = alloc_workqueue("delete_workqueue",
|
||||
WQ_MEM_RECLAIM | WQ_FREEZABLE,
|
||||
0);
|
||||
if (IS_ERR(gfs2_delete_workqueue)) {
|
||||
if (!gfs2_delete_workqueue) {
|
||||
destroy_workqueue(glock_workqueue);
|
||||
return PTR_ERR(gfs2_delete_workqueue);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
register_shrinker(&glock_shrinker);
|
||||
|
|
|
@ -47,7 +47,8 @@ static void gfs2_ail_error(struct gfs2_glock *gl, const struct buffer_head *bh)
|
|||
* None of the buffers should be dirty, locked, or pinned.
|
||||
*/
|
||||
|
||||
static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
|
||||
static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync,
|
||||
unsigned int nr_revokes)
|
||||
{
|
||||
struct gfs2_sbd *sdp = gl->gl_sbd;
|
||||
struct list_head *head = &gl->gl_ail_list;
|
||||
|
@ -57,7 +58,9 @@ static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
|
|||
|
||||
gfs2_log_lock(sdp);
|
||||
spin_lock(&sdp->sd_ail_lock);
|
||||
list_for_each_entry_safe(bd, tmp, head, bd_ail_gl_list) {
|
||||
list_for_each_entry_safe_reverse(bd, tmp, head, bd_ail_gl_list) {
|
||||
if (nr_revokes == 0)
|
||||
break;
|
||||
bh = bd->bd_bh;
|
||||
if (bh->b_state & b_state) {
|
||||
if (fsync)
|
||||
|
@ -65,6 +68,7 @@ static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
|
|||
gfs2_ail_error(gl, bh);
|
||||
}
|
||||
gfs2_trans_add_revoke(sdp, bd);
|
||||
nr_revokes--;
|
||||
}
|
||||
GLOCK_BUG_ON(gl, !fsync && atomic_read(&gl->gl_ail_count));
|
||||
spin_unlock(&sdp->sd_ail_lock);
|
||||
|
@ -91,7 +95,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
|
|||
WARN_ON_ONCE(current->journal_info);
|
||||
current->journal_info = &tr;
|
||||
|
||||
__gfs2_ail_flush(gl, 0);
|
||||
__gfs2_ail_flush(gl, 0, tr.tr_revokes);
|
||||
|
||||
gfs2_trans_end(sdp);
|
||||
gfs2_log_flush(sdp, NULL);
|
||||
|
@ -101,15 +105,19 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
|
|||
{
|
||||
struct gfs2_sbd *sdp = gl->gl_sbd;
|
||||
unsigned int revokes = atomic_read(&gl->gl_ail_count);
|
||||
unsigned int max_revokes = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / sizeof(u64);
|
||||
int ret;
|
||||
|
||||
if (!revokes)
|
||||
return;
|
||||
|
||||
ret = gfs2_trans_begin(sdp, 0, revokes);
|
||||
while (revokes > max_revokes)
|
||||
max_revokes += (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header)) / sizeof(u64);
|
||||
|
||||
ret = gfs2_trans_begin(sdp, 0, max_revokes);
|
||||
if (ret)
|
||||
return;
|
||||
__gfs2_ail_flush(gl, fsync);
|
||||
__gfs2_ail_flush(gl, fsync, max_revokes);
|
||||
gfs2_trans_end(sdp);
|
||||
gfs2_log_flush(sdp, NULL);
|
||||
}
|
||||
|
|
|
@ -594,7 +594,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
|
|||
}
|
||||
gfs2_glock_dq_uninit(ghs);
|
||||
if (IS_ERR(d))
|
||||
return PTR_RET(d);
|
||||
return PTR_ERR(d);
|
||||
return error;
|
||||
} else if (error != -ENOENT) {
|
||||
goto fail_gunlock;
|
||||
|
@ -1750,6 +1750,10 @@ static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name,
|
|||
struct gfs2_holder gh;
|
||||
int ret;
|
||||
|
||||
/* For selinux during lookup */
|
||||
if (gfs2_glock_is_locked_by_me(ip->i_gl))
|
||||
return generic_getxattr(dentry, name, data, size);
|
||||
|
||||
gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh);
|
||||
ret = gfs2_glock_nq(&gh);
|
||||
if (ret == 0) {
|
||||
|
|
|
@ -155,7 +155,7 @@ static int __init init_gfs2_fs(void)
|
|||
goto fail_wq;
|
||||
|
||||
gfs2_control_wq = alloc_workqueue("gfs2_control",
|
||||
WQ_NON_REENTRANT | WQ_UNBOUND | WQ_FREEZABLE, 0);
|
||||
WQ_UNBOUND | WQ_FREEZABLE, 0);
|
||||
if (!gfs2_control_wq)
|
||||
goto fail_recovery;
|
||||
|
||||
|
|
Loading…
Reference in a new issue