diff options
-rw-r--r-- | fs/btrfs/backref.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 34a8952de8dd..dcf2448c16f1 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -1302,20 +1302,45 @@ int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical, | |||
1302 | ret = btrfs_search_slot(NULL, fs_info->extent_root, &key, path, 0, 0); | 1302 | ret = btrfs_search_slot(NULL, fs_info->extent_root, &key, path, 0, 0); |
1303 | if (ret < 0) | 1303 | if (ret < 0) |
1304 | return ret; | 1304 | return ret; |
1305 | ret = btrfs_previous_item(fs_info->extent_root, path, | ||
1306 | 0, BTRFS_EXTENT_ITEM_KEY); | ||
1307 | if (ret < 0) | ||
1308 | return ret; | ||
1309 | 1305 | ||
1310 | btrfs_item_key_to_cpu(path->nodes[0], found_key, path->slots[0]); | 1306 | while (1) { |
1307 | u32 nritems; | ||
1308 | if (path->slots[0] == 0) { | ||
1309 | btrfs_set_path_blocking(path); | ||
1310 | ret = btrfs_prev_leaf(fs_info->extent_root, path); | ||
1311 | if (ret != 0) { | ||
1312 | if (ret > 0) { | ||
1313 | pr_debug("logical %llu is not within " | ||
1314 | "any extent\n", logical); | ||
1315 | ret = -ENOENT; | ||
1316 | } | ||
1317 | return ret; | ||
1318 | } | ||
1319 | } else { | ||
1320 | path->slots[0]--; | ||
1321 | } | ||
1322 | nritems = btrfs_header_nritems(path->nodes[0]); | ||
1323 | if (nritems == 0) { | ||
1324 | pr_debug("logical %llu is not within any extent\n", | ||
1325 | logical); | ||
1326 | return -ENOENT; | ||
1327 | } | ||
1328 | if (path->slots[0] == nritems) | ||
1329 | path->slots[0]--; | ||
1330 | |||
1331 | btrfs_item_key_to_cpu(path->nodes[0], found_key, | ||
1332 | path->slots[0]); | ||
1333 | if (found_key->type == BTRFS_EXTENT_ITEM_KEY || | ||
1334 | found_key->type == BTRFS_METADATA_ITEM_KEY) | ||
1335 | break; | ||
1336 | } | ||
1337 | |||
1311 | if (found_key->type == BTRFS_METADATA_ITEM_KEY) | 1338 | if (found_key->type == BTRFS_METADATA_ITEM_KEY) |
1312 | size = fs_info->extent_root->leafsize; | 1339 | size = fs_info->extent_root->leafsize; |
1313 | else if (found_key->type == BTRFS_EXTENT_ITEM_KEY) | 1340 | else if (found_key->type == BTRFS_EXTENT_ITEM_KEY) |
1314 | size = found_key->offset; | 1341 | size = found_key->offset; |
1315 | 1342 | ||
1316 | if ((found_key->type != BTRFS_EXTENT_ITEM_KEY && | 1343 | if (found_key->objectid > logical || |
1317 | found_key->type != BTRFS_METADATA_ITEM_KEY) || | ||
1318 | found_key->objectid > logical || | ||
1319 | found_key->objectid + size <= logical) { | 1344 | found_key->objectid + size <= logical) { |
1320 | pr_debug("logical %llu is not within any extent\n", logical); | 1345 | pr_debug("logical %llu is not within any extent\n", logical); |
1321 | return -ENOENT; | 1346 | return -ENOENT; |