diff options
author | Benjamin Marzinski <bmarzins@redhat.com> | 2010-11-23 23:52:55 -0600 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2010-11-30 15:41:54 +0000 |
commit | 086d8334cf73b3bb695b82dd864a7a8b00d96b7e (patch) | |
tree | acadf5458a2ccfde44049bcb7ba63e136844f875 | |
parent | 0489b3f5eba735413ccedd425651cf41d6b1f7c5 (diff) | |
download | op-kernel-dev-086d8334cf73b3bb695b82dd864a7a8b00d96b7e.zip op-kernel-dev-086d8334cf73b3bb695b82dd864a7a8b00d96b7e.tar.gz |
GFS2: fix recursive locking during rindex truncates
When you truncate the rindex file, you need to avoid calling gfs2_rindex_hold,
since you already hold it. However, if you haven't already read in the
resource groups, you need to do that.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r-- | fs/gfs2/bmap.c | 9 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 2 | ||||
-rw-r--r-- | fs/gfs2/rgrp.h | 1 |
3 files changed, 9 insertions, 3 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 5476c06..ae7d205 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -780,7 +780,11 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, if (metadata) revokes = (height) ? sdp->sd_inptrs : sdp->sd_diptrs; - error = gfs2_rindex_hold(sdp, &ip->i_alloc->al_ri_gh); + if (ip != GFS2_I(sdp->sd_rindex)) + error = gfs2_rindex_hold(sdp, &ip->i_alloc->al_ri_gh); + else if (!sdp->sd_rgrps) + error = gfs2_ri_update(ip); + if (error) return error; @@ -879,7 +883,8 @@ out_rg_gunlock: out_rlist: gfs2_rlist_free(&rlist); out: - gfs2_glock_dq_uninit(&ip->i_alloc->al_ri_gh); + if (ip != GFS2_I(sdp->sd_rindex)) + gfs2_glock_dq_uninit(&ip->i_alloc->al_ri_gh); return error; } diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 6375b38..25dbe5c 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -583,7 +583,7 @@ static int read_rindex_entry(struct gfs2_inode *ip, * Returns: 0 on successful update, error code otherwise */ -static int gfs2_ri_update(struct gfs2_inode *ip) +int gfs2_ri_update(struct gfs2_inode *ip) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct inode *inode = &ip->i_inode; diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index 0e35c04..50c2bb0 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h @@ -48,6 +48,7 @@ extern int gfs2_inplace_reserve_i(struct gfs2_inode *ip, int hold_rindex, extern void gfs2_inplace_release(struct gfs2_inode *ip); +extern int gfs2_ri_update(struct gfs2_inode *ip); extern int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n); extern int gfs2_alloc_di(struct gfs2_inode *ip, u64 *bn, u64 *generation); |