aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/rgrp.c
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2010-05-20 23:30:11 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2010-05-21 11:11:36 -0400
commited4878e8a4f550fd357ce5144cfd412015f6a111 (patch)
tree897124839ad6b529c42601037dee74d16abe941a /fs/gfs2/rgrp.c
parentd7dbf4ffee1c7a17e2e5b5f01efe76fbd1671db6 (diff)
GFS2: Rework reclaiming unlinked dinodes
The previous patch I wrote for reclaiming unlinked dinodes had some shortcomings and did not prevent all hangs. This version is much cleaner and more logical, and has passed very difficult testing. Sorry for the churn. Signed-off-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r--fs/gfs2/rgrp.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 8bce73ed4d8e..6daf4c65a3c8 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -1191,7 +1191,6 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
1191{ 1191{
1192 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1192 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1193 struct gfs2_alloc *al = ip->i_alloc; 1193 struct gfs2_alloc *al = ip->i_alloc;
1194 struct inode *inode;
1195 int error = 0; 1194 int error = 0;
1196 u64 last_unlinked = NO_BLOCK, unlinked; 1195 u64 last_unlinked = NO_BLOCK, unlinked;
1197 1196
@@ -1209,22 +1208,27 @@ try_again:
1209 if (error) 1208 if (error)
1210 return error; 1209 return error;
1211 1210
1211 /* Find an rgrp suitable for allocation. If it encounters any unlinked
1212 dinodes along the way, error will equal -EAGAIN and unlinked will
1213 contains it block address. We then need to look up that inode and
1214 try to free it, and try the allocation again. */
1212 error = get_local_rgrp(ip, &unlinked, &last_unlinked); 1215 error = get_local_rgrp(ip, &unlinked, &last_unlinked);
1213 if (error) { 1216 if (error) {
1214 if (ip != GFS2_I(sdp->sd_rindex)) 1217 if (ip != GFS2_I(sdp->sd_rindex))
1215 gfs2_glock_dq_uninit(&al->al_ri_gh); 1218 gfs2_glock_dq_uninit(&al->al_ri_gh);
1216 if (error != -EAGAIN) 1219 if (error != -EAGAIN)
1217 return error; 1220 return error;
1218 error = gfs2_unlinked_inode_lookup(ip->i_inode.i_sb, 1221
1219 unlinked, &inode); 1222 gfs2_process_unlinked_inode(ip->i_inode.i_sb, unlinked);
1220 if (inode) 1223 /* regardless of whether or not gfs2_process_unlinked_inode
1221 iput(inode); 1224 was successful, we don't want to repeat it again. */
1225 last_unlinked = unlinked;
1222 gfs2_log_flush(sdp, NULL); 1226 gfs2_log_flush(sdp, NULL);
1223 if (error == GLR_TRYFAILED) 1227 error = 0;
1224 error = 0; 1228
1225 goto try_again; 1229 goto try_again;
1226 } 1230 }
1227 1231 /* no error, so we have the rgrp set in the inode's allocation. */
1228 al->al_file = file; 1232 al->al_file = file;
1229 al->al_line = line; 1233 al->al_line = line;
1230 1234