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) |
