diff options
Diffstat (limited to 'fs/ext4/extents.c')
| -rw-r--r-- | fs/ext4/extents.c | 368 |
1 files changed, 153 insertions, 215 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 06328d3e5717..0554c48cb1fd 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
| @@ -44,55 +44,6 @@ | |||
| 44 | #include "ext4_jbd2.h" | 44 | #include "ext4_jbd2.h" |
| 45 | #include "ext4_extents.h" | 45 | #include "ext4_extents.h" |
| 46 | 46 | ||
| 47 | |||
| 48 | /* | ||
| 49 | * ext_pblock: | ||
| 50 | * combine low and high parts of physical block number into ext4_fsblk_t | ||
| 51 | */ | ||
| 52 | ext4_fsblk_t ext_pblock(struct ext4_extent *ex) | ||
| 53 | { | ||
| 54 | ext4_fsblk_t block; | ||
| 55 | |||
| 56 | block = le32_to_cpu(ex->ee_start_lo); | ||
| 57 | block |= ((ext4_fsblk_t) le16_to_cpu(ex->ee_start_hi) << 31) << 1; | ||
| 58 | return block; | ||
| 59 | } | ||
| 60 | |||
| 61 | /* | ||
| 62 | * idx_pblock: | ||
| 63 | * combine low and high parts of a leaf physical block number into ext4_fsblk_t | ||
| 64 | */ | ||
| 65 | ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) | ||
| 66 | { | ||
| 67 | ext4_fsblk_t block; | ||
| 68 | |||
| 69 | block = le32_to_cpu(ix->ei_leaf_lo); | ||
| 70 | block |= ((ext4_fsblk_t) le16_to_cpu(ix->ei_leaf_hi) << 31) << 1; | ||
| 71 | return block; | ||
| 72 | } | ||
| 73 | |||
| 74 | /* | ||
| 75 | * ext4_ext_store_pblock: | ||
| 76 | * stores a large physical block number into an extent struct, | ||
| 77 | * breaking it into parts | ||
| 78 | */ | ||
| 79 | void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb) | ||
| 80 | { | ||
| 81 | ex->ee_start_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff)); | ||
| 82 | ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); | ||
| 83 | } | ||
| 84 | |||
| 85 | /* | ||
| 86 | * ext4_idx_store_pblock: | ||
| 87 | * stores a large physical block number into an index struct, | ||
| 88 | * breaking it into parts | ||
| 89 | */ | ||
| 90 | static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb) | ||
| 91 | { | ||
| 92 | ix->ei_leaf_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff)); | ||
| 93 | ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); | ||
| 94 | } | ||
| 95 | |||
| 96 | static int ext4_ext_truncate_extend_restart(handle_t *handle, | 47 | static int ext4_ext_truncate_extend_restart(handle_t *handle, |
| 97 | struct inode *inode, | 48 | struct inode *inode, |
| 98 | int needed) | 49 | int needed) |
| @@ -169,7 +120,8 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, | |||
| 169 | /* try to predict block placement */ | 120 | /* try to predict block placement */ |
| 170 | ex = path[depth].p_ext; | 121 | ex = path[depth].p_ext; |
| 171 | if (ex) | 122 | if (ex) |
| 172 | return ext_pblock(ex)+(block-le32_to_cpu(ex->ee_block)); | 123 | return (ext4_ext_pblock(ex) + |
| 124 | (block - le32_to_cpu(ex->ee_block))); | ||
| 173 | 125 | ||
| 174 | /* it looks like index is empty; | 126 | /* it looks like index is empty; |
| 175 | * try to find starting block from index itself */ | 127 | * try to find starting block from index itself */ |
| @@ -354,7 +306,7 @@ ext4_ext_max_entries(struct inode *inode, int depth) | |||
| 354 | 306 | ||
| 355 | static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext) | 307 | static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext) |
| 356 | { | 308 | { |
| 357 | ext4_fsblk_t block = ext_pblock(ext); | 309 | ext4_fsblk_t block = ext4_ext_pblock(ext); |
| 358 | int len = ext4_ext_get_actual_len(ext); | 310 | int len = ext4_ext_get_actual_len(ext); |
| 359 | 311 | ||
| 360 | return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len); | 312 | return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len); |
| @@ -363,7 +315,7 @@ static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext) | |||
| 363 | static int ext4_valid_extent_idx(struct inode *inode, | 315 | static int ext4_valid_extent_idx(struct inode *inode, |
| 364 | struct ext4_extent_idx *ext_idx) | 316 | struct ext4_extent_idx *ext_idx) |
| 365 | { | 317 | { |
| 366 | ext4_fsblk_t block = idx_pblock(ext_idx); | 318 | ext4_fsblk_t block = ext4_idx_pblock(ext_idx); |
| 367 | 319 | ||
| 368 | return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, 1); | 320 | return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, 1); |
| 369 | } | 321 | } |
| @@ -463,13 +415,13 @@ static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) | |||
| 463 | for (k = 0; k <= l; k++, path++) { | 415 | for (k = 0; k <= l; k++, path++) { |
| 464 | if (path->p_idx) { | 416 | if (path->p_idx) { |
| 465 | ext_debug(" %d->%llu", le32_to_cpu(path->p_idx->ei_block), | 417 | ext_debug(" %d->%llu", le32_to_cpu(path->p_idx->ei_block), |
| 466 | idx_pblock(path->p_idx)); | 418 | ext4_idx_pblock(path->p_idx)); |
| 467 | } else if (path->p_ext) { | 419 | } else if (path->p_ext) { |
| 468 | ext_debug(" %d:[%d]%d:%llu ", | 420 | ext_debug(" %d:[%d]%d:%llu ", |
| 469 | le32_to_cpu(path->p_ext->ee_block), | 421 | le32_to_cpu(path->p_ext->ee_block), |
| 470 | ext4_ext_is_uninitialized(path->p_ext), | 422 | ext4_ext_is_uninitialized(path->p_ext), |
| 471 | ext4_ext_get_actual_len(path->p_ext), | 423 | ext4_ext_get_actual_len(path->p_ext), |
| 472 | ext_pblock(path->p_ext)); | 424 | ext4_ext_pblock(path->p_ext)); |
| 473 | } else | 425 | } else |
| 474 | ext_debug(" []"); | 426 | ext_debug(" []"); |
| 475 | } | 427 | } |
| @@ -494,7 +446,7 @@ static void ext4_ext_show_leaf(struct inode *inode, struct ext4_ext_path *path) | |||
| 494 | for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ex++) { | 446 | for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ex++) { |
| 495 | ext_debug("%d:[%d]%d:%llu ", le32_to_cpu(ex->ee_block), | 447 | ext_debug("%d:[%d]%d:%llu ", le32_to_cpu(ex->ee_block), |
| 496 | ext4_ext_is_uninitialized(ex), | 448 | ext4_ext_is_uninitialized(ex), |
| 497 | ext4_ext_get_actual_len(ex), ext_pblock(ex)); | 449 | ext4_ext_get_actual_len(ex), ext4_ext_pblock(ex)); |
| 498 | } | 450 | } |
| 499 | ext_debug("\n"); | 451 | ext_debug("\n"); |
| 500 | } | 452 | } |
| @@ -545,7 +497,7 @@ ext4_ext_binsearch_idx(struct inode *inode, | |||
| 545 | 497 | ||
| 546 | path->p_idx = l - 1; | 498 | path->p_idx = l - 1; |
| 547 | ext_debug(" -> %d->%lld ", le32_to_cpu(path->p_idx->ei_block), | 499 | ext_debug(" -> %d->%lld ", le32_to_cpu(path->p_idx->ei_block), |
| 548 | idx_pblock(path->p_idx)); | 500 | ext4_idx_pblock(path->p_idx)); |
| 549 | 501 | ||
| 550 | #ifdef CHECK_BINSEARCH | 502 | #ifdef CHECK_BINSEARCH |
| 551 | { | 503 | { |
| @@ -614,7 +566,7 @@ ext4_ext_binsearch(struct inode *inode, | |||
| 614 | path->p_ext = l - 1; | 566 | path->p_ext = l - 1; |
| 615 | ext_debug(" -> %d:%llu:[%d]%d ", | 567 | ext_debug(" -> %d:%llu:[%d]%d ", |
| 616 | le32_to_cpu(path->p_ext->ee_block), | 568 | le32_to_cpu(path->p_ext->ee_block), |
| 617 | ext_pblock(path->p_ext), | 569 | ext4_ext_pblock(path->p_ext), |
| 618 | ext4_ext_is_uninitialized(path->p_ext), | 570 | ext4_ext_is_uninitialized(path->p_ext), |
| 619 | ext4_ext_get_actual_len(path->p_ext)); | 571 | ext4_ext_get_actual_len(path->p_ext)); |
| 620 | 572 | ||
| @@ -682,7 +634,7 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, | |||
| 682 | ppos, le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max)); | 634 | ppos, le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max)); |
| 683 | 635 | ||
| 684 | ext4_ext_binsearch_idx(inode, path + ppos, block); | 636 | ext4_ext_binsearch_idx(inode, path + ppos, block); |
| 685 | path[ppos].p_block = idx_pblock(path[ppos].p_idx); | 637 | path[ppos].p_block = ext4_idx_pblock(path[ppos].p_idx); |
| 686 | path[ppos].p_depth = i; | 638 | path[ppos].p_depth = i; |
| 687 | path[ppos].p_ext = NULL; | 639 | path[ppos].p_ext = NULL; |
| 688 | 640 | ||
| @@ -721,7 +673,7 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, | |||
| 721 | ext4_ext_binsearch(inode, path + ppos, block); | 673 | ext4_ext_binsearch(inode, path + ppos, block); |
| 722 | /* if not an empty leaf */ | 674 | /* if not an empty leaf */ |
| 723 | if (path[ppos].p_ext) | 675 | if (path[ppos].p_ext) |
| 724 | path[ppos].p_block = ext_pblock(path[ppos].p_ext); | 676 | path[ppos].p_block = ext4_ext_pblock(path[ppos].p_ext); |
| 725 | 677 | ||
| 726 | ext4_ext_show_path(inode, path); | 678 | ext4_ext_show_path(inode, path); |
| 727 | 679 | ||
| @@ -739,9 +691,9 @@ err: | |||
| 739 | * insert new index [@logical;@ptr] into the block at @curp; | 691 | * insert new index [@logical;@ptr] into the block at @curp; |
| 740 | * check where to insert: before @curp or after @curp | 692 | * check where to insert: before @curp or after @curp |
| 741 | */ | 693 | */ |
| 742 | int ext4_ext_insert_index(handle_t *handle, struct inode *inode, | 694 | static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, |
| 743 | struct ext4_ext_path *curp, | 695 | struct ext4_ext_path *curp, |
| 744 | int logical, ext4_fsblk_t ptr) | 696 | int logical, ext4_fsblk_t ptr) |
| 745 | { | 697 | { |
| 746 | struct ext4_extent_idx *ix; | 698 | struct ext4_extent_idx *ix; |
| 747 | int len, err; | 699 | int len, err; |
| @@ -917,7 +869,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
| 917 | EXT_MAX_EXTENT(path[depth].p_hdr)) { | 869 | EXT_MAX_EXTENT(path[depth].p_hdr)) { |
| 918 | ext_debug("move %d:%llu:[%d]%d in new leaf %llu\n", | 870 | ext_debug("move %d:%llu:[%d]%d in new leaf %llu\n", |
| 919 | le32_to_cpu(path[depth].p_ext->ee_block), | 871 | le32_to_cpu(path[depth].p_ext->ee_block), |
| 920 | ext_pblock(path[depth].p_ext), | 872 | ext4_ext_pblock(path[depth].p_ext), |
| 921 | ext4_ext_is_uninitialized(path[depth].p_ext), | 873 | ext4_ext_is_uninitialized(path[depth].p_ext), |
| 922 | ext4_ext_get_actual_len(path[depth].p_ext), | 874 | ext4_ext_get_actual_len(path[depth].p_ext), |
| 923 | newblock); | 875 | newblock); |
| @@ -1007,7 +959,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
| 1007 | while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { | 959 | while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { |
| 1008 | ext_debug("%d: move %d:%llu in new index %llu\n", i, | 960 | ext_debug("%d: move %d:%llu in new index %llu\n", i, |
| 1009 | le32_to_cpu(path[i].p_idx->ei_block), | 961 | le32_to_cpu(path[i].p_idx->ei_block), |
| 1010 | idx_pblock(path[i].p_idx), | 962 | ext4_idx_pblock(path[i].p_idx), |
| 1011 | newblock); | 963 | newblock); |
| 1012 | /*memmove(++fidx, path[i].p_idx++, | 964 | /*memmove(++fidx, path[i].p_idx++, |
| 1013 | sizeof(struct ext4_extent_idx)); | 965 | sizeof(struct ext4_extent_idx)); |
| @@ -1146,7 +1098,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, | |||
| 1146 | ext_debug("new root: num %d(%d), lblock %d, ptr %llu\n", | 1098 | ext_debug("new root: num %d(%d), lblock %d, ptr %llu\n", |
| 1147 | le16_to_cpu(neh->eh_entries), le16_to_cpu(neh->eh_max), | 1099 | le16_to_cpu(neh->eh_entries), le16_to_cpu(neh->eh_max), |
| 1148 | le32_to_cpu(EXT_FIRST_INDEX(neh)->ei_block), | 1100 | le32_to_cpu(EXT_FIRST_INDEX(neh)->ei_block), |
| 1149 | idx_pblock(EXT_FIRST_INDEX(neh))); | 1101 | ext4_idx_pblock(EXT_FIRST_INDEX(neh))); |
| 1150 | 1102 | ||
| 1151 | neh->eh_depth = cpu_to_le16(path->p_depth + 1); | 1103 | neh->eh_depth = cpu_to_le16(path->p_depth + 1); |
| 1152 | err = ext4_ext_dirty(handle, inode, curp); | 1104 | err = ext4_ext_dirty(handle, inode, curp); |
| @@ -1232,9 +1184,9 @@ out: | |||
| 1232 | * returns 0 at @phys | 1184 | * returns 0 at @phys |
| 1233 | * return value contains 0 (success) or error code | 1185 | * return value contains 0 (success) or error code |
| 1234 | */ | 1186 | */ |
| 1235 | int | 1187 | static int ext4_ext_search_left(struct inode *inode, |
| 1236 | ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path, | 1188 | struct ext4_ext_path *path, |
| 1237 | ext4_lblk_t *logical, ext4_fsblk_t *phys) | 1189 | ext4_lblk_t *logical, ext4_fsblk_t *phys) |
| 1238 | { | 1190 | { |
| 1239 | struct ext4_extent_idx *ix; | 1191 | struct ext4_extent_idx *ix; |
| 1240 | struct ext4_extent *ex; | 1192 | struct ext4_extent *ex; |
| @@ -1286,7 +1238,7 @@ ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path, | |||
| 1286 | } | 1238 | } |
| 1287 | 1239 | ||
| 1288 | *logical = le32_to_cpu(ex->ee_block) + ee_len - 1; | 1240 | *logical = le32_to_cpu(ex->ee_block) + ee_len - 1; |
| 1289 | *phys = ext_pblock(ex) + ee_len - 1; | 1241 | *phys = ext4_ext_pblock(ex) + ee_len - 1; |
| 1290 | return 0; | 1242 | return 0; |
| 1291 | } | 1243 | } |
| 1292 | 1244 | ||
| @@ -1297,9 +1249,9 @@ ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path, | |||
| 1297 | * returns 0 at @phys | 1249 | * returns 0 at @phys |
| 1298 | * return value contains 0 (success) or error code | 1250 | * return value contains 0 (success) or error code |
| 1299 | */ | 1251 | */ |
| 1300 | int | 1252 | static int ext4_ext_search_right(struct inode *inode, |
| 1301 | ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path, | 1253 | struct ext4_ext_path *path, |
| 1302 | ext4_lblk_t *logical, ext4_fsblk_t *phys) | 1254 | ext4_lblk_t *logical, ext4_fsblk_t *phys) |
| 1303 | { | 1255 | { |
| 1304 | struct buffer_head *bh = NULL; | 1256 | struct buffer_head *bh = NULL; |
| 1305 | struct ext4_extent_header *eh; | 1257 | struct ext4_extent_header *eh; |
| @@ -1342,7 +1294,7 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path, | |||
| 1342 | } | 1294 | } |
| 1343 | } | 1295 | } |
| 1344 | *logical = le32_to_cpu(ex->ee_block); | 1296 | *logical = le32_to_cpu(ex->ee_block); |
| 1345 | *phys = ext_pblock(ex); | 1297 | *phys = ext4_ext_pblock(ex); |
| 1346 | return 0; | 1298 | return 0; |
| 1347 | } | 1299 | } |
| 1348 | 1300 | ||
| @@ -1357,7 +1309,7 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path, | |||
| 1357 | /* next allocated block in this leaf */ | 1309 | /* next allocated block in this leaf */ |
| 1358 | ex++; | 1310 | ex++; |
| 1359 | *logical = le32_to_cpu(ex->ee_block); | 1311 | *logical = le32_to_cpu(ex->ee_block); |
| 1360 | *phys = ext_pblock(ex); | 1312 | *phys = ext4_ext_pblock(ex); |
| 1361 | return 0; | 1313 | return 0; |
| 1362 | } | 1314 | } |
| 1363 | 1315 | ||
| @@ -1376,7 +1328,7 @@ got_index: | |||
| 1376 | * follow it and find the closest allocated | 1328 | * follow it and find the closest allocated |
| 1377 | * block to the right */ | 1329 | * block to the right */ |
| 1378 | ix++; | 1330 | ix++; |
| 1379 | block = idx_pblock(ix); | 1331 | block = ext4_idx_pblock(ix); |
| 1380 | while (++depth < path->p_depth) { | 1332 | while (++depth < path->p_depth) { |
| 1381 | bh = sb_bread(inode->i_sb, block); | 1333 | bh = sb_bread(inode->i_sb, block); |
| 1382 | if (bh == NULL) | 1334 | if (bh == NULL) |
| @@ -1388,7 +1340,7 @@ got_index: | |||
| 1388 | return -EIO; | 1340 | return -EIO; |
| 1389 | } | 1341 | } |
| 1390 | ix = EXT_FIRST_INDEX(eh); | 1342 | ix = EXT_FIRST_INDEX(eh); |
| 1391 | block = idx_pblock(ix); | 1343 | block = ext4_idx_pblock(ix); |
| 1392 | put_bh(bh); | 1344 | put_bh(bh); |
| 1393 | } | 1345 | } |
| 1394 | 1346 | ||
| @@ -1402,7 +1354,7 @@ got_index: | |||
| 1402 | } | 1354 | } |
| 1403 | ex = EXT_FIRST_EXTENT(eh); | 1355 | ex = EXT_FIRST_EXTENT(eh); |
| 1404 | *logical = le32_to_cpu(ex->ee_block); | 1356 | *logical = le32_to_cpu(ex->ee_block); |
| 1405 | *phys = ext_pblock(ex); | 1357 | *phys = ext4_ext_pblock(ex); |
| 1406 | put_bh(bh); | 1358 | put_bh(bh); |
| 1407 | return 0; | 1359 | return 0; |
| 1408 | } | 1360 | } |
| @@ -1573,7 +1525,7 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, | |||
| 1573 | return 0; | 1525 | return 0; |
| 1574 | #endif | 1526 | #endif |
| 1575 | 1527 | ||
| 1576 | if (ext_pblock(ex1) + ext1_ee_len == ext_pblock(ex2)) | 1528 | if (ext4_ext_pblock(ex1) + ext1_ee_len == ext4_ext_pblock(ex2)) |
| 1577 | return 1; | 1529 | return 1; |
| 1578 | return 0; | 1530 | return 0; |
| 1579 | } | 1531 | } |
| @@ -1585,9 +1537,9 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, | |||
| 1585 | * Returns 0 if the extents (ex and ex+1) were _not_ merged and returns | 1537 | * Returns 0 if the extents (ex and ex+1) were _not_ merged and returns |
| 1586 | * 1 if they got merged. | 1538 | * 1 if they got merged. |
| 1587 | */ | 1539 | */ |
| 1588 | int ext4_ext_try_to_merge(struct inode *inode, | 1540 | static int ext4_ext_try_to_merge(struct inode *inode, |
| 1589 | struct ext4_ext_path *path, | 1541 | struct ext4_ext_path *path, |
| 1590 | struct ext4_extent *ex) | 1542 | struct ext4_extent *ex) |
| 1591 | { | 1543 | { |
| 1592 | struct ext4_extent_header *eh; | 1544 | struct ext4_extent_header *eh; |
| 1593 | unsigned int depth, len; | 1545 | unsigned int depth, len; |
| @@ -1632,9 +1584,9 @@ int ext4_ext_try_to_merge(struct inode *inode, | |||
| 1632 | * such that there will be no overlap, and then returns 1. | 1584 | * such that there will be no overlap, and then returns 1. |
| 1633 | * If there is no overlap found, it returns 0. | 1585 | * If there is no overlap found, it returns 0. |
| 1634 | */ | 1586 | */ |
| 1635 | unsigned int ext4_ext_check_overlap(struct inode *inode, | 1587 | static unsigned int ext4_ext_check_overlap(struct inode *inode, |
| 1636 | struct ext4_extent *newext, | 1588 | struct ext4_extent *newext, |
| 1637 | struct ext4_ext_path *path) | 1589 | struct ext4_ext_path *path) |
| 1638 | { | 1590 | { |
| 1639 | ext4_lblk_t b1, b2; | 1591 | ext4_lblk_t b1, b2; |
| 1640 | unsigned int depth, len1; | 1592 | unsigned int depth, len1; |
| @@ -1706,11 +1658,12 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, | |||
| 1706 | if (ex && !(flag & EXT4_GET_BLOCKS_PRE_IO) | 1658 | if (ex && !(flag & EXT4_GET_BLOCKS_PRE_IO) |
| 1707 | && ext4_can_extents_be_merged(inode, ex, newext)) { | 1659 | && ext4_can_extents_be_merged(inode, ex, newext)) { |
| 1708 | ext_debug("append [%d]%d block to %d:[%d]%d (from %llu)\n", | 1660 | ext_debug("append [%d]%d block to %d:[%d]%d (from %llu)\n", |
| 1709 | ext4_ext_is_uninitialized(newext), | 1661 | ext4_ext_is_uninitialized(newext), |
| 1710 | ext4_ext_get_actual_len(newext), | 1662 | ext4_ext_get_actual_len(newext), |
| 1711 | le32_to_cpu(ex->ee_block), | 1663 | le32_to_cpu(ex->ee_block), |
| 1712 | ext4_ext_is_uninitialized(ex), | 1664 | ext4_ext_is_uninitialized(ex), |
| 1713 | ext4_ext_get_actual_len(ex), ext_pblock(ex)); | 1665 | ext4_ext_get_actual_len(ex), |
| 1666 | ext4_ext_pblock(ex)); | ||
| 1714 | err = ext4_ext_get_access(handle, inode, path + depth); | 1667 | err = ext4_ext_get_access(handle, inode, path + depth); |
| 1715 | if (err) | 1668 | if (err) |
| 1716 | return err; | 1669 | return err; |
| @@ -1780,7 +1733,7 @@ has_space: | |||
| 1780 | /* there is no extent in this leaf, create first one */ | 1733 | /* there is no extent in this leaf, create first one */ |
| 1781 | ext_debug("first extent in the leaf: %d:%llu:[%d]%d\n", | 1734 | ext_debug("first extent in the leaf: %d:%llu:[%d]%d\n", |
| 1782 | le32_to_cpu(newext->ee_block), | 1735 | le32_to_cpu(newext->ee_block), |
| 1783 | ext_pblock(newext), | 1736 | ext4_ext_pblock(newext), |
| 1784 | ext4_ext_is_uninitialized(newext), | 1737 | ext4_ext_is_uninitialized(newext), |
| 1785 | ext4_ext_get_actual_len(newext)); | 1738 | ext4_ext_get_actual_len(newext)); |
| 1786 | path[depth].p_ext = EXT_FIRST_EXTENT(eh); | 1739 | path[depth].p_ext = EXT_FIRST_EXTENT(eh); |
| @@ -1794,7 +1747,7 @@ has_space: | |||
| 1794 | ext_debug("insert %d:%llu:[%d]%d after: nearest 0x%p, " | 1747 | ext_debug("insert %d:%llu:[%d]%d after: nearest 0x%p, " |
| 1795 | "move %d from 0x%p to 0x%p\n", | 1748 | "move %d from 0x%p to 0x%p\n", |
| 1796 | le32_to_cpu(newext->ee_block), | 1749 | le32_to_cpu(newext->ee_block), |
| 1797 | ext_pblock(newext), | 1750 | ext4_ext_pblock(newext), |
| 1798 | ext4_ext_is_uninitialized(newext), | 1751 | ext4_ext_is_uninitialized(newext), |
| 1799 | ext4_ext_get_actual_len(newext), | 1752 | ext4_ext_get_actual_len(newext), |
| 1800 | nearex, len, nearex + 1, nearex + 2); | 1753 | nearex, len, nearex + 1, nearex + 2); |
| @@ -1808,7 +1761,7 @@ has_space: | |||
| 1808 | ext_debug("insert %d:%llu:[%d]%d before: nearest 0x%p, " | 1761 | ext_debug("insert %d:%llu:[%d]%d before: nearest 0x%p, " |
| 1809 | "move %d from 0x%p to 0x%p\n", | 1762 | "move %d from 0x%p to 0x%p\n", |
| 1810 | le32_to_cpu(newext->ee_block), | 1763 | le32_to_cpu(newext->ee_block), |
| 1811 | ext_pblock(newext), | 1764 | ext4_ext_pblock(newext), |
| 1812 | ext4_ext_is_uninitialized(newext), | 1765 | ext4_ext_is_uninitialized(newext), |
| 1813 | ext4_ext_get_actual_len(newext), | 1766 | ext4_ext_get_actual_len(newext), |
| 1814 | nearex, len, nearex + 1, nearex + 2); | 1767 | nearex, len, nearex + 1, nearex + 2); |
| @@ -1819,7 +1772,7 @@ has_space: | |||
| 1819 | le16_add_cpu(&eh->eh_entries, 1); | 1772 | le16_add_cpu(&eh->eh_entries, 1); |
| 1820 | nearex = path[depth].p_ext; | 1773 | nearex = path[depth].p_ext; |
| 1821 | nearex->ee_block = newext->ee_block; | 1774 | nearex->ee_block = newext->ee_block; |
| 1822 | ext4_ext_store_pblock(nearex, ext_pblock(newext)); | 1775 | ext4_ext_store_pblock(nearex, ext4_ext_pblock(newext)); |
| 1823 | nearex->ee_len = newext->ee_len; | 1776 | nearex->ee_len = newext->ee_len; |
| 1824 | 1777 | ||
| 1825 | merge: | 1778 | merge: |
| @@ -1845,9 +1798,9 @@ cleanup: | |||
| 1845 | return err; | 1798 | return err; |
| 1846 | } | 1799 | } |
| 1847 | 1800 | ||
| 1848 | int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block, | 1801 | static int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block, |
| 1849 | ext4_lblk_t num, ext_prepare_callback func, | 1802 | ext4_lblk_t num, ext_prepare_callback func, |
| 1850 | void *cbdata) | 1803 | void *cbdata) |
| 1851 | { | 1804 | { |
| 1852 | struct ext4_ext_path *path = NULL; | 1805 | struct ext4_ext_path *path = NULL; |
| 1853 | struct ext4_ext_cache cbex; | 1806 | struct ext4_ext_cache cbex; |
| @@ -1923,7 +1876,7 @@ int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block, | |||
| 1923 | } else { | 1876 | } else { |
| 1924 | cbex.ec_block = le32_to_cpu(ex->ee_block); | 1877 | cbex.ec_block = le32_to_cpu(ex->ee_block); |
| 1925 | cbex.ec_len = ext4_ext_get_actual_len(ex); | 1878 | cbex.ec_len = ext4_ext_get_actual_len(ex); |
| 1926 | cbex.ec_start = ext_pblock(ex); | 1879 | cbex.ec_start = ext4_ext_pblock(ex); |
| 1927 | cbex.ec_type = EXT4_EXT_CACHE_EXTENT; | 1880 | cbex.ec_type = EXT4_EXT_CACHE_EXTENT; |
| 1928 | } | 1881 | } |
| 1929 | 1882 | ||
| @@ -2073,7 +2026,7 @@ static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode, | |||
| 2073 | 2026 | ||
| 2074 | /* free index block */ | 2027 | /* free index block */ |
| 2075 | path--; | 2028 | path--; |
| 2076 | leaf = idx_pblock(path->p_idx); | 2029 | leaf = ext4_idx_pblock(path->p_idx); |
| 2077 | if (unlikely(path->p_hdr->eh_entries == 0)) { | 2030 | if (unlikely(path->p_hdr->eh_entries == 0)) { |
| 2078 | EXT4_ERROR_INODE(inode, "path->p_hdr->eh_entries == 0"); | 2031 | EXT4_ERROR_INODE(inode, "path->p_hdr->eh_entries == 0"); |
| 2079 | return -EIO; | 2032 | return -EIO; |
| @@ -2181,7 +2134,7 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode, | |||
| 2181 | ext4_fsblk_t start; | 2134 | ext4_fsblk_t start; |
| 2182 | 2135 | ||
| 2183 | num = le32_to_cpu(ex->ee_block) + ee_len - from; | 2136 | num = le32_to_cpu(ex->ee_block) + ee_len - from; |
| 2184 | start = ext_pblock(ex) + ee_len - num; | 2137 | start = ext4_ext_pblock(ex) + ee_len - num; |
| 2185 | ext_debug("free last %u blocks starting %llu\n", num, start); | 2138 | ext_debug("free last %u blocks starting %llu\n", num, start); |
| 2186 | ext4_free_blocks(handle, inode, 0, start, num, flags); | 2139 | ext4_free_blocks(handle, inode, 0, start, num, flags); |
| 2187 | } else if (from == le32_to_cpu(ex->ee_block) | 2140 | } else if (from == le32_to_cpu(ex->ee_block) |
| @@ -2310,7 +2263,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
| 2310 | goto out; | 2263 | goto out; |
| 2311 | 2264 | ||
| 2312 | ext_debug("new extent: %u:%u:%llu\n", block, num, | 2265 | ext_debug("new extent: %u:%u:%llu\n", block, num, |
| 2313 | ext_pblock(ex)); | 2266 | ext4_ext_pblock(ex)); |
| 2314 | ex--; | 2267 | ex--; |
| 2315 | ex_ee_block = le32_to_cpu(ex->ee_block); | 2268 | ex_ee_block = le32_to_cpu(ex->ee_block); |
| 2316 | ex_ee_len = ext4_ext_get_actual_len(ex); | 2269 | ex_ee_len = ext4_ext_get_actual_len(ex); |
| @@ -2421,9 +2374,9 @@ again: | |||
| 2421 | struct buffer_head *bh; | 2374 | struct buffer_head *bh; |
| 2422 | /* go to the next level */ | 2375 | /* go to the next level */ |
| 2423 | ext_debug("move to level %d (block %llu)\n", | 2376 | ext_debug("move to level %d (block %llu)\n", |
| 2424 | i + 1, idx_pblock(path[i].p_idx)); | 2377 | i + 1, ext4_idx_pblock(path[i].p_idx)); |
| 2425 | memset(path + i + 1, 0, sizeof(*path)); | 2378 | memset(path + i + 1, 0, sizeof(*path)); |
| 2426 | bh = sb_bread(sb, idx_pblock(path[i].p_idx)); | 2379 | bh = sb_bread(sb, ext4_idx_pblock(path[i].p_idx)); |
| 2427 | if (!bh) { | 2380 | if (!bh) { |
| 2428 | /* should we reset i_size? */ | 2381 | /* should we reset i_size? */ |
| 2429 | err = -EIO; | 2382 | err = -EIO; |
| @@ -2535,77 +2488,21 @@ void ext4_ext_release(struct super_block *sb) | |||
| 2535 | #endif | 2488 | #endif |
| 2536 | } | 2489 | } |
| 2537 | 2490 | ||
| 2538 | static void bi_complete(struct bio *bio, int error) | ||
| 2539 | { | ||
| 2540 | complete((struct completion *)bio->bi_private); | ||
| 2541 | } | ||
| 2542 | |||
| 2543 | /* FIXME!! we need to try to merge to left or right after zero-out */ | 2491 | /* FIXME!! we need to try to merge to left or right after zero-out */ |
| 2544 | static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) | 2492 | static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) |
| 2545 | { | 2493 | { |
| 2494 | ext4_fsblk_t ee_pblock; | ||
| 2495 | unsigned int ee_len; | ||
| 2546 | int ret; | 2496 | int ret; |
| 2547 | struct bio *bio; | ||
| 2548 | int blkbits, blocksize; | ||
| 2549 | sector_t ee_pblock; | ||
| 2550 | struct completion event; | ||
| 2551 | unsigned int ee_len, len, done, offset; | ||
| 2552 | 2497 | ||
| 2553 | |||
| 2554 | blkbits = inode->i_blkbits; | ||
| 2555 | blocksize = inode->i_sb->s_blocksize; | ||
| 2556 | ee_len = ext4_ext_get_actual_len(ex); | 2498 | ee_len = ext4_ext_get_actual_len(ex); |
| 2557 | ee_pblock = ext_pblock(ex); | 2499 | ee_pblock = ext4_ext_pblock(ex); |
| 2558 | |||
| 2559 | /* convert ee_pblock to 512 byte sectors */ | ||
| 2560 | ee_pblock = ee_pblock << (blkbits - 9); | ||
| 2561 | |||
| 2562 | while (ee_len > 0) { | ||
| 2563 | |||
| 2564 | if (ee_len > BIO_MAX_PAGES) | ||
| 2565 | len = BIO_MAX_PAGES; | ||
| 2566 | else | ||
| 2567 | len = ee_len; | ||
| 2568 | |||
| 2569 | bio = bio_alloc(GFP_NOIO, len); | ||
| 2570 | if (!bio) | ||
| 2571 | return -ENOMEM; | ||
| 2572 | |||
| 2573 | bio->bi_sector = ee_pblock; | ||
| 2574 | bio->bi_bdev = inode->i_sb->s_bdev; | ||
| 2575 | |||
| 2576 | done = 0; | ||
| 2577 | offset = 0; | ||
| 2578 | while (done < len) { | ||
| 2579 | ret = bio_add_page(bio, ZERO_PAGE(0), | ||
| 2580 | blocksize, offset); | ||
| 2581 | if (ret != blocksize) { | ||
| 2582 | /* | ||
| 2583 | * We can't add any more pages because of | ||
| 2584 | * hardware limitations. Start a new bio. | ||
| 2585 | */ | ||
| 2586 | break; | ||
| 2587 | } | ||
| 2588 | done++; | ||
| 2589 | offset += blocksize; | ||
| 2590 | if (offset >= PAGE_CACHE_SIZE) | ||
| 2591 | offset = 0; | ||
| 2592 | } | ||
| 2593 | 2500 | ||
| 2594 | init_completion(&event); | 2501 | ret = sb_issue_zeroout(inode->i_sb, ee_pblock, ee_len, GFP_NOFS); |
| 2595 | bio->bi_private = &event; | 2502 | if (ret > 0) |
| 2596 | bio->bi_end_io = bi_complete; | 2503 | ret = 0; |
| 2597 | submit_bio(WRITE, bio); | ||
| 2598 | wait_for_completion(&event); | ||
| 2599 | 2504 | ||
| 2600 | if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) { | 2505 | return ret; |
| 2601 | bio_put(bio); | ||
| 2602 | return -EIO; | ||
| 2603 | } | ||
| 2604 | bio_put(bio); | ||
| 2605 | ee_len -= done; | ||
| 2606 | ee_pblock += done << (blkbits - 9); | ||
| 2607 | } | ||
| 2608 | return 0; | ||
| 2609 | } | 2506 | } |
| 2610 | 2507 | ||
| 2611 | #define EXT4_EXT_ZERO_LEN 7 | 2508 | #define EXT4_EXT_ZERO_LEN 7 |
| @@ -2651,12 +2548,12 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
| 2651 | ee_block = le32_to_cpu(ex->ee_block); | 2548 | ee_block = le32_to_cpu(ex->ee_block); |
| 2652 | ee_len = ext4_ext_get_actual_len(ex); | 2549 | ee_len = ext4_ext_get_actual_len(ex); |
| 2653 | allocated = ee_len - (map->m_lblk - ee_block); | 2550 | allocated = ee_len - (map->m_lblk - ee_block); |
| 2654 | newblock = map->m_lblk - ee_block + ext_pblock(ex); | 2551 | newblock = map->m_lblk - ee_block + ext4_ext_pblock(ex); |
| 2655 | 2552 | ||
| 2656 | ex2 = ex; | 2553 | ex2 = ex; |
| 2657 | orig_ex.ee_block = ex->ee_block; | 2554 | orig_ex.ee_block = ex->ee_block; |
| 2658 | orig_ex.ee_len = cpu_to_le16(ee_len); | 2555 | orig_ex.ee_len = cpu_to_le16(ee_len); |
| 2659 | ext4_ext_store_pblock(&orig_ex, ext_pblock(ex)); | 2556 | ext4_ext_store_pblock(&orig_ex, ext4_ext_pblock(ex)); |
| 2660 | 2557 | ||
| 2661 | /* | 2558 | /* |
| 2662 | * It is safe to convert extent to initialized via explicit | 2559 | * It is safe to convert extent to initialized via explicit |
| @@ -2675,7 +2572,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
| 2675 | /* update the extent length and mark as initialized */ | 2572 | /* update the extent length and mark as initialized */ |
| 2676 | ex->ee_block = orig_ex.ee_block; | 2573 | ex->ee_block = orig_ex.ee_block; |
| 2677 | ex->ee_len = orig_ex.ee_len; | 2574 | ex->ee_len = orig_ex.ee_len; |
| 2678 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2575 | ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex)); |
| 2679 | ext4_ext_dirty(handle, inode, path + depth); | 2576 | ext4_ext_dirty(handle, inode, path + depth); |
| 2680 | /* zeroed the full extent */ | 2577 | /* zeroed the full extent */ |
| 2681 | return allocated; | 2578 | return allocated; |
| @@ -2710,7 +2607,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
| 2710 | ex->ee_block = orig_ex.ee_block; | 2607 | ex->ee_block = orig_ex.ee_block; |
| 2711 | ex->ee_len = cpu_to_le16(ee_len - allocated); | 2608 | ex->ee_len = cpu_to_le16(ee_len - allocated); |
| 2712 | ext4_ext_mark_uninitialized(ex); | 2609 | ext4_ext_mark_uninitialized(ex); |
| 2713 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2610 | ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex)); |
| 2714 | ext4_ext_dirty(handle, inode, path + depth); | 2611 | ext4_ext_dirty(handle, inode, path + depth); |
| 2715 | 2612 | ||
| 2716 | ex3 = &newex; | 2613 | ex3 = &newex; |
| @@ -2725,7 +2622,8 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
| 2725 | goto fix_extent_len; | 2622 | goto fix_extent_len; |
| 2726 | ex->ee_block = orig_ex.ee_block; | 2623 | ex->ee_block = orig_ex.ee_block; |
| 2727 | ex->ee_len = orig_ex.ee_len; | 2624 | ex->ee_len = orig_ex.ee_len; |
| 2728 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2625 | ext4_ext_store_pblock(ex, |
| 2626 | ext4_ext_pblock(&orig_ex)); | ||
| 2729 | ext4_ext_dirty(handle, inode, path + depth); | 2627 | ext4_ext_dirty(handle, inode, path + depth); |
| 2730 | /* blocks available from map->m_lblk */ | 2628 | /* blocks available from map->m_lblk */ |
| 2731 | return allocated; | 2629 | return allocated; |
| @@ -2782,7 +2680,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
| 2782 | /* update the extent length and mark as initialized */ | 2680 | /* update the extent length and mark as initialized */ |
| 2783 | ex->ee_block = orig_ex.ee_block; | 2681 | ex->ee_block = orig_ex.ee_block; |
| 2784 | ex->ee_len = orig_ex.ee_len; | 2682 | ex->ee_len = orig_ex.ee_len; |
| 2785 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2683 | ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex)); |
| 2786 | ext4_ext_dirty(handle, inode, path + depth); | 2684 | ext4_ext_dirty(handle, inode, path + depth); |
| 2787 | /* zeroed the full extent */ | 2685 | /* zeroed the full extent */ |
| 2788 | /* blocks available from map->m_lblk */ | 2686 | /* blocks available from map->m_lblk */ |
| @@ -2833,7 +2731,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
| 2833 | /* update the extent length and mark as initialized */ | 2731 | /* update the extent length and mark as initialized */ |
| 2834 | ex->ee_block = orig_ex.ee_block; | 2732 | ex->ee_block = orig_ex.ee_block; |
| 2835 | ex->ee_len = orig_ex.ee_len; | 2733 | ex->ee_len = orig_ex.ee_len; |
| 2836 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2734 | ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex)); |
| 2837 | ext4_ext_dirty(handle, inode, path + depth); | 2735 | ext4_ext_dirty(handle, inode, path + depth); |
| 2838 | /* zero out the first half */ | 2736 | /* zero out the first half */ |
| 2839 | /* blocks available from map->m_lblk */ | 2737 | /* blocks available from map->m_lblk */ |
| @@ -2902,7 +2800,7 @@ insert: | |||
| 2902 | /* update the extent length and mark as initialized */ | 2800 | /* update the extent length and mark as initialized */ |
| 2903 | ex->ee_block = orig_ex.ee_block; | 2801 | ex->ee_block = orig_ex.ee_block; |
| 2904 | ex->ee_len = orig_ex.ee_len; | 2802 | ex->ee_len = orig_ex.ee_len; |
| 2905 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2803 | ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex)); |
| 2906 | ext4_ext_dirty(handle, inode, path + depth); | 2804 | ext4_ext_dirty(handle, inode, path + depth); |
| 2907 | /* zero out the first half */ | 2805 | /* zero out the first half */ |
| 2908 | return allocated; | 2806 | return allocated; |
| @@ -2915,7 +2813,7 @@ out: | |||
| 2915 | fix_extent_len: | 2813 | fix_extent_len: |
| 2916 | ex->ee_block = orig_ex.ee_block; | 2814 | ex->ee_block = orig_ex.ee_block; |
| 2917 | ex->ee_len = orig_ex.ee_len; | 2815 | ex->ee_len = orig_ex.ee_len; |
| 2918 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2816 | ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex)); |
| 2919 | ext4_ext_mark_uninitialized(ex); | 2817 | ext4_ext_mark_uninitialized(ex); |
| 2920 | ext4_ext_dirty(handle, inode, path + depth); | 2818 | ext4_ext_dirty(handle, inode, path + depth); |
| 2921 | return err; | 2819 | return err; |
| @@ -2973,12 +2871,12 @@ static int ext4_split_unwritten_extents(handle_t *handle, | |||
| 2973 | ee_block = le32_to_cpu(ex->ee_block); | 2871 | ee_block = le32_to_cpu(ex->ee_block); |
| 2974 | ee_len = ext4_ext_get_actual_len(ex); | 2872 | ee_len = ext4_ext_get_actual_len(ex); |
| 2975 | allocated = ee_len - (map->m_lblk - ee_block); | 2873 | allocated = ee_len - (map->m_lblk - ee_block); |
| 2976 | newblock = map->m_lblk - ee_block + ext_pblock(ex); | 2874 | newblock = map->m_lblk - ee_block + ext4_ext_pblock(ex); |
| 2977 | 2875 | ||
| 2978 | ex2 = ex; | 2876 | ex2 = ex; |
| 2979 | orig_ex.ee_block = ex->ee_block; | 2877 | orig_ex.ee_block = ex->ee_block; |
| 2980 | orig_ex.ee_len = cpu_to_le16(ee_len); | 2878 | orig_ex.ee_len = cpu_to_le16(ee_len); |
| 2981 | ext4_ext_store_pblock(&orig_ex, ext_pblock(ex)); | 2879 | ext4_ext_store_pblock(&orig_ex, ext4_ext_pblock(ex)); |
| 2982 | 2880 | ||
| 2983 | /* | 2881 | /* |
| 2984 | * It is safe to convert extent to initialized via explicit | 2882 | * It is safe to convert extent to initialized via explicit |
| @@ -3027,7 +2925,7 @@ static int ext4_split_unwritten_extents(handle_t *handle, | |||
| 3027 | /* update the extent length and mark as initialized */ | 2925 | /* update the extent length and mark as initialized */ |
| 3028 | ex->ee_block = orig_ex.ee_block; | 2926 | ex->ee_block = orig_ex.ee_block; |
| 3029 | ex->ee_len = orig_ex.ee_len; | 2927 | ex->ee_len = orig_ex.ee_len; |
| 3030 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 2928 | ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex)); |
| 3031 | ext4_ext_dirty(handle, inode, path + depth); | 2929 | ext4_ext_dirty(handle, inode, path + depth); |
| 3032 | /* zeroed the full extent */ | 2930 | /* zeroed the full extent */ |
| 3033 | /* blocks available from map->m_lblk */ | 2931 | /* blocks available from map->m_lblk */ |
| @@ -3099,7 +2997,7 @@ insert: | |||
| 3099 | /* update the extent length and mark as initialized */ | 2997 | /* update the extent length and mark as initialized */ |
| 3100 | ex->ee_block = orig_ex.ee_block; | 2998 | ex->ee_block = orig_ex.ee_block; |
| 3101 | ex->ee_len = orig_ex.ee_len; | 2999 | ex->ee_len = orig_ex.ee_len; |
| 3102 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 3000 | ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex)); |
| 3103 | ext4_ext_dirty(handle, inode, path + depth); | 3001 | ext4_ext_dirty(handle, inode, path + depth); |
| 3104 | /* zero out the first half */ | 3002 | /* zero out the first half */ |
| 3105 | return allocated; | 3003 | return allocated; |
| @@ -3112,7 +3010,7 @@ out: | |||
| 3112 | fix_extent_len: | 3010 | fix_extent_len: |
| 3113 | ex->ee_block = orig_ex.ee_block; | 3011 | ex->ee_block = orig_ex.ee_block; |
| 3114 | ex->ee_len = orig_ex.ee_len; | 3012 | ex->ee_len = orig_ex.ee_len; |
| 3115 | ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); | 3013 | ext4_ext_store_pblock(ex, ext4_ext_pblock(&orig_ex)); |
| 3116 | ext4_ext_mark_uninitialized(ex); | 3014 | ext4_ext_mark_uninitialized(ex); |
| 3117 | ext4_ext_dirty(handle, inode, path + depth); | 3015 | ext4_ext_dirty(handle, inode, path + depth); |
| 3118 | return err; | 3016 | return err; |
| @@ -3180,6 +3078,57 @@ static void unmap_underlying_metadata_blocks(struct block_device *bdev, | |||
| 3180 | unmap_underlying_metadata(bdev, block + i); | 3078 | unmap_underlying_metadata(bdev, block + i); |
| 3181 | } | 3079 | } |
| 3182 | 3080 | ||
| 3081 | /* | ||
| 3082 | * Handle EOFBLOCKS_FL flag, clearing it if necessary | ||
| 3083 | */ | ||
| 3084 | static int check_eofblocks_fl(handle_t *handle, struct inode *inode, | ||
| 3085 | struct ext4_map_blocks *map, | ||
| 3086 | struct ext4_ext_path *path, | ||
| 3087 | unsigned int len) | ||
| 3088 | { | ||
| 3089 | int i, depth; | ||
| 3090 | struct ext4_extent_header *eh; | ||
| 3091 | struct ext4_extent *ex, *last_ex; | ||
| 3092 | |||
| 3093 | if (!ext4_test_inode_flag(inode, EXT4_INODE_EOFBLOCKS)) | ||
| 3094 | return 0; | ||
| 3095 | |||
| 3096 | depth = ext_depth(inode); | ||
| 3097 | eh = path[depth].p_hdr; | ||
| 3098 | ex = path[depth].p_ext; | ||
| 3099 | |||
| 3100 | if (unlikely(!eh->eh_entries)) { | ||
| 3101 | EXT4_ERROR_INODE(inode, "eh->eh_entries == 0 and " | ||
| 3102 | "EOFBLOCKS_FL set"); | ||
| 3103 | return -EIO; | ||
| 3104 | } | ||
| 3105 | last_ex = EXT_LAST_EXTENT(eh); | ||
| 3106 | /* | ||
| 3107 | * We should clear the EOFBLOCKS_FL flag if we are writing the | ||
| 3108 | * last block in the last extent in the file. We test this by | ||
| 3109 | * first checking to see if the caller to | ||
| 3110 | * ext4_ext_get_blocks() was interested in the last block (or | ||
| 3111 | * a block beyond the last block) in the current extent. If | ||
| 3112 | * this turns out to be false, we can bail out from this | ||
| 3113 | * function immediately. | ||
| 3114 | */ | ||
| 3115 | if (map->m_lblk + len < le32_to_cpu(last_ex->ee_block) + | ||
| 3116 | ext4_ext_get_actual_len(last_ex)) | ||
| 3117 | return 0; | ||
| 3118 | /* | ||
| 3119 | * If the caller does appear to be planning to write at or | ||
| 3120 | * beyond the end of the current extent, we then test to see | ||
| 3121 | * if the current extent is the last extent in the file, by | ||
| 3122 | * checking to make sure it was reached via the rightmost node | ||
| 3123 | * at each level of the tree. | ||
| 3124 | */ | ||
| 3125 | for (i = depth-1; i >= 0; i--) | ||
| 3126 | if (path[i].p_idx != EXT_LAST_INDEX(path[i].p_hdr)) | ||
| 3127 | return 0; | ||
| 3128 | ext4_clear_inode_flag(inode, EXT4_INODE_EOFBLOCKS); | ||
| 3129 | return ext4_mark_inode_dirty(handle, inode); | ||
| 3130 | } | ||
| 3131 | |||
| 3183 | static int | 3132 | static int |
| 3184 | ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, | 3133 | ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, |
| 3185 | struct ext4_map_blocks *map, | 3134 | struct ext4_map_blocks *map, |
| @@ -3206,7 +3155,7 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, | |||
| 3206 | * completed | 3155 | * completed |
| 3207 | */ | 3156 | */ |
| 3208 | if (io) | 3157 | if (io) |
| 3209 | io->flag = EXT4_IO_UNWRITTEN; | 3158 | io->flag = EXT4_IO_END_UNWRITTEN; |
| 3210 | else | 3159 | else |
| 3211 | ext4_set_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN); | 3160 | ext4_set_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN); |
| 3212 | if (ext4_should_dioread_nolock(inode)) | 3161 | if (ext4_should_dioread_nolock(inode)) |
| @@ -3217,8 +3166,12 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, | |||
| 3217 | if ((flags & EXT4_GET_BLOCKS_CONVERT)) { | 3166 | if ((flags & EXT4_GET_BLOCKS_CONVERT)) { |
| 3218 | ret = ext4_convert_unwritten_extents_endio(handle, inode, | 3167 | ret = ext4_convert_unwritten_extents_endio(handle, inode, |
| 3219 | path); | 3168 | path); |
| 3220 | if (ret >= 0) | 3169 | if (ret >= 0) { |
| 3221 | ext4_update_inode_fsync_trans(handle, inode, 1); | 3170 | ext4_update_inode_fsync_trans(handle, inode, 1); |
| 3171 | err = check_eofblocks_fl(handle, inode, map, path, | ||
| 3172 | map->m_len); | ||
| 3173 | } else | ||
| 3174 | err = ret; | ||
| 3222 | goto out2; | 3175 | goto out2; |
| 3223 | } | 3176 | } |
| 3224 | /* buffered IO case */ | 3177 | /* buffered IO case */ |
| @@ -3244,8 +3197,13 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, | |||
| 3244 | 3197 | ||
| 3245 | /* buffered write, writepage time, convert*/ | 3198 | /* buffered write, writepage time, convert*/ |
| 3246 | ret = ext4_ext_convert_to_initialized(handle, inode, map, path); | 3199 | ret = ext4_ext_convert_to_initialized(handle, inode, map, path); |
| 3247 | if (ret >= 0) | 3200 | if (ret >= 0) { |
| 3248 | ext4_update_inode_fsync_trans(handle, inode, 1); | 3201 | ext4_update_inode_fsync_trans(handle, inode, 1); |
| 3202 | err = check_eofblocks_fl(handle, inode, map, path, map->m_len); | ||
| 3203 | if (err < 0) | ||
| 3204 | goto out2; | ||
| 3205 | } | ||
| 3206 | |||
| 3249 | out: | 3207 | out: |
| 3250 | if (ret <= 0) { | 3208 | if (ret <= 0) { |
| 3251 | err = ret; | 3209 | err = ret; |
| @@ -3292,6 +3250,7 @@ out2: | |||
| 3292 | } | 3250 | } |
| 3293 | return err ? err : allocated; | 3251 | return err ? err : allocated; |
| 3294 | } | 3252 | } |
| 3253 | |||
| 3295 | /* | 3254 | /* |
| 3296 | * Block allocation/map/preallocation routine for extents based files | 3255 | * Block allocation/map/preallocation routine for extents based files |
| 3297 | * | 3256 | * |
| @@ -3315,9 +3274,9 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, | |||
| 3315 | { | 3274 | { |
| 3316 | struct ext4_ext_path *path = NULL; | 3275 | struct ext4_ext_path *path = NULL; |
| 3317 | struct ext4_extent_header *eh; | 3276 | struct ext4_extent_header *eh; |
| 3318 | struct ext4_extent newex, *ex, *last_ex; | 3277 | struct ext4_extent newex, *ex; |
| 3319 | ext4_fsblk_t newblock; | 3278 | ext4_fsblk_t newblock; |
| 3320 | int i, err = 0, depth, ret, cache_type; | 3279 | int err = 0, depth, ret, cache_type; |
| 3321 | unsigned int allocated = 0; | 3280 | unsigned int allocated = 0; |
| 3322 | struct ext4_allocation_request ar; | 3281 | struct ext4_allocation_request ar; |
| 3323 | ext4_io_end_t *io = EXT4_I(inode)->cur_aio_dio; | 3282 | ext4_io_end_t *io = EXT4_I(inode)->cur_aio_dio; |
| @@ -3341,7 +3300,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, | |||
| 3341 | /* block is already allocated */ | 3300 | /* block is already allocated */ |
| 3342 | newblock = map->m_lblk | 3301 | newblock = map->m_lblk |
| 3343 | - le32_to_cpu(newex.ee_block) | 3302 | - le32_to_cpu(newex.ee_block) |
| 3344 | + ext_pblock(&newex); | 3303 | + ext4_ext_pblock(&newex); |
| 3345 | /* number of remaining blocks in the extent */ | 3304 | /* number of remaining blocks in the extent */ |
| 3346 | allocated = ext4_ext_get_actual_len(&newex) - | 3305 | allocated = ext4_ext_get_actual_len(&newex) - |
| 3347 | (map->m_lblk - le32_to_cpu(newex.ee_block)); | 3306 | (map->m_lblk - le32_to_cpu(newex.ee_block)); |
| @@ -3379,7 +3338,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, | |||
| 3379 | ex = path[depth].p_ext; | 3338 | ex = path[depth].p_ext; |
| 3380 | if (ex) { | 3339 | if (ex) { |
| 3381 | ext4_lblk_t ee_block = le32_to_cpu(ex->ee_block); | 3340 | ext4_lblk_t ee_block = le32_to_cpu(ex->ee_block); |
| 3382 | ext4_fsblk_t ee_start = ext_pblock(ex); | 3341 | ext4_fsblk_t ee_start = ext4_ext_pblock(ex); |
| 3383 | unsigned short ee_len; | 3342 | unsigned short ee_len; |
| 3384 | 3343 | ||
| 3385 | /* | 3344 | /* |
| @@ -3488,7 +3447,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, | |||
| 3488 | */ | 3447 | */ |
| 3489 | if ((flags & EXT4_GET_BLOCKS_PRE_IO)) { | 3448 | if ((flags & EXT4_GET_BLOCKS_PRE_IO)) { |
| 3490 | if (io) | 3449 | if (io) |
| 3491 | io->flag = EXT4_IO_UNWRITTEN; | 3450 | io->flag = EXT4_IO_END_UNWRITTEN; |
| 3492 | else | 3451 | else |
| 3493 | ext4_set_inode_state(inode, | 3452 | ext4_set_inode_state(inode, |
| 3494 | EXT4_STATE_DIO_UNWRITTEN); | 3453 | EXT4_STATE_DIO_UNWRITTEN); |
| @@ -3497,44 +3456,23 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, | |||
| 3497 | map->m_flags |= EXT4_MAP_UNINIT; | 3456 | map->m_flags |= EXT4_MAP_UNINIT; |
| 3498 | } | 3457 | } |
| 3499 | 3458 | ||
| 3500 | if (unlikely(ext4_test_inode_flag(inode, EXT4_INODE_EOFBLOCKS))) { | 3459 | err = check_eofblocks_fl(handle, inode, map, path, ar.len); |
| 3501 | if (unlikely(!eh->eh_entries)) { | 3460 | if (err) |
| 3502 | EXT4_ERROR_INODE(inode, | 3461 | goto out2; |
| 3503 | "eh->eh_entries == 0 and " | 3462 | |
| 3504 | "EOFBLOCKS_FL set"); | ||
| 3505 | err = -EIO; | ||
| 3506 | goto out2; | ||
| 3507 | } | ||
| 3508 | last_ex = EXT_LAST_EXTENT(eh); | ||
| 3509 | /* | ||
| 3510 | * If the current leaf block was reached by looking at | ||
| 3511 | * the last index block all the way down the tree, and | ||
| 3512 | * we are extending the inode beyond the last extent | ||
| 3513 | * in the current leaf block, then clear the | ||
| 3514 | * EOFBLOCKS_FL flag. | ||
| 3515 | */ | ||
| 3516 | for (i = depth-1; i >= 0; i--) { | ||
| 3517 | if (path[i].p_idx != EXT_LAST_INDEX(path[i].p_hdr)) | ||
| 3518 | break; | ||
| 3519 | } | ||
| 3520 | if ((i < 0) && | ||
| 3521 | (map->m_lblk + ar.len > le32_to_cpu(last_ex->ee_block) + | ||
| 3522 | ext4_ext_get_actual_len(last_ex))) | ||
| 3523 | ext4_clear_inode_flag(inode, EXT4_INODE_EOFBLOCKS); | ||
| 3524 | } | ||
| 3525 | err = ext4_ext_insert_extent(handle, inode, path, &newex, flags); | 3463 | err = ext4_ext_insert_extent(handle, inode, path, &newex, flags); |
| 3526 | if (err) { | 3464 | if (err) { |
| 3527 | /* free data blocks we just allocated */ | 3465 | /* free data blocks we just allocated */ |
| 3528 | /* not a good idea to call discard here directly, | 3466 | /* not a good idea to call discard here directly, |
| 3529 | * but otherwise we'd need to call it every free() */ | 3467 | * but otherwise we'd need to call it every free() */ |
| 3530 | ext4_discard_preallocations(inode); | 3468 | ext4_discard_preallocations(inode); |
| 3531 | ext4_free_blocks(handle, inode, 0, ext_pblock(&newex), | 3469 | ext4_free_blocks(handle, inode, 0, ext4_ext_pblock(&newex), |
| 3532 | ext4_ext_get_actual_len(&newex), 0); | 3470 | ext4_ext_get_actual_len(&newex), 0); |
| 3533 | goto out2; | 3471 | goto out2; |
| 3534 | } | 3472 | } |
| 3535 | 3473 | ||
| 3536 | /* previous routine could use block we allocated */ | 3474 | /* previous routine could use block we allocated */ |
| 3537 | newblock = ext_pblock(&newex); | 3475 | newblock = ext4_ext_pblock(&newex); |
| 3538 | allocated = ext4_ext_get_actual_len(&newex); | 3476 | allocated = ext4_ext_get_actual_len(&newex); |
| 3539 | if (allocated > map->m_len) | 3477 | if (allocated > map->m_len) |
| 3540 | allocated = map->m_len; | 3478 | allocated = map->m_len; |
| @@ -3729,7 +3667,7 @@ retry: | |||
| 3729 | printk(KERN_ERR "%s: ext4_ext_map_blocks " | 3667 | printk(KERN_ERR "%s: ext4_ext_map_blocks " |
| 3730 | "returned error inode#%lu, block=%u, " | 3668 | "returned error inode#%lu, block=%u, " |
| 3731 | "max_blocks=%u", __func__, | 3669 | "max_blocks=%u", __func__, |
| 3732 | inode->i_ino, block, max_blocks); | 3670 | inode->i_ino, map.m_lblk, max_blocks); |
| 3733 | #endif | 3671 | #endif |
| 3734 | ext4_mark_inode_dirty(handle, inode); | 3672 | ext4_mark_inode_dirty(handle, inode); |
| 3735 | ret2 = ext4_journal_stop(handle); | 3673 | ret2 = ext4_journal_stop(handle); |
