aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2012-11-13 10:58:56 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2012-11-14 04:37:04 -0500
commitfb6791d100d1bba20b5cdbc4912e1f7086ec60f8 (patch)
tree939570529b651b02ab06b491d4a672fa4bcc5ebc
parentaa8920c96897dd82f0520f9e7db7311b42547ce6 (diff)
GFS2: skip dlm_unlock calls in unmount
When unmounting, gfs2 does a full dlm_unlock operation on every cached lock. This can create a very large amount of work and can take a long time to complete. However, the vast majority of these dlm unlock operations are unnecessary because after all the unlocks are done, gfs2 leaves the dlm lockspace, which automatically clears the locks of the leaving node, without unlocking each one individually. So, gfs2 can skip explicit dlm unlocks, and use dlm_release_lockspace to remove the locks implicitly. The one exception is when the lock's lvb is being used. In this case, dlm_unlock is called because it may update the lvb of the resource. Signed-off-by: David Teigland <teigland@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/glock.c1
-rw-r--r--fs/gfs2/incore.h1
-rw-r--r--fs/gfs2/lock_dlm.c8
3 files changed, 10 insertions, 0 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 6114571a979a..9d29a5167d34 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -1526,6 +1526,7 @@ static void dump_glock_func(struct gfs2_glock *gl)
1526 1526
1527void gfs2_gl_hash_clear(struct gfs2_sbd *sdp) 1527void gfs2_gl_hash_clear(struct gfs2_sbd *sdp)
1528{ 1528{
1529 set_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags);
1529 glock_hash_walk(clear_glock, sdp); 1530 glock_hash_walk(clear_glock, sdp);
1530 flush_workqueue(glock_workqueue); 1531 flush_workqueue(glock_workqueue);
1531 wait_event(sdp->sd_glock_wait, atomic_read(&sdp->sd_glock_disposal) == 0); 1532 wait_event(sdp->sd_glock_wait, atomic_read(&sdp->sd_glock_disposal) == 0);
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index a46f03485936..a35ef5cd1480 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -539,6 +539,7 @@ enum {
539 SDF_DEMOTE = 5, 539 SDF_DEMOTE = 5,
540 SDF_NOJOURNALID = 6, 540 SDF_NOJOURNALID = 6,
541 SDF_RORECOVERY = 7, /* read only recovery */ 541 SDF_RORECOVERY = 7, /* read only recovery */
542 SDF_SKIP_DLM_UNLOCK = 8,
542}; 543};
543 544
544#define GFS2_FSNAME_LEN 256 545#define GFS2_FSNAME_LEN 256
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c
index 0fb6539b0c8c..f6504d3fadb3 100644
--- a/fs/gfs2/lock_dlm.c
+++ b/fs/gfs2/lock_dlm.c
@@ -289,6 +289,14 @@ static void gdlm_put_lock(struct gfs2_glock *gl)
289 gfs2_glstats_inc(gl, GFS2_LKS_DCOUNT); 289 gfs2_glstats_inc(gl, GFS2_LKS_DCOUNT);
290 gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT); 290 gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT);
291 gfs2_update_request_times(gl); 291 gfs2_update_request_times(gl);
292
293 /* don't want to skip dlm_unlock writing the lvb when lock is ex */
294 if (test_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags) &&
295 gl->gl_state != LM_ST_EXCLUSIVE) {
296 gfs2_glock_free(gl);
297 return;
298 }
299
292 error = dlm_unlock(ls->ls_dlm, gl->gl_lksb.sb_lkid, DLM_LKF_VALBLK, 300 error = dlm_unlock(ls->ls_dlm, gl->gl_lksb.sb_lkid, DLM_LKF_VALBLK,
293 NULL, gl); 301 NULL, gl);
294 if (error) { 302 if (error) {