Merge tag 'for-5.4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 19 Sep 2019 00:29:31 +0000 (17:29 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 19 Sep 2019 00:29:31 +0000 (17:29 -0700)
Pull btrfs updates from David Sterba:
 "This continues with work on code refactoring, sanity checks and space
  handling. There are some less user visible changes, nothing that would
  particularly stand out.

  User visible changes:
   - tree checker, more sanity checks of:
       - ROOT_ITEM (key, size, generation, level, alignment, flags)
       - EXTENT_ITEM and METADATA_ITEM checks (key, size, offset,
         alignment, refs)
       - tree block reference items
       - EXTENT_DATA_REF (key, hash, offset)

   - deprecate flag BTRFS_SUBVOL_CREATE_ASYNC for subvolume creation
     ioctl, scheduled removal in 5.7

   - delete stale and unused UAPI definitions
     BTRFS_DEV_REPLACE_ITEM_STATE_*

   - improved export of debugging information available via existing
     sysfs directory structure

   - try harder to delete relations between qgroups and allow to delete
     orphan entries

   - remove unreliable space checks before relocation starts

  Core:
   - space handling:
       - improved ticket reservations and other high level logic in
         order to remove special cases
       - factor flushing infrastructure and use it for different
         contexts, allows to remove some special case handling
       - reduce metadata reservation when only updating inodes
       - reduce global block reserve minimum size (affects small
         filesystems)
       - improved overcommit logic wrt global block reserve

   - tests:
       - fix memory leaks in extent IO tree
       - catch all TRIM range

  Fixes:
   - fix ENOSPC errors, leading to transaction aborts, when cloning
     extents

   - several fixes for inode number cache (mount option inode_cache)

   - fix potential soft lockups during send when traversing large trees

   - fix unaligned access to space cache pages with SLUB debug on
     (PowerPC)

  Other:
   - refactoring public/private functions, moving to new or more
     appropriate files

   - defines converted to enums

   - error handling improvements

   - more assertions and comments

   - old code deletion"

* tag 'for-5.4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: (138 commits)
  btrfs: Relinquish CPUs in btrfs_compare_trees
  btrfs: Don't assign retval of btrfs_try_tree_write_lock/btrfs_tree_read_lock_atomic
  btrfs: create structure to encode checksum type and length
  btrfs: turn checksum type define into an enum
  btrfs: add enospc debug messages for ticket failure
  btrfs: do not account global reserve in can_overcommit
  btrfs: use btrfs_try_granting_tickets in update_global_rsv
  btrfs: always reserve our entire size for the global reserve
  btrfs: change the minimum global reserve size
  btrfs: rename btrfs_space_info_add_old_bytes
  btrfs: remove orig_bytes from reserve_ticket
  btrfs: fix may_commit_transaction to deal with no partial filling
  btrfs: rework wake_all_tickets
  btrfs: refactor the ticket wakeup code
  btrfs: stop partially refilling tickets when releasing space
  btrfs: add space reservation tracepoint for reserved bytes
  btrfs: roll tracepoint into btrfs_space_info_update helper
  btrfs: do not allow reservations if we have pending tickets
  btrfs: stop clearing EXTENT_DIRTY in inode I/O tree
  btrfs: treat RWF_{,D}SYNC writes as sync for CRCs
  ...

1  2 
fs/btrfs/extent_io.c
fs/btrfs/tree-log.c

diff --combined fs/btrfs/extent_io.c
@@@ -1938,9 -1938,9 +1938,9 @@@ out
  }
  
  void extent_clear_unlock_delalloc(struct inode *inode, u64 start, u64 end,
-                                u64 delalloc_end, struct page *locked_page,
-                                unsigned clear_bits,
-                                unsigned long page_ops)
+                                 struct page *locked_page,
+                                 unsigned clear_bits,
+                                 unsigned long page_ops)
  {
        clear_extent_bit(&BTRFS_I(inode)->io_tree, start, end, clear_bits, 1, 0,
                         NULL);
@@@ -3628,13 -3628,6 +3628,13 @@@ void wait_on_extent_buffer_writeback(st
                       TASK_UNINTERRUPTIBLE);
  }
  
 +static void end_extent_buffer_writeback(struct extent_buffer *eb)
 +{
 +      clear_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags);
 +      smp_mb__after_atomic();
 +      wake_up_bit(&eb->bflags, EXTENT_BUFFER_WRITEBACK);
 +}
 +
  /*
   * Lock eb pages and flush the bio if we can't the locks
   *
@@@ -3706,11 -3699,8 +3706,11 @@@ static noinline_for_stack int lock_exte
  
                if (!trylock_page(p)) {
                        if (!flush) {
 -                              ret = flush_write_bio(epd);
 -                              if (ret < 0) {
 +                              int err;
 +
 +                              err = flush_write_bio(epd);
 +                              if (err < 0) {
 +                                      ret = err;
                                        failed_page_nr = i;
                                        goto err_unlock;
                                }
@@@ -3725,23 -3715,16 +3725,23 @@@ err_unlock
        /* Unlock already locked pages */
        for (i = 0; i < failed_page_nr; i++)
                unlock_page(eb->pages[i]);
 +      /*
 +       * Clear EXTENT_BUFFER_WRITEBACK and wake up anyone waiting on it.
 +       * Also set back EXTENT_BUFFER_DIRTY so future attempts to this eb can
 +       * be made and undo everything done before.
 +       */
 +      btrfs_tree_lock(eb);
 +      spin_lock(&eb->refs_lock);
 +      set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags);
 +      end_extent_buffer_writeback(eb);
 +      spin_unlock(&eb->refs_lock);
 +      percpu_counter_add_batch(&fs_info->dirty_metadata_bytes, eb->len,
 +                               fs_info->dirty_metadata_batch);
 +      btrfs_clear_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN);
 +      btrfs_tree_unlock(eb);
        return ret;
  }
  
 -static void end_extent_buffer_writeback(struct extent_buffer *eb)
 -{
 -      clear_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags);
 -      smp_mb__after_atomic();
 -      wake_up_bit(&eb->bflags, EXTENT_BUFFER_WRITEBACK);
 -}
 -
  static void set_btree_ioerr(struct page *page)
  {
        struct extent_buffer *eb = (struct extent_buffer *)page->private;
@@@ -4339,10 -4322,8 +4339,8 @@@ int extent_invalidatepage(struct extent
  
        lock_extent_bits(tree, start, end, &cached_state);
        wait_on_page_writeback(page);
-       clear_extent_bit(tree, start, end,
-                        EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
-                        EXTENT_DO_ACCOUNTING,
-                        1, 1, &cached_state);
+       clear_extent_bit(tree, start, end, EXTENT_LOCKED | EXTENT_DELALLOC |
+                        EXTENT_DO_ACCOUNTING, 1, 1, &cached_state);
        return 0;
  }
  
diff --combined fs/btrfs/tree-log.c
@@@ -8,6 -8,7 +8,7 @@@
  #include <linux/blkdev.h>
  #include <linux/list_sort.h>
  #include <linux/iversion.h>
+ #include "misc.h"
  #include "ctree.h"
  #include "tree-log.h"
  #include "disk-io.h"
   * LOG_INODE_EXISTS means to log just enough to recreate the inode
   * during log replay
   */
- #define LOG_INODE_ALL 0
- #define LOG_INODE_EXISTS 1
- #define LOG_OTHER_INODE 2
- #define LOG_OTHER_INODE_ALL 3
+ enum {
+       LOG_INODE_ALL,
+       LOG_INODE_EXISTS,
+       LOG_OTHER_INODE,
+       LOG_OTHER_INODE_ALL,
+ };
  
  /*
   * directory trouble cases
   * The last stage is to deal with directories and links and extents
   * and all the other fun semantics
   */
- #define LOG_WALK_PIN_ONLY 0
- #define LOG_WALK_REPLAY_INODES 1
- #define LOG_WALK_REPLAY_DIR_INDEX 2
- #define LOG_WALK_REPLAY_ALL 3
+ enum {
+       LOG_WALK_PIN_ONLY,
+       LOG_WALK_REPLAY_INODES,
+       LOG_WALK_REPLAY_DIR_INDEX,
+       LOG_WALK_REPLAY_ALL,
+ };
  
  static int btrfs_log_inode(struct btrfs_trans_handle *trans,
                           struct btrfs_root *root, struct btrfs_inode *inode,
@@@ -188,10 -193,6 +193,6 @@@ static int join_running_log_trans(struc
  {
        int ret = -ENOENT;
  
-       smp_mb();
-       if (!root->log_root)
-               return -ENOENT;
        mutex_lock(&root->log_mutex);
        if (root->log_root) {
                ret = 0;
@@@ -505,7 -506,7 +506,7 @@@ insert
                            ino_size != 0) {
                                struct btrfs_map_token token;
  
-                               btrfs_init_map_token(&token);
+                               btrfs_init_map_token(&token, dst_eb);
                                btrfs_set_token_inode_size(dst_eb, dst_item,
                                                           ino_size, &token);
                        }
@@@ -967,7 -968,7 +968,7 @@@ static noinline int backref_in_log(stru
                if (btrfs_find_name_in_ext_backref(path->nodes[0],
                                                   path->slots[0],
                                                   ref_objectid,
-                                                  name, namelen, NULL))
+                                                  name, namelen))
                        match = 1;
  
                goto out;
@@@ -1266,12 -1267,12 +1267,12 @@@ again
                        goto out;
  
                if (key->type == BTRFS_INODE_EXTREF_KEY)
-                       ret = btrfs_find_name_in_ext_backref(log_eb, log_slot,
-                                                            parent_id, name,
-                                                            namelen, NULL);
+                       ret = !!btrfs_find_name_in_ext_backref(log_eb, log_slot,
+                                                              parent_id, name,
+                                                              namelen);
                else
-                       ret = btrfs_find_name_in_backref(log_eb, log_slot, name,
-                                                        namelen, NULL);
+                       ret = !!btrfs_find_name_in_backref(log_eb, log_slot,
+                                                          name, namelen);
  
                if (!ret) {
                        struct inode *dir;
@@@ -1333,12 -1334,11 +1334,11 @@@ static int btrfs_inode_ref_exists(struc
                goto out;
        }
        if (key.type == BTRFS_INODE_EXTREF_KEY)
-               ret = btrfs_find_name_in_ext_backref(path->nodes[0],
-                                                    path->slots[0], parent_id,
-                                                    name, namelen, NULL);
+               ret = !!btrfs_find_name_in_ext_backref(path->nodes[0],
+                               path->slots[0], parent_id, name, namelen);
        else
-               ret = btrfs_find_name_in_backref(path->nodes[0], path->slots[0],
-                                                name, namelen, NULL);
+               ret = !!btrfs_find_name_in_backref(path->nodes[0], path->slots[0],
+                                                  name, namelen);
  
  out:
        btrfs_free_path(path);
@@@ -3842,7 -3842,7 +3842,7 @@@ static void fill_inode_item(struct btrf
  {
        struct btrfs_map_token token;
  
-       btrfs_init_map_token(&token);
+       btrfs_init_map_token(&token, leaf);
  
        if (log_inode_only) {
                /* set the generation to zero so the recover code
@@@ -4302,8 -4302,6 +4302,6 @@@ static int log_one_extent(struct btrfs_
        if (ret)
                return ret;
  
-       btrfs_init_map_token(&token);
        ret = __btrfs_drop_extents(trans, log, &inode->vfs_inode, path, em->start,
                                   em->start + em->len, NULL, 0, 1,
                                   sizeof(*fi), &extent_inserted);
                        return ret;
        }
        leaf = path->nodes[0];
+       btrfs_init_map_token(&token, leaf);
        fi = btrfs_item_ptr(leaf, path->slots[0],
                            struct btrfs_file_extent_item);
  
@@@ -4985,7 -4984,7 +4984,7 @@@ static int log_conflicting_inodes(struc
                                                      BTRFS_I(inode),
                                                      LOG_OTHER_INODE_ALL,
                                                      0, LLONG_MAX, ctx);
 -                                      iput(inode);
 +                                      btrfs_add_delayed_iput(inode);
                                }
                        }
                        continue;
                ret = btrfs_log_inode(trans, root, BTRFS_I(inode),
                                      LOG_OTHER_INODE, 0, LLONG_MAX, ctx);
                if (ret) {
 -                      iput(inode);
 +                      btrfs_add_delayed_iput(inode);
                        continue;
                }
  
                key.offset = 0;
                ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
                if (ret < 0) {
 -                      iput(inode);
 +                      btrfs_add_delayed_iput(inode);
                        continue;
                }
  
                        }
                        path->slots[0]++;
                }
 -              iput(inode);
 +              btrfs_add_delayed_iput(inode);
        }
  
        return ret;
@@@ -5689,7 -5688,7 +5688,7 @@@ process_leaf
                        }
  
                        if (btrfs_inode_in_log(BTRFS_I(di_inode), trans->transid)) {
 -                              iput(di_inode);
 +                              btrfs_add_delayed_iput(di_inode);
                                break;
                        }
  
                        if (!ret &&
                            btrfs_must_commit_transaction(trans, BTRFS_I(di_inode)))
                                ret = 1;
 -                      iput(di_inode);
 +                      btrfs_add_delayed_iput(di_inode);
                        if (ret)
                                goto next_dir_inode;
                        if (ctx->log_new_dentries) {
@@@ -5848,7 -5847,7 +5847,7 @@@ static int btrfs_log_all_parents(struc
                        if (!ret && ctx && ctx->log_new_dentries)
                                ret = log_new_dir_dentries(trans, root,
                                                   BTRFS_I(dir_inode), ctx);
 -                      iput(dir_inode);
 +                      btrfs_add_delayed_iput(dir_inode);
                        if (ret)
                                goto out;
                }
@@@ -5891,7 -5890,7 +5890,7 @@@ static int log_new_ancestors(struct btr
                        ret = btrfs_log_inode(trans, root, BTRFS_I(inode),
                                              LOG_INODE_EXISTS,
                                              0, LLONG_MAX, ctx);
 -              iput(inode);
 +              btrfs_add_delayed_iput(inode);
                if (ret)
                        return ret;
  
@@@ -6233,7 -6232,7 +6232,7 @@@ int btrfs_recover_log_trees(struct btrf
        struct btrfs_fs_info *fs_info = log_root_tree->fs_info;
        struct walk_control wc = {
                .process_func = process_one_buffer,
-               .stage = 0,
+               .stage = LOG_WALK_PIN_ONLY,
        };
  
        path = btrfs_alloc_path();