Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d6a5e06c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -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);
+13 −5
Original line number Diff line number Diff line
@@ -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);
}
+5 −1
Original line number Diff line number Diff line
@@ -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) {
+1 −1
Original line number Diff line number Diff line
@@ -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;