diff options
author | Bob Peterson <rpeterso@redhat.com> | 2010-05-20 23:30:11 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2010-05-21 16:11:36 +0100 |
commit | ed4878e8a4f550fd357ce5144cfd412015f6a111 (patch) | |
tree | 897124839ad6b529c42601037dee74d16abe941a /fs/gfs2/rgrp.c | |
parent | d7dbf4ffee1c7a17e2e5b5f01efe76fbd1671db6 (diff) | |
download | lwn-ed4878e8a4f550fd357ce5144cfd412015f6a111.tar.gz lwn-ed4878e8a4f550fd357ce5144cfd412015f6a111.zip |
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.c | 20 |
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) { struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); struct gfs2_alloc *al = ip->i_alloc; - struct inode *inode; int error = 0; u64 last_unlinked = NO_BLOCK, unlinked; @@ -1209,22 +1208,27 @@ try_again: if (error) return error; + /* Find an rgrp suitable for allocation. If it encounters any unlinked + dinodes along the way, error will equal -EAGAIN and unlinked will + contains it block address. We then need to look up that inode and + try to free it, and try the allocation again. */ error = get_local_rgrp(ip, &unlinked, &last_unlinked); if (error) { if (ip != GFS2_I(sdp->sd_rindex)) gfs2_glock_dq_uninit(&al->al_ri_gh); if (error != -EAGAIN) return error; - error = gfs2_unlinked_inode_lookup(ip->i_inode.i_sb, - unlinked, &inode); - if (inode) - iput(inode); + + gfs2_process_unlinked_inode(ip->i_inode.i_sb, unlinked); + /* regardless of whether or not gfs2_process_unlinked_inode + was successful, we don't want to repeat it again. */ + last_unlinked = unlinked; gfs2_log_flush(sdp, NULL); - if (error == GLR_TRYFAILED) - error = 0; + error = 0; + goto try_again; } - + /* no error, so we have the rgrp set in the inode's allocation. */ al->al_file = file; al->al_line = line; |