Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs

Pull one more btrfs fix from Chris Mason:
"This has a recent fix from Josef for our tree log replay code. It
fixes problems where the inode counter for the number of bytes in the
file wasn't getting updated properly during fsync replay.

The commit did get rebased this morning, but it was only to clean up
the subject line. The code hasn't changed."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
Btrfs: make sure nbytes are right after log replay

+42 -6
+42 -6
fs/btrfs/tree-log.c
··· 317 317 unsigned long src_ptr; 318 318 unsigned long dst_ptr; 319 319 int overwrite_root = 0; 320 + bool inode_item = key->type == BTRFS_INODE_ITEM_KEY; 320 321 321 322 if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) 322 323 overwrite_root = 1; ··· 327 326 328 327 /* look for the key in the destination tree */ 329 328 ret = btrfs_search_slot(NULL, root, key, path, 0, 0); 329 + if (ret < 0) 330 + return ret; 331 + 330 332 if (ret == 0) { 331 333 char *src_copy; 332 334 char *dst_copy; ··· 371 367 return 0; 372 368 } 373 369 370 + /* 371 + * We need to load the old nbytes into the inode so when we 372 + * replay the extents we've logged we get the right nbytes. 373 + */ 374 + if (inode_item) { 375 + struct btrfs_inode_item *item; 376 + u64 nbytes; 377 + 378 + item = btrfs_item_ptr(path->nodes[0], path->slots[0], 379 + struct btrfs_inode_item); 380 + nbytes = btrfs_inode_nbytes(path->nodes[0], item); 381 + item = btrfs_item_ptr(eb, slot, 382 + struct btrfs_inode_item); 383 + btrfs_set_inode_nbytes(eb, item, nbytes); 384 + } 385 + } else if (inode_item) { 386 + struct btrfs_inode_item *item; 387 + 388 + /* 389 + * New inode, set nbytes to 0 so that the nbytes comes out 390 + * properly when we replay the extents. 391 + */ 392 + item = btrfs_item_ptr(eb, slot, struct btrfs_inode_item); 393 + btrfs_set_inode_nbytes(eb, item, 0); 374 394 } 375 395 insert: 376 396 btrfs_release_path(path); ··· 514 486 int found_type; 515 487 u64 extent_end; 516 488 u64 start = key->offset; 517 - u64 saved_nbytes; 489 + u64 nbytes = 0; 518 490 struct btrfs_file_extent_item *item; 519 491 struct inode *inode = NULL; 520 492 unsigned long size; ··· 524 496 found_type = btrfs_file_extent_type(eb, item); 525 497 526 498 if (found_type == BTRFS_FILE_EXTENT_REG || 527 - found_type == BTRFS_FILE_EXTENT_PREALLOC) 528 - extent_end = start + btrfs_file_extent_num_bytes(eb, item); 529 - else if (found_type == BTRFS_FILE_EXTENT_INLINE) { 499 + found_type == BTRFS_FILE_EXTENT_PREALLOC) { 500 + nbytes = btrfs_file_extent_num_bytes(eb, item); 501 + extent_end = start + nbytes; 502 + 503 + /* 504 + * We don't add to the inodes nbytes if we are prealloc or a 505 + * hole. 506 + */ 507 + if (btrfs_file_extent_disk_bytenr(eb, item) == 0) 508 + nbytes = 0; 509 + } else if (found_type == BTRFS_FILE_EXTENT_INLINE) { 530 510 size = btrfs_file_extent_inline_len(eb, item); 511 + nbytes = btrfs_file_extent_ram_bytes(eb, item); 531 512 extent_end = ALIGN(start + size, root->sectorsize); 532 513 } else { 533 514 ret = 0; ··· 585 548 } 586 549 btrfs_release_path(path); 587 550 588 - saved_nbytes = inode_get_bytes(inode); 589 551 /* drop any overlapping extents */ 590 552 ret = btrfs_drop_extents(trans, root, inode, start, extent_end, 1); 591 553 BUG_ON(ret); ··· 671 635 BUG_ON(ret); 672 636 } 673 637 674 - inode_set_bytes(inode, saved_nbytes); 638 + inode_add_bytes(inode, nbytes); 675 639 ret = btrfs_update_inode(trans, root, inode); 676 640 out: 677 641 if (inode)