aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-log.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-16 18:12:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-16 18:12:56 -0400
commita18f8775419d3df282dd83efdb51c5a64d092f31 (patch)
tree1e0abc5c1d30e8bc58dc23099017eca496992fd2 /fs/btrfs/tree-log.c
parent3eb514866f20c5eb74637279774b6d73b855480a (diff)
parente02d48eaaed77f6c36916a7aa65c451e1f9d9aab (diff)
Merge tag 'for-5.3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs updates from David Sterba: "Highlights: - chunks that have been trimmed and unchanged since last mount are tracked and skipped on repeated trims - use hw assissed crc32c on more arches, speedups if native instructions or optimized implementation is available - the RAID56 incompat bit is automatically removed when the last block group of that type is removed Fixes: - fsync fix for reflink on NODATACOW files that could lead to ENOSPC - fix data loss after inode eviction, renaming it, and fsync it - fix fsync not persisting dentry deletions due to inode evictions - update ctime/mtime/iversion after hole punching - fix compression type validation (reported by KASAN) - send won't be allowed to start when relocation is in progress, this can cause spurious errors or produce incorrect send stream Core: - new tracepoints for space update - tree-checker: better check for end of extents for some tree items - preparatory work for more checksum algorithms - run delayed iput at unlink time and don't push the work to cleaner thread where it's not properly throttled - wrap block mapping to structures and helpers, base for further refactoring - split large files, part 1: - space info handling - block group reservations - delayed refs - delayed allocation - other cleanups and refactoring" * tag 'for-5.3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: (103 commits) btrfs: fix memory leak of path on error return path btrfs: move the subvolume reservation stuff out of extent-tree.c btrfs: migrate the delalloc space stuff to it's own home btrfs: migrate btrfs_trans_release_chunk_metadata btrfs: migrate the delayed refs rsv code btrfs: Evaluate io_tree in find_lock_delalloc_range() btrfs: migrate the global_block_rsv helpers to block-rsv.c btrfs: migrate the block-rsv code to block-rsv.c btrfs: stop using block_rsv_release_bytes everywhere btrfs: cleanup the target logic in __btrfs_block_rsv_release btrfs: export __btrfs_block_rsv_release btrfs: export btrfs_block_rsv_add_bytes btrfs: move btrfs_block_rsv definitions into it's own header btrfs: Simplify update of space_info in __reserve_metadata_bytes() btrfs: unexport can_overcommit btrfs: move reserve_metadata_bytes and supporting code to space-info.c btrfs: move dump_space_info to space-info.c btrfs: export block_rsv_use_bytes btrfs: move btrfs_space_info_add_*_bytes to space-info.c btrfs: move the space info update macro to space-info.h ...
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r--fs/btrfs/tree-log.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 3fc8d854d7fb..6c8297bcfeb7 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -3323,6 +3323,30 @@ int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans,
3323} 3323}
3324 3324
3325/* 3325/*
3326 * Check if an inode was logged in the current transaction. We can't always rely
3327 * on an inode's logged_trans value, because it's an in-memory only field and
3328 * therefore not persisted. This means that its value is lost if the inode gets
3329 * evicted and loaded again from disk (in which case it has a value of 0, and
3330 * certainly it is smaller then any possible transaction ID), when that happens
3331 * the full_sync flag is set in the inode's runtime flags, so on that case we
3332 * assume eviction happened and ignore the logged_trans value, assuming the
3333 * worst case, that the inode was logged before in the current transaction.
3334 */
3335static bool inode_logged(struct btrfs_trans_handle *trans,
3336 struct btrfs_inode *inode)
3337{
3338 if (inode->logged_trans == trans->transid)
3339 return true;
3340
3341 if (inode->last_trans == trans->transid &&
3342 test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &inode->runtime_flags) &&
3343 !test_bit(BTRFS_FS_LOG_RECOVERING, &trans->fs_info->flags))
3344 return true;
3345
3346 return false;
3347}
3348
3349/*
3326 * If both a file and directory are logged, and unlinks or renames are 3350 * If both a file and directory are logged, and unlinks or renames are
3327 * mixed in, we have a few interesting corners: 3351 * mixed in, we have a few interesting corners:
3328 * 3352 *
@@ -3356,7 +3380,7 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans,
3356 int bytes_del = 0; 3380 int bytes_del = 0;
3357 u64 dir_ino = btrfs_ino(dir); 3381 u64 dir_ino = btrfs_ino(dir);
3358 3382
3359 if (dir->logged_trans < trans->transid) 3383 if (!inode_logged(trans, dir))
3360 return 0; 3384 return 0;
3361 3385
3362 ret = join_running_log_trans(root); 3386 ret = join_running_log_trans(root);
@@ -3460,7 +3484,7 @@ int btrfs_del_inode_ref_in_log(struct btrfs_trans_handle *trans,
3460 u64 index; 3484 u64 index;
3461 int ret; 3485 int ret;
3462 3486
3463 if (inode->logged_trans < trans->transid) 3487 if (!inode_logged(trans, inode))
3464 return 0; 3488 return 0;
3465 3489
3466 ret = join_running_log_trans(root); 3490 ret = join_running_log_trans(root);
@@ -5420,9 +5444,19 @@ log_extents:
5420 } 5444 }
5421 } 5445 }
5422 5446
5447 /*
5448 * Don't update last_log_commit if we logged that an inode exists after
5449 * it was loaded to memory (full_sync bit set).
5450 * This is to prevent data loss when we do a write to the inode, then
5451 * the inode gets evicted after all delalloc was flushed, then we log
5452 * it exists (due to a rename for example) and then fsync it. This last
5453 * fsync would do nothing (not logging the extents previously written).
5454 */
5423 spin_lock(&inode->lock); 5455 spin_lock(&inode->lock);
5424 inode->logged_trans = trans->transid; 5456 inode->logged_trans = trans->transid;
5425 inode->last_log_commit = inode->last_sub_trans; 5457 if (inode_only != LOG_INODE_EXISTS ||
5458 !test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &inode->runtime_flags))
5459 inode->last_log_commit = inode->last_sub_trans;
5426 spin_unlock(&inode->lock); 5460 spin_unlock(&inode->lock);
5427out_unlock: 5461out_unlock:
5428 mutex_unlock(&inode->log_mutex); 5462 mutex_unlock(&inode->log_mutex);