]> Git Repo - linux.git/commitdiff
Merge tag 'for-6.7-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
authorLinus Torvalds <[email protected]>
Tue, 28 Nov 2023 19:16:04 +0000 (11:16 -0800)
committerLinus Torvalds <[email protected]>
Tue, 28 Nov 2023 19:16:04 +0000 (11:16 -0800)
Pull btrfs fixes from David Sterba:
 "A few fixes and message updates:

   - for simple quotas, handle the case when a snapshot is created and
     the target qgroup already exists

   - fix a warning when file descriptor given to send ioctl is not
     writable

   - fix off-by-one condition when checking chunk maps

   - free pages when page array allocation fails during compression
     read, other cases were handled

   - fix memory leak on error handling path in ref-verify debugging
     feature

   - copy missing struct member 'version' in 64/32bit compat send ioctl

   - tree-checker verifies inline backref ordering

   - print messages to syslog on first mount and last unmount

   - update error messages when reading chunk maps"

* tag 'for-6.7-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: send: ensure send_fd is writable
  btrfs: free the allocated memory if btrfs_alloc_page_array() fails
  btrfs: fix 64bit compat send ioctl arguments not initializing version member
  btrfs: make error messages more clear when getting a chunk map
  btrfs: fix off-by-one when checking chunk map includes logical address
  btrfs: ref-verify: fix memory leaks in btrfs_ref_tree_mod()
  btrfs: add dmesg output for first mount and last unmount of a filesystem
  btrfs: do not abort transaction if there is already an existing qgroup
  btrfs: tree-checker: add type and sequence check for inline backrefs

1  2 
fs/btrfs/ioctl.c
fs/btrfs/super.c
fs/btrfs/transaction.c
fs/btrfs/volumes.c

diff --combined fs/btrfs/ioctl.c
index dfe257e1845b6f4c4c72f15710758d12bd419af3,2429ae87ad44399d4a04578feeeea0e324a8b291..4e50b62db2a8feba629ee2ceb2040e28b4c2485b
@@@ -2682,7 -2682,8 +2682,7 @@@ static long btrfs_ioctl_rm_dev_v2(struc
        struct inode *inode = file_inode(file);
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        struct btrfs_ioctl_vol_args_v2 *vol_args;
 -      struct block_device *bdev = NULL;
 -      void *holder;
 +      struct bdev_handle *bdev_handle = NULL;
        int ret;
        bool cancel = false;
  
                goto err_drop;
  
        /* Exclusive operation is now claimed */
 -      ret = btrfs_rm_device(fs_info, &args, &bdev, &holder);
 +      ret = btrfs_rm_device(fs_info, &args, &bdev_handle);
  
        btrfs_exclop_finish(fs_info);
  
        }
  err_drop:
        mnt_drop_write_file(file);
 -      if (bdev)
 -              blkdev_put(bdev, holder);
 +      if (bdev_handle)
 +              bdev_release(bdev_handle);
  out:
        btrfs_put_dev_args_from_path(&args);
        kfree(vol_args);
@@@ -2747,7 -2748,8 +2747,7 @@@ static long btrfs_ioctl_rm_dev(struct f
        struct inode *inode = file_inode(file);
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        struct btrfs_ioctl_vol_args *vol_args;
 -      struct block_device *bdev = NULL;
 -      void *holder;
 +      struct bdev_handle *bdev_handle = NULL;
        int ret;
        bool cancel = false;
  
        ret = exclop_start_or_cancel_reloc(fs_info, BTRFS_EXCLOP_DEV_REMOVE,
                                           cancel);
        if (ret == 0) {
 -              ret = btrfs_rm_device(fs_info, &args, &bdev, &holder);
 +              ret = btrfs_rm_device(fs_info, &args, &bdev_handle);
                if (!ret)
                        btrfs_info(fs_info, "disk deleted %s", vol_args->name);
                btrfs_exclop_finish(fs_info);
        }
  
        mnt_drop_write_file(file);
 -      if (bdev)
 -              blkdev_put(bdev, holder);
 +      if (bdev_handle)
 +              bdev_release(bdev_handle);
  out:
        btrfs_put_dev_args_from_path(&args);
        kfree(vol_args);
@@@ -4356,6 -4358,7 +4356,7 @@@ static int _btrfs_ioctl_send(struct ino
                arg->clone_sources = compat_ptr(args32.clone_sources);
                arg->parent_root = args32.parent_root;
                arg->flags = args32.flags;
+               arg->version = args32.version;
                memcpy(arg->reserved, args32.reserved,
                       sizeof(args32.reserved));
  #else
diff --combined fs/btrfs/super.c
index f638dc339693bc1a65c1d5637d58b998ad5b95d4,9e1f3dbc80fa5321a42f5130c826710e29cf4e66..ef256b944c72aca283d00e9fd23d1af9a3adc2b6
@@@ -80,7 -80,10 +80,10 @@@ static int btrfs_remount(struct super_b
  
  static void btrfs_put_super(struct super_block *sb)
  {
-       close_ctree(btrfs_sb(sb));
+       struct btrfs_fs_info *fs_info = btrfs_sb(sb);
+       btrfs_info(fs_info, "last unmount of filesystem %pU", fs_info->fs_devices->fsid);
+       close_ctree(fs_info);
  }
  
  enum {
@@@ -1472,7 -1475,7 +1475,7 @@@ static struct dentry *btrfs_mount_root(
                        error = -EBUSY;
        } else {
                snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
 -              shrinker_debugfs_rename(&s->s_shrink, "sb-%s:%s", fs_type->name,
 +              shrinker_debugfs_rename(s->s_shrink, "sb-%s:%s", fs_type->name,
                                        s->s_id);
                btrfs_sb(s)->bdev_holder = fs_type;
                error = btrfs_fill_super(s, fs_devices, data);
diff --combined fs/btrfs/transaction.c
index 6e63816dddcbea20f160a274cc8fa06f10ebd7a0,7af9665bebae4f74d7dc263dc143f242da2a5fa6..bfc0eb5e3b7c22f90ec83b4c5b53abd2fda5cd04
@@@ -1774,7 -1774,7 +1774,7 @@@ static noinline int create_pending_snap
        btrfs_release_path(path);
  
        ret = btrfs_create_qgroup(trans, objectid);
-       if (ret) {
+       if (ret && ret != -EEXIST) {
                btrfs_abort_transaction(trans, ret);
                goto fail;
        }
  
        btrfs_i_size_write(BTRFS_I(parent_inode), parent_inode->i_size +
                                                  fname.disk_name.len * 2);
 -      parent_inode->i_mtime = inode_set_ctime_current(parent_inode);
 +      inode_set_mtime_to_ts(parent_inode,
 +                            inode_set_ctime_current(parent_inode));
        ret = btrfs_update_inode_fallback(trans, BTRFS_I(parent_inode));
        if (ret) {
                btrfs_abort_transaction(trans, ret);
diff --combined fs/btrfs/volumes.c
index c6f16625af51f5c9ede23329f16b9bca8031e4af,3b61c47306c015f5b9e6ee27bede8834855d005b..f627674b37db50bfd9f5e1149bb65d237e590f17
@@@ -457,39 -457,37 +457,39 @@@ static noinline struct btrfs_fs_device
  
  static int
  btrfs_get_bdev_and_sb(const char *device_path, blk_mode_t flags, void *holder,
 -                    int flush, struct block_device **bdev,
 +                    int flush, struct bdev_handle **bdev_handle,
                      struct btrfs_super_block **disk_super)
  {
 +      struct block_device *bdev;
        int ret;
  
 -      *bdev = blkdev_get_by_path(device_path, flags, holder, NULL);
 +      *bdev_handle = bdev_open_by_path(device_path, flags, holder, NULL);
  
 -      if (IS_ERR(*bdev)) {
 -              ret = PTR_ERR(*bdev);
 +      if (IS_ERR(*bdev_handle)) {
 +              ret = PTR_ERR(*bdev_handle);
                goto error;
        }
 +      bdev = (*bdev_handle)->bdev;
  
        if (flush)
 -              sync_blockdev(*bdev);
 -      ret = set_blocksize(*bdev, BTRFS_BDEV_BLOCKSIZE);
 +              sync_blockdev(bdev);
 +      ret = set_blocksize(bdev, BTRFS_BDEV_BLOCKSIZE);
        if (ret) {
 -              blkdev_put(*bdev, holder);
 +              bdev_release(*bdev_handle);
                goto error;
        }
 -      invalidate_bdev(*bdev);
 -      *disk_super = btrfs_read_dev_super(*bdev);
 +      invalidate_bdev(bdev);
 +      *disk_super = btrfs_read_dev_super(bdev);
        if (IS_ERR(*disk_super)) {
                ret = PTR_ERR(*disk_super);
 -              blkdev_put(*bdev, holder);
 +              bdev_release(*bdev_handle);
                goto error;
        }
  
        return 0;
  
  error:
 -      *bdev = NULL;
 +      *bdev_handle = NULL;
        return ret;
  }
  
@@@ -632,7 -630,7 +632,7 @@@ static int btrfs_open_one_device(struc
                        struct btrfs_device *device, blk_mode_t flags,
                        void *holder)
  {
 -      struct block_device *bdev;
 +      struct bdev_handle *bdev_handle;
        struct btrfs_super_block *disk_super;
        u64 devid;
        int ret;
                return -EINVAL;
  
        ret = btrfs_get_bdev_and_sb(device->name->str, flags, holder, 1,
 -                                  &bdev, &disk_super);
 +                                  &bdev_handle, &disk_super);
        if (ret)
                return ret;
  
                clear_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state);
                fs_devices->seeding = true;
        } else {
 -              if (bdev_read_only(bdev))
 +              if (bdev_read_only(bdev_handle->bdev))
                        clear_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state);
                else
                        set_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state);
        }
  
 -      if (!bdev_nonrot(bdev))
 +      if (!bdev_nonrot(bdev_handle->bdev))
                fs_devices->rotating = true;
  
 -      if (bdev_max_discard_sectors(bdev))
 +      if (bdev_max_discard_sectors(bdev_handle->bdev))
                fs_devices->discardable = true;
  
 -      device->bdev = bdev;
 +      device->bdev_handle = bdev_handle;
 +      device->bdev = bdev_handle->bdev;
        clear_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state);
 -      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, holder);
 +      bdev_release(bdev_handle);
  
        return -EINVAL;
  }
@@@ -1004,10 -1002,9 +1004,10 @@@ static void __btrfs_free_extra_devids(s
                if (device->devid == BTRFS_DEV_REPLACE_DEVID)
                        continue;
  
 -              if (device->bdev) {
 -                      blkdev_put(device->bdev, device->holder);
 +              if (device->bdev_handle) {
 +                      bdev_release(device->bdev_handle);
                        device->bdev = NULL;
 +                      device->bdev_handle = NULL;
                        fs_devices->open_devices--;
                }
                if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state)) {
@@@ -1052,7 -1049,7 +1052,7 @@@ static void btrfs_close_bdev(struct btr
                invalidate_bdev(device->bdev);
        }
  
 -      blkdev_put(device->bdev, device->holder);
 +      bdev_release(device->bdev_handle);
  }
  
  static void btrfs_close_one_device(struct btrfs_device *device)
@@@ -1305,7 -1302,7 +1305,7 @@@ struct btrfs_device *btrfs_scan_one_dev
        struct btrfs_super_block *disk_super;
        bool new_device_added = false;
        struct btrfs_device *device = NULL;
 -      struct block_device *bdev;
 +      struct bdev_handle *bdev_handle;
        u64 bytenr, bytenr_orig;
        int ret;
  
         * 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, NULL, NULL);
 -      if (IS_ERR(bdev))
 -              return ERR_CAST(bdev);
 +      bdev_handle = bdev_open_by_path(path, flags, NULL, NULL);
 +      if (IS_ERR(bdev_handle))
 +              return ERR_CAST(bdev_handle);
  
        bytenr_orig = btrfs_sb_offset(0);
 -      ret = btrfs_sb_log_location_bdev(bdev, 0, READ, &bytenr);
 +      ret = btrfs_sb_log_location_bdev(bdev_handle->bdev, 0, READ, &bytenr);
        if (ret) {
                device = ERR_PTR(ret);
                goto error_bdev_put;
        }
  
 -      disk_super = btrfs_read_disk_super(bdev, bytenr, bytenr_orig);
 +      disk_super = btrfs_read_disk_super(bdev_handle->bdev, bytenr,
 +                                         bytenr_orig);
        if (IS_ERR(disk_super)) {
                device = ERR_CAST(disk_super);
                goto error_bdev_put;
@@@ -1370,7 -1366,7 +1370,7 @@@ free_disk_super
        btrfs_release_disk_super(disk_super);
  
  error_bdev_put:
 -      blkdev_put(bdev, NULL);
 +      bdev_release(bdev_handle);
  
        return device;
  }
@@@ -2047,7 -2043,7 +2047,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, void **holder)
 +                  struct bdev_handle **bdev_handle)
  {
        struct btrfs_trans_handle *trans;
        struct btrfs_device *device;
  
        btrfs_assign_next_active_device(device, NULL);
  
 -      if (device->bdev) {
 +      if (device->bdev_handle) {
                cur_devices->open_devices--;
                /* remove sysfs entry */
                btrfs_sysfs_remove_device(device);
         * free the device.
         *
         * We cannot call btrfs_close_bdev() here because we're holding the sb
 -       * write lock, and blkdev_put() will pull in the ->open_mutex on the
 -       * block device and it's dependencies.  Instead just flush the device
 -       * and let the caller do the final blkdev_put.
 +       * write lock, and bdev_release() will pull in the ->open_mutex on
 +       * the block device and it's dependencies.  Instead just flush the
 +       * device and let the caller do the final bdev_release.
         */
        if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state)) {
                btrfs_scratch_superblocks(fs_info, device->bdev,
                }
        }
  
 -      *bdev = device->bdev;
 -      *holder = device->holder;
 +      *bdev_handle = device->bdev_handle;
        synchronize_rcu();
        btrfs_free_device(device);
  
@@@ -2322,7 -2319,7 +2322,7 @@@ int btrfs_get_dev_args_from_path(struc
                                 const char *path)
  {
        struct btrfs_super_block *disk_super;
 -      struct block_device *bdev;
 +      struct bdev_handle *bdev_handle;
        int ret;
  
        if (!path || !path[0])
        }
  
        ret = btrfs_get_bdev_and_sb(path, BLK_OPEN_READ, NULL, 0,
 -                                  &bdev, &disk_super);
 +                                  &bdev_handle, &disk_super);
        if (ret) {
                btrfs_put_dev_args_from_path(args);
                return ret;
        else
                memcpy(args->fsid, disk_super->fsid, BTRFS_FSID_SIZE);
        btrfs_release_disk_super(disk_super);
 -      blkdev_put(bdev, NULL);
 +      bdev_release(bdev_handle);
        return 0;
  }
  
@@@ -2573,7 -2570,7 +2573,7 @@@ int btrfs_init_new_device(struct btrfs_
        struct btrfs_root *root = fs_info->dev_root;
        struct btrfs_trans_handle *trans;
        struct btrfs_device *device;
 -      struct block_device *bdev;
 +      struct bdev_handle *bdev_handle;
        struct super_block *sb = fs_info->sb;
        struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
        struct btrfs_fs_devices *seed_devices = NULL;
        if (sb_rdonly(sb) && !fs_devices->seeding)
                return -EROFS;
  
 -      bdev = blkdev_get_by_path(device_path, BLK_OPEN_WRITE,
 -                                fs_info->bdev_holder, NULL);
 -      if (IS_ERR(bdev))
 -              return PTR_ERR(bdev);
 +      bdev_handle = bdev_open_by_path(device_path, BLK_OPEN_WRITE,
 +                                      fs_info->bdev_holder, NULL);
 +      if (IS_ERR(bdev_handle))
 +              return PTR_ERR(bdev_handle);
  
 -      if (!btrfs_check_device_zone_type(fs_info, bdev)) {
 +      if (!btrfs_check_device_zone_type(fs_info, bdev_handle->bdev)) {
                ret = -EINVAL;
                goto error;
        }
                locked = true;
        }
  
 -      sync_blockdev(bdev);
 +      sync_blockdev(bdev_handle->bdev);
  
        rcu_read_lock();
        list_for_each_entry_rcu(device, &fs_devices->devices, dev_list) {
 -              if (device->bdev == bdev) {
 +              if (device->bdev == bdev_handle->bdev) {
                        ret = -EEXIST;
                        rcu_read_unlock();
                        goto error;
        }
  
        device->fs_info = fs_info;
 -      device->bdev = bdev;
 +      device->bdev_handle = bdev_handle;
 +      device->bdev = bdev_handle->bdev;
        ret = lookup_bdev(device_path, &device->devt);
        if (ret)
                goto error_free_device;
        device->io_align = fs_info->sectorsize;
        device->sector_size = fs_info->sectorsize;
        device->total_bytes =
 -              round_down(bdev_nr_bytes(bdev), fs_info->sectorsize);
 +              round_down(bdev_nr_bytes(device->bdev), fs_info->sectorsize);
        device->disk_total_bytes = device->total_bytes;
        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->holder = fs_info->bdev_holder;
        device->dev_stats_valid = 1;
        set_blocksize(device->bdev, BTRFS_BDEV_BLOCKSIZE);
  
  
        atomic64_add(device->total_bytes, &fs_info->free_chunk_space);
  
 -      if (!bdev_nonrot(bdev))
 +      if (!bdev_nonrot(device->bdev))
                fs_devices->rotating = true;
  
        orig_super_total_bytes = btrfs_super_total_bytes(fs_info->super_copy);
@@@ -2807,7 -2804,7 +2807,7 @@@ error_free_zone
  error_free_device:
        btrfs_free_device(device);
  error:
 -      blkdev_put(bdev, fs_info->bdev_holder);
 +      bdev_release(bdev_handle);
        if (locked) {
                mutex_unlock(&uuid_mutex);
                up_write(&sb->s_umount);
@@@ -3006,15 -3003,16 +3006,16 @@@ struct extent_map *btrfs_get_chunk_map(
        read_unlock(&em_tree->lock);
  
        if (!em) {
-               btrfs_crit(fs_info, "unable to find logical %llu length %llu",
+               btrfs_crit(fs_info,
+                          "unable to find chunk map for logical %llu length %llu",
                           logical, length);
                return ERR_PTR(-EINVAL);
        }
  
-       if (em->start > logical || em->start + em->len < logical) {
+       if (em->start > logical || em->start + em->len <= logical) {
                btrfs_crit(fs_info,
-                          "found a bad mapping, wanted %llu-%llu, found %llu-%llu",
-                          logical, length, em->start, em->start + em->len);
+                          "found a bad chunk map, wanted %llu-%llu, found %llu-%llu",
+                          logical, logical + length, em->start, em->start + em->len);
                free_extent_map(em);
                return ERR_PTR(-EINVAL);
        }
@@@ -5084,7 -5082,7 +5085,7 @@@ static void init_alloc_chunk_ctl_policy
        ASSERT(space_info);
  
        ctl->max_chunk_size = READ_ONCE(space_info->chunk_size);
 -      ctl->max_stripe_size = ctl->max_chunk_size;
 +      ctl->max_stripe_size = min_t(u64, ctl->max_chunk_size, SZ_1G);
  
        if (ctl->type & BTRFS_BLOCK_GROUP_SYSTEM)
                ctl->devs_max = min_t(int, ctl->devs_max, BTRFS_MAX_DEVS_SYS_CHUNK);
This page took 0.097728 seconds and 4 git commands to generate.