summaryrefslogtreecommitdiffstats
path: root/fs/gfs2/super.c
diff options
context:
space:
mode:
authorSteven Whitehouse2009-09-08 19:00:30 +0200
committerSteven Whitehouse2009-09-08 19:00:30 +0200
commitacf7e2444acfaf4c8540603b76d71010eea3fc24 (patch)
tree7c31957ffbbb4008f368b8640c289f72657330a5 /fs/gfs2/super.c
parentGFS2: Remove no_formal_ino generating code (diff)
downloadkernel-qcow2-linux-acf7e2444acfaf4c8540603b76d71010eea3fc24.tar.gz
kernel-qcow2-linux-acf7e2444acfaf4c8540603b76d71010eea3fc24.tar.xz
kernel-qcow2-linux-acf7e2444acfaf4c8540603b76d71010eea3fc24.zip
GFS2: Be extra careful about deallocating inodes
There is a potential race in the inode deallocation code if two nodes try to deallocate the same inode at the same time. Most of the issue is solved by the iopen locking. There is still a small window which is not covered by the iopen lock. This patches fixes that and also makes the deallocation code more robust in the face of any errors in the rgrp bitmaps, or erroneous iopen callbacks from other nodes. This does introduce one extra disk read, but that is generally not an issue since its the same block that must be written to later in the deallocation process. The total disk accesses therefore stay the same, Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/super.c')
-rw-r--r--fs/gfs2/super.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index d95cf777d244..0ec3ec672de1 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1286,6 +1286,10 @@ static void gfs2_delete_inode(struct inode *inode)
goto out;
}
+ error = gfs2_check_blk_type(sdp, ip->i_no_addr, GFS2_BLKST_UNLINKED);
+ if (error)
+ goto out_truncate;
+
gfs2_glock_dq_wait(&ip->i_iopen_gh);
gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh);
error = gfs2_glock_nq(&ip->i_iopen_gh);