diff options
author | 2018-12-27 16:44:40 -0800 | |
---|---|---|
committer | 2018-12-27 16:44:40 -0800 | |
commit | 32ee34eddad13cd44ad0cb3e659fe6fd49143b62 (patch) | |
tree | 4c392ff23c0be6d00fbf67e7d8b13ce0d6d14999 /fs/btrfs/tree-log.c | |
parent | Merge tag 'gfs2-4.21.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2 (diff) | |
parent | btrfs: Fix typos in comments and strings (diff) | |
download | wireguard-linux-32ee34eddad13cd44ad0cb3e659fe6fd49143b62.tar.xz wireguard-linux-32ee34eddad13cd44ad0cb3e659fe6fd49143b62.zip |
Merge tag 'for-4.21-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs updates from David Sterba:
"New features:
- swapfile support - after a long time it's here, with some
limitations where COW design does not work well with the swap
implementation (nodatacow file, no compression, cannot be
snapshotted, not possible on multiple devices, ...), as this is the
most restricted but working setup, we'll try to improve that in the
future
- metadata uuid - an optional incompat feature to assign a new
filesystem UUID without overwriting all metadata blocks, stored
only in superblock
- more balance messages are printed to system log, initial is in the
format of the command line that would be used to start it
Fixes:
- tag pages of a snapshot to better separate pages that are involved
in the snapshot (and need to get synced) from newly dirtied pages
that could slow down or even livelock the snapshot operation
- improved check of filesystem id associated with a device during
scan to detect duplicate devices that could be mixed up during
mount
- fix device replace state transitions, eg. when it ends up
interrupted and reboot tries to restart balance too, or when
start/cancel ioctls race
- fix a crash due to a race when quotas are enabled during snapshot
creation
- GFP_NOFS/memalloc_nofs_* fixes due to GFP_KERNEL allocations in
transaction context
- fix fsync of files with multiple hard links in new directories
- fix race of send with transaction commits that create snapshots
Core changes:
- cleanups:
* further removals of now-dead fsync code
* core function for finding free extent has been split and
provides a base for further cleanups to make the logic more
understandable
* removed lot of indirect callbacks for data and metadata inodes
* simplified refcounting and locking for cloned extent buffers
* removed redundant function arguments
* defines converted to enums where appropriate
- separate reserve for delayed refs from global reserve, update logic
to do less trickery and ad-hoc heuristics, move out some related
expensive operations from transaction commit or file truncate
- dev-replace switched from custom locking scheme to semaphore
- remove first phase of balance that tried to make some space for the
relocation by calling shrink and grow, this did not work as
expected and only introduced more error states due to potential
resize failures, slightly improves the runtime as the chunks on all
devices are not needlessly enumerated
- clone and deduplication now use generic helper that adds a few more
checks that were missing from the original btrfs implementation of
the ioctls"
* tag 'for-4.21-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: (125 commits)
btrfs: Fix typos in comments and strings
btrfs: improve error handling of btrfs_add_link
Btrfs: use generic_remap_file_range_prep() for cloning and deduplication
btrfs: Refactor main loop in extent_readpages
btrfs: Remove 1st shrink/grow phase from balance
Btrfs: send, fix race with transaction commits that create snapshots
Btrfs: use nofs context when initializing security xattrs to avoid deadlock
btrfs: run delayed items before dropping the snapshot
btrfs: catch cow on deleting snapshots
btrfs: extent-tree: cleanup one-shot usage of @blocksize in do_walk_down
Btrfs: scrub, move setup of nofs contexts higher in the stack
btrfs: scrub: move scrub_setup_ctx allocation out of device_list_mutex
btrfs: scrub: pass fs_info to scrub_setup_ctx
btrfs: fix truncate throttling
btrfs: don't run delayed refs in the end transaction logic
btrfs: rework btrfs_check_space_for_delayed_refs
btrfs: add new flushing states for the delayed refs rsv
btrfs: update may_commit_transaction to use the delayed refs rsv
btrfs: introduce delayed_refs_rsv
btrfs: only track ref_heads in delayed_ref_updates
...
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r-- | fs/btrfs/tree-log.c | 44 |
1 files changed, 20 insertions, 24 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index a5ce99a6c936..ac232b3d6d7e 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -1144,7 +1144,7 @@ next: } btrfs_release_path(path); - /* look for a conflicing name */ + /* look for a conflicting name */ di = btrfs_lookup_dir_item(trans, root, path, btrfs_ino(dir), name, namelen, 0); if (di && !IS_ERR(di)) { @@ -3149,7 +3149,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, mutex_unlock(&log_root_tree->log_mutex); /* - * nobody else is going to jump in and write the the ctree + * Nobody else is going to jump in and write the ctree * super here because the log_commit atomic below is protecting * us. We must be called with a transaction handle pinning * the running transaction open, so a full commit can't hop @@ -3201,8 +3201,6 @@ static void free_log_tree(struct btrfs_trans_handle *trans, struct btrfs_root *log) { int ret; - u64 start; - u64 end; struct walk_control wc = { .free = 1, .process_func = process_one_buffer @@ -3216,18 +3214,8 @@ static void free_log_tree(struct btrfs_trans_handle *trans, btrfs_handle_fs_error(log->fs_info, ret, NULL); } - while (1) { - ret = find_first_extent_bit(&log->dirty_log_pages, - 0, &start, &end, - EXTENT_DIRTY | EXTENT_NEW | EXTENT_NEED_WAIT, - NULL); - if (ret) - break; - - clear_extent_bits(&log->dirty_log_pages, start, end, - EXTENT_DIRTY | EXTENT_NEW | EXTENT_NEED_WAIT); - } - + clear_extent_bits(&log->dirty_log_pages, 0, (u64)-1, + EXTENT_DIRTY | EXTENT_NEW | EXTENT_NEED_WAIT); free_extent_buffer(log->node); kfree(log); } @@ -4383,7 +4371,6 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, struct extent_map *em, *n; struct list_head extents; struct extent_map_tree *tree = &inode->extent_tree; - u64 logged_start, logged_end; u64 test_gen; int ret = 0; int num = 0; @@ -4392,8 +4379,6 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, write_lock(&tree->lock); test_gen = root->fs_info->last_trans_committed; - logged_start = start; - logged_end = end; list_for_each_entry_safe(em, n, &tree->modified_extents, list) { /* @@ -4434,11 +4419,6 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, em->start >= i_size_read(&inode->vfs_inode)) continue; - if (em->start < logged_start) - logged_start = em->start; - if ((em->start + em->len - 1) > logged_end) - logged_end = em->start + em->len - 1; - /* Need a ref to keep it from getting evicted from cache */ refcount_inc(&em->refs); set_bit(EXTENT_FLAG_LOGGING, &em->flags); @@ -5778,6 +5758,22 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, goto end_trans; } + /* + * If a new hard link was added to the inode in the current transaction + * and its link count is now greater than 1, we need to fallback to a + * transaction commit, otherwise we can end up not logging all its new + * parents for all the hard links. Here just from the dentry used to + * fsync, we can not visit the ancestor inodes for all the other hard + * links to figure out if any is new, so we fallback to a transaction + * commit (instead of adding a lot of complexity of scanning a btree, + * since this scenario is not a common use case). + */ + if (inode->vfs_inode.i_nlink > 1 && + inode->last_link_trans > last_committed) { + ret = -EMLINK; + goto end_trans; + } + while (1) { if (!parent || d_really_is_negative(parent) || sb != parent->d_sb) break; |