Merge tag 'for-6.5-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 19 Aug 2023 15:57:07 +0000 (17:57 +0200)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 19 Aug 2023 15:57:07 +0000 (17:57 +0200)
Pull btrfs fixes from David Sterba:

 - fix infinite loop in readdir(), could happen in a big directory when
   files get renamed during enumeration

 - fix extent map handling of skipped pinned ranges

 - fix a corner case when handling ordered extent length

 - fix a potential crash when balance cancel races with pause

 - verify correct uuid when starting scrub or device replace

* tag 'for-6.5-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: fix incorrect splitting in btrfs_drop_extent_map_range
  btrfs: fix BUG_ON condition in btrfs_cancel_balance
  btrfs: only subtract from len_to_oe_boundary when it is tracking an extent
  btrfs: fix replace/scrub failure with metadata_uuid
  btrfs: fix infinite directory reads

1  2 
fs/btrfs/scrub.c
fs/btrfs/volumes.c

diff --combined fs/btrfs/scrub.c
@@@ -605,7 -605,8 +605,8 @@@ static void scrub_verify_one_metadata(s
                              btrfs_stack_header_bytenr(header), logical);
                return;
        }
-       if (memcmp(header->fsid, fs_info->fs_devices->fsid, BTRFS_FSID_SIZE) != 0) {
+       if (memcmp(header->fsid, fs_info->fs_devices->metadata_uuid,
+                  BTRFS_FSID_SIZE) != 0) {
                bitmap_set(&stripe->meta_error_bitmap, sector_nr, sectors_per_tree);
                bitmap_set(&stripe->error_bitmap, sector_nr, sectors_per_tree);
                btrfs_warn_rl(fs_info,
@@@ -1255,7 -1256,7 +1256,7 @@@ static int get_raid56_logic_offset(u64 
                u32 stripe_index;
                u32 rot;
  
 -              *offset = last_offset + (i << BTRFS_STRIPE_LEN_SHIFT);
 +              *offset = last_offset + btrfs_stripe_nr_to_offset(i);
  
                stripe_nr = (u32)(*offset >> BTRFS_STRIPE_LEN_SHIFT) / data_stripes;
  
                if (stripe_index < num)
                        j++;
        }
 -      *offset = last_offset + (j << BTRFS_STRIPE_LEN_SHIFT);
 +      *offset = last_offset + btrfs_stripe_nr_to_offset(j);
        return 1;
  }
  
@@@ -1666,7 -1667,7 +1667,7 @@@ static int flush_scrub_stripes(struct s
        ASSERT(test_bit(SCRUB_STRIPE_FLAG_INITIALIZED, &sctx->stripes[0].state));
  
        scrub_throttle_dev_io(sctx, sctx->stripes[0].dev,
 -                            nr_stripes << BTRFS_STRIPE_LEN_SHIFT);
 +                            btrfs_stripe_nr_to_offset(nr_stripes));
        for (int i = 0; i < nr_stripes; i++) {
                stripe = &sctx->stripes[i];
                scrub_submit_initial_read(sctx, stripe);
@@@ -1789,7 -1790,7 +1790,7 @@@ static int scrub_raid56_parity_stripe(s
        bool all_empty = true;
        const int data_stripes = nr_data_stripes(map);
        unsigned long extent_bitmap = 0;
 -      u64 length = data_stripes << BTRFS_STRIPE_LEN_SHIFT;
 +      u64 length = btrfs_stripe_nr_to_offset(data_stripes);
        int ret;
  
        ASSERT(sctx->raid56_data_stripes);
                              data_stripes) >> BTRFS_STRIPE_LEN_SHIFT;
                stripe_index = (i + rot) % map->num_stripes;
                physical = map->stripes[stripe_index].physical +
 -                         (rot << BTRFS_STRIPE_LEN_SHIFT);
 +                         btrfs_stripe_nr_to_offset(rot);
  
                scrub_reset_stripe(stripe);
                set_bit(SCRUB_STRIPE_FLAG_NO_REPORT, &stripe->state);
                ret = scrub_find_fill_first_stripe(bg,
                                map->stripes[stripe_index].dev, physical, 1,
 -                              full_stripe_start + (i << BTRFS_STRIPE_LEN_SHIFT),
 +                              full_stripe_start + btrfs_stripe_nr_to_offset(i),
                                BTRFS_STRIPE_LEN, stripe);
                if (ret < 0)
                        goto out;
                 */
                if (ret > 0) {
                        stripe->logical = full_stripe_start +
 -                                        (i << BTRFS_STRIPE_LEN_SHIFT);
 +                                        btrfs_stripe_nr_to_offset(i);
                        stripe->dev = map->stripes[stripe_index].dev;
                        stripe->mirror_num = 1;
                        set_bit(SCRUB_STRIPE_FLAG_INITIALIZED, &stripe->state);
@@@ -2020,7 -2021,7 +2021,7 @@@ static u64 simple_stripe_full_stripe_le
        ASSERT(map->type & (BTRFS_BLOCK_GROUP_RAID0 |
                            BTRFS_BLOCK_GROUP_RAID10));
  
 -      return (map->num_stripes / map->sub_stripes) << BTRFS_STRIPE_LEN_SHIFT;
 +      return btrfs_stripe_nr_to_offset(map->num_stripes / map->sub_stripes);
  }
  
  /* Get the logical bytenr for the stripe */
@@@ -2036,7 -2037,7 +2037,7 @@@ static u64 simple_stripe_get_logical(st
         * (stripe_index / sub_stripes) gives how many data stripes we need to
         * skip.
         */
 -      return ((stripe_index / map->sub_stripes) << BTRFS_STRIPE_LEN_SHIFT) +
 +      return btrfs_stripe_nr_to_offset(stripe_index / map->sub_stripes) +
               bg->start;
  }
  
@@@ -2162,7 -2163,7 +2163,7 @@@ static noinline_for_stack int scrub_str
        }
        if (profile & (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID10)) {
                ret = scrub_simple_stripe(sctx, bg, map, scrub_dev, stripe_index);
 -              offset = (stripe_index / map->sub_stripes) << BTRFS_STRIPE_LEN_SHIFT;
 +              offset = btrfs_stripe_nr_to_offset(stripe_index / map->sub_stripes);
                goto out;
        }
  
  
        /* Initialize @offset in case we need to go to out: label */
        get_raid56_logic_offset(physical, stripe_index, map, &offset, NULL);
 -      increment = nr_data_stripes(map) << BTRFS_STRIPE_LEN_SHIFT;
 +      increment = btrfs_stripe_nr_to_offset(nr_data_stripes(map));
  
        /*
         * Due to the rotation, for RAID56 it's better to iterate each stripe
diff --combined fs/btrfs/volumes.c
@@@ -510,13 -510,13 +510,13 @@@ static struct btrfs_fs_devices *find_fs
  
  
  static int
 -btrfs_get_bdev_and_sb(const char *device_path, fmode_t flags, void *holder,
 +btrfs_get_bdev_and_sb(const char *device_path, blk_mode_t flags, void *holder,
                      int flush, struct block_device **bdev,
                      struct btrfs_super_block **disk_super)
  {
        int ret;
  
 -      *bdev = blkdev_get_by_path(device_path, flags, holder);
 +      *bdev = blkdev_get_by_path(device_path, flags, holder, NULL);
  
        if (IS_ERR(*bdev)) {
                ret = PTR_ERR(*bdev);
                sync_blockdev(*bdev);
        ret = set_blocksize(*bdev, BTRFS_BDEV_BLOCKSIZE);
        if (ret) {
 -              blkdev_put(*bdev, flags);
 +              blkdev_put(*bdev, holder);
                goto error;
        }
        invalidate_bdev(*bdev);
        *disk_super = btrfs_read_dev_super(*bdev);
        if (IS_ERR(*disk_super)) {
                ret = PTR_ERR(*disk_super);
 -              blkdev_put(*bdev, flags);
 +              blkdev_put(*bdev, holder);
                goto error;
        }
  
@@@ -610,7 -610,7 +610,7 @@@ static int btrfs_free_stale_devices(dev
   * fs_devices->device_list_mutex here.
   */
  static int btrfs_open_one_device(struct btrfs_fs_devices *fs_devices,
 -                      struct btrfs_device *device, fmode_t flags,
 +                      struct btrfs_device *device, blk_mode_t flags,
                        void *holder)
  {
        struct block_device *bdev;
  
        device->bdev = bdev;
        clear_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state);
 -      device->mode = flags;
 +      device->holder = holder;
  
        fs_devices->open_devices++;
        if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state) &&
  
  error_free_page:
        btrfs_release_disk_super(disk_super);
 -      blkdev_put(bdev, flags);
 +      blkdev_put(bdev, holder);
  
        return -EINVAL;
  }
@@@ -1067,7 -1067,7 +1067,7 @@@ static void __btrfs_free_extra_devids(s
                        continue;
  
                if (device->bdev) {
 -                      blkdev_put(device->bdev, device->mode);
 +                      blkdev_put(device->bdev, device->holder);
                        device->bdev = NULL;
                        fs_devices->open_devices--;
                }
@@@ -1113,7 -1113,7 +1113,7 @@@ static void btrfs_close_bdev(struct btr
                invalidate_bdev(device->bdev);
        }
  
 -      blkdev_put(device->bdev, device->mode);
 +      blkdev_put(device->bdev, device->holder);
  }
  
  static void btrfs_close_one_device(struct btrfs_device *device)
@@@ -1217,12 -1217,14 +1217,12 @@@ void btrfs_close_devices(struct btrfs_f
  }
  
  static int open_fs_devices(struct btrfs_fs_devices *fs_devices,
 -                              fmode_t flags, void *holder)
 +                              blk_mode_t flags, void *holder)
  {
        struct btrfs_device *device;
        struct btrfs_device *latest_dev = NULL;
        struct btrfs_device *tmp_device;
  
 -      flags |= FMODE_EXCL;
 -
        list_for_each_entry_safe(device, tmp_device, &fs_devices->devices,
                                 dev_list) {
                int ret;
@@@ -1265,7 -1267,7 +1265,7 @@@ static int devid_cmp(void *priv, const 
  }
  
  int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
 -                     fmode_t flags, void *holder)
 +                     blk_mode_t flags, void *holder)
  {
        int ret;
  
@@@ -1356,7 -1358,8 +1356,7 @@@ int btrfs_forget_devices(dev_t devt
   * and we are not allowed to call set_blocksize during the scan. The superblock
   * is read via pagecache
   */
 -struct btrfs_device *btrfs_scan_one_device(const char *path, fmode_t flags,
 -                                         void *holder)
 +struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags)
  {
        struct btrfs_super_block *disk_super;
        bool new_device_added = false;
         */
  
        /*
 -       * Avoid using flag |= FMODE_EXCL here, as the systemd-udev may
 -       * initiate the device scan which may race with the user's mount
 -       * or mkfs command, resulting in failure.
 -       * Since the device scan is solely for reading purposes, there is
 -       * no need for FMODE_EXCL. Additionally, the devices are read again
 +       * Avoid an exclusive open here, as the systemd-udev may initiate the
 +       * device scan which may race with the user's mount or mkfs command,
 +       * resulting in failure.
 +       * Since the device scan is solely for reading purposes, there is no
 +       * need for an exclusive open. Additionally, the devices are read again
         * during the mount process. It is ok to get some inconsistent
         * values temporarily, as the device paths of the fsid are the only
         * required information for assembling the volume.
         */
 -      bdev = blkdev_get_by_path(path, flags, holder);
 +      bdev = blkdev_get_by_path(path, flags, NULL, NULL);
        if (IS_ERR(bdev))
                return ERR_CAST(bdev);
  
        btrfs_release_disk_super(disk_super);
  
  error_bdev_put:
 -      blkdev_put(bdev, flags);
 +      blkdev_put(bdev, NULL);
  
        return device;
  }
@@@ -2095,7 -2098,7 +2095,7 @@@ void btrfs_scratch_superblocks(struct b
  
  int btrfs_rm_device(struct btrfs_fs_info *fs_info,
                    struct btrfs_dev_lookup_args *args,
 -                  struct block_device **bdev, fmode_t *mode)
 +                  struct block_device **bdev, void **holder)
  {
        struct btrfs_trans_handle *trans;
        struct btrfs_device *device;
        }
  
        *bdev = device->bdev;
 -      *mode = device->mode;
 +      *holder = device->holder;
        synchronize_rcu();
        btrfs_free_device(device);
  
@@@ -2388,7 -2391,7 +2388,7 @@@ int btrfs_get_dev_args_from_path(struc
                return -ENOMEM;
        }
  
 -      ret = btrfs_get_bdev_and_sb(path, FMODE_READ, fs_info->bdev_holder, 0,
 +      ret = btrfs_get_bdev_and_sb(path, BLK_OPEN_READ, NULL, 0,
                                    &bdev, &disk_super);
        if (ret) {
                btrfs_put_dev_args_from_path(args);
        else
                memcpy(args->fsid, disk_super->fsid, BTRFS_FSID_SIZE);
        btrfs_release_disk_super(disk_super);
 -      blkdev_put(bdev, FMODE_READ);
 +      blkdev_put(bdev, NULL);
        return 0;
  }
  
@@@ -2635,8 -2638,8 +2635,8 @@@ int btrfs_init_new_device(struct btrfs_
        if (sb_rdonly(sb) && !fs_devices->seeding)
                return -EROFS;
  
 -      bdev = blkdev_get_by_path(device_path, FMODE_WRITE | FMODE_EXCL,
 -                                fs_info->bdev_holder);
 +      bdev = blkdev_get_by_path(device_path, BLK_OPEN_WRITE,
 +                                fs_info->bdev_holder, NULL);
        if (IS_ERR(bdev))
                return PTR_ERR(bdev);
  
        device->commit_total_bytes = device->total_bytes;
        set_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state);
        clear_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state);
 -      device->mode = FMODE_EXCL;
 +      device->holder = fs_info->bdev_holder;
        device->dev_stats_valid = 1;
        set_blocksize(device->bdev, BTRFS_BDEV_BLOCKSIZE);
  
@@@ -2856,7 -2859,7 +2856,7 @@@ error_free_zone
  error_free_device:
        btrfs_free_device(device);
  error:
 -      blkdev_put(bdev, FMODE_EXCL);
 +      blkdev_put(bdev, fs_info->bdev_holder);
        if (locked) {
                mutex_unlock(&uuid_mutex);
                up_write(&sb->s_umount);
@@@ -4638,8 -4641,7 +4638,7 @@@ int btrfs_cancel_balance(struct btrfs_f
                }
        }
  
-       BUG_ON(fs_info->balance_ctl ||
-               test_bit(BTRFS_FS_BALANCE_RUNNING, &fs_info->flags));
+       ASSERT(!test_bit(BTRFS_FS_BALANCE_RUNNING, &fs_info->flags));
        atomic_dec(&fs_info->balance_cancel_req);
        mutex_unlock(&fs_info->balance_mutex);
        return 0;
@@@ -5126,7 -5128,7 +5125,7 @@@ static void init_alloc_chunk_ctl_policy
        /* We don't want a chunk larger than 10% of writable space */
        ctl->max_chunk_size = min(mult_perc(fs_devices->total_rw_bytes, 10),
                                  ctl->max_chunk_size);
 -      ctl->dev_extent_min = ctl->dev_stripes << BTRFS_STRIPE_LEN_SHIFT;
 +      ctl->dev_extent_min = btrfs_stripe_nr_to_offset(ctl->dev_stripes);
  }
  
  static void init_alloc_chunk_ctl_policy_zoned(
@@@ -5802,7 -5804,7 +5801,7 @@@ unsigned long btrfs_full_stripe_len(str
        if (!WARN_ON(IS_ERR(em))) {
                map = em->map_lookup;
                if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK)
 -                      len = nr_data_stripes(map) << BTRFS_STRIPE_LEN_SHIFT;
 +                      len = btrfs_stripe_nr_to_offset(nr_data_stripes(map));
                free_extent_map(em);
        }
        return len;
@@@ -5976,12 -5978,12 +5975,12 @@@ struct btrfs_discard_stripe *btrfs_map_
        stripe_nr = offset >> BTRFS_STRIPE_LEN_SHIFT;
  
        /* stripe_offset is the offset of this block in its stripe */
 -      stripe_offset = offset - (stripe_nr << BTRFS_STRIPE_LEN_SHIFT);
 +      stripe_offset = offset - btrfs_stripe_nr_to_offset(stripe_nr);
  
        stripe_nr_end = round_up(offset + length, BTRFS_STRIPE_LEN) >>
                        BTRFS_STRIPE_LEN_SHIFT;
        stripe_cnt = stripe_nr_end - stripe_nr;
 -      stripe_end_offset = (stripe_nr_end << BTRFS_STRIPE_LEN_SHIFT) -
 +      stripe_end_offset = btrfs_stripe_nr_to_offset(stripe_nr_end) -
                            (offset + length);
        /*
         * after this, stripe_nr is the number of stripes on this
        for (i = 0; i < *num_stripes; i++) {
                stripes[i].physical =
                        map->stripes[stripe_index].physical +
 -                      stripe_offset + (stripe_nr << BTRFS_STRIPE_LEN_SHIFT);
 +                      stripe_offset + btrfs_stripe_nr_to_offset(stripe_nr);
                stripes[i].dev = map->stripes[stripe_index].dev;
  
                if (map->type & (BTRFS_BLOCK_GROUP_RAID0 |
                                 BTRFS_BLOCK_GROUP_RAID10)) {
 -                      stripes[i].length = stripes_per_dev << BTRFS_STRIPE_LEN_SHIFT;
 +                      stripes[i].length = btrfs_stripe_nr_to_offset(stripes_per_dev);
  
                        if (i / sub_stripes < remaining_stripes)
                                stripes[i].length += BTRFS_STRIPE_LEN;
@@@ -6177,8 -6179,8 +6176,8 @@@ static u64 btrfs_max_io_len(struct map_
        ASSERT(*stripe_offset < U32_MAX);
  
        if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) {
 -              unsigned long full_stripe_len = nr_data_stripes(map) <<
 -                                              BTRFS_STRIPE_LEN_SHIFT;
 +              unsigned long full_stripe_len =
 +                      btrfs_stripe_nr_to_offset(nr_data_stripes(map));
  
                /*
                 * For full stripe start, we use previously calculated
                 * not ensured to be power of 2.
                 */
                *full_stripe_start =
 -                      rounddown(*stripe_nr, nr_data_stripes(map)) <<
 -                      BTRFS_STRIPE_LEN_SHIFT;
 +                      btrfs_stripe_nr_to_offset(
 +                              rounddown(*stripe_nr, nr_data_stripes(map)));
  
 +              ASSERT(*full_stripe_start + full_stripe_len > offset);
 +              ASSERT(*full_stripe_start <= offset);
                /*
                 * For writes to RAID56, allow to write a full stripe set, but
                 * no straddling of stripe sets.
@@@ -6217,7 -6217,7 +6216,7 @@@ static void set_io_stripe(struct btrfs_
  {
        dst->dev = map->stripes[stripe_index].dev;
        dst->physical = map->stripes[stripe_index].physical +
 -                      stripe_offset + (stripe_nr << BTRFS_STRIPE_LEN_SHIFT);
 +                      stripe_offset + btrfs_stripe_nr_to_offset(stripe_nr);
  }
  
  int btrfs_map_block(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
                        /* Return the length to the full stripe end */
                        *length = min(logical + *length,
                                      raid56_full_stripe_start + em->start +
 -                                    (data_stripes << BTRFS_STRIPE_LEN_SHIFT)) - logical;
 +                                    btrfs_stripe_nr_to_offset(data_stripes)) -
 +                                logical;
                        stripe_index = 0;
                        stripe_offset = 0;
                } else {
                 * modulo, to reduce one modulo call.
                 */
                bioc->full_stripe_logical = em->start +
 -                      ((stripe_nr * data_stripes) << BTRFS_STRIPE_LEN_SHIFT);
 +                      btrfs_stripe_nr_to_offset(stripe_nr * data_stripes);
                for (i = 0; i < num_stripes; i++)
                        set_io_stripe(&bioc->stripes[i], map,
                                      (i + stripe_nr) % num_stripes,
@@@ -6890,7 -6889,7 +6889,7 @@@ static struct btrfs_fs_devices *open_se
        if (IS_ERR(fs_devices))
                return fs_devices;
  
 -      ret = open_fs_devices(fs_devices, FMODE_READ, fs_info->bdev_holder);
 +      ret = open_fs_devices(fs_devices, BLK_OPEN_READ, fs_info->bdev_holder);
        if (ret) {
                free_fs_devices(fs_devices);
                return ERR_PTR(ret);
@@@ -8010,7 -8009,7 +8009,7 @@@ static void map_raid56_repair_block(str
  
        for (i = 0; i < data_stripes; i++) {
                u64 stripe_start = bioc->full_stripe_logical +
 -                                 (i << BTRFS_STRIPE_LEN_SHIFT);
 +                                 btrfs_stripe_nr_to_offset(i);
  
                if (logical >= stripe_start &&
                    logical < stripe_start + BTRFS_STRIPE_LEN)