aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/tree-log.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index f06454a55e00..5256cddf3a43 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -4544,6 +4544,19 @@ static int logged_inode_size(struct btrfs_root *log, struct btrfs_inode *inode,
4544 item = btrfs_item_ptr(path->nodes[0], path->slots[0], 4544 item = btrfs_item_ptr(path->nodes[0], path->slots[0],
4545 struct btrfs_inode_item); 4545 struct btrfs_inode_item);
4546 *size_ret = btrfs_inode_size(path->nodes[0], item); 4546 *size_ret = btrfs_inode_size(path->nodes[0], item);
4547 /*
4548 * If the in-memory inode's i_size is smaller then the inode
4549 * size stored in the btree, return the inode's i_size, so
4550 * that we get a correct inode size after replaying the log
4551 * when before a power failure we had a shrinking truncate
4552 * followed by addition of a new name (rename / new hard link).
4553 * Otherwise return the inode size from the btree, to avoid
4554 * data loss when replaying a log due to previously doing a
4555 * write that expands the inode's size and logging a new name
4556 * immediately after.
4557 */
4558 if (*size_ret > inode->vfs_inode.i_size)
4559 *size_ret = inode->vfs_inode.i_size;
4547 } 4560 }
4548 4561
4549 btrfs_release_path(path); 4562 btrfs_release_path(path);