diff options
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r-- | fs/ext4/extents.c | 296 |
1 files changed, 203 insertions, 93 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 72ba4705d4fa..54d52afcdb19 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -407,7 +407,7 @@ static int ext4_valid_extent_entries(struct inode *inode, | |||
407 | 407 | ||
408 | static int __ext4_ext_check(const char *function, unsigned int line, | 408 | static int __ext4_ext_check(const char *function, unsigned int line, |
409 | struct inode *inode, struct ext4_extent_header *eh, | 409 | struct inode *inode, struct ext4_extent_header *eh, |
410 | int depth) | 410 | int depth, ext4_fsblk_t pblk) |
411 | { | 411 | { |
412 | const char *error_msg; | 412 | const char *error_msg; |
413 | int max = 0; | 413 | int max = 0; |
@@ -447,42 +447,149 @@ static int __ext4_ext_check(const char *function, unsigned int line, | |||
447 | 447 | ||
448 | corrupted: | 448 | corrupted: |
449 | ext4_error_inode(inode, function, line, 0, | 449 | ext4_error_inode(inode, function, line, 0, |
450 | "bad header/extent: %s - magic %x, " | 450 | "pblk %llu bad header/extent: %s - magic %x, " |
451 | "entries %u, max %u(%u), depth %u(%u)", | 451 | "entries %u, max %u(%u), depth %u(%u)", |
452 | error_msg, le16_to_cpu(eh->eh_magic), | 452 | (unsigned long long) pblk, error_msg, |
453 | le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max), | 453 | le16_to_cpu(eh->eh_magic), |
454 | max, le16_to_cpu(eh->eh_depth), depth); | 454 | le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max), |
455 | 455 | max, le16_to_cpu(eh->eh_depth), depth); | |
456 | return -EIO; | 456 | return -EIO; |
457 | } | 457 | } |
458 | 458 | ||
459 | #define ext4_ext_check(inode, eh, depth) \ | 459 | #define ext4_ext_check(inode, eh, depth, pblk) \ |
460 | __ext4_ext_check(__func__, __LINE__, inode, eh, depth) | 460 | __ext4_ext_check(__func__, __LINE__, (inode), (eh), (depth), (pblk)) |
461 | 461 | ||
462 | int ext4_ext_check_inode(struct inode *inode) | 462 | int ext4_ext_check_inode(struct inode *inode) |
463 | { | 463 | { |
464 | return ext4_ext_check(inode, ext_inode_hdr(inode), ext_depth(inode)); | 464 | return ext4_ext_check(inode, ext_inode_hdr(inode), ext_depth(inode), 0); |
465 | } | 465 | } |
466 | 466 | ||
467 | static int __ext4_ext_check_block(const char *function, unsigned int line, | 467 | static struct buffer_head * |
468 | struct inode *inode, | 468 | __read_extent_tree_block(const char *function, unsigned int line, |
469 | struct ext4_extent_header *eh, | 469 | struct inode *inode, ext4_fsblk_t pblk, int depth, |
470 | int depth, | 470 | int flags) |
471 | struct buffer_head *bh) | ||
472 | { | 471 | { |
473 | int ret; | 472 | struct buffer_head *bh; |
473 | int err; | ||
474 | 474 | ||
475 | if (buffer_verified(bh)) | 475 | bh = sb_getblk(inode->i_sb, pblk); |
476 | return 0; | 476 | if (unlikely(!bh)) |
477 | ret = ext4_ext_check(inode, eh, depth); | 477 | return ERR_PTR(-ENOMEM); |
478 | if (ret) | 478 | |
479 | return ret; | 479 | if (!bh_uptodate_or_lock(bh)) { |
480 | trace_ext4_ext_load_extent(inode, pblk, _RET_IP_); | ||
481 | err = bh_submit_read(bh); | ||
482 | if (err < 0) | ||
483 | goto errout; | ||
484 | } | ||
485 | if (buffer_verified(bh) && !(flags & EXT4_EX_FORCE_CACHE)) | ||
486 | return bh; | ||
487 | err = __ext4_ext_check(function, line, inode, | ||
488 | ext_block_hdr(bh), depth, pblk); | ||
489 | if (err) | ||
490 | goto errout; | ||
480 | set_buffer_verified(bh); | 491 | set_buffer_verified(bh); |
481 | return ret; | 492 | /* |
493 | * If this is a leaf block, cache all of its entries | ||
494 | */ | ||
495 | if (!(flags & EXT4_EX_NOCACHE) && depth == 0) { | ||
496 | struct ext4_extent_header *eh = ext_block_hdr(bh); | ||
497 | struct ext4_extent *ex = EXT_FIRST_EXTENT(eh); | ||
498 | ext4_lblk_t prev = 0; | ||
499 | int i; | ||
500 | |||
501 | for (i = le16_to_cpu(eh->eh_entries); i > 0; i--, ex++) { | ||
502 | unsigned int status = EXTENT_STATUS_WRITTEN; | ||
503 | ext4_lblk_t lblk = le32_to_cpu(ex->ee_block); | ||
504 | int len = ext4_ext_get_actual_len(ex); | ||
505 | |||
506 | if (prev && (prev != lblk)) | ||
507 | ext4_es_cache_extent(inode, prev, | ||
508 | lblk - prev, ~0, | ||
509 | EXTENT_STATUS_HOLE); | ||
510 | |||
511 | if (ext4_ext_is_uninitialized(ex)) | ||
512 | status = EXTENT_STATUS_UNWRITTEN; | ||
513 | ext4_es_cache_extent(inode, lblk, len, | ||
514 | ext4_ext_pblock(ex), status); | ||
515 | prev = lblk + len; | ||
516 | } | ||
517 | } | ||
518 | return bh; | ||
519 | errout: | ||
520 | put_bh(bh); | ||
521 | return ERR_PTR(err); | ||
522 | |||
482 | } | 523 | } |
483 | 524 | ||
484 | #define ext4_ext_check_block(inode, eh, depth, bh) \ | 525 | #define read_extent_tree_block(inode, pblk, depth, flags) \ |
485 | __ext4_ext_check_block(__func__, __LINE__, inode, eh, depth, bh) | 526 | __read_extent_tree_block(__func__, __LINE__, (inode), (pblk), \ |
527 | (depth), (flags)) | ||
528 | |||
529 | /* | ||
530 | * This function is called to cache a file's extent information in the | ||
531 | * extent status tree | ||
532 | */ | ||
533 | int ext4_ext_precache(struct inode *inode) | ||
534 | { | ||
535 | struct ext4_inode_info *ei = EXT4_I(inode); | ||
536 | struct ext4_ext_path *path = NULL; | ||
537 | struct buffer_head *bh; | ||
538 | int i = 0, depth, ret = 0; | ||
539 | |||
540 | if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) | ||
541 | return 0; /* not an extent-mapped inode */ | ||
542 | |||
543 | down_read(&ei->i_data_sem); | ||
544 | depth = ext_depth(inode); | ||
545 | |||
546 | path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), | ||
547 | GFP_NOFS); | ||
548 | if (path == NULL) { | ||
549 | up_read(&ei->i_data_sem); | ||
550 | return -ENOMEM; | ||
551 | } | ||
552 | |||
553 | /* Don't cache anything if there are no external extent blocks */ | ||
554 | if (depth == 0) | ||
555 | goto out; | ||
556 | path[0].p_hdr = ext_inode_hdr(inode); | ||
557 | ret = ext4_ext_check(inode, path[0].p_hdr, depth, 0); | ||
558 | if (ret) | ||
559 | goto out; | ||
560 | path[0].p_idx = EXT_FIRST_INDEX(path[0].p_hdr); | ||
561 | while (i >= 0) { | ||
562 | /* | ||
563 | * If this is a leaf block or we've reached the end of | ||
564 | * the index block, go up | ||
565 | */ | ||
566 | if ((i == depth) || | ||
567 | path[i].p_idx > EXT_LAST_INDEX(path[i].p_hdr)) { | ||
568 | brelse(path[i].p_bh); | ||
569 | path[i].p_bh = NULL; | ||
570 | i--; | ||
571 | continue; | ||
572 | } | ||
573 | bh = read_extent_tree_block(inode, | ||
574 | ext4_idx_pblock(path[i].p_idx++), | ||
575 | depth - i - 1, | ||
576 | EXT4_EX_FORCE_CACHE); | ||
577 | if (IS_ERR(bh)) { | ||
578 | ret = PTR_ERR(bh); | ||
579 | break; | ||
580 | } | ||
581 | i++; | ||
582 | path[i].p_bh = bh; | ||
583 | path[i].p_hdr = ext_block_hdr(bh); | ||
584 | path[i].p_idx = EXT_FIRST_INDEX(path[i].p_hdr); | ||
585 | } | ||
586 | ext4_set_inode_state(inode, EXT4_STATE_EXT_PRECACHED); | ||
587 | out: | ||
588 | up_read(&ei->i_data_sem); | ||
589 | ext4_ext_drop_refs(path); | ||
590 | kfree(path); | ||
591 | return ret; | ||
592 | } | ||
486 | 593 | ||
487 | #ifdef EXT_DEBUG | 594 | #ifdef EXT_DEBUG |
488 | static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) | 595 | static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) |
@@ -716,7 +823,7 @@ int ext4_ext_tree_init(handle_t *handle, struct inode *inode) | |||
716 | 823 | ||
717 | struct ext4_ext_path * | 824 | struct ext4_ext_path * |
718 | ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, | 825 | ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, |
719 | struct ext4_ext_path *path) | 826 | struct ext4_ext_path *path, int flags) |
720 | { | 827 | { |
721 | struct ext4_extent_header *eh; | 828 | struct ext4_extent_header *eh; |
722 | struct buffer_head *bh; | 829 | struct buffer_head *bh; |
@@ -748,20 +855,13 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, | |||
748 | path[ppos].p_depth = i; | 855 | path[ppos].p_depth = i; |
749 | path[ppos].p_ext = NULL; | 856 | path[ppos].p_ext = NULL; |
750 | 857 | ||
751 | bh = sb_getblk(inode->i_sb, path[ppos].p_block); | 858 | bh = read_extent_tree_block(inode, path[ppos].p_block, --i, |
752 | if (unlikely(!bh)) { | 859 | flags); |
753 | ret = -ENOMEM; | 860 | if (IS_ERR(bh)) { |
861 | ret = PTR_ERR(bh); | ||
754 | goto err; | 862 | goto err; |
755 | } | 863 | } |
756 | if (!bh_uptodate_or_lock(bh)) { | 864 | |
757 | trace_ext4_ext_load_extent(inode, block, | ||
758 | path[ppos].p_block); | ||
759 | ret = bh_submit_read(bh); | ||
760 | if (ret < 0) { | ||
761 | put_bh(bh); | ||
762 | goto err; | ||
763 | } | ||
764 | } | ||
765 | eh = ext_block_hdr(bh); | 865 | eh = ext_block_hdr(bh); |
766 | ppos++; | 866 | ppos++; |
767 | if (unlikely(ppos > depth)) { | 867 | if (unlikely(ppos > depth)) { |
@@ -773,11 +873,6 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, | |||
773 | } | 873 | } |
774 | path[ppos].p_bh = bh; | 874 | path[ppos].p_bh = bh; |
775 | path[ppos].p_hdr = eh; | 875 | path[ppos].p_hdr = eh; |
776 | i--; | ||
777 | |||
778 | ret = ext4_ext_check_block(inode, eh, i, bh); | ||
779 | if (ret < 0) | ||
780 | goto err; | ||
781 | } | 876 | } |
782 | 877 | ||
783 | path[ppos].p_depth = i; | 878 | path[ppos].p_depth = i; |
@@ -1198,7 +1293,8 @@ out: | |||
1198 | * if no free index is found, then it requests in-depth growing. | 1293 | * if no free index is found, then it requests in-depth growing. |
1199 | */ | 1294 | */ |
1200 | static int ext4_ext_create_new_leaf(handle_t *handle, struct inode *inode, | 1295 | static int ext4_ext_create_new_leaf(handle_t *handle, struct inode *inode, |
1201 | unsigned int flags, | 1296 | unsigned int mb_flags, |
1297 | unsigned int gb_flags, | ||
1202 | struct ext4_ext_path *path, | 1298 | struct ext4_ext_path *path, |
1203 | struct ext4_extent *newext) | 1299 | struct ext4_extent *newext) |
1204 | { | 1300 | { |
@@ -1220,7 +1316,7 @@ repeat: | |||
1220 | if (EXT_HAS_FREE_INDEX(curp)) { | 1316 | if (EXT_HAS_FREE_INDEX(curp)) { |
1221 | /* if we found index with free entry, then use that | 1317 | /* if we found index with free entry, then use that |
1222 | * entry: create all needed subtree and add new leaf */ | 1318 | * entry: create all needed subtree and add new leaf */ |
1223 | err = ext4_ext_split(handle, inode, flags, path, newext, i); | 1319 | err = ext4_ext_split(handle, inode, mb_flags, path, newext, i); |
1224 | if (err) | 1320 | if (err) |
1225 | goto out; | 1321 | goto out; |
1226 | 1322 | ||
@@ -1228,12 +1324,12 @@ repeat: | |||
1228 | ext4_ext_drop_refs(path); | 1324 | ext4_ext_drop_refs(path); |
1229 | path = ext4_ext_find_extent(inode, | 1325 | path = ext4_ext_find_extent(inode, |
1230 | (ext4_lblk_t)le32_to_cpu(newext->ee_block), | 1326 | (ext4_lblk_t)le32_to_cpu(newext->ee_block), |
1231 | path); | 1327 | path, gb_flags); |
1232 | if (IS_ERR(path)) | 1328 | if (IS_ERR(path)) |
1233 | err = PTR_ERR(path); | 1329 | err = PTR_ERR(path); |
1234 | } else { | 1330 | } else { |
1235 | /* tree is full, time to grow in depth */ | 1331 | /* tree is full, time to grow in depth */ |
1236 | err = ext4_ext_grow_indepth(handle, inode, flags, newext); | 1332 | err = ext4_ext_grow_indepth(handle, inode, mb_flags, newext); |
1237 | if (err) | 1333 | if (err) |
1238 | goto out; | 1334 | goto out; |
1239 | 1335 | ||
@@ -1241,7 +1337,7 @@ repeat: | |||
1241 | ext4_ext_drop_refs(path); | 1337 | ext4_ext_drop_refs(path); |
1242 | path = ext4_ext_find_extent(inode, | 1338 | path = ext4_ext_find_extent(inode, |
1243 | (ext4_lblk_t)le32_to_cpu(newext->ee_block), | 1339 | (ext4_lblk_t)le32_to_cpu(newext->ee_block), |
1244 | path); | 1340 | path, gb_flags); |
1245 | if (IS_ERR(path)) { | 1341 | if (IS_ERR(path)) { |
1246 | err = PTR_ERR(path); | 1342 | err = PTR_ERR(path); |
1247 | goto out; | 1343 | goto out; |
@@ -1412,29 +1508,21 @@ got_index: | |||
1412 | ix++; | 1508 | ix++; |
1413 | block = ext4_idx_pblock(ix); | 1509 | block = ext4_idx_pblock(ix); |
1414 | while (++depth < path->p_depth) { | 1510 | while (++depth < path->p_depth) { |
1415 | bh = sb_bread(inode->i_sb, block); | ||
1416 | if (bh == NULL) | ||
1417 | return -EIO; | ||
1418 | eh = ext_block_hdr(bh); | ||
1419 | /* subtract from p_depth to get proper eh_depth */ | 1511 | /* subtract from p_depth to get proper eh_depth */ |
1420 | if (ext4_ext_check_block(inode, eh, | 1512 | bh = read_extent_tree_block(inode, block, |
1421 | path->p_depth - depth, bh)) { | 1513 | path->p_depth - depth, 0); |
1422 | put_bh(bh); | 1514 | if (IS_ERR(bh)) |
1423 | return -EIO; | 1515 | return PTR_ERR(bh); |
1424 | } | 1516 | eh = ext_block_hdr(bh); |
1425 | ix = EXT_FIRST_INDEX(eh); | 1517 | ix = EXT_FIRST_INDEX(eh); |
1426 | block = ext4_idx_pblock(ix); | 1518 | block = ext4_idx_pblock(ix); |
1427 | put_bh(bh); | 1519 | put_bh(bh); |
1428 | } | 1520 | } |
1429 | 1521 | ||
1430 | bh = sb_bread(inode->i_sb, block); | 1522 | bh = read_extent_tree_block(inode, block, path->p_depth - depth, 0); |
1431 | if (bh == NULL) | 1523 | if (IS_ERR(bh)) |
1432 | return -EIO; | 1524 | return PTR_ERR(bh); |
1433 | eh = ext_block_hdr(bh); | 1525 | eh = ext_block_hdr(bh); |
1434 | if (ext4_ext_check_block(inode, eh, path->p_depth - depth, bh)) { | ||
1435 | put_bh(bh); | ||
1436 | return -EIO; | ||
1437 | } | ||
1438 | ex = EXT_FIRST_EXTENT(eh); | 1526 | ex = EXT_FIRST_EXTENT(eh); |
1439 | found_extent: | 1527 | found_extent: |
1440 | *logical = le32_to_cpu(ex->ee_block); | 1528 | *logical = le32_to_cpu(ex->ee_block); |
@@ -1705,7 +1793,8 @@ static void ext4_ext_try_to_merge_up(handle_t *handle, | |||
1705 | 1793 | ||
1706 | brelse(path[1].p_bh); | 1794 | brelse(path[1].p_bh); |
1707 | ext4_free_blocks(handle, inode, NULL, blk, 1, | 1795 | ext4_free_blocks(handle, inode, NULL, blk, 1, |
1708 | EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET); | 1796 | EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET | |
1797 | EXT4_FREE_BLOCKS_RESERVE); | ||
1709 | } | 1798 | } |
1710 | 1799 | ||
1711 | /* | 1800 | /* |
@@ -1793,7 +1882,7 @@ out: | |||
1793 | */ | 1882 | */ |
1794 | int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, | 1883 | int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, |
1795 | struct ext4_ext_path *path, | 1884 | struct ext4_ext_path *path, |
1796 | struct ext4_extent *newext, int flag) | 1885 | struct ext4_extent *newext, int gb_flags) |
1797 | { | 1886 | { |
1798 | struct ext4_extent_header *eh; | 1887 | struct ext4_extent_header *eh; |
1799 | struct ext4_extent *ex, *fex; | 1888 | struct ext4_extent *ex, *fex; |
@@ -1802,7 +1891,7 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, | |||
1802 | int depth, len, err; | 1891 | int depth, len, err; |
1803 | ext4_lblk_t next; | 1892 | ext4_lblk_t next; |
1804 | unsigned uninitialized = 0; | 1893 | unsigned uninitialized = 0; |
1805 | int flags = 0; | 1894 | int mb_flags = 0; |
1806 | 1895 | ||
1807 | if (unlikely(ext4_ext_get_actual_len(newext) == 0)) { | 1896 | if (unlikely(ext4_ext_get_actual_len(newext) == 0)) { |
1808 | EXT4_ERROR_INODE(inode, "ext4_ext_get_actual_len(newext) == 0"); | 1897 | EXT4_ERROR_INODE(inode, "ext4_ext_get_actual_len(newext) == 0"); |
@@ -1817,7 +1906,7 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, | |||
1817 | } | 1906 | } |
1818 | 1907 | ||
1819 | /* try to insert block into found extent and return */ | 1908 | /* try to insert block into found extent and return */ |
1820 | if (ex && !(flag & EXT4_GET_BLOCKS_PRE_IO)) { | 1909 | if (ex && !(gb_flags & EXT4_GET_BLOCKS_PRE_IO)) { |
1821 | 1910 | ||
1822 | /* | 1911 | /* |
1823 | * Try to see whether we should rather test the extent on | 1912 | * Try to see whether we should rather test the extent on |
@@ -1920,7 +2009,7 @@ prepend: | |||
1920 | if (next != EXT_MAX_BLOCKS) { | 2009 | if (next != EXT_MAX_BLOCKS) { |
1921 | ext_debug("next leaf block - %u\n", next); | 2010 | ext_debug("next leaf block - %u\n", next); |
1922 | BUG_ON(npath != NULL); | 2011 | BUG_ON(npath != NULL); |
1923 | npath = ext4_ext_find_extent(inode, next, NULL); | 2012 | npath = ext4_ext_find_extent(inode, next, NULL, 0); |
1924 | if (IS_ERR(npath)) | 2013 | if (IS_ERR(npath)) |
1925 | return PTR_ERR(npath); | 2014 | return PTR_ERR(npath); |
1926 | BUG_ON(npath->p_depth != path->p_depth); | 2015 | BUG_ON(npath->p_depth != path->p_depth); |
@@ -1939,9 +2028,10 @@ prepend: | |||
1939 | * There is no free space in the found leaf. | 2028 | * There is no free space in the found leaf. |
1940 | * We're gonna add a new leaf in the tree. | 2029 | * We're gonna add a new leaf in the tree. |
1941 | */ | 2030 | */ |
1942 | if (flag & EXT4_GET_BLOCKS_METADATA_NOFAIL) | 2031 | if (gb_flags & EXT4_GET_BLOCKS_METADATA_NOFAIL) |
1943 | flags = EXT4_MB_USE_RESERVED; | 2032 | mb_flags = EXT4_MB_USE_RESERVED; |
1944 | err = ext4_ext_create_new_leaf(handle, inode, flags, path, newext); | 2033 | err = ext4_ext_create_new_leaf(handle, inode, mb_flags, gb_flags, |
2034 | path, newext); | ||
1945 | if (err) | 2035 | if (err) |
1946 | goto cleanup; | 2036 | goto cleanup; |
1947 | depth = ext_depth(inode); | 2037 | depth = ext_depth(inode); |
@@ -2007,7 +2097,7 @@ has_space: | |||
2007 | 2097 | ||
2008 | merge: | 2098 | merge: |
2009 | /* try to merge extents */ | 2099 | /* try to merge extents */ |
2010 | if (!(flag & EXT4_GET_BLOCKS_PRE_IO)) | 2100 | if (!(gb_flags & EXT4_GET_BLOCKS_PRE_IO)) |
2011 | ext4_ext_try_to_merge(handle, inode, path, nearex); | 2101 | ext4_ext_try_to_merge(handle, inode, path, nearex); |
2012 | 2102 | ||
2013 | 2103 | ||
@@ -2050,7 +2140,7 @@ static int ext4_fill_fiemap_extents(struct inode *inode, | |||
2050 | path = NULL; | 2140 | path = NULL; |
2051 | } | 2141 | } |
2052 | 2142 | ||
2053 | path = ext4_ext_find_extent(inode, block, path); | 2143 | path = ext4_ext_find_extent(inode, block, path, 0); |
2054 | if (IS_ERR(path)) { | 2144 | if (IS_ERR(path)) { |
2055 | up_read(&EXT4_I(inode)->i_data_sem); | 2145 | up_read(&EXT4_I(inode)->i_data_sem); |
2056 | err = PTR_ERR(path); | 2146 | err = PTR_ERR(path); |
@@ -2195,8 +2285,8 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, | |||
2195 | ext4_lblk_t block) | 2285 | ext4_lblk_t block) |
2196 | { | 2286 | { |
2197 | int depth = ext_depth(inode); | 2287 | int depth = ext_depth(inode); |
2198 | unsigned long len; | 2288 | unsigned long len = 0; |
2199 | ext4_lblk_t lblock; | 2289 | ext4_lblk_t lblock = 0; |
2200 | struct ext4_extent *ex; | 2290 | struct ext4_extent *ex; |
2201 | 2291 | ||
2202 | ex = path[depth].p_ext; | 2292 | ex = path[depth].p_ext; |
@@ -2233,7 +2323,6 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, | |||
2233 | ext4_es_insert_extent(inode, lblock, len, ~0, | 2323 | ext4_es_insert_extent(inode, lblock, len, ~0, |
2234 | EXTENT_STATUS_HOLE); | 2324 | EXTENT_STATUS_HOLE); |
2235 | } else { | 2325 | } else { |
2236 | lblock = len = 0; | ||
2237 | BUG(); | 2326 | BUG(); |
2238 | } | 2327 | } |
2239 | 2328 | ||
@@ -2712,7 +2801,7 @@ again: | |||
2712 | ext4_lblk_t ee_block; | 2801 | ext4_lblk_t ee_block; |
2713 | 2802 | ||
2714 | /* find extent for this block */ | 2803 | /* find extent for this block */ |
2715 | path = ext4_ext_find_extent(inode, end, NULL); | 2804 | path = ext4_ext_find_extent(inode, end, NULL, EXT4_EX_NOCACHE); |
2716 | if (IS_ERR(path)) { | 2805 | if (IS_ERR(path)) { |
2717 | ext4_journal_stop(handle); | 2806 | ext4_journal_stop(handle); |
2718 | return PTR_ERR(path); | 2807 | return PTR_ERR(path); |
@@ -2754,6 +2843,7 @@ again: | |||
2754 | */ | 2843 | */ |
2755 | err = ext4_split_extent_at(handle, inode, path, | 2844 | err = ext4_split_extent_at(handle, inode, path, |
2756 | end + 1, split_flag, | 2845 | end + 1, split_flag, |
2846 | EXT4_EX_NOCACHE | | ||
2757 | EXT4_GET_BLOCKS_PRE_IO | | 2847 | EXT4_GET_BLOCKS_PRE_IO | |
2758 | EXT4_GET_BLOCKS_METADATA_NOFAIL); | 2848 | EXT4_GET_BLOCKS_METADATA_NOFAIL); |
2759 | 2849 | ||
@@ -2782,7 +2872,7 @@ again: | |||
2782 | path[0].p_hdr = ext_inode_hdr(inode); | 2872 | path[0].p_hdr = ext_inode_hdr(inode); |
2783 | i = 0; | 2873 | i = 0; |
2784 | 2874 | ||
2785 | if (ext4_ext_check(inode, path[0].p_hdr, depth)) { | 2875 | if (ext4_ext_check(inode, path[0].p_hdr, depth, 0)) { |
2786 | err = -EIO; | 2876 | err = -EIO; |
2787 | goto out; | 2877 | goto out; |
2788 | } | 2878 | } |
@@ -2829,10 +2919,12 @@ again: | |||
2829 | ext_debug("move to level %d (block %llu)\n", | 2919 | ext_debug("move to level %d (block %llu)\n", |
2830 | i + 1, ext4_idx_pblock(path[i].p_idx)); | 2920 | i + 1, ext4_idx_pblock(path[i].p_idx)); |
2831 | memset(path + i + 1, 0, sizeof(*path)); | 2921 | memset(path + i + 1, 0, sizeof(*path)); |
2832 | bh = sb_bread(sb, ext4_idx_pblock(path[i].p_idx)); | 2922 | bh = read_extent_tree_block(inode, |
2833 | if (!bh) { | 2923 | ext4_idx_pblock(path[i].p_idx), depth - i - 1, |
2924 | EXT4_EX_NOCACHE); | ||
2925 | if (IS_ERR(bh)) { | ||
2834 | /* should we reset i_size? */ | 2926 | /* should we reset i_size? */ |
2835 | err = -EIO; | 2927 | err = PTR_ERR(bh); |
2836 | break; | 2928 | break; |
2837 | } | 2929 | } |
2838 | /* Yield here to deal with large extent trees. | 2930 | /* Yield here to deal with large extent trees. |
@@ -2842,11 +2934,6 @@ again: | |||
2842 | err = -EIO; | 2934 | err = -EIO; |
2843 | break; | 2935 | break; |
2844 | } | 2936 | } |
2845 | if (ext4_ext_check_block(inode, ext_block_hdr(bh), | ||
2846 | depth - i - 1, bh)) { | ||
2847 | err = -EIO; | ||
2848 | break; | ||
2849 | } | ||
2850 | path[i + 1].p_bh = bh; | 2937 | path[i + 1].p_bh = bh; |
2851 | 2938 | ||
2852 | /* save actual number of indexes since this | 2939 | /* save actual number of indexes since this |
@@ -2961,6 +3048,23 @@ void ext4_ext_release(struct super_block *sb) | |||
2961 | #endif | 3048 | #endif |
2962 | } | 3049 | } |
2963 | 3050 | ||
3051 | static int ext4_zeroout_es(struct inode *inode, struct ext4_extent *ex) | ||
3052 | { | ||
3053 | ext4_lblk_t ee_block; | ||
3054 | ext4_fsblk_t ee_pblock; | ||
3055 | unsigned int ee_len; | ||
3056 | |||
3057 | ee_block = le32_to_cpu(ex->ee_block); | ||
3058 | ee_len = ext4_ext_get_actual_len(ex); | ||
3059 | ee_pblock = ext4_ext_pblock(ex); | ||
3060 | |||
3061 | if (ee_len == 0) | ||
3062 | return 0; | ||
3063 | |||
3064 | return ext4_es_insert_extent(inode, ee_block, ee_len, ee_pblock, | ||
3065 | EXTENT_STATUS_WRITTEN); | ||
3066 | } | ||
3067 | |||
2964 | /* FIXME!! we need to try to merge to left or right after zero-out */ | 3068 | /* FIXME!! we need to try to merge to left or right after zero-out */ |
2965 | static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) | 3069 | static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) |
2966 | { | 3070 | { |
@@ -3113,7 +3217,7 @@ static int ext4_split_extent_at(handle_t *handle, | |||
3113 | goto fix_extent_len; | 3217 | goto fix_extent_len; |
3114 | 3218 | ||
3115 | /* update extent status tree */ | 3219 | /* update extent status tree */ |
3116 | err = ext4_es_zeroout(inode, &zero_ex); | 3220 | err = ext4_zeroout_es(inode, &zero_ex); |
3117 | 3221 | ||
3118 | goto out; | 3222 | goto out; |
3119 | } else if (err) | 3223 | } else if (err) |
@@ -3133,7 +3237,7 @@ fix_extent_len: | |||
3133 | * ext4_split_extents() splits an extent and mark extent which is covered | 3237 | * ext4_split_extents() splits an extent and mark extent which is covered |
3134 | * by @map as split_flags indicates | 3238 | * by @map as split_flags indicates |
3135 | * | 3239 | * |
3136 | * It may result in splitting the extent into multiple extents (upto three) | 3240 | * It may result in splitting the extent into multiple extents (up to three) |
3137 | * There are three possibilities: | 3241 | * There are three possibilities: |
3138 | * a> There is no split required | 3242 | * a> There is no split required |
3139 | * b> Splits in two extents: Split is happening at either end of the extent | 3243 | * b> Splits in two extents: Split is happening at either end of the extent |
@@ -3181,7 +3285,7 @@ static int ext4_split_extent(handle_t *handle, | |||
3181 | * result in split of original leaf or extent zeroout. | 3285 | * result in split of original leaf or extent zeroout. |
3182 | */ | 3286 | */ |
3183 | ext4_ext_drop_refs(path); | 3287 | ext4_ext_drop_refs(path); |
3184 | path = ext4_ext_find_extent(inode, map->m_lblk, path); | 3288 | path = ext4_ext_find_extent(inode, map->m_lblk, path, 0); |
3185 | if (IS_ERR(path)) | 3289 | if (IS_ERR(path)) |
3186 | return PTR_ERR(path); | 3290 | return PTR_ERR(path); |
3187 | depth = ext_depth(inode); | 3291 | depth = ext_depth(inode); |
@@ -3464,7 +3568,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
3464 | out: | 3568 | out: |
3465 | /* If we have gotten a failure, don't zero out status tree */ | 3569 | /* If we have gotten a failure, don't zero out status tree */ |
3466 | if (!err) | 3570 | if (!err) |
3467 | err = ext4_es_zeroout(inode, &zero_ex); | 3571 | err = ext4_zeroout_es(inode, &zero_ex); |
3468 | return err ? err : allocated; | 3572 | return err ? err : allocated; |
3469 | } | 3573 | } |
3470 | 3574 | ||
@@ -3565,7 +3669,7 @@ static int ext4_convert_unwritten_extents_endio(handle_t *handle, | |||
3565 | if (err < 0) | 3669 | if (err < 0) |
3566 | goto out; | 3670 | goto out; |
3567 | ext4_ext_drop_refs(path); | 3671 | ext4_ext_drop_refs(path); |
3568 | path = ext4_ext_find_extent(inode, map->m_lblk, path); | 3672 | path = ext4_ext_find_extent(inode, map->m_lblk, path, 0); |
3569 | if (IS_ERR(path)) { | 3673 | if (IS_ERR(path)) { |
3570 | err = PTR_ERR(path); | 3674 | err = PTR_ERR(path); |
3571 | goto out; | 3675 | goto out; |
@@ -4052,7 +4156,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, | |||
4052 | trace_ext4_ext_map_blocks_enter(inode, map->m_lblk, map->m_len, flags); | 4156 | trace_ext4_ext_map_blocks_enter(inode, map->m_lblk, map->m_len, flags); |
4053 | 4157 | ||
4054 | /* find extent for this block */ | 4158 | /* find extent for this block */ |
4055 | path = ext4_ext_find_extent(inode, map->m_lblk, NULL); | 4159 | path = ext4_ext_find_extent(inode, map->m_lblk, NULL, 0); |
4056 | if (IS_ERR(path)) { | 4160 | if (IS_ERR(path)) { |
4057 | err = PTR_ERR(path); | 4161 | err = PTR_ERR(path); |
4058 | path = NULL; | 4162 | path = NULL; |
@@ -4744,6 +4848,12 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
4744 | return error; | 4848 | return error; |
4745 | } | 4849 | } |
4746 | 4850 | ||
4851 | if (fieinfo->fi_flags & FIEMAP_FLAG_CACHE) { | ||
4852 | error = ext4_ext_precache(inode); | ||
4853 | if (error) | ||
4854 | return error; | ||
4855 | } | ||
4856 | |||
4747 | /* fallback to generic here if not in extents fmt */ | 4857 | /* fallback to generic here if not in extents fmt */ |
4748 | if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) | 4858 | if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) |
4749 | return generic_block_fiemap(inode, fieinfo, start, len, | 4859 | return generic_block_fiemap(inode, fieinfo, start, len, |
@@ -4771,6 +4881,6 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
4771 | error = ext4_fill_fiemap_extents(inode, start_blk, | 4881 | error = ext4_fill_fiemap_extents(inode, start_blk, |
4772 | len_blks, fieinfo); | 4882 | len_blks, fieinfo); |
4773 | } | 4883 | } |
4774 | 4884 | ext4_es_lru_add(inode); | |
4775 | return error; | 4885 | return error; |
4776 | } | 4886 | } |