summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2009-08-07 19:51:33 +0200
committerChris Mason <chris.mason@oracle.com>2009-08-07 19:51:33 +0200
commitceab36edd3d3ad3ffd01d41d6d1e05ac1ff8357e (patch)
treea6d899030878d52ae6d7932e459deece3524c787 /fs
parentBtrfs: correct error-handling zlib error handling (diff)
downloadlinux-ceab36edd3d3ad3ffd01d41d6d1e05ac1ff8357e.tar.xz
linux-ceab36edd3d3ad3ffd01d41d6d1e05ac1ff8357e.zip
Btrfs: fix balancing oops when invalidate_inode_pages2 returns EBUSY
invalidate_inode_pages2_range may return -EBUSY occasionally which results Oops. This patch fixes the issue by moving invalidate_inode_pages2_range into a loop and keeping calling it until the return value is not -EBUSY. The EBUSY return is temporary, and can happen when the btrfs release page function is unable to release a page because the EXTENT_LOCK bit is set. Signed-off-by: Yan Zheng <zheng.yan@oracle.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/relocation.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index e71264d1c2c9..c04f7f212602 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2553,8 +2553,13 @@ int relocate_inode_pages(struct inode *inode, u64 start, u64 len)
last_index = (start + len - 1) >> PAGE_CACHE_SHIFT;
/* make sure the dirty trick played by the caller work */
- ret = invalidate_inode_pages2_range(inode->i_mapping,
- first_index, last_index);
+ while (1) {
+ ret = invalidate_inode_pages2_range(inode->i_mapping,
+ first_index, last_index);
+ if (ret != -EBUSY)
+ break;
+ schedule_timeout(HZ/10);
+ }
if (ret)
goto out_unlock;