diff options
Diffstat (limited to 'fs/ext4/extents.c')
| -rw-r--r-- | fs/ext4/extents.c | 682 |
1 files changed, 548 insertions, 134 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index b9ce24129070..750c46f7d893 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/quotaops.h> | 39 | #include <linux/quotaops.h> |
| 40 | #include <linux/string.h> | 40 | #include <linux/string.h> |
| 41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
| 42 | #include <linux/falloc.h> | ||
| 42 | #include <linux/ext4_fs_extents.h> | 43 | #include <linux/ext4_fs_extents.h> |
| 43 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
| 44 | 45 | ||
| @@ -91,36 +92,6 @@ static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb) | |||
| 91 | ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); | 92 | ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); |
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | static int ext4_ext_check_header(const char *function, struct inode *inode, | ||
| 95 | struct ext4_extent_header *eh) | ||
| 96 | { | ||
| 97 | const char *error_msg = NULL; | ||
| 98 | |||
| 99 | if (unlikely(eh->eh_magic != EXT4_EXT_MAGIC)) { | ||
| 100 | error_msg = "invalid magic"; | ||
| 101 | goto corrupted; | ||
| 102 | } | ||
| 103 | if (unlikely(eh->eh_max == 0)) { | ||
| 104 | error_msg = "invalid eh_max"; | ||
| 105 | goto corrupted; | ||
| 106 | } | ||
| 107 | if (unlikely(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max))) { | ||
| 108 | error_msg = "invalid eh_entries"; | ||
| 109 | goto corrupted; | ||
| 110 | } | ||
| 111 | return 0; | ||
| 112 | |||
| 113 | corrupted: | ||
| 114 | ext4_error(inode->i_sb, function, | ||
| 115 | "bad header in inode #%lu: %s - magic %x, " | ||
| 116 | "entries %u, max %u, depth %u", | ||
| 117 | inode->i_ino, error_msg, le16_to_cpu(eh->eh_magic), | ||
| 118 | le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max), | ||
| 119 | le16_to_cpu(eh->eh_depth)); | ||
| 120 | |||
| 121 | return -EIO; | ||
| 122 | } | ||
| 123 | |||
| 124 | static handle_t *ext4_ext_journal_restart(handle_t *handle, int needed) | 95 | static handle_t *ext4_ext_journal_restart(handle_t *handle, int needed) |
| 125 | { | 96 | { |
| 126 | int err; | 97 | int err; |
| @@ -269,6 +240,70 @@ static int ext4_ext_space_root_idx(struct inode *inode) | |||
| 269 | return size; | 240 | return size; |
| 270 | } | 241 | } |
| 271 | 242 | ||
| 243 | static int | ||
| 244 | ext4_ext_max_entries(struct inode *inode, int depth) | ||
| 245 | { | ||
| 246 | int max; | ||
| 247 | |||
| 248 | if (depth == ext_depth(inode)) { | ||
| 249 | if (depth == 0) | ||
| 250 | max = ext4_ext_space_root(inode); | ||
| 251 | else | ||
| 252 | max = ext4_ext_space_root_idx(inode); | ||
| 253 | } else { | ||
| 254 | if (depth == 0) | ||
| 255 | max = ext4_ext_space_block(inode); | ||
| 256 | else | ||
| 257 | max = ext4_ext_space_block_idx(inode); | ||
| 258 | } | ||
| 259 | |||
| 260 | return max; | ||
| 261 | } | ||
| 262 | |||
| 263 | static int __ext4_ext_check_header(const char *function, struct inode *inode, | ||
| 264 | struct ext4_extent_header *eh, | ||
| 265 | int depth) | ||
| 266 | { | ||
| 267 | const char *error_msg; | ||
| 268 | int max = 0; | ||
| 269 | |||
| 270 | if (unlikely(eh->eh_magic != EXT4_EXT_MAGIC)) { | ||
| 271 | error_msg = "invalid magic"; | ||
| 272 | goto corrupted; | ||
| 273 | } | ||
| 274 | if (unlikely(le16_to_cpu(eh->eh_depth) != depth)) { | ||
| 275 | error_msg = "unexpected eh_depth"; | ||
| 276 | goto corrupted; | ||
| 277 | } | ||
| 278 | if (unlikely(eh->eh_max == 0)) { | ||
| 279 | error_msg = "invalid eh_max"; | ||
| 280 | goto corrupted; | ||
| 281 | } | ||
| 282 | max = ext4_ext_max_entries(inode, depth); | ||
| 283 | if (unlikely(le16_to_cpu(eh->eh_max) > max)) { | ||
| 284 | error_msg = "too large eh_max"; | ||
| 285 | goto corrupted; | ||
| 286 | } | ||
| 287 | if (unlikely(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max))) { | ||
| 288 | error_msg = "invalid eh_entries"; | ||
| 289 | goto corrupted; | ||
| 290 | } | ||
| 291 | return 0; | ||
| 292 | |||
| 293 | corrupted: | ||
| 294 | ext4_error(inode->i_sb, function, | ||
| 295 | "bad header in inode #%lu: %s - magic %x, " | ||
| 296 | "entries %u, max %u(%u), depth %u(%u)", | ||
| 297 | inode->i_ino, error_msg, le16_to_cpu(eh->eh_magic), | ||
| 298 | le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max), | ||
| 299 | max, le16_to_cpu(eh->eh_depth), depth); | ||
| 300 | |||
| 301 | return -EIO; | ||
| 302 | } | ||
| 303 | |||
| 304 | #define ext4_ext_check_header(inode, eh, depth) \ | ||
| 305 | __ext4_ext_check_header(__FUNCTION__, inode, eh, depth) | ||
| 306 | |||
| 272 | #ifdef EXT_DEBUG | 307 | #ifdef EXT_DEBUG |
| 273 | static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) | 308 | static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) |
| 274 | { | 309 | { |
| @@ -282,7 +317,7 @@ static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path) | |||
| 282 | } else if (path->p_ext) { | 317 | } else if (path->p_ext) { |
| 283 | ext_debug(" %d:%d:%llu ", | 318 | ext_debug(" %d:%d:%llu ", |
| 284 | le32_to_cpu(path->p_ext->ee_block), | 319 | le32_to_cpu(path->p_ext->ee_block), |
| 285 | le16_to_cpu(path->p_ext->ee_len), | 320 | ext4_ext_get_actual_len(path->p_ext), |
| 286 | ext_pblock(path->p_ext)); | 321 | ext_pblock(path->p_ext)); |
| 287 | } else | 322 | } else |
| 288 | ext_debug(" []"); | 323 | ext_debug(" []"); |
| @@ -305,7 +340,7 @@ static void ext4_ext_show_leaf(struct inode *inode, struct ext4_ext_path *path) | |||
| 305 | 340 | ||
| 306 | for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ex++) { | 341 | for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ex++) { |
| 307 | ext_debug("%d:%d:%llu ", le32_to_cpu(ex->ee_block), | 342 | ext_debug("%d:%d:%llu ", le32_to_cpu(ex->ee_block), |
| 308 | le16_to_cpu(ex->ee_len), ext_pblock(ex)); | 343 | ext4_ext_get_actual_len(ex), ext_pblock(ex)); |
| 309 | } | 344 | } |
| 310 | ext_debug("\n"); | 345 | ext_debug("\n"); |
| 311 | } | 346 | } |
| @@ -329,6 +364,7 @@ static void ext4_ext_drop_refs(struct ext4_ext_path *path) | |||
| 329 | /* | 364 | /* |
| 330 | * ext4_ext_binsearch_idx: | 365 | * ext4_ext_binsearch_idx: |
| 331 | * binary search for the closest index of the given block | 366 | * binary search for the closest index of the given block |
| 367 | * the header must be checked before calling this | ||
| 332 | */ | 368 | */ |
| 333 | static void | 369 | static void |
| 334 | ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, int block) | 370 | ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, int block) |
| @@ -336,27 +372,25 @@ ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, int bloc | |||
| 336 | struct ext4_extent_header *eh = path->p_hdr; | 372 | struct ext4_extent_header *eh = path->p_hdr; |
| 337 | struct ext4_extent_idx *r, *l, *m; | 373 | struct ext4_extent_idx *r, *l, *m; |
| 338 | 374 | ||
| 339 | BUG_ON(eh->eh_magic != EXT4_EXT_MAGIC); | ||
| 340 | BUG_ON(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max)); | ||
| 341 | BUG_ON(le16_to_cpu(eh->eh_entries) <= 0); | ||
| 342 | 375 | ||
| 343 | ext_debug("binsearch for %d(idx): ", block); | 376 | ext_debug("binsearch for %d(idx): ", block); |
| 344 | 377 | ||
| 345 | l = EXT_FIRST_INDEX(eh) + 1; | 378 | l = EXT_FIRST_INDEX(eh) + 1; |
| 346 | r = EXT_FIRST_INDEX(eh) + le16_to_cpu(eh->eh_entries) - 1; | 379 | r = EXT_LAST_INDEX(eh); |
| 347 | while (l <= r) { | 380 | while (l <= r) { |
| 348 | m = l + (r - l) / 2; | 381 | m = l + (r - l) / 2; |
| 349 | if (block < le32_to_cpu(m->ei_block)) | 382 | if (block < le32_to_cpu(m->ei_block)) |
| 350 | r = m - 1; | 383 | r = m - 1; |
| 351 | else | 384 | else |
| 352 | l = m + 1; | 385 | l = m + 1; |
| 353 | ext_debug("%p(%u):%p(%u):%p(%u) ", l, l->ei_block, | 386 | ext_debug("%p(%u):%p(%u):%p(%u) ", l, le32_to_cpu(l->ei_block), |
| 354 | m, m->ei_block, r, r->ei_block); | 387 | m, le32_to_cpu(m->ei_block), |
| 388 | r, le32_to_cpu(r->ei_block)); | ||
| 355 | } | 389 | } |
| 356 | 390 | ||
| 357 | path->p_idx = l - 1; | 391 | path->p_idx = l - 1; |
| 358 | ext_debug(" -> %d->%lld ", le32_to_cpu(path->p_idx->ei_block), | 392 | ext_debug(" -> %d->%lld ", le32_to_cpu(path->p_idx->ei_block), |
| 359 | idx_block(path->p_idx)); | 393 | idx_pblock(path->p_idx)); |
| 360 | 394 | ||
| 361 | #ifdef CHECK_BINSEARCH | 395 | #ifdef CHECK_BINSEARCH |
| 362 | { | 396 | { |
| @@ -388,6 +422,7 @@ ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, int bloc | |||
| 388 | /* | 422 | /* |
| 389 | * ext4_ext_binsearch: | 423 | * ext4_ext_binsearch: |
| 390 | * binary search for closest extent of the given block | 424 | * binary search for closest extent of the given block |
| 425 | * the header must be checked before calling this | ||
| 391 | */ | 426 | */ |
| 392 | static void | 427 | static void |
| 393 | ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block) | 428 | ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block) |
| @@ -395,9 +430,6 @@ ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block) | |||
| 395 | struct ext4_extent_header *eh = path->p_hdr; | 430 | struct ext4_extent_header *eh = path->p_hdr; |
| 396 | struct ext4_extent *r, *l, *m; | 431 | struct ext4_extent *r, *l, *m; |
| 397 | 432 | ||
| 398 | BUG_ON(eh->eh_magic != EXT4_EXT_MAGIC); | ||
| 399 | BUG_ON(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max)); | ||
| 400 | |||
| 401 | if (eh->eh_entries == 0) { | 433 | if (eh->eh_entries == 0) { |
| 402 | /* | 434 | /* |
| 403 | * this leaf is empty: | 435 | * this leaf is empty: |
| @@ -409,7 +441,7 @@ ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block) | |||
| 409 | ext_debug("binsearch for %d: ", block); | 441 | ext_debug("binsearch for %d: ", block); |
| 410 | 442 | ||
| 411 | l = EXT_FIRST_EXTENT(eh) + 1; | 443 | l = EXT_FIRST_EXTENT(eh) + 1; |
| 412 | r = EXT_FIRST_EXTENT(eh) + le16_to_cpu(eh->eh_entries) - 1; | 444 | r = EXT_LAST_EXTENT(eh); |
| 413 | 445 | ||
| 414 | while (l <= r) { | 446 | while (l <= r) { |
| 415 | m = l + (r - l) / 2; | 447 | m = l + (r - l) / 2; |
| @@ -417,15 +449,16 @@ ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, int block) | |||
| 417 | r = m - 1; | 449 | r = m - 1; |
| 418 | else | 450 | else |
| 419 | l = m + 1; | 451 | l = m + 1; |
| 420 | ext_debug("%p(%u):%p(%u):%p(%u) ", l, l->ee_block, | 452 | ext_debug("%p(%u):%p(%u):%p(%u) ", l, le32_to_cpu(l->ee_block), |
| 421 | m, m->ee_block, r, r->ee_block); | 453 | m, le32_to_cpu(m->ee_block), |
| 454 | r, le32_to_cpu(r->ee_block)); | ||
| 422 | } | 455 | } |
| 423 | 456 | ||
| 424 | path->p_ext = l - 1; | 457 | path->p_ext = l - 1; |
| 425 | ext_debug(" -> %d:%llu:%d ", | 458 | ext_debug(" -> %d:%llu:%d ", |
| 426 | le32_to_cpu(path->p_ext->ee_block), | 459 | le32_to_cpu(path->p_ext->ee_block), |
| 427 | ext_pblock(path->p_ext), | 460 | ext_pblock(path->p_ext), |
| 428 | le16_to_cpu(path->p_ext->ee_len)); | 461 | ext4_ext_get_actual_len(path->p_ext)); |
| 429 | 462 | ||
| 430 | #ifdef CHECK_BINSEARCH | 463 | #ifdef CHECK_BINSEARCH |
| 431 | { | 464 | { |
| @@ -468,11 +501,10 @@ ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path) | |||
| 468 | short int depth, i, ppos = 0, alloc = 0; | 501 | short int depth, i, ppos = 0, alloc = 0; |
| 469 | 502 | ||
| 470 | eh = ext_inode_hdr(inode); | 503 | eh = ext_inode_hdr(inode); |
| 471 | BUG_ON(eh == NULL); | 504 | depth = ext_depth(inode); |
| 472 | if (ext4_ext_check_header(__FUNCTION__, inode, eh)) | 505 | if (ext4_ext_check_header(inode, eh, depth)) |
| 473 | return ERR_PTR(-EIO); | 506 | return ERR_PTR(-EIO); |
| 474 | 507 | ||
| 475 | i = depth = ext_depth(inode); | ||
| 476 | 508 | ||
| 477 | /* account possible depth increase */ | 509 | /* account possible depth increase */ |
| 478 | if (!path) { | 510 | if (!path) { |
| @@ -484,10 +516,12 @@ ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path) | |||
| 484 | } | 516 | } |
| 485 | path[0].p_hdr = eh; | 517 | path[0].p_hdr = eh; |
| 486 | 518 | ||
| 519 | i = depth; | ||
| 487 | /* walk through the tree */ | 520 | /* walk through the tree */ |
| 488 | while (i) { | 521 | while (i) { |
| 489 | ext_debug("depth %d: num %d, max %d\n", | 522 | ext_debug("depth %d: num %d, max %d\n", |
| 490 | ppos, le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max)); | 523 | ppos, le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max)); |
| 524 | |||
| 491 | ext4_ext_binsearch_idx(inode, path + ppos, block); | 525 | ext4_ext_binsearch_idx(inode, path + ppos, block); |
| 492 | path[ppos].p_block = idx_pblock(path[ppos].p_idx); | 526 | path[ppos].p_block = idx_pblock(path[ppos].p_idx); |
| 493 | path[ppos].p_depth = i; | 527 | path[ppos].p_depth = i; |
| @@ -504,7 +538,7 @@ ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path) | |||
| 504 | path[ppos].p_hdr = eh; | 538 | path[ppos].p_hdr = eh; |
| 505 | i--; | 539 | i--; |
| 506 | 540 | ||
| 507 | if (ext4_ext_check_header(__FUNCTION__, inode, eh)) | 541 | if (ext4_ext_check_header(inode, eh, i)) |
| 508 | goto err; | 542 | goto err; |
| 509 | } | 543 | } |
| 510 | 544 | ||
| @@ -513,9 +547,6 @@ ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path) | |||
| 513 | path[ppos].p_ext = NULL; | 547 | path[ppos].p_ext = NULL; |
| 514 | path[ppos].p_idx = NULL; | 548 | path[ppos].p_idx = NULL; |
| 515 | 549 | ||
| 516 | if (ext4_ext_check_header(__FUNCTION__, inode, eh)) | ||
| 517 | goto err; | ||
| 518 | |||
| 519 | /* find extent */ | 550 | /* find extent */ |
| 520 | ext4_ext_binsearch(inode, path + ppos, block); | 551 | ext4_ext_binsearch(inode, path + ppos, block); |
| 521 | 552 | ||
| @@ -553,7 +584,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, | |||
| 553 | if (curp->p_idx != EXT_LAST_INDEX(curp->p_hdr)) { | 584 | if (curp->p_idx != EXT_LAST_INDEX(curp->p_hdr)) { |
| 554 | len = (len - 1) * sizeof(struct ext4_extent_idx); | 585 | len = (len - 1) * sizeof(struct ext4_extent_idx); |
| 555 | len = len < 0 ? 0 : len; | 586 | len = len < 0 ? 0 : len; |
| 556 | ext_debug("insert new index %d after: %d. " | 587 | ext_debug("insert new index %d after: %llu. " |
| 557 | "move %d from 0x%p to 0x%p\n", | 588 | "move %d from 0x%p to 0x%p\n", |
| 558 | logical, ptr, len, | 589 | logical, ptr, len, |
| 559 | (curp->p_idx + 1), (curp->p_idx + 2)); | 590 | (curp->p_idx + 1), (curp->p_idx + 2)); |
| @@ -564,7 +595,7 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, | |||
| 564 | /* insert before */ | 595 | /* insert before */ |
| 565 | len = len * sizeof(struct ext4_extent_idx); | 596 | len = len * sizeof(struct ext4_extent_idx); |
| 566 | len = len < 0 ? 0 : len; | 597 | len = len < 0 ? 0 : len; |
| 567 | ext_debug("insert new index %d before: %d. " | 598 | ext_debug("insert new index %d before: %llu. " |
| 568 | "move %d from 0x%p to 0x%p\n", | 599 | "move %d from 0x%p to 0x%p\n", |
| 569 | logical, ptr, len, | 600 | logical, ptr, len, |
| 570 | curp->p_idx, (curp->p_idx + 1)); | 601 | curp->p_idx, (curp->p_idx + 1)); |
| @@ -686,7 +717,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
| 686 | ext_debug("move %d:%llu:%d in new leaf %llu\n", | 717 | ext_debug("move %d:%llu:%d in new leaf %llu\n", |
| 687 | le32_to_cpu(path[depth].p_ext->ee_block), | 718 | le32_to_cpu(path[depth].p_ext->ee_block), |
| 688 | ext_pblock(path[depth].p_ext), | 719 | ext_pblock(path[depth].p_ext), |
| 689 | le16_to_cpu(path[depth].p_ext->ee_len), | 720 | ext4_ext_get_actual_len(path[depth].p_ext), |
| 690 | newblock); | 721 | newblock); |
| 691 | /*memmove(ex++, path[depth].p_ext++, | 722 | /*memmove(ex++, path[depth].p_ext++, |
| 692 | sizeof(struct ext4_extent)); | 723 | sizeof(struct ext4_extent)); |
| @@ -764,7 +795,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
| 764 | BUG_ON(EXT_MAX_INDEX(path[i].p_hdr) != | 795 | BUG_ON(EXT_MAX_INDEX(path[i].p_hdr) != |
| 765 | EXT_LAST_INDEX(path[i].p_hdr)); | 796 | EXT_LAST_INDEX(path[i].p_hdr)); |
| 766 | while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { | 797 | while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { |
| 767 | ext_debug("%d: move %d:%d in new index %llu\n", i, | 798 | ext_debug("%d: move %d:%llu in new index %llu\n", i, |
| 768 | le32_to_cpu(path[i].p_idx->ei_block), | 799 | le32_to_cpu(path[i].p_idx->ei_block), |
| 769 | idx_pblock(path[i].p_idx), | 800 | idx_pblock(path[i].p_idx), |
| 770 | newblock); | 801 | newblock); |
| @@ -893,8 +924,13 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, | |||
| 893 | curp->p_hdr->eh_max = cpu_to_le16(ext4_ext_space_root_idx(inode)); | 924 | curp->p_hdr->eh_max = cpu_to_le16(ext4_ext_space_root_idx(inode)); |
| 894 | curp->p_hdr->eh_entries = cpu_to_le16(1); | 925 | curp->p_hdr->eh_entries = cpu_to_le16(1); |
| 895 | curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr); | 926 | curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr); |
| 896 | /* FIXME: it works, but actually path[0] can be index */ | 927 | |
| 897 | curp->p_idx->ei_block = EXT_FIRST_EXTENT(path[0].p_hdr)->ee_block; | 928 | if (path[0].p_hdr->eh_depth) |
| 929 | curp->p_idx->ei_block = | ||
| 930 | EXT_FIRST_INDEX(path[0].p_hdr)->ei_block; | ||
| 931 | else | ||
| 932 | curp->p_idx->ei_block = | ||
| 933 | EXT_FIRST_EXTENT(path[0].p_hdr)->ee_block; | ||
| 898 | ext4_idx_store_pblock(curp->p_idx, newblock); | 934 | ext4_idx_store_pblock(curp->p_idx, newblock); |
| 899 | 935 | ||
| 900 | neh = ext_inode_hdr(inode); | 936 | neh = ext_inode_hdr(inode); |
| @@ -1106,7 +1142,24 @@ static int | |||
| 1106 | ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, | 1142 | ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, |
| 1107 | struct ext4_extent *ex2) | 1143 | struct ext4_extent *ex2) |
| 1108 | { | 1144 | { |
| 1109 | if (le32_to_cpu(ex1->ee_block) + le16_to_cpu(ex1->ee_len) != | 1145 | unsigned short ext1_ee_len, ext2_ee_len, max_len; |
| 1146 | |||
| 1147 | /* | ||
| 1148 | * Make sure that either both extents are uninitialized, or | ||
| 1149 | * both are _not_. | ||
| 1150 | */ | ||
| 1151 | if (ext4_ext_is_uninitialized(ex1) ^ ext4_ext_is_uninitialized(ex2)) | ||
| 1152 | return 0; | ||
| 1153 | |||
| 1154 | if (ext4_ext_is_uninitialized(ex1)) | ||
| 1155 | max_len = EXT_UNINIT_MAX_LEN; | ||
| 1156 | else | ||
| 1157 | max_len = EXT_INIT_MAX_LEN; | ||
| 1158 | |||
| 1159 | ext1_ee_len = ext4_ext_get_actual_len(ex1); | ||
| 1160 | ext2_ee_len = ext4_ext_get_actual_len(ex2); | ||
| 1161 | |||
| 1162 | if (le32_to_cpu(ex1->ee_block) + ext1_ee_len != | ||
| 1110 | le32_to_cpu(ex2->ee_block)) | 1163 | le32_to_cpu(ex2->ee_block)) |
| 1111 | return 0; | 1164 | return 0; |
| 1112 | 1165 | ||
| @@ -1115,19 +1168,66 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, | |||
| 1115 | * as an RO_COMPAT feature, refuse to merge to extents if | 1168 | * as an RO_COMPAT feature, refuse to merge to extents if |
| 1116 | * this can result in the top bit of ee_len being set. | 1169 | * this can result in the top bit of ee_len being set. |
| 1117 | */ | 1170 | */ |
| 1118 | if (le16_to_cpu(ex1->ee_len) + le16_to_cpu(ex2->ee_len) > EXT_MAX_LEN) | 1171 | if (ext1_ee_len + ext2_ee_len > max_len) |
| 1119 | return 0; | 1172 | return 0; |
| 1120 | #ifdef AGGRESSIVE_TEST | 1173 | #ifdef AGGRESSIVE_TEST |
| 1121 | if (le16_to_cpu(ex1->ee_len) >= 4) | 1174 | if (le16_to_cpu(ex1->ee_len) >= 4) |
| 1122 | return 0; | 1175 | return 0; |
| 1123 | #endif | 1176 | #endif |
| 1124 | 1177 | ||
| 1125 | if (ext_pblock(ex1) + le16_to_cpu(ex1->ee_len) == ext_pblock(ex2)) | 1178 | if (ext_pblock(ex1) + ext1_ee_len == ext_pblock(ex2)) |
| 1126 | return 1; | 1179 | return 1; |
| 1127 | return 0; | 1180 | return 0; |
| 1128 | } | 1181 | } |
| 1129 | 1182 | ||
| 1130 | /* | 1183 | /* |
| 1184 | * This function tries to merge the "ex" extent to the next extent in the tree. | ||
| 1185 | * It always tries to merge towards right. If you want to merge towards | ||
| 1186 | * left, pass "ex - 1" as argument instead of "ex". | ||
| 1187 | * Returns 0 if the extents (ex and ex+1) were _not_ merged and returns | ||
| 1188 | * 1 if they got merged. | ||
| 1189 | */ | ||
| 1190 | int ext4_ext_try_to_merge(struct inode *inode, | ||
| 1191 | struct ext4_ext_path *path, | ||
| 1192 | struct ext4_extent *ex) | ||
| 1193 | { | ||
| 1194 | struct ext4_extent_header *eh; | ||
| 1195 | unsigned int depth, len; | ||
| 1196 | int merge_done = 0; | ||
| 1197 | int uninitialized = 0; | ||
| 1198 | |||
| 1199 | depth = ext_depth(inode); | ||
| 1200 | BUG_ON(path[depth].p_hdr == NULL); | ||
| 1201 | eh = path[depth].p_hdr; | ||
| 1202 | |||
| 1203 | while (ex < EXT_LAST_EXTENT(eh)) { | ||
| 1204 | if (!ext4_can_extents_be_merged(inode, ex, ex + 1)) | ||
| 1205 | break; | ||
| 1206 | /* merge with next extent! */ | ||
| 1207 | if (ext4_ext_is_uninitialized(ex)) | ||
| 1208 | uninitialized = 1; | ||
| 1209 | ex->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ex) | ||
| 1210 | + ext4_ext_get_actual_len(ex + 1)); | ||
| 1211 | if (uninitialized) | ||
| 1212 | ext4_ext_mark_uninitialized(ex); | ||
| 1213 | |||
| 1214 | if (ex + 1 < EXT_LAST_EXTENT(eh)) { | ||
| 1215 | len = (EXT_LAST_EXTENT(eh) - ex - 1) | ||
| 1216 | * sizeof(struct ext4_extent); | ||
| 1217 | memmove(ex + 1, ex + 2, len); | ||
| 1218 | } | ||
| 1219 | eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries) - 1); | ||
| 1220 | merge_done = 1; | ||
| 1221 | WARN_ON(eh->eh_entries == 0); | ||
| 1222 | if (!eh->eh_entries) | ||
| 1223 | ext4_error(inode->i_sb, "ext4_ext_try_to_merge", | ||
| 1224 | "inode#%lu, eh->eh_entries = 0!", inode->i_ino); | ||
| 1225 | } | ||
| 1226 | |||
| 1227 | return merge_done; | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | /* | ||
| 1131 | * check if a portion of the "newext" extent overlaps with an | 1231 | * check if a portion of the "newext" extent overlaps with an |
| 1132 | * existing extent. | 1232 | * existing extent. |
| 1133 | * | 1233 | * |
| @@ -1144,7 +1244,7 @@ unsigned int ext4_ext_check_overlap(struct inode *inode, | |||
| 1144 | unsigned int ret = 0; | 1244 | unsigned int ret = 0; |
| 1145 | 1245 | ||
| 1146 | b1 = le32_to_cpu(newext->ee_block); | 1246 | b1 = le32_to_cpu(newext->ee_block); |
| 1147 | len1 = le16_to_cpu(newext->ee_len); | 1247 | len1 = ext4_ext_get_actual_len(newext); |
| 1148 | depth = ext_depth(inode); | 1248 | depth = ext_depth(inode); |
| 1149 | if (!path[depth].p_ext) | 1249 | if (!path[depth].p_ext) |
| 1150 | goto out; | 1250 | goto out; |
| @@ -1191,8 +1291,9 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, | |||
| 1191 | struct ext4_extent *nearex; /* nearest extent */ | 1291 | struct ext4_extent *nearex; /* nearest extent */ |
| 1192 | struct ext4_ext_path *npath = NULL; | 1292 | struct ext4_ext_path *npath = NULL; |
| 1193 | int depth, len, err, next; | 1293 | int depth, len, err, next; |
| 1294 | unsigned uninitialized = 0; | ||
| 1194 | 1295 | ||
| 1195 | BUG_ON(newext->ee_len == 0); | 1296 | BUG_ON(ext4_ext_get_actual_len(newext) == 0); |
| 1196 | depth = ext_depth(inode); | 1297 | depth = ext_depth(inode); |
| 1197 | ex = path[depth].p_ext; | 1298 | ex = path[depth].p_ext; |
| 1198 | BUG_ON(path[depth].p_hdr == NULL); | 1299 | BUG_ON(path[depth].p_hdr == NULL); |
| @@ -1200,14 +1301,24 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, | |||
| 1200 | /* try to insert block into found extent and return */ | 1301 | /* try to insert block into found extent and return */ |
| 1201 | if (ex && ext4_can_extents_be_merged(inode, ex, newext)) { | 1302 | if (ex && ext4_can_extents_be_merged(inode, ex, newext)) { |
| 1202 | ext_debug("append %d block to %d:%d (from %llu)\n", | 1303 | ext_debug("append %d block to %d:%d (from %llu)\n", |
| 1203 | le16_to_cpu(newext->ee_len), | 1304 | ext4_ext_get_actual_len(newext), |
| 1204 | le32_to_cpu(ex->ee_block), | 1305 | le32_to_cpu(ex->ee_block), |
| 1205 | le16_to_cpu(ex->ee_len), ext_pblock(ex)); | 1306 | ext4_ext_get_actual_len(ex), ext_pblock(ex)); |
| 1206 | err = ext4_ext_get_access(handle, inode, path + depth); | 1307 | err = ext4_ext_get_access(handle, inode, path + depth); |
| 1207 | if (err) | 1308 | if (err) |
| 1208 | return err; | 1309 | return err; |
| 1209 | ex->ee_len = cpu_to_le16(le16_to_cpu(ex->ee_len) | 1310 | |
| 1210 | + le16_to_cpu(newext->ee_len)); | 1311 | /* |
| 1312 | * ext4_can_extents_be_merged should have checked that either | ||
| 1313 | * both extents are uninitialized, or both aren't. Thus we | ||
| 1314 | * need to check only one of them here. | ||
| 1315 | */ | ||
| 1316 | if (ext4_ext_is_uninitialized(ex)) | ||
| 1317 | uninitialized = 1; | ||
| 1318 | ex->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ex) | ||
| 1319 | + ext4_ext_get_actual_len(newext)); | ||
| 1320 | if (uninitialized) | ||
| 1321 | ext4_ext_mark_uninitialized(ex); | ||
| 1211 | eh = path[depth].p_hdr; | 1322 | eh = path[depth].p_hdr; |
| 1212 | nearex = ex; | 1323 | nearex = ex; |
| 1213 | goto merge; | 1324 | goto merge; |
| @@ -1263,7 +1374,7 @@ has_space: | |||
| 1263 | ext_debug("first extent in the leaf: %d:%llu:%d\n", | 1374 | ext_debug("first extent in the leaf: %d:%llu:%d\n", |
| 1264 | le32_to_cpu(newext->ee_block), | 1375 | le32_to_cpu(newext->ee_block), |
| 1265 | ext_pblock(newext), | 1376 | ext_pblock(newext), |
| 1266 | le16_to_cpu(newext->ee_len)); | 1377 | ext4_ext_get_actual_len(newext)); |
| 1267 | path[depth].p_ext = EXT_FIRST_EXTENT(eh); | 1378 | path[depth].p_ext = EXT_FIRST_EXTENT(eh); |
| 1268 | } else if (le32_to_cpu(newext->ee_block) | 1379 | } else if (le32_to_cpu(newext->ee_block) |
| 1269 | > le32_to_cpu(nearex->ee_block)) { | 1380 | > le32_to_cpu(nearex->ee_block)) { |
| @@ -1276,7 +1387,7 @@ has_space: | |||
| 1276 | "move %d from 0x%p to 0x%p\n", | 1387 | "move %d from 0x%p to 0x%p\n", |
| 1277 | le32_to_cpu(newext->ee_block), | 1388 | le32_to_cpu(newext->ee_block), |
| 1278 | ext_pblock(newext), | 1389 | ext_pblock(newext), |
| 1279 | le16_to_cpu(newext->ee_len), | 1390 | ext4_ext_get_actual_len(newext), |
| 1280 | nearex, len, nearex + 1, nearex + 2); | 1391 | nearex, len, nearex + 1, nearex + 2); |
| 1281 | memmove(nearex + 2, nearex + 1, len); | 1392 | memmove(nearex + 2, nearex + 1, len); |
| 1282 | } | 1393 | } |
| @@ -1289,7 +1400,7 @@ has_space: | |||
| 1289 | "move %d from 0x%p to 0x%p\n", | 1400 | "move %d from 0x%p to 0x%p\n", |
| 1290 | le32_to_cpu(newext->ee_block), | 1401 | le32_to_cpu(newext->ee_block), |
| 1291 | ext_pblock(newext), | 1402 | ext_pblock(newext), |
| 1292 | le16_to_cpu(newext->ee_len), | 1403 | ext4_ext_get_actual_len(newext), |
| 1293 | nearex, len, nearex + 1, nearex + 2); | 1404 | nearex, len, nearex + 1, nearex + 2); |
| 1294 | memmove(nearex + 1, nearex, len); | 1405 | memmove(nearex + 1, nearex, len); |
| 1295 | path[depth].p_ext = nearex; | 1406 | path[depth].p_ext = nearex; |
| @@ -1304,20 +1415,7 @@ has_space: | |||
| 1304 | 1415 | ||
| 1305 | merge: | 1416 | merge: |
| 1306 | /* try to merge extents to the right */ | 1417 | /* try to merge extents to the right */ |
| 1307 | while (nearex < EXT_LAST_EXTENT(eh)) { | 1418 | ext4_ext_try_to_merge(inode, path, nearex); |
| 1308 | if (!ext4_can_extents_be_merged(inode, nearex, nearex + 1)) | ||
| 1309 | break; | ||
| 1310 | /* merge with next extent! */ | ||
| 1311 | nearex->ee_len = cpu_to_le16(le16_to_cpu(nearex->ee_len) | ||
| 1312 | + le16_to_cpu(nearex[1].ee_len)); | ||
| 1313 | if (nearex + 1 < EXT_LAST_EXTENT(eh)) { | ||
| 1314 | len = (EXT_LAST_EXTENT(eh) - nearex - 1) | ||
| 1315 | * sizeof(struct ext4_extent); | ||
| 1316 | memmove(nearex + 1, nearex + 2, len); | ||
| 1317 | } | ||
| 1318 | eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)-1); | ||
| 1319 | BUG_ON(eh->eh_entries == 0); | ||
| 1320 | } | ||
| 1321 | 1419 | ||
| 1322 | /* try to merge extents to the left */ | 1420 | /* try to merge extents to the left */ |
| 1323 | 1421 | ||
| @@ -1379,8 +1477,8 @@ int ext4_ext_walk_space(struct inode *inode, unsigned long block, | |||
| 1379 | end = le32_to_cpu(ex->ee_block); | 1477 | end = le32_to_cpu(ex->ee_block); |
| 1380 | if (block + num < end) | 1478 | if (block + num < end) |
| 1381 | end = block + num; | 1479 | end = block + num; |
| 1382 | } else if (block >= | 1480 | } else if (block >= le32_to_cpu(ex->ee_block) |
| 1383 | le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len)) { | 1481 | + ext4_ext_get_actual_len(ex)) { |
| 1384 | /* need to allocate space after found extent */ | 1482 | /* need to allocate space after found extent */ |
| 1385 | start = block; | 1483 | start = block; |
| 1386 | end = block + num; | 1484 | end = block + num; |
| @@ -1392,7 +1490,8 @@ int ext4_ext_walk_space(struct inode *inode, unsigned long block, | |||
| 1392 | * by found extent | 1490 | * by found extent |
| 1393 | */ | 1491 | */ |
| 1394 | start = block; | 1492 | start = block; |
| 1395 | end = le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len); | 1493 | end = le32_to_cpu(ex->ee_block) |
| 1494 | + ext4_ext_get_actual_len(ex); | ||
| 1396 | if (block + num < end) | 1495 | if (block + num < end) |
| 1397 | end = block + num; | 1496 | end = block + num; |
| 1398 | exists = 1; | 1497 | exists = 1; |
| @@ -1408,7 +1507,7 @@ int ext4_ext_walk_space(struct inode *inode, unsigned long block, | |||
| 1408 | cbex.ec_type = EXT4_EXT_CACHE_GAP; | 1507 | cbex.ec_type = EXT4_EXT_CACHE_GAP; |
| 1409 | } else { | 1508 | } else { |
| 1410 | cbex.ec_block = le32_to_cpu(ex->ee_block); | 1509 | cbex.ec_block = le32_to_cpu(ex->ee_block); |
| 1411 | cbex.ec_len = le16_to_cpu(ex->ee_len); | 1510 | cbex.ec_len = ext4_ext_get_actual_len(ex); |
| 1412 | cbex.ec_start = ext_pblock(ex); | 1511 | cbex.ec_start = ext_pblock(ex); |
| 1413 | cbex.ec_type = EXT4_EXT_CACHE_EXTENT; | 1512 | cbex.ec_type = EXT4_EXT_CACHE_EXTENT; |
| 1414 | } | 1513 | } |
| @@ -1481,15 +1580,15 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, | |||
| 1481 | ext_debug("cache gap(before): %lu [%lu:%lu]", | 1580 | ext_debug("cache gap(before): %lu [%lu:%lu]", |
| 1482 | (unsigned long) block, | 1581 | (unsigned long) block, |
| 1483 | (unsigned long) le32_to_cpu(ex->ee_block), | 1582 | (unsigned long) le32_to_cpu(ex->ee_block), |
| 1484 | (unsigned long) le16_to_cpu(ex->ee_len)); | 1583 | (unsigned long) ext4_ext_get_actual_len(ex)); |
| 1485 | } else if (block >= le32_to_cpu(ex->ee_block) | 1584 | } else if (block >= le32_to_cpu(ex->ee_block) |
| 1486 | + le16_to_cpu(ex->ee_len)) { | 1585 | + ext4_ext_get_actual_len(ex)) { |
| 1487 | lblock = le32_to_cpu(ex->ee_block) | 1586 | lblock = le32_to_cpu(ex->ee_block) |
| 1488 | + le16_to_cpu(ex->ee_len); | 1587 | + ext4_ext_get_actual_len(ex); |
| 1489 | len = ext4_ext_next_allocated_block(path); | 1588 | len = ext4_ext_next_allocated_block(path); |
| 1490 | ext_debug("cache gap(after): [%lu:%lu] %lu", | 1589 | ext_debug("cache gap(after): [%lu:%lu] %lu", |
| 1491 | (unsigned long) le32_to_cpu(ex->ee_block), | 1590 | (unsigned long) le32_to_cpu(ex->ee_block), |
| 1492 | (unsigned long) le16_to_cpu(ex->ee_len), | 1591 | (unsigned long) ext4_ext_get_actual_len(ex), |
| 1493 | (unsigned long) block); | 1592 | (unsigned long) block); |
| 1494 | BUG_ON(len == lblock); | 1593 | BUG_ON(len == lblock); |
| 1495 | len = len - lblock; | 1594 | len = len - lblock; |
| @@ -1619,12 +1718,12 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode, | |||
| 1619 | unsigned long from, unsigned long to) | 1718 | unsigned long from, unsigned long to) |
| 1620 | { | 1719 | { |
| 1621 | struct buffer_head *bh; | 1720 | struct buffer_head *bh; |
| 1721 | unsigned short ee_len = ext4_ext_get_actual_len(ex); | ||
| 1622 | int i; | 1722 | int i; |
| 1623 | 1723 | ||
| 1624 | #ifdef EXTENTS_STATS | 1724 | #ifdef EXTENTS_STATS |
| 1625 | { | 1725 | { |
| 1626 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | 1726 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
| 1627 | unsigned short ee_len = le16_to_cpu(ex->ee_len); | ||
| 1628 | spin_lock(&sbi->s_ext_stats_lock); | 1727 | spin_lock(&sbi->s_ext_stats_lock); |
| 1629 | sbi->s_ext_blocks += ee_len; | 1728 | sbi->s_ext_blocks += ee_len; |
| 1630 | sbi->s_ext_extents++; | 1729 | sbi->s_ext_extents++; |
| @@ -1638,12 +1737,12 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode, | |||
| 1638 | } | 1737 | } |
| 1639 | #endif | 1738 | #endif |
| 1640 | if (from >= le32_to_cpu(ex->ee_block) | 1739 | if (from >= le32_to_cpu(ex->ee_block) |
| 1641 | && to == le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - 1) { | 1740 | && to == le32_to_cpu(ex->ee_block) + ee_len - 1) { |
| 1642 | /* tail removal */ | 1741 | /* tail removal */ |
| 1643 | unsigned long num; | 1742 | unsigned long num; |
| 1644 | ext4_fsblk_t start; | 1743 | ext4_fsblk_t start; |
| 1645 | num = le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - from; | 1744 | num = le32_to_cpu(ex->ee_block) + ee_len - from; |
| 1646 | start = ext_pblock(ex) + le16_to_cpu(ex->ee_len) - num; | 1745 | start = ext_pblock(ex) + ee_len - num; |
| 1647 | ext_debug("free last %lu blocks starting %llu\n", num, start); | 1746 | ext_debug("free last %lu blocks starting %llu\n", num, start); |
| 1648 | for (i = 0; i < num; i++) { | 1747 | for (i = 0; i < num; i++) { |
| 1649 | bh = sb_find_get_block(inode->i_sb, start + i); | 1748 | bh = sb_find_get_block(inode->i_sb, start + i); |
| @@ -1651,12 +1750,12 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode, | |||
| 1651 | } | 1750 | } |
| 1652 | ext4_free_blocks(handle, inode, start, num); | 1751 | ext4_free_blocks(handle, inode, start, num); |
| 1653 | } else if (from == le32_to_cpu(ex->ee_block) | 1752 | } else if (from == le32_to_cpu(ex->ee_block) |
| 1654 | && to <= le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - 1) { | 1753 | && to <= le32_to_cpu(ex->ee_block) + ee_len - 1) { |
| 1655 | printk("strange request: removal %lu-%lu from %u:%u\n", | 1754 | printk("strange request: removal %lu-%lu from %u:%u\n", |
| 1656 | from, to, le32_to_cpu(ex->ee_block), le16_to_cpu(ex->ee_len)); | 1755 | from, to, le32_to_cpu(ex->ee_block), ee_len); |
| 1657 | } else { | 1756 | } else { |
| 1658 | printk("strange request: removal(2) %lu-%lu from %u:%u\n", | 1757 | printk("strange request: removal(2) %lu-%lu from %u:%u\n", |
| 1659 | from, to, le32_to_cpu(ex->ee_block), le16_to_cpu(ex->ee_len)); | 1758 | from, to, le32_to_cpu(ex->ee_block), ee_len); |
| 1660 | } | 1759 | } |
| 1661 | return 0; | 1760 | return 0; |
| 1662 | } | 1761 | } |
| @@ -1671,21 +1770,23 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
| 1671 | unsigned a, b, block, num; | 1770 | unsigned a, b, block, num; |
| 1672 | unsigned long ex_ee_block; | 1771 | unsigned long ex_ee_block; |
| 1673 | unsigned short ex_ee_len; | 1772 | unsigned short ex_ee_len; |
| 1773 | unsigned uninitialized = 0; | ||
| 1674 | struct ext4_extent *ex; | 1774 | struct ext4_extent *ex; |
| 1675 | 1775 | ||
| 1776 | /* the header must be checked already in ext4_ext_remove_space() */ | ||
| 1676 | ext_debug("truncate since %lu in leaf\n", start); | 1777 | ext_debug("truncate since %lu in leaf\n", start); |
| 1677 | if (!path[depth].p_hdr) | 1778 | if (!path[depth].p_hdr) |
| 1678 | path[depth].p_hdr = ext_block_hdr(path[depth].p_bh); | 1779 | path[depth].p_hdr = ext_block_hdr(path[depth].p_bh); |
| 1679 | eh = path[depth].p_hdr; | 1780 | eh = path[depth].p_hdr; |
| 1680 | BUG_ON(eh == NULL); | 1781 | BUG_ON(eh == NULL); |
| 1681 | BUG_ON(le16_to_cpu(eh->eh_entries) > le16_to_cpu(eh->eh_max)); | ||
| 1682 | BUG_ON(eh->eh_magic != EXT4_EXT_MAGIC); | ||
| 1683 | 1782 | ||
| 1684 | /* find where to start removing */ | 1783 | /* find where to start removing */ |
| 1685 | ex = EXT_LAST_EXTENT(eh); | 1784 | ex = EXT_LAST_EXTENT(eh); |
| 1686 | 1785 | ||
| 1687 | ex_ee_block = le32_to_cpu(ex->ee_block); | 1786 | ex_ee_block = le32_to_cpu(ex->ee_block); |
| 1688 | ex_ee_len = le16_to_cpu(ex->ee_len); | 1787 | if (ext4_ext_is_uninitialized(ex)) |
| 1788 | uninitialized = 1; | ||
| 1789 | ex_ee_len = ext4_ext_get_actual_len(ex); | ||
| 1689 | 1790 | ||
| 1690 | while (ex >= EXT_FIRST_EXTENT(eh) && | 1791 | while (ex >= EXT_FIRST_EXTENT(eh) && |
| 1691 | ex_ee_block + ex_ee_len > start) { | 1792 | ex_ee_block + ex_ee_len > start) { |
| @@ -1753,6 +1854,12 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
| 1753 | 1854 | ||
| 1754 | ex->ee_block = cpu_to_le32(block); | 1855 | ex->ee_block = cpu_to_le32(block); |
| 1755 | ex->ee_len = cpu_to_le16(num); | 1856 | ex->ee_len = cpu_to_le16(num); |
| 1857 | /* | ||
| 1858 | * Do not mark uninitialized if all the blocks in the | ||
| 1859 | * extent have been removed. | ||
| 1860 | */ | ||
| 1861 | if (uninitialized && num) | ||
| 1862 | ext4_ext_mark_uninitialized(ex); | ||
| 1756 | 1863 | ||
| 1757 | err = ext4_ext_dirty(handle, inode, path + depth); | 1864 | err = ext4_ext_dirty(handle, inode, path + depth); |
| 1758 | if (err) | 1865 | if (err) |
| @@ -1762,7 +1869,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
| 1762 | ext_pblock(ex)); | 1869 | ext_pblock(ex)); |
| 1763 | ex--; | 1870 | ex--; |
| 1764 | ex_ee_block = le32_to_cpu(ex->ee_block); | 1871 | ex_ee_block = le32_to_cpu(ex->ee_block); |
| 1765 | ex_ee_len = le16_to_cpu(ex->ee_len); | 1872 | ex_ee_len = ext4_ext_get_actual_len(ex); |
| 1766 | } | 1873 | } |
| 1767 | 1874 | ||
| 1768 | if (correct_index && eh->eh_entries) | 1875 | if (correct_index && eh->eh_entries) |
| @@ -1825,7 +1932,7 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start) | |||
| 1825 | return -ENOMEM; | 1932 | return -ENOMEM; |
| 1826 | } | 1933 | } |
| 1827 | path[0].p_hdr = ext_inode_hdr(inode); | 1934 | path[0].p_hdr = ext_inode_hdr(inode); |
| 1828 | if (ext4_ext_check_header(__FUNCTION__, inode, path[0].p_hdr)) { | 1935 | if (ext4_ext_check_header(inode, path[0].p_hdr, depth)) { |
| 1829 | err = -EIO; | 1936 | err = -EIO; |
| 1830 | goto out; | 1937 | goto out; |
| 1831 | } | 1938 | } |
| @@ -1846,17 +1953,8 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start) | |||
| 1846 | if (!path[i].p_hdr) { | 1953 | if (!path[i].p_hdr) { |
| 1847 | ext_debug("initialize header\n"); | 1954 | ext_debug("initialize header\n"); |
| 1848 | path[i].p_hdr = ext_block_hdr(path[i].p_bh); | 1955 | path[i].p_hdr = ext_block_hdr(path[i].p_bh); |
| 1849 | if (ext4_ext_check_header(__FUNCTION__, inode, | ||
| 1850 | path[i].p_hdr)) { | ||
| 1851 | err = -EIO; | ||
| 1852 | goto out; | ||
| 1853 | } | ||
| 1854 | } | 1956 | } |
| 1855 | 1957 | ||
| 1856 | BUG_ON(le16_to_cpu(path[i].p_hdr->eh_entries) | ||
| 1857 | > le16_to_cpu(path[i].p_hdr->eh_max)); | ||
| 1858 | BUG_ON(path[i].p_hdr->eh_magic != EXT4_EXT_MAGIC); | ||
| 1859 | |||
| 1860 | if (!path[i].p_idx) { | 1958 | if (!path[i].p_idx) { |
| 1861 | /* this level hasn't been touched yet */ | 1959 | /* this level hasn't been touched yet */ |
| 1862 | path[i].p_idx = EXT_LAST_INDEX(path[i].p_hdr); | 1960 | path[i].p_idx = EXT_LAST_INDEX(path[i].p_hdr); |
| @@ -1873,17 +1971,27 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start) | |||
| 1873 | i, EXT_FIRST_INDEX(path[i].p_hdr), | 1971 | i, EXT_FIRST_INDEX(path[i].p_hdr), |
| 1874 | path[i].p_idx); | 1972 | path[i].p_idx); |
| 1875 | if (ext4_ext_more_to_rm(path + i)) { | 1973 | if (ext4_ext_more_to_rm(path + i)) { |
| 1974 | struct buffer_head *bh; | ||
| 1876 | /* go to the next level */ | 1975 | /* go to the next level */ |
| 1877 | ext_debug("move to level %d (block %llu)\n", | 1976 | ext_debug("move to level %d (block %llu)\n", |
| 1878 | i + 1, idx_pblock(path[i].p_idx)); | 1977 | i + 1, idx_pblock(path[i].p_idx)); |
| 1879 | memset(path + i + 1, 0, sizeof(*path)); | 1978 | memset(path + i + 1, 0, sizeof(*path)); |
| 1880 | path[i+1].p_bh = | 1979 | bh = sb_bread(sb, idx_pblock(path[i].p_idx)); |
| 1881 | sb_bread(sb, idx_pblock(path[i].p_idx)); | 1980 | if (!bh) { |
| 1882 | if (!path[i+1].p_bh) { | ||
| 1883 | /* should we reset i_size? */ | 1981 | /* should we reset i_size? */ |
| 1884 | err = -EIO; | 1982 | err = -EIO; |
| 1885 | break; | 1983 | break; |
| 1886 | } | 1984 | } |
| 1985 | if (WARN_ON(i + 1 > depth)) { | ||
| 1986 | err = -EIO; | ||
| 1987 | break; | ||
| 1988 | } | ||
| 1989 | if (ext4_ext_check_header(inode, ext_block_hdr(bh), | ||
| 1990 | depth - i - 1)) { | ||
| 1991 | err = -EIO; | ||
| 1992 | break; | ||
| 1993 | } | ||
| 1994 | path[i + 1].p_bh = bh; | ||
| 1887 | 1995 | ||
| 1888 | /* save actual number of indexes since this | 1996 | /* save actual number of indexes since this |
| 1889 | * number is changed at the next iteration */ | 1997 | * number is changed at the next iteration */ |
| @@ -1977,15 +2085,158 @@ void ext4_ext_release(struct super_block *sb) | |||
| 1977 | #endif | 2085 | #endif |
| 1978 | } | 2086 | } |
| 1979 | 2087 | ||
| 2088 | /* | ||
| 2089 | * This function is called by ext4_ext_get_blocks() if someone tries to write | ||
| 2090 | * to an uninitialized extent. It may result in splitting the uninitialized | ||
| 2091 | * extent into multiple extents (upto three - one initialized and two | ||
| 2092 | * uninitialized). | ||
| 2093 | * There are three possibilities: | ||
| 2094 | * a> There is no split required: Entire extent should be initialized | ||
| 2095 | * b> Splits in two extents: Write is happening at either end of the extent | ||
| 2096 | * c> Splits in three extents: Somone is writing in middle of the extent | ||
| 2097 | */ | ||
| 2098 | int ext4_ext_convert_to_initialized(handle_t *handle, struct inode *inode, | ||
| 2099 | struct ext4_ext_path *path, | ||
| 2100 | ext4_fsblk_t iblock, | ||
| 2101 | unsigned long max_blocks) | ||
| 2102 | { | ||
| 2103 | struct ext4_extent *ex, newex; | ||
| 2104 | struct ext4_extent *ex1 = NULL; | ||
| 2105 | struct ext4_extent *ex2 = NULL; | ||
| 2106 | struct ext4_extent *ex3 = NULL; | ||
| 2107 | struct ext4_extent_header *eh; | ||
| 2108 | unsigned int allocated, ee_block, ee_len, depth; | ||
| 2109 | ext4_fsblk_t newblock; | ||
| 2110 | int err = 0; | ||
| 2111 | int ret = 0; | ||
| 2112 | |||
| 2113 | depth = ext_depth(inode); | ||
| 2114 | eh = path[depth].p_hdr; | ||
| 2115 | ex = path[depth].p_ext; | ||
| 2116 | ee_block = le32_to_cpu(ex->ee_block); | ||
| 2117 | ee_len = ext4_ext_get_actual_len(ex); | ||
| 2118 | allocated = ee_len - (iblock - ee_block); | ||
| 2119 | newblock = iblock - ee_block + ext_pblock(ex); | ||
| 2120 | ex2 = ex; | ||
| 2121 | |||
| 2122 | /* ex1: ee_block to iblock - 1 : uninitialized */ | ||
| 2123 | if (iblock > ee_block) { | ||
| 2124 | ex1 = ex; | ||
| 2125 | ex1->ee_len = cpu_to_le16(iblock - ee_block); | ||
| 2126 | ext4_ext_mark_uninitialized(ex1); | ||
| 2127 | ex2 = &newex; | ||
| 2128 | } | ||
| 2129 | /* | ||
| 2130 | * for sanity, update the length of the ex2 extent before | ||
| 2131 | * we insert ex3, if ex1 is NULL. This is to avoid temporary | ||
| 2132 | * overlap of blocks. | ||
| 2133 | */ | ||
| 2134 | if (!ex1 && allocated > max_blocks) | ||
| 2135 | ex2->ee_len = cpu_to_le16(max_blocks); | ||
| 2136 | /* ex3: to ee_block + ee_len : uninitialised */ | ||
| 2137 | if (allocated > max_blocks) { | ||
| 2138 | unsigned int newdepth; | ||
| 2139 | ex3 = &newex; | ||
| 2140 | ex3->ee_block = cpu_to_le32(iblock + max_blocks); | ||
| 2141 | ext4_ext_store_pblock(ex3, newblock + max_blocks); | ||
| 2142 | ex3->ee_len = cpu_to_le16(allocated - max_blocks); | ||
| 2143 | ext4_ext_mark_uninitialized(ex3); | ||
| 2144 | err = ext4_ext_insert_extent(handle, inode, path, ex3); | ||
| 2145 | if (err) | ||
| 2146 | goto out; | ||
| 2147 | /* | ||
| 2148 | * The depth, and hence eh & ex might change | ||
| 2149 | * as part of the insert above. | ||
| 2150 | */ | ||
| 2151 | newdepth = ext_depth(inode); | ||
| 2152 | if (newdepth != depth) { | ||
| 2153 | depth = newdepth; | ||
| 2154 | path = ext4_ext_find_extent(inode, iblock, NULL); | ||
| 2155 | if (IS_ERR(path)) { | ||
| 2156 | err = PTR_ERR(path); | ||
| 2157 | path = NULL; | ||
| 2158 | goto out; | ||
| 2159 | } | ||
| 2160 | eh = path[depth].p_hdr; | ||
| 2161 | ex = path[depth].p_ext; | ||
| 2162 | if (ex2 != &newex) | ||
| 2163 | ex2 = ex; | ||
| 2164 | } | ||
| 2165 | allocated = max_blocks; | ||
| 2166 | } | ||
| 2167 | /* | ||
| 2168 | * If there was a change of depth as part of the | ||
| 2169 | * insertion of ex3 above, we need to update the length | ||
| 2170 | * of the ex1 extent again here | ||
| 2171 | */ | ||
| 2172 | if (ex1 && ex1 != ex) { | ||
| 2173 | ex1 = ex; | ||
| 2174 | ex1->ee_len = cpu_to_le16(iblock - ee_block); | ||
| 2175 | ext4_ext_mark_uninitialized(ex1); | ||
| 2176 | ex2 = &newex; | ||
| 2177 | } | ||
| 2178 | /* ex2: iblock to iblock + maxblocks-1 : initialised */ | ||
| 2179 | ex2->ee_block = cpu_to_le32(iblock); | ||
| 2180 | ex2->ee_start = cpu_to_le32(newblock); | ||
| 2181 | ext4_ext_store_pblock(ex2, newblock); | ||
| 2182 | ex2->ee_len = cpu_to_le16(allocated); | ||
| 2183 | if (ex2 != ex) | ||
| 2184 | goto insert; | ||
| 2185 | err = ext4_ext_get_access(handle, inode, path + depth); | ||
| 2186 | if (err) | ||
| 2187 | goto out; | ||
| 2188 | /* | ||
| 2189 | * New (initialized) extent starts from the first block | ||
| 2190 | * in the current extent. i.e., ex2 == ex | ||
| 2191 | * We have to see if it can be merged with the extent | ||
| 2192 | * on the left. | ||
| 2193 | */ | ||
| 2194 | if (ex2 > EXT_FIRST_EXTENT(eh)) { | ||
| 2195 | /* | ||
| 2196 | * To merge left, pass "ex2 - 1" to try_to_merge(), | ||
| 2197 | * since it merges towards right _only_. | ||
| 2198 | */ | ||
| 2199 | ret = ext4_ext_try_to_merge(inode, path, ex2 - 1); | ||
| 2200 | if (ret) { | ||
| 2201 | err = ext4_ext_correct_indexes(handle, inode, path); | ||
| 2202 | if (err) | ||
| 2203 | goto out; | ||
| 2204 | depth = ext_depth(inode); | ||
| 2205 | ex2--; | ||
| 2206 | } | ||
| 2207 | } | ||
| 2208 | /* | ||
| 2209 | * Try to Merge towards right. This might be required | ||
| 2210 | * only when the whole extent is being written to. | ||
| 2211 | * i.e. ex2 == ex and ex3 == NULL. | ||
| 2212 | */ | ||
| 2213 | if (!ex3) { | ||
| 2214 | ret = ext4_ext_try_to_merge(inode, path, ex2); | ||
| 2215 | if (ret) { | ||
| 2216 | err = ext4_ext_correct_indexes(handle, inode, path); | ||
| 2217 | if (err) | ||
| 2218 | goto out; | ||
| 2219 | } | ||
| 2220 | } | ||
| 2221 | /* Mark modified extent as dirty */ | ||
| 2222 | err = ext4_ext_dirty(handle, inode, path + depth); | ||
| 2223 | goto out; | ||
| 2224 | insert: | ||
| 2225 | err = ext4_ext_insert_extent(handle, inode, path, &newex); | ||
| 2226 | out: | ||
| 2227 | return err ? err : allocated; | ||
| 2228 | } | ||
| 2229 | |||
| 1980 | int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | 2230 | int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, |
| 1981 | ext4_fsblk_t iblock, | 2231 | ext4_fsblk_t iblock, |
| 1982 | unsigned long max_blocks, struct buffer_head *bh_result, | 2232 | unsigned long max_blocks, struct buffer_head *bh_result, |
| 1983 | int create, int extend_disksize) | 2233 | int create, int extend_disksize) |
| 1984 | { | 2234 | { |
| 1985 | struct ext4_ext_path *path = NULL; | 2235 | struct ext4_ext_path *path = NULL; |
| 2236 | struct ext4_extent_header *eh; | ||
| 1986 | struct ext4_extent newex, *ex; | 2237 | struct ext4_extent newex, *ex; |
| 1987 | ext4_fsblk_t goal, newblock; | 2238 | ext4_fsblk_t goal, newblock; |
| 1988 | int err = 0, depth; | 2239 | int err = 0, depth, ret; |
| 1989 | unsigned long allocated = 0; | 2240 | unsigned long allocated = 0; |
| 1990 | 2241 | ||
| 1991 | __clear_bit(BH_New, &bh_result->b_state); | 2242 | __clear_bit(BH_New, &bh_result->b_state); |
| @@ -1998,8 +2249,10 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
| 1998 | if (goal) { | 2249 | if (goal) { |
| 1999 | if (goal == EXT4_EXT_CACHE_GAP) { | 2250 | if (goal == EXT4_EXT_CACHE_GAP) { |
| 2000 | if (!create) { | 2251 | if (!create) { |
| 2001 | /* block isn't allocated yet and | 2252 | /* |
| 2002 | * user doesn't want to allocate it */ | 2253 | * block isn't allocated yet and |
| 2254 | * user doesn't want to allocate it | ||
| 2255 | */ | ||
| 2003 | goto out2; | 2256 | goto out2; |
| 2004 | } | 2257 | } |
| 2005 | /* we should allocate requested block */ | 2258 | /* we should allocate requested block */ |
| @@ -2033,21 +2286,19 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
| 2033 | * this is why assert can't be put in ext4_ext_find_extent() | 2286 | * this is why assert can't be put in ext4_ext_find_extent() |
| 2034 | */ | 2287 | */ |
| 2035 | BUG_ON(path[depth].p_ext == NULL && depth != 0); | 2288 | BUG_ON(path[depth].p_ext == NULL && depth != 0); |
| 2289 | eh = path[depth].p_hdr; | ||
| 2036 | 2290 | ||
| 2037 | ex = path[depth].p_ext; | 2291 | ex = path[depth].p_ext; |
| 2038 | if (ex) { | 2292 | if (ex) { |
| 2039 | unsigned long ee_block = le32_to_cpu(ex->ee_block); | 2293 | unsigned long ee_block = le32_to_cpu(ex->ee_block); |
| 2040 | ext4_fsblk_t ee_start = ext_pblock(ex); | 2294 | ext4_fsblk_t ee_start = ext_pblock(ex); |
| 2041 | unsigned short ee_len = le16_to_cpu(ex->ee_len); | 2295 | unsigned short ee_len; |
| 2042 | 2296 | ||
| 2043 | /* | 2297 | /* |
| 2044 | * Allow future support for preallocated extents to be added | ||
| 2045 | * as an RO_COMPAT feature: | ||
| 2046 | * Uninitialized extents are treated as holes, except that | 2298 | * Uninitialized extents are treated as holes, except that |
| 2047 | * we avoid (fail) allocating new blocks during a write. | 2299 | * we split out initialized portions during a write. |
| 2048 | */ | 2300 | */ |
| 2049 | if (ee_len > EXT_MAX_LEN) | 2301 | ee_len = ext4_ext_get_actual_len(ex); |
| 2050 | goto out2; | ||
| 2051 | /* if found extent covers block, simply return it */ | 2302 | /* if found extent covers block, simply return it */ |
| 2052 | if (iblock >= ee_block && iblock < ee_block + ee_len) { | 2303 | if (iblock >= ee_block && iblock < ee_block + ee_len) { |
| 2053 | newblock = iblock - ee_block + ee_start; | 2304 | newblock = iblock - ee_block + ee_start; |
| @@ -2055,9 +2306,27 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
| 2055 | allocated = ee_len - (iblock - ee_block); | 2306 | allocated = ee_len - (iblock - ee_block); |
| 2056 | ext_debug("%d fit into %lu:%d -> %llu\n", (int) iblock, | 2307 | ext_debug("%d fit into %lu:%d -> %llu\n", (int) iblock, |
| 2057 | ee_block, ee_len, newblock); | 2308 | ee_block, ee_len, newblock); |
| 2058 | ext4_ext_put_in_cache(inode, ee_block, ee_len, | 2309 | |
| 2059 | ee_start, EXT4_EXT_CACHE_EXTENT); | 2310 | /* Do not put uninitialized extent in the cache */ |
| 2060 | goto out; | 2311 | if (!ext4_ext_is_uninitialized(ex)) { |
| 2312 | ext4_ext_put_in_cache(inode, ee_block, | ||
| 2313 | ee_len, ee_start, | ||
| 2314 | EXT4_EXT_CACHE_EXTENT); | ||
| 2315 | goto out; | ||
| 2316 | } | ||
| 2317 | if (create == EXT4_CREATE_UNINITIALIZED_EXT) | ||
| 2318 | goto out; | ||
| 2319 | if (!create) | ||
| 2320 | goto out2; | ||
| 2321 | |||
| 2322 | ret = ext4_ext_convert_to_initialized(handle, inode, | ||
| 2323 | path, iblock, | ||
| 2324 | max_blocks); | ||
| 2325 | if (ret <= 0) | ||
| 2326 | goto out2; | ||
| 2327 | else | ||
| 2328 | allocated = ret; | ||
| 2329 | goto outnew; | ||
| 2061 | } | 2330 | } |
| 2062 | } | 2331 | } |
| 2063 | 2332 | ||
| @@ -2066,8 +2335,10 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
| 2066 | * we couldn't try to create block if create flag is zero | 2335 | * we couldn't try to create block if create flag is zero |
| 2067 | */ | 2336 | */ |
| 2068 | if (!create) { | 2337 | if (!create) { |
| 2069 | /* put just found gap into cache to speed up | 2338 | /* |
| 2070 | * subsequent requests */ | 2339 | * put just found gap into cache to speed up |
| 2340 | * subsequent requests | ||
| 2341 | */ | ||
| 2071 | ext4_ext_put_gap_in_cache(inode, path, iblock); | 2342 | ext4_ext_put_gap_in_cache(inode, path, iblock); |
| 2072 | goto out2; | 2343 | goto out2; |
| 2073 | } | 2344 | } |
| @@ -2081,6 +2352,19 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
| 2081 | /* allocate new block */ | 2352 | /* allocate new block */ |
| 2082 | goal = ext4_ext_find_goal(inode, path, iblock); | 2353 | goal = ext4_ext_find_goal(inode, path, iblock); |
| 2083 | 2354 | ||
| 2355 | /* | ||
| 2356 | * See if request is beyond maximum number of blocks we can have in | ||
| 2357 | * a single extent. For an initialized extent this limit is | ||
| 2358 | * EXT_INIT_MAX_LEN and for an uninitialized extent this limit is | ||
| 2359 | * EXT_UNINIT_MAX_LEN. | ||
| 2360 | */ | ||
| 2361 | if (max_blocks > EXT_INIT_MAX_LEN && | ||
| 2362 | create != EXT4_CREATE_UNINITIALIZED_EXT) | ||
| 2363 | max_blocks = EXT_INIT_MAX_LEN; | ||
| 2364 | else if (max_blocks > EXT_UNINIT_MAX_LEN && | ||
| 2365 | create == EXT4_CREATE_UNINITIALIZED_EXT) | ||
| 2366 | max_blocks = EXT_UNINIT_MAX_LEN; | ||
| 2367 | |||
| 2084 | /* Check if we can really insert (iblock)::(iblock+max_blocks) extent */ | 2368 | /* Check if we can really insert (iblock)::(iblock+max_blocks) extent */ |
| 2085 | newex.ee_block = cpu_to_le32(iblock); | 2369 | newex.ee_block = cpu_to_le32(iblock); |
| 2086 | newex.ee_len = cpu_to_le16(max_blocks); | 2370 | newex.ee_len = cpu_to_le16(max_blocks); |
| @@ -2098,6 +2382,8 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
| 2098 | /* try to insert new extent into found leaf and return */ | 2382 | /* try to insert new extent into found leaf and return */ |
| 2099 | ext4_ext_store_pblock(&newex, newblock); | 2383 | ext4_ext_store_pblock(&newex, newblock); |
| 2100 | newex.ee_len = cpu_to_le16(allocated); | 2384 | newex.ee_len = cpu_to_le16(allocated); |
| 2385 | if (create == EXT4_CREATE_UNINITIALIZED_EXT) /* Mark uninitialized */ | ||
| 2386 | ext4_ext_mark_uninitialized(&newex); | ||
| 2101 | err = ext4_ext_insert_extent(handle, inode, path, &newex); | 2387 | err = ext4_ext_insert_extent(handle, inode, path, &newex); |
| 2102 | if (err) { | 2388 | if (err) { |
| 2103 | /* free data blocks we just allocated */ | 2389 | /* free data blocks we just allocated */ |
| @@ -2111,10 +2397,13 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
| 2111 | 2397 | ||
| 2112 | /* previous routine could use block we allocated */ | 2398 | /* previous routine could use block we allocated */ |
| 2113 | newblock = ext_pblock(&newex); | 2399 | newblock = ext_pblock(&newex); |
| 2400 | outnew: | ||
| 2114 | __set_bit(BH_New, &bh_result->b_state); | 2401 | __set_bit(BH_New, &bh_result->b_state); |
| 2115 | 2402 | ||
| 2116 | ext4_ext_put_in_cache(inode, iblock, allocated, newblock, | 2403 | /* Cache only when it is _not_ an uninitialized extent */ |
| 2117 | EXT4_EXT_CACHE_EXTENT); | 2404 | if (create != EXT4_CREATE_UNINITIALIZED_EXT) |
| 2405 | ext4_ext_put_in_cache(inode, iblock, allocated, newblock, | ||
| 2406 | EXT4_EXT_CACHE_EXTENT); | ||
| 2118 | out: | 2407 | out: |
| 2119 | if (allocated > max_blocks) | 2408 | if (allocated > max_blocks) |
| 2120 | allocated = max_blocks; | 2409 | allocated = max_blocks; |
| @@ -2178,7 +2467,8 @@ void ext4_ext_truncate(struct inode * inode, struct page *page) | |||
| 2178 | err = ext4_ext_remove_space(inode, last_block); | 2467 | err = ext4_ext_remove_space(inode, last_block); |
| 2179 | 2468 | ||
| 2180 | /* In a multi-transaction truncate, we only make the final | 2469 | /* In a multi-transaction truncate, we only make the final |
| 2181 | * transaction synchronous. */ | 2470 | * transaction synchronous. |
| 2471 | */ | ||
| 2182 | if (IS_SYNC(inode)) | 2472 | if (IS_SYNC(inode)) |
| 2183 | handle->h_sync = 1; | 2473 | handle->h_sync = 1; |
| 2184 | 2474 | ||
| @@ -2217,3 +2507,127 @@ int ext4_ext_writepage_trans_blocks(struct inode *inode, int num) | |||
| 2217 | 2507 | ||
| 2218 | return needed; | 2508 | return needed; |
| 2219 | } | 2509 | } |
| 2510 | |||
| 2511 | /* | ||
| 2512 | * preallocate space for a file. This implements ext4's fallocate inode | ||
| 2513 | * operation, which gets called from sys_fallocate system call. | ||
| 2514 | * For block-mapped files, posix_fallocate should fall back to the method | ||
| 2515 | * of writing zeroes to the required new blocks (the same behavior which is | ||
| 2516 | * expected for file systems which do not support fallocate() system call). | ||
| 2517 | */ | ||
| 2518 | long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) | ||
| 2519 | { | ||
| 2520 | handle_t *handle; | ||
| 2521 | ext4_fsblk_t block, max_blocks; | ||
| 2522 | ext4_fsblk_t nblocks = 0; | ||
| 2523 | int ret = 0; | ||
| 2524 | int ret2 = 0; | ||
| 2525 | int retries = 0; | ||
| 2526 | struct buffer_head map_bh; | ||
| 2527 | unsigned int credits, blkbits = inode->i_blkbits; | ||
| 2528 | |||
| 2529 | /* | ||
| 2530 | * currently supporting (pre)allocate mode for extent-based | ||
| 2531 | * files _only_ | ||
| 2532 | */ | ||
| 2533 | if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)) | ||
| 2534 | return -EOPNOTSUPP; | ||
| 2535 | |||
| 2536 | /* preallocation to directories is currently not supported */ | ||
| 2537 | if (S_ISDIR(inode->i_mode)) | ||
| 2538 | return -ENODEV; | ||
| 2539 | |||
| 2540 | block = offset >> blkbits; | ||
| 2541 | max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits) | ||
| 2542 | - block; | ||
| 2543 | |||
| 2544 | /* | ||
| 2545 | * credits to insert 1 extent into extent tree + buffers to be able to | ||
| 2546 | * modify 1 super block, 1 block bitmap and 1 group descriptor. | ||
| 2547 | */ | ||
| 2548 | credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3; | ||
| 2549 | retry: | ||
| 2550 | while (ret >= 0 && ret < max_blocks) { | ||
| 2551 | block = block + ret; | ||
| 2552 | max_blocks = max_blocks - ret; | ||
| 2553 | handle = ext4_journal_start(inode, credits); | ||
| 2554 | if (IS_ERR(handle)) { | ||
| 2555 | ret = PTR_ERR(handle); | ||
| 2556 | break; | ||
| 2557 | } | ||
| 2558 | |||
| 2559 | ret = ext4_ext_get_blocks(handle, inode, block, | ||
| 2560 | max_blocks, &map_bh, | ||
| 2561 | EXT4_CREATE_UNINITIALIZED_EXT, 0); | ||
| 2562 | WARN_ON(!ret); | ||
| 2563 | if (!ret) { | ||
| 2564 | ext4_error(inode->i_sb, "ext4_fallocate", | ||
| 2565 | "ext4_ext_get_blocks returned 0! inode#%lu" | ||
| 2566 | ", block=%llu, max_blocks=%llu", | ||
| 2567 | inode->i_ino, block, max_blocks); | ||
| 2568 | ret = -EIO; | ||
| 2569 | ext4_mark_inode_dirty(handle, inode); | ||
| 2570 | ret2 = ext4_journal_stop(handle); | ||
| 2571 | break; | ||
| 2572 | } | ||
| 2573 | if (ret > 0) { | ||
| 2574 | /* check wrap through sign-bit/zero here */ | ||
| 2575 | if ((block + ret) < 0 || (block + ret) < block) { | ||
| 2576 | ret = -EIO; | ||
| 2577 | ext4_mark_inode_dirty(handle, inode); | ||
| 2578 | ret2 = ext4_journal_stop(handle); | ||
| 2579 | break; | ||
| 2580 | } | ||
| 2581 | if (buffer_new(&map_bh) && ((block + ret) > | ||
| 2582 | (EXT4_BLOCK_ALIGN(i_size_read(inode), blkbits) | ||
| 2583 | >> blkbits))) | ||
| 2584 | nblocks = nblocks + ret; | ||
| 2585 | } | ||
| 2586 | |||
| 2587 | /* Update ctime if new blocks get allocated */ | ||
| 2588 | if (nblocks) { | ||
| 2589 | struct timespec now; | ||
| 2590 | |||
| 2591 | now = current_fs_time(inode->i_sb); | ||
| 2592 | if (!timespec_equal(&inode->i_ctime, &now)) | ||
| 2593 | inode->i_ctime = now; | ||
| 2594 | } | ||
| 2595 | |||
| 2596 | ext4_mark_inode_dirty(handle, inode); | ||
| 2597 | ret2 = ext4_journal_stop(handle); | ||
| 2598 | if (ret2) | ||
| 2599 | break; | ||
| 2600 | } | ||
| 2601 | |||
| 2602 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) | ||
| 2603 | goto retry; | ||
| 2604 | |||
| 2605 | /* | ||
| 2606 | * Time to update the file size. | ||
| 2607 | * Update only when preallocation was requested beyond the file size. | ||
| 2608 | */ | ||
| 2609 | if (!(mode & FALLOC_FL_KEEP_SIZE) && | ||
| 2610 | (offset + len) > i_size_read(inode)) { | ||
| 2611 | if (ret > 0) { | ||
| 2612 | /* | ||
| 2613 | * if no error, we assume preallocation succeeded | ||
| 2614 | * completely | ||
| 2615 | */ | ||
| 2616 | mutex_lock(&inode->i_mutex); | ||
| 2617 | i_size_write(inode, offset + len); | ||
| 2618 | EXT4_I(inode)->i_disksize = i_size_read(inode); | ||
| 2619 | mutex_unlock(&inode->i_mutex); | ||
| 2620 | } else if (ret < 0 && nblocks) { | ||
| 2621 | /* Handle partial allocation scenario */ | ||
| 2622 | loff_t newsize; | ||
| 2623 | |||
| 2624 | mutex_lock(&inode->i_mutex); | ||
| 2625 | newsize = (nblocks << blkbits) + i_size_read(inode); | ||
| 2626 | i_size_write(inode, EXT4_BLOCK_ALIGN(newsize, blkbits)); | ||
| 2627 | EXT4_I(inode)->i_disksize = i_size_read(inode); | ||
| 2628 | mutex_unlock(&inode->i_mutex); | ||
| 2629 | } | ||
| 2630 | } | ||
| 2631 | |||
| 2632 | return ret > 0 ? ret2 : ret; | ||
| 2633 | } | ||
