aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2009-01-21 10:49:16 -0500
committerChris Mason <chris.mason@oracle.com>2009-01-21 10:49:16 -0500
commit86288a198d8e4e8411ff02f9ab848245e8f11257 (patch)
treef580414864d322799a750a1dcc371f6dd62ce543
parent95029d7d598babf62276d9006e575992b1333ba5 (diff)
Btrfs: fix stop searching test in replace_one_extent
replace_one_extent searches tree leaves for references to a given extent. It stops searching if it goes beyond the last possible position. The last possible position is computed by adding the starting offset of a found file extent to the full size of the extent. The code uses physical size of the extent as the full size. This is incorrect when compression is used. The fix is get the full size from ram_bytes field of file extent item. Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
-rw-r--r--fs/btrfs/extent-tree.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index c643433629a7..1d7f043152b0 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4440,7 +4440,7 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans,
4440 u64 lock_end = 0; 4440 u64 lock_end = 0;
4441 u64 num_bytes; 4441 u64 num_bytes;
4442 u64 ext_offset; 4442 u64 ext_offset;
4443 u64 first_pos; 4443 u64 search_end = (u64)-1;
4444 u32 nritems; 4444 u32 nritems;
4445 int nr_scaned = 0; 4445 int nr_scaned = 0;
4446 int extent_locked = 0; 4446 int extent_locked = 0;
@@ -4448,7 +4448,6 @@ static noinline int replace_one_extent(struct btrfs_trans_handle *trans,
4448 int ret; 4448 int ret;
4449 4449
4450 memcpy(&key, leaf_key, sizeof(key)); 4450 memcpy(&key, leaf_key, sizeof(key));
4451 first_pos = INT_LIMIT(loff_t) - extent_key->offset;
4452 if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS) { 4451 if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS) {
4453 if (key.objectid < ref_path->owner_objectid || 4452 if (key.objectid < ref_path->owner_objectid ||
4454 (key.objectid == ref_path->owner_objectid && 4453 (key.objectid == ref_path->owner_objectid &&
@@ -4497,7 +4496,7 @@ next:
4497 if ((key.objectid > ref_path->owner_objectid) || 4496 if ((key.objectid > ref_path->owner_objectid) ||
4498 (key.objectid == ref_path->owner_objectid && 4497 (key.objectid == ref_path->owner_objectid &&
4499 key.type > BTRFS_EXTENT_DATA_KEY) || 4498 key.type > BTRFS_EXTENT_DATA_KEY) ||
4500 (key.offset >= first_pos + extent_key->offset)) 4499 key.offset >= search_end)
4501 break; 4500 break;
4502 } 4501 }
4503 4502
@@ -4530,8 +4529,10 @@ next:
4530 num_bytes = btrfs_file_extent_num_bytes(leaf, fi); 4529 num_bytes = btrfs_file_extent_num_bytes(leaf, fi);
4531 ext_offset = btrfs_file_extent_offset(leaf, fi); 4530 ext_offset = btrfs_file_extent_offset(leaf, fi);
4532 4531
4533 if (first_pos > key.offset - ext_offset) 4532 if (search_end == (u64)-1) {
4534 first_pos = key.offset - ext_offset; 4533 search_end = key.offset - ext_offset +
4534 btrfs_file_extent_ram_bytes(leaf, fi);
4535 }
4535 4536
4536 if (!extent_locked) { 4537 if (!extent_locked) {
4537 lock_start = key.offset; 4538 lock_start = key.offset;
@@ -4720,7 +4721,7 @@ next:
4720 } 4721 }
4721skip: 4722skip:
4722 if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS && 4723 if (ref_path->owner_objectid != BTRFS_MULTIPLE_OBJECTIDS &&
4723 key.offset >= first_pos + extent_key->offset) 4724 key.offset >= search_end)
4724 break; 4725 break;
4725 4726
4726 cond_resched(); 4727 cond_resched();