diff options
-rw-r--r-- | fs/btrfs/tree-log.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 3fc8d854d7fb..4a04659fded7 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -5420,9 +5420,19 @@ log_extents: | |||
5420 | } | 5420 | } |
5421 | } | 5421 | } |
5422 | 5422 | ||
5423 | /* | ||
5424 | * Don't update last_log_commit if we logged that an inode exists after | ||
5425 | * it was loaded to memory (full_sync bit set). | ||
5426 | * This is to prevent data loss when we do a write to the inode, then | ||
5427 | * the inode gets evicted after all delalloc was flushed, then we log | ||
5428 | * it exists (due to a rename for example) and then fsync it. This last | ||
5429 | * fsync would do nothing (not logging the extents previously written). | ||
5430 | */ | ||
5423 | spin_lock(&inode->lock); | 5431 | spin_lock(&inode->lock); |
5424 | inode->logged_trans = trans->transid; | 5432 | inode->logged_trans = trans->transid; |
5425 | inode->last_log_commit = inode->last_sub_trans; | 5433 | if (inode_only != LOG_INODE_EXISTS || |
5434 | !test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &inode->runtime_flags)) | ||
5435 | inode->last_log_commit = inode->last_sub_trans; | ||
5426 | spin_unlock(&inode->lock); | 5436 | spin_unlock(&inode->lock); |
5427 | out_unlock: | 5437 | out_unlock: |
5428 | mutex_unlock(&inode->log_mutex); | 5438 | mutex_unlock(&inode->log_mutex); |