aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2009-07-10 16:13:38 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2009-07-30 05:59:50 -0400
commit1e19a19584b332eb92a573b66b7342fb97e67507 (patch)
treec02ad1ff429ba770da8bee47c5444be829729666
parenta51b56fff3f04fc5aa66b21a2a6d693ee9862d66 (diff)
GFS2: Don't try and dealloc own inode
When searching for unlinked, but still allocated inodes during block allocation, avoid the block relating to the inode that is doing the allocation. This fixes a hang caused when an unlinked, but still open, inode tries to allocate some more blocks and lands up finding itself during the search for deallocatable inodes. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/rgrp.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index daa4ae341a29..5e5074176daa 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -961,7 +961,8 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al)
961 * Returns: The inode, if one has been found 961 * Returns: The inode, if one has been found
962 */ 962 */
963 963
964static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) 964static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked,
965 u64 skip)
965{ 966{
966 struct inode *inode; 967 struct inode *inode;
967 u32 goal = 0, block; 968 u32 goal = 0, block;
@@ -985,6 +986,8 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked)
985 goal++; 986 goal++;
986 if (*last_unlinked != NO_BLOCK && no_addr <= *last_unlinked) 987 if (*last_unlinked != NO_BLOCK && no_addr <= *last_unlinked)
987 continue; 988 continue;
989 if (no_addr == skip)
990 continue;
988 *last_unlinked = no_addr; 991 *last_unlinked = no_addr;
989 inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, 992 inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN,
990 no_addr, -1, 1); 993 no_addr, -1, 1);
@@ -1104,7 +1107,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1104 if (try_rgrp_fit(rgd, al)) 1107 if (try_rgrp_fit(rgd, al))
1105 goto out; 1108 goto out;
1106 if (rgd->rd_flags & GFS2_RDF_CHECK) 1109 if (rgd->rd_flags & GFS2_RDF_CHECK)
1107 inode = try_rgrp_unlink(rgd, last_unlinked); 1110 inode = try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr);
1108 if (!rg_locked) 1111 if (!rg_locked)
1109 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1112 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1110 if (inode) 1113 if (inode)
@@ -1138,7 +1141,7 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1138 if (try_rgrp_fit(rgd, al)) 1141 if (try_rgrp_fit(rgd, al))
1139 goto out; 1142 goto out;
1140 if (rgd->rd_flags & GFS2_RDF_CHECK) 1143 if (rgd->rd_flags & GFS2_RDF_CHECK)
1141 inode = try_rgrp_unlink(rgd, last_unlinked); 1144 inode = try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr);
1142 if (!rg_locked) 1145 if (!rg_locked)
1143 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1146 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1144 if (inode) 1147 if (inode)