diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2009-07-10 16:13:38 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2009-07-30 05:59:50 -0400 |
commit | 1e19a19584b332eb92a573b66b7342fb97e67507 (patch) | |
tree | c02ad1ff429ba770da8bee47c5444be829729666 | |
parent | a51b56fff3f04fc5aa66b21a2a6d693ee9862d66 (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.c | 9 |
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 | ||
964 | static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked) | 964 | static 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) |