diff options
author | Yan Zheng <zheng.yan@oracle.com> | 2009-08-07 13:51:33 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2009-08-07 13:51:33 -0400 |
commit | ceab36edd3d3ad3ffd01d41d6d1e05ac1ff8357e (patch) | |
tree | a6d899030878d52ae6d7932e459deece3524c787 | |
parent | 60f2e8f8a07331097a57ec4abcdc680405579377 (diff) |
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>
-rw-r--r-- | fs/btrfs/relocation.c | 9 |
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; |