summaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r--fs/ext4/extents.c87
1 files changed, 60 insertions, 27 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 6e7b7d928f4a..08c1ac976479 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -466,7 +466,8 @@ int ext4_ext_check_inode(struct inode *inode)
466 466
467static struct buffer_head * 467static struct buffer_head *
468__read_extent_tree_block(const char *function, unsigned int line, 468__read_extent_tree_block(const char *function, unsigned int line,
469 struct inode *inode, ext4_fsblk_t pblk, int depth) 469 struct inode *inode, ext4_fsblk_t pblk, int depth,
470 int flags)
470{ 471{
471 struct buffer_head *bh; 472 struct buffer_head *bh;
472 int err; 473 int err;
@@ -488,6 +489,32 @@ __read_extent_tree_block(const char *function, unsigned int line,
488 if (err) 489 if (err)
489 goto errout; 490 goto errout;
490 set_buffer_verified(bh); 491 set_buffer_verified(bh);
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 }
491 return bh; 518 return bh;
492errout: 519errout:
493 put_bh(bh); 520 put_bh(bh);
@@ -495,8 +522,9 @@ errout:
495 522
496} 523}
497 524
498#define read_extent_tree_block(inode, pblk, depth) \ 525#define read_extent_tree_block(inode, pblk, depth, flags) \
499 __read_extent_tree_block(__func__, __LINE__, (inode), (pblk), (depth)) 526 __read_extent_tree_block(__func__, __LINE__, (inode), (pblk), \
527 (depth), (flags))
500 528
501#ifdef EXT_DEBUG 529#ifdef EXT_DEBUG
502static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) 530static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path)
@@ -730,7 +758,7 @@ int ext4_ext_tree_init(handle_t *handle, struct inode *inode)
730 758
731struct ext4_ext_path * 759struct ext4_ext_path *
732ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, 760ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block,
733 struct ext4_ext_path *path) 761 struct ext4_ext_path *path, int flags)
734{ 762{
735 struct ext4_extent_header *eh; 763 struct ext4_extent_header *eh;
736 struct buffer_head *bh; 764 struct buffer_head *bh;
@@ -762,7 +790,8 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block,
762 path[ppos].p_depth = i; 790 path[ppos].p_depth = i;
763 path[ppos].p_ext = NULL; 791 path[ppos].p_ext = NULL;
764 792
765 bh = read_extent_tree_block(inode, path[ppos].p_block, --i); 793 bh = read_extent_tree_block(inode, path[ppos].p_block, --i,
794 flags);
766 if (IS_ERR(bh)) { 795 if (IS_ERR(bh)) {
767 ret = PTR_ERR(bh); 796 ret = PTR_ERR(bh);
768 goto err; 797 goto err;
@@ -1199,7 +1228,8 @@ out:
1199 * if no free index is found, then it requests in-depth growing. 1228 * if no free index is found, then it requests in-depth growing.
1200 */ 1229 */
1201static int ext4_ext_create_new_leaf(handle_t *handle, struct inode *inode, 1230static int ext4_ext_create_new_leaf(handle_t *handle, struct inode *inode,
1202 unsigned int flags, 1231 unsigned int mb_flags,
1232 unsigned int gb_flags,
1203 struct ext4_ext_path *path, 1233 struct ext4_ext_path *path,
1204 struct ext4_extent *newext) 1234 struct ext4_extent *newext)
1205{ 1235{
@@ -1221,7 +1251,7 @@ repeat:
1221 if (EXT_HAS_FREE_INDEX(curp)) { 1251 if (EXT_HAS_FREE_INDEX(curp)) {
1222 /* if we found index with free entry, then use that 1252 /* if we found index with free entry, then use that
1223 * entry: create all needed subtree and add new leaf */ 1253 * entry: create all needed subtree and add new leaf */
1224 err = ext4_ext_split(handle, inode, flags, path, newext, i); 1254 err = ext4_ext_split(handle, inode, mb_flags, path, newext, i);
1225 if (err) 1255 if (err)
1226 goto out; 1256 goto out;
1227 1257
@@ -1229,12 +1259,12 @@ repeat:
1229 ext4_ext_drop_refs(path); 1259 ext4_ext_drop_refs(path);
1230 path = ext4_ext_find_extent(inode, 1260 path = ext4_ext_find_extent(inode,
1231 (ext4_lblk_t)le32_to_cpu(newext->ee_block), 1261 (ext4_lblk_t)le32_to_cpu(newext->ee_block),
1232 path); 1262 path, gb_flags);
1233 if (IS_ERR(path)) 1263 if (IS_ERR(path))
1234 err = PTR_ERR(path); 1264 err = PTR_ERR(path);
1235 } else { 1265 } else {
1236 /* tree is full, time to grow in depth */ 1266 /* tree is full, time to grow in depth */
1237 err = ext4_ext_grow_indepth(handle, inode, flags, newext); 1267 err = ext4_ext_grow_indepth(handle, inode, mb_flags, newext);
1238 if (err) 1268 if (err)
1239 goto out; 1269 goto out;
1240 1270
@@ -1242,7 +1272,7 @@ repeat:
1242 ext4_ext_drop_refs(path); 1272 ext4_ext_drop_refs(path);
1243 path = ext4_ext_find_extent(inode, 1273 path = ext4_ext_find_extent(inode,
1244 (ext4_lblk_t)le32_to_cpu(newext->ee_block), 1274 (ext4_lblk_t)le32_to_cpu(newext->ee_block),
1245 path); 1275 path, gb_flags);
1246 if (IS_ERR(path)) { 1276 if (IS_ERR(path)) {
1247 err = PTR_ERR(path); 1277 err = PTR_ERR(path);
1248 goto out; 1278 goto out;
@@ -1415,7 +1445,7 @@ got_index:
1415 while (++depth < path->p_depth) { 1445 while (++depth < path->p_depth) {
1416 /* subtract from p_depth to get proper eh_depth */ 1446 /* subtract from p_depth to get proper eh_depth */
1417 bh = read_extent_tree_block(inode, block, 1447 bh = read_extent_tree_block(inode, block,
1418 path->p_depth - depth); 1448 path->p_depth - depth, 0);
1419 if (IS_ERR(bh)) 1449 if (IS_ERR(bh))
1420 return PTR_ERR(bh); 1450 return PTR_ERR(bh);
1421 eh = ext_block_hdr(bh); 1451 eh = ext_block_hdr(bh);
@@ -1424,7 +1454,7 @@ got_index:
1424 put_bh(bh); 1454 put_bh(bh);
1425 } 1455 }
1426 1456
1427 bh = read_extent_tree_block(inode, block, path->p_depth - depth); 1457 bh = read_extent_tree_block(inode, block, path->p_depth - depth, 0);
1428 if (IS_ERR(bh)) 1458 if (IS_ERR(bh))
1429 return PTR_ERR(bh); 1459 return PTR_ERR(bh);
1430 eh = ext_block_hdr(bh); 1460 eh = ext_block_hdr(bh);
@@ -1786,7 +1816,7 @@ out:
1786 */ 1816 */
1787int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, 1817int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
1788 struct ext4_ext_path *path, 1818 struct ext4_ext_path *path,
1789 struct ext4_extent *newext, int flag) 1819 struct ext4_extent *newext, int gb_flags)
1790{ 1820{
1791 struct ext4_extent_header *eh; 1821 struct ext4_extent_header *eh;
1792 struct ext4_extent *ex, *fex; 1822 struct ext4_extent *ex, *fex;
@@ -1795,7 +1825,7 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
1795 int depth, len, err; 1825 int depth, len, err;
1796 ext4_lblk_t next; 1826 ext4_lblk_t next;
1797 unsigned uninitialized = 0; 1827 unsigned uninitialized = 0;
1798 int flags = 0; 1828 int mb_flags = 0;
1799 1829
1800 if (unlikely(ext4_ext_get_actual_len(newext) == 0)) { 1830 if (unlikely(ext4_ext_get_actual_len(newext) == 0)) {
1801 EXT4_ERROR_INODE(inode, "ext4_ext_get_actual_len(newext) == 0"); 1831 EXT4_ERROR_INODE(inode, "ext4_ext_get_actual_len(newext) == 0");
@@ -1810,7 +1840,7 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
1810 } 1840 }
1811 1841
1812 /* try to insert block into found extent and return */ 1842 /* try to insert block into found extent and return */
1813 if (ex && !(flag & EXT4_GET_BLOCKS_PRE_IO)) { 1843 if (ex && !(gb_flags & EXT4_GET_BLOCKS_PRE_IO)) {
1814 1844
1815 /* 1845 /*
1816 * Try to see whether we should rather test the extent on 1846 * Try to see whether we should rather test the extent on
@@ -1913,7 +1943,7 @@ prepend:
1913 if (next != EXT_MAX_BLOCKS) { 1943 if (next != EXT_MAX_BLOCKS) {
1914 ext_debug("next leaf block - %u\n", next); 1944 ext_debug("next leaf block - %u\n", next);
1915 BUG_ON(npath != NULL); 1945 BUG_ON(npath != NULL);
1916 npath = ext4_ext_find_extent(inode, next, NULL); 1946 npath = ext4_ext_find_extent(inode, next, NULL, 0);
1917 if (IS_ERR(npath)) 1947 if (IS_ERR(npath))
1918 return PTR_ERR(npath); 1948 return PTR_ERR(npath);
1919 BUG_ON(npath->p_depth != path->p_depth); 1949 BUG_ON(npath->p_depth != path->p_depth);
@@ -1932,9 +1962,10 @@ prepend:
1932 * There is no free space in the found leaf. 1962 * There is no free space in the found leaf.
1933 * We're gonna add a new leaf in the tree. 1963 * We're gonna add a new leaf in the tree.
1934 */ 1964 */
1935 if (flag & EXT4_GET_BLOCKS_METADATA_NOFAIL) 1965 if (gb_flags & EXT4_GET_BLOCKS_METADATA_NOFAIL)
1936 flags = EXT4_MB_USE_RESERVED; 1966 mb_flags = EXT4_MB_USE_RESERVED;
1937 err = ext4_ext_create_new_leaf(handle, inode, flags, path, newext); 1967 err = ext4_ext_create_new_leaf(handle, inode, mb_flags, gb_flags,
1968 path, newext);
1938 if (err) 1969 if (err)
1939 goto cleanup; 1970 goto cleanup;
1940 depth = ext_depth(inode); 1971 depth = ext_depth(inode);
@@ -2000,7 +2031,7 @@ has_space:
2000 2031
2001merge: 2032merge:
2002 /* try to merge extents */ 2033 /* try to merge extents */
2003 if (!(flag & EXT4_GET_BLOCKS_PRE_IO)) 2034 if (!(gb_flags & EXT4_GET_BLOCKS_PRE_IO))
2004 ext4_ext_try_to_merge(handle, inode, path, nearex); 2035 ext4_ext_try_to_merge(handle, inode, path, nearex);
2005 2036
2006 2037
@@ -2043,7 +2074,7 @@ static int ext4_fill_fiemap_extents(struct inode *inode,
2043 path = NULL; 2074 path = NULL;
2044 } 2075 }
2045 2076
2046 path = ext4_ext_find_extent(inode, block, path); 2077 path = ext4_ext_find_extent(inode, block, path, 0);
2047 if (IS_ERR(path)) { 2078 if (IS_ERR(path)) {
2048 up_read(&EXT4_I(inode)->i_data_sem); 2079 up_read(&EXT4_I(inode)->i_data_sem);
2049 err = PTR_ERR(path); 2080 err = PTR_ERR(path);
@@ -2705,7 +2736,7 @@ again:
2705 ext4_lblk_t ee_block; 2736 ext4_lblk_t ee_block;
2706 2737
2707 /* find extent for this block */ 2738 /* find extent for this block */
2708 path = ext4_ext_find_extent(inode, end, NULL); 2739 path = ext4_ext_find_extent(inode, end, NULL, EXT4_EX_NOCACHE);
2709 if (IS_ERR(path)) { 2740 if (IS_ERR(path)) {
2710 ext4_journal_stop(handle); 2741 ext4_journal_stop(handle);
2711 return PTR_ERR(path); 2742 return PTR_ERR(path);
@@ -2747,6 +2778,7 @@ again:
2747 */ 2778 */
2748 err = ext4_split_extent_at(handle, inode, path, 2779 err = ext4_split_extent_at(handle, inode, path,
2749 end + 1, split_flag, 2780 end + 1, split_flag,
2781 EXT4_EX_NOCACHE |
2750 EXT4_GET_BLOCKS_PRE_IO | 2782 EXT4_GET_BLOCKS_PRE_IO |
2751 EXT4_GET_BLOCKS_METADATA_NOFAIL); 2783 EXT4_GET_BLOCKS_METADATA_NOFAIL);
2752 2784
@@ -2823,7 +2855,8 @@ again:
2823 i + 1, ext4_idx_pblock(path[i].p_idx)); 2855 i + 1, ext4_idx_pblock(path[i].p_idx));
2824 memset(path + i + 1, 0, sizeof(*path)); 2856 memset(path + i + 1, 0, sizeof(*path));
2825 bh = read_extent_tree_block(inode, 2857 bh = read_extent_tree_block(inode,
2826 ext4_idx_pblock(path[i].p_idx), depth - i - 1); 2858 ext4_idx_pblock(path[i].p_idx), depth - i - 1,
2859 EXT4_EX_NOCACHE);
2827 if (IS_ERR(bh)) { 2860 if (IS_ERR(bh)) {
2828 /* should we reset i_size? */ 2861 /* should we reset i_size? */
2829 err = PTR_ERR(bh); 2862 err = PTR_ERR(bh);
@@ -3170,7 +3203,7 @@ static int ext4_split_extent(handle_t *handle,
3170 * result in split of original leaf or extent zeroout. 3203 * result in split of original leaf or extent zeroout.
3171 */ 3204 */
3172 ext4_ext_drop_refs(path); 3205 ext4_ext_drop_refs(path);
3173 path = ext4_ext_find_extent(inode, map->m_lblk, path); 3206 path = ext4_ext_find_extent(inode, map->m_lblk, path, 0);
3174 if (IS_ERR(path)) 3207 if (IS_ERR(path))
3175 return PTR_ERR(path); 3208 return PTR_ERR(path);
3176 depth = ext_depth(inode); 3209 depth = ext_depth(inode);
@@ -3554,7 +3587,7 @@ static int ext4_convert_unwritten_extents_endio(handle_t *handle,
3554 if (err < 0) 3587 if (err < 0)
3555 goto out; 3588 goto out;
3556 ext4_ext_drop_refs(path); 3589 ext4_ext_drop_refs(path);
3557 path = ext4_ext_find_extent(inode, map->m_lblk, path); 3590 path = ext4_ext_find_extent(inode, map->m_lblk, path, 0);
3558 if (IS_ERR(path)) { 3591 if (IS_ERR(path)) {
3559 err = PTR_ERR(path); 3592 err = PTR_ERR(path);
3560 goto out; 3593 goto out;
@@ -4041,7 +4074,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
4041 trace_ext4_ext_map_blocks_enter(inode, map->m_lblk, map->m_len, flags); 4074 trace_ext4_ext_map_blocks_enter(inode, map->m_lblk, map->m_len, flags);
4042 4075
4043 /* find extent for this block */ 4076 /* find extent for this block */
4044 path = ext4_ext_find_extent(inode, map->m_lblk, NULL); 4077 path = ext4_ext_find_extent(inode, map->m_lblk, NULL, 0);
4045 if (IS_ERR(path)) { 4078 if (IS_ERR(path)) {
4046 err = PTR_ERR(path); 4079 err = PTR_ERR(path);
4047 path = NULL; 4080 path = NULL;
@@ -4760,6 +4793,6 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
4760 error = ext4_fill_fiemap_extents(inode, start_blk, 4793 error = ext4_fill_fiemap_extents(inode, start_blk,
4761 len_blks, fieinfo); 4794 len_blks, fieinfo);
4762 } 4795 }
4763 4796 ext4_es_lru_add(inode);
4764 return error; 4797 return error;
4765} 4798}