Commit d6a5e06c authored by Linus Torvalds's avatar Linus Torvalds

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()
parents 7067552d 7bd9ee58
...@@ -1838,14 +1838,14 @@ int __init gfs2_glock_init(void) ...@@ -1838,14 +1838,14 @@ int __init gfs2_glock_init(void)
glock_workqueue = alloc_workqueue("glock_workqueue", WQ_MEM_RECLAIM | glock_workqueue = alloc_workqueue("glock_workqueue", WQ_MEM_RECLAIM |
WQ_HIGHPRI | WQ_FREEZABLE, 0); WQ_HIGHPRI | WQ_FREEZABLE, 0);
if (IS_ERR(glock_workqueue)) if (!glock_workqueue)
return PTR_ERR(glock_workqueue); return -ENOMEM;
gfs2_delete_workqueue = alloc_workqueue("delete_workqueue", gfs2_delete_workqueue = alloc_workqueue("delete_workqueue",
WQ_MEM_RECLAIM | WQ_FREEZABLE, WQ_MEM_RECLAIM | WQ_FREEZABLE,
0); 0);
if (IS_ERR(gfs2_delete_workqueue)) { if (!gfs2_delete_workqueue) {
destroy_workqueue(glock_workqueue); destroy_workqueue(glock_workqueue);
return PTR_ERR(gfs2_delete_workqueue); return -ENOMEM;
} }
register_shrinker(&glock_shrinker); register_shrinker(&glock_shrinker);
......
...@@ -47,7 +47,8 @@ static void gfs2_ail_error(struct gfs2_glock *gl, const struct buffer_head *bh) ...@@ -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. * 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 gfs2_sbd *sdp = gl->gl_sbd;
struct list_head *head = &gl->gl_ail_list; struct list_head *head = &gl->gl_ail_list;
...@@ -57,7 +58,9 @@ static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) ...@@ -57,7 +58,9 @@ static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
gfs2_log_lock(sdp); gfs2_log_lock(sdp);
spin_lock(&sdp->sd_ail_lock); 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; bh = bd->bd_bh;
if (bh->b_state & b_state) { if (bh->b_state & b_state) {
if (fsync) if (fsync)
...@@ -65,6 +68,7 @@ static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) ...@@ -65,6 +68,7 @@ static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
gfs2_ail_error(gl, bh); gfs2_ail_error(gl, bh);
} }
gfs2_trans_add_revoke(sdp, bd); gfs2_trans_add_revoke(sdp, bd);
nr_revokes--;
} }
GLOCK_BUG_ON(gl, !fsync && atomic_read(&gl->gl_ail_count)); GLOCK_BUG_ON(gl, !fsync && atomic_read(&gl->gl_ail_count));
spin_unlock(&sdp->sd_ail_lock); spin_unlock(&sdp->sd_ail_lock);
...@@ -91,7 +95,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) ...@@ -91,7 +95,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
WARN_ON_ONCE(current->journal_info); WARN_ON_ONCE(current->journal_info);
current->journal_info = &tr; current->journal_info = &tr;
__gfs2_ail_flush(gl, 0); __gfs2_ail_flush(gl, 0, tr.tr_revokes);
gfs2_trans_end(sdp); gfs2_trans_end(sdp);
gfs2_log_flush(sdp, NULL); gfs2_log_flush(sdp, NULL);
...@@ -101,15 +105,19 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) ...@@ -101,15 +105,19 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
{ {
struct gfs2_sbd *sdp = gl->gl_sbd; struct gfs2_sbd *sdp = gl->gl_sbd;
unsigned int revokes = atomic_read(&gl->gl_ail_count); 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; int ret;
if (!revokes) if (!revokes)
return; 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) if (ret)
return; return;
__gfs2_ail_flush(gl, fsync); __gfs2_ail_flush(gl, fsync, max_revokes);
gfs2_trans_end(sdp); gfs2_trans_end(sdp);
gfs2_log_flush(sdp, NULL); gfs2_log_flush(sdp, NULL);
} }
......
...@@ -594,7 +594,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, ...@@ -594,7 +594,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
} }
gfs2_glock_dq_uninit(ghs); gfs2_glock_dq_uninit(ghs);
if (IS_ERR(d)) if (IS_ERR(d))
return PTR_RET(d); return PTR_ERR(d);
return error; return error;
} else if (error != -ENOENT) { } else if (error != -ENOENT) {
goto fail_gunlock; goto fail_gunlock;
...@@ -1750,6 +1750,10 @@ static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name, ...@@ -1750,6 +1750,10 @@ static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name,
struct gfs2_holder gh; struct gfs2_holder gh;
int ret; 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); gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh);
ret = gfs2_glock_nq(&gh); ret = gfs2_glock_nq(&gh);
if (ret == 0) { if (ret == 0) {
......
...@@ -155,7 +155,7 @@ static int __init init_gfs2_fs(void) ...@@ -155,7 +155,7 @@ static int __init init_gfs2_fs(void)
goto fail_wq; goto fail_wq;
gfs2_control_wq = alloc_workqueue("gfs2_control", gfs2_control_wq = alloc_workqueue("gfs2_control",
WQ_NON_REENTRANT | WQ_UNBOUND | WQ_FREEZABLE, 0); WQ_UNBOUND | WQ_FREEZABLE, 0);
if (!gfs2_control_wq) if (!gfs2_control_wq)
goto fail_recovery; goto fail_recovery;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment