Commit e402746a authored by Steven Whitehouse's avatar Steven Whitehouse

GFS2: Wait for unlock completion on umount

This patch adds a wait on umount between the point at which we
dispose of all glocks and the point at which we unmount the
lock protocol. This ensures that we've received all the replies
to our unlock requests before we stop the locking.
Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
Reported-by: default avatarFabio M. Di Nitto <fdinitto@redhat.com>
parent 1a45dcfe
...@@ -544,6 +544,8 @@ struct gfs2_sbd { ...@@ -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 */
......
...@@ -21,6 +21,7 @@ static void gdlm_ast(void *arg) ...@@ -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) ...@@ -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;
...@@ -167,7 +170,8 @@ static unsigned int gdlm_lock(struct gfs2_glock *gl, ...@@ -167,7 +170,8 @@ static unsigned int gdlm_lock(struct gfs2_glock *gl,
static void gdlm_put_lock(struct kmem_cache *cachep, void *ptr) static void gdlm_put_lock(struct kmem_cache *cachep, void *ptr)
{ {
struct gfs2_glock *gl = ptr; struct gfs2_glock *gl = ptr;
struct lm_lockstruct *ls = &gl->gl_sbd->sd_lockstruct; struct gfs2_sbd *sdp = gl->gl_sbd;
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) {
...@@ -183,6 +187,7 @@ static void gdlm_put_lock(struct kmem_cache *cachep, void *ptr) ...@@ -183,6 +187,7 @@ static void gdlm_put_lock(struct kmem_cache *cachep, void *ptr)
(unsigned long long)gl->gl_name.ln_number, error); (unsigned long long)gl->gl_name.ln_number, error);
return; return;
} }
atomic_inc(&sdp->sd_glock_disposal);
} }
static void gdlm_cancel(struct gfs2_glock *gl) static void gdlm_cancel(struct gfs2_glock *gl)
......
...@@ -82,6 +82,8 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) ...@@ -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);
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/gfs2_ondisk.h> #include <linux/gfs2_ondisk.h>
#include <linux/crc32.h> #include <linux/crc32.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/wait.h>
#include "gfs2.h" #include "gfs2.h"
#include "incore.h" #include "incore.h"
...@@ -860,6 +861,8 @@ static void gfs2_put_super(struct super_block *sb) ...@@ -860,6 +861,8 @@ static void gfs2_put_super(struct super_block *sb)
gfs2_jindex_free(sdp); gfs2_jindex_free(sdp);
/* Take apart glock structures and buffer lists */ /* Take apart glock structures and buffer lists */
gfs2_gl_hash_clear(sdp); gfs2_gl_hash_clear(sdp);
/* Wait for dlm to reply to all our unlock requests */
wait_event(sdp->sd_glock_wait, atomic_read(&sdp->sd_glock_disposal) == 0);
/* Unmount the locking protocol */ /* Unmount the locking protocol */
gfs2_lm_unmount(sdp); gfs2_lm_unmount(sdp);
......
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