]> Git Repo - linux.git/commitdiff
Merge tag 'for-5.6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
authorLinus Torvalds <[email protected]>
Tue, 28 Jan 2020 22:53:31 +0000 (14:53 -0800)
committerLinus Torvalds <[email protected]>
Tue, 28 Jan 2020 22:53:31 +0000 (14:53 -0800)
Pull btrfs updates from David Sterba:
 "Features, highlights:

   - async discard
       - "mount -o discard=async" to enable it
       - freed extents are not discarded immediatelly, but grouped
         together and trimmed later, with IO rate limiting
       - the "sync" mode submits short extents that could have been
         ignored completely by the device, for SATA prior to 3.1 the
         requests are unqueued and have a big impact on performance
       - the actual discard IO requests have been moved out of
         transaction commit to a worker thread, improving commit latency
       - IO rate and request size can be tuned by sysfs files, for now
         enabled only with CONFIG_BTRFS_DEBUG as we might need to
         add/delete the files and don't have a stable-ish ABI for
         general use, defaults are conservative

   - export device state info in sysfs, eg. missing, writeable

   - no discard of extents known to be untouched on disk (eg. after
     reservation)

   - device stats reset is logged with process name and PID that called
     the ioctl

  Fixes:

   - fix missing hole after hole punching and fsync when using NO_HOLES

   - writeback: range cyclic mode could miss some dirty pages and lead
     to OOM

   - two more corner cases for metadata_uuid change after power loss
     during the change

   - fix infinite loop during fsync after mix of rename operations

  Core changes:

   - qgroup assign returns ENOTCONN when quotas not enabled, used to
     return EINVAL that was confusing

   - device closing does not need to allocate memory anymore

   - snapshot aware code got removed, disabled for years due to
     performance problems, reimplmentation will allow to select wheter
     defrag breaks or does not break COW on shared extents

   - tree-checker:
       - check leaf chunk item size, cross check against number of
         stripes
       - verify location keys for DIR_ITEM, DIR_INDEX and XATTR items

   - new self test for physical -> logical mapping code, used for super
     block range exclusion

   - assertion helpers/macros updated to avoid objtool "unreachable
     code" reports on older compilers or config option combinations"

* tag 'for-5.6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: (84 commits)
  btrfs: free block groups after free'ing fs trees
  btrfs: Fix split-brain handling when changing FSID to metadata uuid
  btrfs: Handle another split brain scenario with metadata uuid feature
  btrfs: Factor out metadata_uuid code from find_fsid.
  btrfs: Call find_fsid from find_fsid_inprogress
  Btrfs: fix infinite loop during fsync after rename operations
  btrfs: set trans->drity in btrfs_commit_transaction
  btrfs: drop log root for dropped roots
  btrfs: sysfs, add devid/dev_state kobject and device attributes
  btrfs: Refactor btrfs_rmap_block to improve readability
  btrfs: Add self-tests for btrfs_rmap_block
  btrfs: selftests: Add support for dummy devices
  btrfs: Move and unexport btrfs_rmap_block
  btrfs: separate definition of assertion failure handlers
  btrfs: device stats, log when stats are zeroed
  btrfs: fix improper setting of scanned for range cyclic write cache pages
  btrfs: safely advance counter when looking up bio csums
  btrfs: remove unused member btrfs_device::work
  btrfs: remove unnecessary wrapper get_alloc_profile
  btrfs: add correction to handle -1 edge case in async discard
  ...

1  2 
fs/btrfs/dev-replace.c
fs/btrfs/scrub.c
fs/btrfs/volumes.h

diff --combined fs/btrfs/dev-replace.c
index ba4d8f375b3c1cdcbcc64ded7491fa5749503ae6,8600beb9c086ed81ecfd27e204fa74123fd71d94..2ca2a09d0e238e5e006441974820e0b2fa7b0060
@@@ -500,8 -500,11 +500,8 @@@ static int btrfs_dev_replace_start(stru
                              &dev_replace->scrub_progress, 0, 1);
  
        ret = btrfs_dev_replace_finishing(fs_info, ret);
 -      if (ret == -EINPROGRESS) {
 +      if (ret == -EINPROGRESS)
                ret = BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS;
 -      } else if (ret != -ECANCELED) {
 -              WARN_ON(ret);
 -      }
  
        return ret;
  
@@@ -704,6 -707,7 +704,7 @@@ static int btrfs_dev_replace_finishing(
  
        /* replace the sysfs entry */
        btrfs_sysfs_rm_device_link(fs_info->fs_devices, src_device);
+       btrfs_sysfs_update_devid(tgt_device);
        btrfs_rm_dev_replace_free_srcdev(src_device);
  
        /* write back the superblocks */
diff --combined fs/btrfs/scrub.c
index fd266a2d15ec84959189521312827350b6795ffe,22cf69e6e5bc9390ffa24e5414f07fb53464b0ff..61b37c56a7fb934b25aface21c7736ae6757da78
@@@ -8,6 -8,7 +8,7 @@@
  #include <linux/sched/mm.h>
  #include <crypto/hash.h>
  #include "ctree.h"
+ #include "discard.h"
  #include "volumes.h"
  #include "disk-io.h"
  #include "ordered-data.h"
@@@ -3577,27 -3578,17 +3578,27 @@@ int scrub_enumerate_chunks(struct scrub
                 * This can easily boost the amount of SYSTEM chunks if cleaner
                 * thread can't be triggered fast enough, and use up all space
                 * of btrfs_super_block::sys_chunk_array
 +               *
 +               * While for dev replace, we need to try our best to mark block
 +               * group RO, to prevent race between:
 +               * - Write duplication
 +               *   Contains latest data
 +               * - Scrub copy
 +               *   Contains data from commit tree
 +               *
 +               * If target block group is not marked RO, nocow writes can
 +               * be overwritten by scrub copy, causing data corruption.
 +               * So for dev-replace, it's not allowed to continue if a block
 +               * group is not RO.
                 */
 -              ret = btrfs_inc_block_group_ro(cache, false);
 -              scrub_pause_off(fs_info);
 -
 +              ret = btrfs_inc_block_group_ro(cache, sctx->is_dev_replace);
                if (ret == 0) {
                        ro_set = 1;
 -              } else if (ret == -ENOSPC) {
 +              } else if (ret == -ENOSPC && !sctx->is_dev_replace) {
                        /*
                         * btrfs_inc_block_group_ro return -ENOSPC when it
                         * failed in creating new chunk for metadata.
 -                       * It is not a problem for scrub/replace, because
 +                       * It is not a problem for scrub, because
                         * metadata are always cowed, and our scrub paused
                         * commit_transactions.
                         */
                        btrfs_warn(fs_info,
                                   "failed setting block group ro: %d", ret);
                        btrfs_put_block_group(cache);
 +                      scrub_pause_off(fs_info);
                        break;
                }
  
 +              /*
 +               * Now the target block is marked RO, wait for nocow writes to
 +               * finish before dev-replace.
 +               * COW is fine, as COW never overwrites extents in commit tree.
 +               */
 +              if (sctx->is_dev_replace) {
 +                      btrfs_wait_nocow_writers(cache);
 +                      btrfs_wait_ordered_roots(fs_info, U64_MAX, cache->start,
 +                                      cache->length);
 +              }
 +
 +              scrub_pause_off(fs_info);
                down_write(&dev_replace->rwsem);
                dev_replace->cursor_right = found_key.offset + length;
                dev_replace->cursor_left = found_key.offset;
                if (!cache->removed && !cache->ro && cache->reserved == 0 &&
                    cache->used == 0) {
                        spin_unlock(&cache->lock);
-                       btrfs_mark_bg_unused(cache);
+                       if (btrfs_test_opt(fs_info, DISCARD_ASYNC))
+                               btrfs_discard_queue_work(&fs_info->discard_ctl,
+                                                        cache);
+                       else
+                               btrfs_mark_bg_unused(cache);
                } else {
                        spin_unlock(&cache->lock);
                }
diff --combined fs/btrfs/volumes.h
index 0ee5386926faf178c6fab3fa143be2bd5c1484e4,690d4f5a065368e9a2ca2a6d60796cd999839230..409f4816fb89c458e9dec591b0951d79816dd7d1
@@@ -120,8 -120,6 +120,6 @@@ struct btrfs_device 
        /* per-device scrub information */
        struct scrub_ctx *scrub_ctx;
  
-       struct btrfs_work work;
        /* readahead state */
        atomic_t reada_in_flight;
        u64 reada_next;
        atomic_t dev_stat_values[BTRFS_DEV_STAT_VALUES_MAX];
  
        struct extent_io_tree alloc_state;
+       struct completion kobj_unregister;
+       /* For sysfs/FSID/devinfo/devid/ */
+       struct kobject devid_kobj;
  };
  
  /*
@@@ -168,7 -170,7 +170,7 @@@ btrfs_device_set_##name(struct btrfs_de
        write_seqcount_end(&dev->data_seqcount);                        \
        preempt_enable();                                               \
  }
 -#elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPT)
 +#elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPTION)
  #define BTRFS_DEVICE_GETSET_FUNCS(name)                                       \
  static inline u64                                                     \
  btrfs_device_get_##name(const struct btrfs_device *dev)                       \
@@@ -255,7 -257,7 +257,7 @@@ struct btrfs_fs_devices 
        struct btrfs_fs_info *fs_info;
        /* sysfs kobjects */
        struct kobject fsid_kobj;
-       struct kobject *device_dir_kobj;
+       struct kobject *devices_kobj;
        struct completion kobj_unregister;
  };
  
@@@ -417,8 -419,6 +419,6 @@@ int btrfs_map_sblock(struct btrfs_fs_in
                     struct btrfs_bio **bbio_ret);
  int btrfs_get_io_geometry(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
                u64 logical, u64 len, struct btrfs_io_geometry *io_geom);
- int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start,
-                    u64 physical, u64 **logical, int *naddrs, int *stripe_len);
  int btrfs_read_sys_array(struct btrfs_fs_info *fs_info);
  int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info);
  int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, u64 type);
This page took 0.087006 seconds and 4 git commands to generate.