aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2007-07-12 17:58:50 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-08-14 05:32:43 -0400
commit24c7387333c77b602ece7ecd6a85fc94f8f16d8c (patch)
tree8fd9bba4310f176d8c538e2a22c083882b10dec5 /fs/gfs2
parentbdcb88562ca90e6cfac13130e147c63aaa4f9e41 (diff)
[GFS2] soft lockup in rgblk_search
This patch seems to fix the problem described in bugzilla bug 246114. It was written by Steve Whitehouse with some tweaking by me. The code was looping in the relatively new section of code designed to search for and reuse unlinked inodes. In cases where it was finding an appropriate inode to reuse, it was looping around and finding the same block over and over because a "<=" check should have been a "<" when comparing the goal block to the last unlinked block found. Signed-off-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-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 e4e040625153..bb58e69fd977 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -863,16 +863,19 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked)
863 u64 no_addr; 863 u64 no_addr;
864 864
865 for(;;) { 865 for(;;) {
866 if (goal >= rgd->rd_data)
867 break;
866 goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED, 868 goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED,
867 GFS2_BLKST_UNLINKED); 869 GFS2_BLKST_UNLINKED);
868 if (goal == 0) 870 if (goal == 0)
869 return 0; 871 break;
870 no_addr = goal + rgd->rd_data0; 872 no_addr = goal + rgd->rd_data0;
871 if (no_addr <= *last_unlinked) 873 goal++;
874 if (no_addr < *last_unlinked)
872 continue; 875 continue;
873 *last_unlinked = no_addr; 876 *last_unlinked = no_addr;
874 inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, 877 inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN,
875 no_addr, -1); 878 no_addr, -1);
876 if (!IS_ERR(inode)) 879 if (!IS_ERR(inode))
877 return inode; 880 return inode;
878 } 881 }