Home Home > GIT Browse > SLE15-AZURE
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2019-08-16 16:55:57 +0100
committerFilipe Manana <fdmanana@suse.com>2019-08-16 16:55:57 +0100
commit448c06bff35b4816bd08723f80016a23a447e0a4 (patch)
tree161c3f1ebd041cc210c9c4aa670cc472026a1fa6
parent0acdee9607d3ccb518c735c26deece037c74e3fa (diff)
Btrfs: fix data loss after inode eviction, renaming it, and
fsync it (bsc#1145941). suse-commit: 94c1da33f5a5f0e32f234a8e6ea3c90f912fdb65
-rw-r--r--fs/btrfs/tree-log.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 46ba55a225ff..de05078bc634 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -5591,9 +5591,19 @@ log_extents:
}
}
+ /*
+ * Don't update last_log_commit if we logged that an inode exists after
+ * it was loaded to memory (full_sync bit set).
+ * This is to prevent data loss when we do a write to the inode, then
+ * the inode gets evicted after all delalloc was flushed, then we log
+ * it exists (due to a rename for example) and then fsync it. This last
+ * fsync would do nothing (not logging the extents previously written).
+ */
spin_lock(&inode->lock);
inode->logged_trans = trans->transid;
- inode->last_log_commit = inode->last_sub_trans;
+ if (inode_only != LOG_INODE_EXISTS ||
+ !test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &inode->runtime_flags))
+ inode->last_log_commit = inode->last_sub_trans;
spin_unlock(&inode->lock);
out_unlock:
if (unlikely(err))