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

Commit a3a71ca9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes:
  GFS2: Extend umount wait coverage to full glock lifetime
  GFS2: Wait for unlock completion on umount
parents 6f14a668 8f05228e
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -769,6 +769,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
	if (!gl)
	if (!gl)
		return -ENOMEM;
		return -ENOMEM;


	atomic_inc(&sdp->sd_glock_disposal);
	gl->gl_flags = 0;
	gl->gl_flags = 0;
	gl->gl_name = name;
	gl->gl_name = name;
	atomic_set(&gl->gl_ref, 1);
	atomic_set(&gl->gl_ref, 1);
@@ -1538,6 +1539,9 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp)
		up_write(&gfs2_umount_flush_sem);
		up_write(&gfs2_umount_flush_sem);
		msleep(10);
		msleep(10);
	}
	}
	flush_workqueue(glock_workqueue);
	wait_event(sdp->sd_glock_wait, atomic_read(&sdp->sd_glock_disposal) == 0);
	gfs2_dump_lockstate(sdp);
}
}


void gfs2_glock_finish_truncate(struct gfs2_inode *ip)
void gfs2_glock_finish_truncate(struct gfs2_inode *ip)
+1 −1
Original line number Original line Diff line number Diff line
@@ -123,7 +123,7 @@ struct lm_lockops {
	int (*lm_mount) (struct gfs2_sbd *sdp, const char *fsname);
	int (*lm_mount) (struct gfs2_sbd *sdp, const char *fsname);
 	void (*lm_unmount) (struct gfs2_sbd *sdp);
 	void (*lm_unmount) (struct gfs2_sbd *sdp);
	void (*lm_withdraw) (struct gfs2_sbd *sdp);
	void (*lm_withdraw) (struct gfs2_sbd *sdp);
	void (*lm_put_lock) (struct kmem_cache *cachep, void *gl);
	void (*lm_put_lock) (struct kmem_cache *cachep, struct gfs2_glock *gl);
	unsigned int (*lm_lock) (struct gfs2_glock *gl,
	unsigned int (*lm_lock) (struct gfs2_glock *gl,
				 unsigned int req_state, unsigned int flags);
				 unsigned int req_state, unsigned int flags);
	void (*lm_cancel) (struct gfs2_glock *gl);
	void (*lm_cancel) (struct gfs2_glock *gl);
+2 −0
Original line number Original line Diff line number Diff line
@@ -544,6 +544,8 @@ struct gfs2_sbd {
	struct gfs2_holder sd_live_gh;
	struct gfs2_holder sd_live_gh;
	struct gfs2_glock *sd_rename_gl;
	struct gfs2_glock *sd_rename_gl;
	struct gfs2_glock *sd_trans_gl;
	struct gfs2_glock *sd_trans_gl;
	wait_queue_head_t sd_glock_wait;
	atomic_t sd_glock_disposal;


	/* Inode Stuff */
	/* Inode Stuff */


+8 −3
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@ static void gdlm_ast(void *arg)
{
{
	struct gfs2_glock *gl = arg;
	struct gfs2_glock *gl = arg;
	unsigned ret = gl->gl_state;
	unsigned ret = gl->gl_state;
	struct gfs2_sbd *sdp = gl->gl_sbd;


	BUG_ON(gl->gl_lksb.sb_flags & DLM_SBF_DEMOTED);
	BUG_ON(gl->gl_lksb.sb_flags & DLM_SBF_DEMOTED);


@@ -30,6 +31,8 @@ static void gdlm_ast(void *arg)
	switch (gl->gl_lksb.sb_status) {
	switch (gl->gl_lksb.sb_status) {
	case -DLM_EUNLOCK: /* Unlocked, so glock can be freed */
	case -DLM_EUNLOCK: /* Unlocked, so glock can be freed */
		kmem_cache_free(gfs2_glock_cachep, gl);
		kmem_cache_free(gfs2_glock_cachep, gl);
		if (atomic_dec_and_test(&sdp->sd_glock_disposal))
			wake_up(&sdp->sd_glock_wait);
		return;
		return;
	case -DLM_ECANCEL: /* Cancel while getting lock */
	case -DLM_ECANCEL: /* Cancel while getting lock */
		ret |= LM_OUT_CANCELED;
		ret |= LM_OUT_CANCELED;
@@ -164,14 +167,16 @@ static unsigned int gdlm_lock(struct gfs2_glock *gl,
	return LM_OUT_ASYNC;
	return LM_OUT_ASYNC;
}
}


static void gdlm_put_lock(struct kmem_cache *cachep, void *ptr)
static void gdlm_put_lock(struct kmem_cache *cachep, struct gfs2_glock *gl)
{
{
	struct gfs2_glock *gl = ptr;
	struct gfs2_sbd *sdp = gl->gl_sbd;
	struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct;
	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
	int error;
	int error;


	if (gl->gl_lksb.sb_lkid == 0) {
	if (gl->gl_lksb.sb_lkid == 0) {
		kmem_cache_free(cachep, gl);
		kmem_cache_free(cachep, gl);
		if (atomic_dec_and_test(&sdp->sd_glock_disposal))
			wake_up(&sdp->sd_glock_wait);
		return;
		return;
	}
	}


+11 −1
Original line number Original line Diff line number Diff line
@@ -82,6 +82,8 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)


	gfs2_tune_init(&sdp->sd_tune);
	gfs2_tune_init(&sdp->sd_tune);


	init_waitqueue_head(&sdp->sd_glock_wait);
	atomic_set(&sdp->sd_glock_disposal, 0);
	spin_lock_init(&sdp->sd_statfs_spin);
	spin_lock_init(&sdp->sd_statfs_spin);


	spin_lock_init(&sdp->sd_rindex_spin);
	spin_lock_init(&sdp->sd_rindex_spin);
@@ -983,9 +985,17 @@ static const match_table_t nolock_tokens = {
	{ Opt_err, NULL },
	{ Opt_err, NULL },
};
};


static void nolock_put_lock(struct kmem_cache *cachep, struct gfs2_glock *gl)
{
	struct gfs2_sbd *sdp = gl->gl_sbd;
	kmem_cache_free(cachep, gl);
	if (atomic_dec_and_test(&sdp->sd_glock_disposal))
		wake_up(&sdp->sd_glock_wait);
}

static const struct lm_lockops nolock_ops = {
static const struct lm_lockops nolock_ops = {
	.lm_proto_name = "lock_nolock",
	.lm_proto_name = "lock_nolock",
	.lm_put_lock = kmem_cache_free,
	.lm_put_lock = nolock_put_lock,
	.lm_tokens = &nolock_tokens,
	.lm_tokens = &nolock_tokens,
};
};


Loading