aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glock.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2007-01-29 06:51:45 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2007-02-05 13:38:14 -0500
commit61be084efcc4451934257350281962595418a33c (patch)
tree3f7b3e0d93f52803f27aa3268a4bd7098e48ae4d /fs/gfs2/glock.c
parentbbb28ab7599789740b2233a0805d22aefb97f533 (diff)
[GFS2] Put back semaphore to avoid umount problem
Dave Teigland fixed this bug a while back, but I managed to mistakenly remove the semaphore during later development. It is required to avoid the list of inodes changing during an invalidate_inodes call. I have made it an rwsem since the read side will be taken frequently during normal filesystem operation. The write site will only happen during umount of the file system. Also the bug only triggers when using the DLM lock manager and only then under certain conditions as its timing related. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com> Cc: David Teigland <teigland@redhat.com>
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r--fs/gfs2/glock.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index c070ede531c5..6618c1190252 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -20,6 +20,7 @@
20#include <linux/list.h> 20#include <linux/list.h>
21#include <linux/lm_interface.h> 21#include <linux/lm_interface.h>
22#include <linux/wait.h> 22#include <linux/wait.h>
23#include <linux/rwsem.h>
23#include <asm/uaccess.h> 24#include <asm/uaccess.h>
24 25
25#include "gfs2.h" 26#include "gfs2.h"
@@ -45,6 +46,7 @@ static int dump_glock(struct gfs2_glock *gl);
45static int dump_inode(struct gfs2_inode *ip); 46static int dump_inode(struct gfs2_inode *ip);
46static void gfs2_glock_xmote_th(struct gfs2_holder *gh); 47static void gfs2_glock_xmote_th(struct gfs2_holder *gh);
47static void gfs2_glock_drop_th(struct gfs2_glock *gl); 48static void gfs2_glock_drop_th(struct gfs2_glock *gl);
49static DECLARE_RWSEM(gfs2_umount_flush_sem);
48 50
49#define GFS2_GL_HASH_SHIFT 15 51#define GFS2_GL_HASH_SHIFT 15
50#define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT) 52#define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT)
@@ -1578,12 +1580,14 @@ void gfs2_glock_cb(void *cb_data, unsigned int type, void *data)
1578 struct lm_async_cb *async = data; 1580 struct lm_async_cb *async = data;
1579 struct gfs2_glock *gl; 1581 struct gfs2_glock *gl;
1580 1582
1583 down_read(&gfs2_umount_flush_sem);
1581 gl = gfs2_glock_find(sdp, &async->lc_name); 1584 gl = gfs2_glock_find(sdp, &async->lc_name);
1582 if (gfs2_assert_warn(sdp, gl)) 1585 if (gfs2_assert_warn(sdp, gl))
1583 return; 1586 return;
1584 if (!gfs2_assert_warn(sdp, gl->gl_req_bh)) 1587 if (!gfs2_assert_warn(sdp, gl->gl_req_bh))
1585 gl->gl_req_bh(gl, async->lc_ret); 1588 gl->gl_req_bh(gl, async->lc_ret);
1586 gfs2_glock_put(gl); 1589 gfs2_glock_put(gl);
1590 up_read(&gfs2_umount_flush_sem);
1587 return; 1591 return;
1588 } 1592 }
1589 1593
@@ -1828,7 +1832,9 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait)
1828 t = jiffies; 1832 t = jiffies;
1829 } 1833 }
1830 1834
1835 down_write(&gfs2_umount_flush_sem);
1831 invalidate_inodes(sdp->sd_vfs); 1836 invalidate_inodes(sdp->sd_vfs);
1837 up_write(&gfs2_umount_flush_sem);
1832 msleep(10); 1838 msleep(10);
1833 } 1839 }
1834} 1840}