Merge tag 'for-5.12-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 25 Mar 2021 22:38:22 +0000 (15:38 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 25 Mar 2021 22:38:22 +0000 (15:38 -0700)
Pull btrfs fixes from David Sterba:
 "Fixes for issues that have some user visibility and are simple enough
  for this time of development cycle:

   - a few fixes for rescue= mount option, adding more checks for
     missing trees

   - fix sleeping in atomic context on qgroup deletion

   - fix subvolume deletion on mount

   - fix build with M= syntax

   - fix checksum mismatch error message for direct io"

* tag 'for-5.12-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: fix check_data_csum() error message for direct I/O
  btrfs: fix sleep while in non-sleep context during qgroup removal
  btrfs: fix subvolume/snapshot deletion not triggered on mount
  btrfs: fix build when using M=fs/btrfs
  btrfs: do not initialize dev replace for bad dev root
  btrfs: initialize device::fs_info always
  btrfs: do not initialize dev stats if we have no dev_root
  btrfs: zoned: remove outdated WARN_ON in direct IO

1  2 
fs/btrfs/disk-io.c
fs/btrfs/inode.c
fs/btrfs/volumes.c

diff --combined fs/btrfs/disk-io.c
@@@ -2387,8 -2387,9 +2387,9 @@@ static int btrfs_read_roots(struct btrf
        } else {
                set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);
                fs_info->dev_root = root;
-               btrfs_init_devices_late(fs_info);
        }
+       /* Initialize fs_info for all devices in any case */
+       btrfs_init_devices_late(fs_info);
  
        /* If IGNOREDATACSUMS is set don't bother reading the csum root. */
        if (!btrfs_test_opt(fs_info, IGNOREDATACSUMS)) {
@@@ -3009,6 -3010,21 +3010,21 @@@ int btrfs_start_pre_rw_mount(struct btr
                }
        }
  
+       /*
+        * btrfs_find_orphan_roots() is responsible for finding all the dead
+        * roots (with 0 refs), flag them with BTRFS_ROOT_DEAD_TREE and load
+        * them into the fs_info->fs_roots_radix tree. This must be done before
+        * calling btrfs_orphan_cleanup() on the tree root. If we don't do it
+        * first, then btrfs_orphan_cleanup() will delete a dead root's orphan
+        * item before the root's tree is deleted - this means that if we unmount
+        * or crash before the deletion completes, on the next mount we will not
+        * delete what remains of the tree because the orphan item does not
+        * exists anymore, which is what tells us we have a pending deletion.
+        */
+       ret = btrfs_find_orphan_roots(fs_info);
+       if (ret)
+               goto out;
        ret = btrfs_cleanup_fs_roots(fs_info);
        if (ret)
                goto out;
                }
        }
  
-       ret = btrfs_find_orphan_roots(fs_info);
  out:
        return ret;
  }
@@@ -3140,8 -3155,6 +3155,8 @@@ int __cold open_ctree(struct super_bloc
                goto fail_alloc;
        }
  
 +      fs_info->csum_size = btrfs_super_csum_size(disk_super);
 +
        ret = btrfs_init_csum_hash(fs_info, csum_type);
        if (ret) {
                err = ret;
        fs_info->nodesize = nodesize;
        fs_info->sectorsize = sectorsize;
        fs_info->sectorsize_bits = ilog2(sectorsize);
 -      fs_info->csum_size = btrfs_super_csum_size(disk_super);
        fs_info->csums_per_leaf = BTRFS_MAX_ITEM_SIZE(fs_info) / fs_info->csum_size;
        fs_info->stripesize = stripesize;
  
diff --combined fs/btrfs/inode.c
@@@ -3099,11 -3099,13 +3099,13 @@@ void btrfs_writepage_endio_finish_order
   * @bio_offset:       offset to the beginning of the bio (in bytes)
   * @page:     page where is the data to be verified
   * @pgoff:    offset inside the page
+  * @start:    logical offset in the file
   *
   * The length of such check is always one sector size.
   */
  static int check_data_csum(struct inode *inode, struct btrfs_io_bio *io_bio,
-                          u32 bio_offset, struct page *page, u32 pgoff)
+                          u32 bio_offset, struct page *page, u32 pgoff,
+                          u64 start)
  {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
        kunmap_atomic(kaddr);
        return 0;
  zeroit:
-       btrfs_print_data_csum_error(BTRFS_I(inode), page_offset(page) + pgoff,
-                                   csum, csum_expected, io_bio->mirror_num);
+       btrfs_print_data_csum_error(BTRFS_I(inode), start, csum, csum_expected,
+                                   io_bio->mirror_num);
        if (io_bio->device)
                btrfs_dev_stat_inc_and_print(io_bio->device,
                                             BTRFS_DEV_STAT_CORRUPTION_ERRS);
@@@ -3184,7 -3186,8 +3186,8 @@@ int btrfs_verify_data_csum(struct btrfs
             pg_off += sectorsize, bio_offset += sectorsize) {
                int ret;
  
-               ret = check_data_csum(inode, io_bio, bio_offset, page, pg_off);
+               ret = check_data_csum(inode, io_bio, bio_offset, page, pg_off,
+                                     page_offset(page) + pg_off);
                if (ret < 0)
                        return -EIO;
        }
@@@ -5210,8 -5213,7 +5213,8 @@@ static int btrfs_setsize(struct inode *
        return ret;
  }
  
 -static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
 +static int btrfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
 +                       struct iattr *attr)
  {
        struct inode *inode = d_inode(dentry);
        struct btrfs_root *root = BTRFS_I(inode)->root;
        if (btrfs_root_readonly(root))
                return -EROFS;
  
 -      err = setattr_prepare(dentry, attr);
 +      err = setattr_prepare(&init_user_ns, dentry, attr);
        if (err)
                return err;
  
        }
  
        if (attr->ia_valid) {
 -              setattr_copy(inode, attr);
 +              setattr_copy(&init_user_ns, inode, attr);
                inode_inc_iversion(inode);
                err = btrfs_dirty_inode(inode);
  
                if (!err && attr->ia_valid & ATTR_MODE)
 -                      err = posix_acl_chmod(inode, inode->i_mode);
 +                      err = posix_acl_chmod(&init_user_ns, inode,
 +                                            inode->i_mode);
        }
  
        return err;
@@@ -6357,7 -6358,7 +6360,7 @@@ static struct inode *btrfs_new_inode(st
        if (ret != 0)
                goto fail_unlock;
  
 -      inode_init_owner(inode, dir, mode);
 +      inode_init_owner(&init_user_ns, inode, dir, mode);
        inode_set_bytes(inode, 0);
  
        inode->i_mtime = current_time(inode);
@@@ -6518,8 -6519,8 +6521,8 @@@ static int btrfs_add_nondir(struct btrf
        return err;
  }
  
 -static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
 -                      umode_t mode, dev_t rdev)
 +static int btrfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
 +                     struct dentry *dentry, umode_t mode, dev_t rdev)
  {
        struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
        struct btrfs_trans_handle *trans;
@@@ -6582,8 -6583,8 +6585,8 @@@ out_unlock
        return err;
  }
  
 -static int btrfs_create(struct inode *dir, struct dentry *dentry,
 -                      umode_t mode, bool excl)
 +static int btrfs_create(struct user_namespace *mnt_userns, struct inode *dir,
 +                      struct dentry *dentry, umode_t mode, bool excl)
  {
        struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
        struct btrfs_trans_handle *trans;
@@@ -6727,8 -6728,7 +6730,8 @@@ fail
        return err;
  }
  
 -static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 +static int btrfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
 +                     struct dentry *dentry, umode_t mode)
  {
        struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
        struct inode *inode = NULL;
@@@ -7910,7 -7910,8 +7913,8 @@@ static blk_status_t btrfs_check_read_di
                        ASSERT(pgoff < PAGE_SIZE);
                        if (uptodate &&
                            (!csum || !check_data_csum(inode, io_bio,
-                                       bio_offset, bvec.bv_page, pgoff))) {
+                                                      bio_offset, bvec.bv_page,
+                                                      pgoff, start))) {
                                clean_io_failure(fs_info, failure_tree, io_tree,
                                                 start, bvec.bv_page,
                                                 btrfs_ino(BTRFS_I(inode)),
@@@ -8169,10 -8170,6 +8173,6 @@@ static blk_qc_t btrfs_submit_direct(str
                bio->bi_end_io = btrfs_end_dio_bio;
                btrfs_io_bio(bio)->logical = file_offset;
  
-               WARN_ON_ONCE(write && btrfs_is_zoned(fs_info) &&
-                            fs_info->max_zone_append_size &&
-                            bio_op(bio) != REQ_OP_ZONE_APPEND);
                if (bio_op(bio) == REQ_OP_ZONE_APPEND) {
                        status = extract_ordered_extent(BTRFS_I(inode), bio,
                                                        file_offset);
@@@ -9018,8 -9015,7 +9018,8 @@@ fail
        return -ENOMEM;
  }
  
 -static int btrfs_getattr(const struct path *path, struct kstat *stat,
 +static int btrfs_getattr(struct user_namespace *mnt_userns,
 +                       const struct path *path, struct kstat *stat,
                         u32 request_mask, unsigned int flags)
  {
        u64 delalloc_bytes;
                                  STATX_ATTR_IMMUTABLE |
                                  STATX_ATTR_NODUMP);
  
 -      generic_fillattr(inode, stat);
 +      generic_fillattr(&init_user_ns, inode, stat);
        stat->dev = BTRFS_I(inode)->root->anon_dev;
  
        spin_lock(&BTRFS_I(inode)->lock);
@@@ -9536,9 -9532,9 +9536,9 @@@ out_notrans
        return ret;
  }
  
 -static int btrfs_rename2(struct inode *old_dir, struct dentry *old_dentry,
 -                       struct inode *new_dir, struct dentry *new_dentry,
 -                       unsigned int flags)
 +static int btrfs_rename2(struct user_namespace *mnt_userns, struct inode *old_dir,
 +                       struct dentry *old_dentry, struct inode *new_dir,
 +                       struct dentry *new_dentry, unsigned int flags)
  {
        if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
                return -EINVAL;
@@@ -9746,8 -9742,8 +9746,8 @@@ out
        return ret;
  }
  
 -static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
 -                       const char *symname)
 +static int btrfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
 +                       struct dentry *dentry, const char *symname)
  {
        struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
        struct btrfs_trans_handle *trans;
@@@ -10096,8 -10092,7 +10096,8 @@@ static int btrfs_set_page_dirty(struct 
        return __set_page_dirty_nobuffers(page);
  }
  
 -static int btrfs_permission(struct inode *inode, int mask)
 +static int btrfs_permission(struct user_namespace *mnt_userns,
 +                          struct inode *inode, int mask)
  {
        struct btrfs_root *root = BTRFS_I(inode)->root;
        umode_t mode = inode->i_mode;
                if (BTRFS_I(inode)->flags & BTRFS_INODE_READONLY)
                        return -EACCES;
        }
 -      return generic_permission(inode, mask);
 +      return generic_permission(&init_user_ns, inode, mask);
  }
  
 -static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
 +static int btrfs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir,
 +                       struct dentry *dentry, umode_t mode)
  {
        struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb);
        struct btrfs_trans_handle *trans;
diff --combined fs/btrfs/volumes.c
@@@ -421,7 -421,7 +421,7 @@@ static struct btrfs_device *__alloc_dev
         * Preallocate a bio that's always going to be used for flushing device
         * barriers and matches the device lifespan
         */
 -      dev->flush_bio = bio_alloc_bioset(GFP_KERNEL, 0, NULL);
 +      dev->flush_bio = bio_kmalloc(GFP_KERNEL, 0);
        if (!dev->flush_bio) {
                kfree(dev);
                return ERR_PTR(-ENOMEM);
@@@ -7448,6 -7448,9 +7448,9 @@@ static int btrfs_device_init_dev_stats(
        int item_size;
        int i, ret, slot;
  
+       if (!device->fs_info->dev_root)
+               return 0;
        key.objectid = BTRFS_DEV_STATS_OBJECTID;
        key.type = BTRFS_PERSISTENT_ITEM_KEY;
        key.offset = device->devid;