Merge tag 'for-6.7-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 30 Oct 2023 20:42:06 +0000 (10:42 -1000)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 30 Oct 2023 20:42:06 +0000 (10:42 -1000)
Pull btrfs updates from David Sterba:
 "New features:

   - raid-stripe-tree

     New tree for logical file extent mapping where the physical mapping
     may not match on multiple devices. This is now used in zoned mode
     to implement RAID0/RAID1* profiles, but can be used in non-zoned
     mode as well. The support for RAID56 is in development and will
     eventually fix the problems with the current implementation. This
     is a backward incompatible feature and has to be enabled at mkfs
     time.

   - simple quota accounting (squota)

     A simplified mode of qgroup that accounts all space on the initial
     extent owners (a subvolume), the snapshots are then cheap to create
     and delete. The deletion of snapshots in fully accounting qgroups
     is a known CPU/IO performance bottleneck.

     The squota is not suitable for the general use case but works well
     for containers where the original subvolume exists for the whole
     time. This is a backward incompatible feature as it needs extending
     some structures, but can be enabled on an existing filesystem.

   - temporary filesystem fsid (temp_fsid)

     The fsid identifies a filesystem and is hard coded in the
     structures, which disallows mounting the same fsid found on
     different devices.

     For a single device filesystem this is not strictly necessary, a
     new temporary fsid can be generated on mount e.g. after a device is
     cloned. This will be used by Steam Deck for root partition A/B
     testing, or can be used for VM root images.

  Other user visible changes:

   - filesystems with partially finished metadata_uuid conversion cannot
     be mounted anymore and the uuid fixup has to be done by btrfs-progs
     (btrfstune).

  Performance improvements:

   - reduce reservations for checksum deletions (with enabled free space
     tree by factor of 4), on a sample workload on file with many
     extents the deletion time decreased by 12%

   - make extent state merges more efficient during insertions, reduce
     rb-tree iterations (run time of critical functions reduced by 5%)

  Core changes:

   - the integrity check functionality has been removed, this was a
     debugging feature and removal does not affect other integrity
     checks like checksums or tree-checker

   - space reservation changes:

      - more efficient delayed ref reservations, this avoids building up
        too much work or overusing or exhausting the global block
        reserve in some situations

      - move delayed refs reservation to the transaction start time,
        this prevents some ENOSPC corner cases related to exhaustion of
        global reserve

      - improvements in reducing excessive reservations for block group
        items

      - adjust overcommit logic in near full situations, account for one
        more chunk to eventually allocate metadata chunk, this is mostly
        relevant for small filesystems (<10GiB)

   - single device filesystems are scanned but not registered (except
     seed devices), this allows temp_fsid to work

   - qgroup iterations do not need GFP_ATOMIC allocations anymore

   - cleanups, refactoring, reduced data structure size, function
     parameter simplifications, error handling fixes"

* tag 'for-6.7-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: (156 commits)
  btrfs: open code timespec64 in struct btrfs_inode
  btrfs: remove redundant log root tree index assignment during log sync
  btrfs: remove redundant initialization of variable dirty in btrfs_update_time()
  btrfs: sysfs: show temp_fsid feature
  btrfs: disable the device add feature for temp-fsid
  btrfs: disable the seed feature for temp-fsid
  btrfs: update comment for temp-fsid, fsid, and metadata_uuid
  btrfs: remove pointless empty log context list check when syncing log
  btrfs: update comment for struct btrfs_inode::lock
  btrfs: remove pointless barrier from btrfs_sync_file()
  btrfs: add and use helpers for reading and writing last_trans_committed
  btrfs: add and use helpers for reading and writing fs_info->generation
  btrfs: add and use helpers for reading and writing log_transid
  btrfs: add and use helpers for reading and writing last_log_commit
  btrfs: support cloned-device mount capability
  btrfs: add helper function find_fsid_by_disk
  btrfs: stop reserving excessive space for block group item insertions
  btrfs: stop reserving excessive space for block group item updates
  btrfs: reorder btrfs_inode to fill gaps
  btrfs: open code btrfs_ordered_inode_tree in btrfs_inode
  ...

16 files changed:
1  2 
fs/btrfs/backref.c
fs/btrfs/backref.h
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/delayed-inode.c
fs/btrfs/dev-replace.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/reflink.c
fs/btrfs/relocation.c
fs/btrfs/transaction.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.c
fs/btrfs/volumes.h
fs/btrfs/xattr.c

Simple merge
Simple merge
Simple merge
Simple merge
index c401908eb4683a7733f82e0a00a97211a3460f45,c640f87038a68a4ffd93dfea90d16ff86fcffb3e..7381241334e8dbcf713843373b1f03ded8698b9c
@@@ -1834,24 -1833,22 +1833,22 @@@ static void fill_stack_inode_item(struc
        btrfs_set_stack_inode_block_group(inode_item, 0);
  
        btrfs_set_stack_timespec_sec(&inode_item->atime,
 -                                   inode->i_atime.tv_sec);
 +                                   inode_get_atime_sec(inode));
        btrfs_set_stack_timespec_nsec(&inode_item->atime,
 -                                    inode->i_atime.tv_nsec);
 +                                    inode_get_atime_nsec(inode));
  
        btrfs_set_stack_timespec_sec(&inode_item->mtime,
 -                                   inode->i_mtime.tv_sec);
 +                                   inode_get_mtime_sec(inode));
        btrfs_set_stack_timespec_nsec(&inode_item->mtime,
 -                                    inode->i_mtime.tv_nsec);
 +                                    inode_get_mtime_nsec(inode));
  
        btrfs_set_stack_timespec_sec(&inode_item->ctime,
 -                                   inode_get_ctime(inode).tv_sec);
 +                                   inode_get_ctime_sec(inode));
        btrfs_set_stack_timespec_nsec(&inode_item->ctime,
 -                                    inode_get_ctime(inode).tv_nsec);
 +                                    inode_get_ctime_nsec(inode));
  
-       btrfs_set_stack_timespec_sec(&inode_item->otime,
-                                    BTRFS_I(inode)->i_otime.tv_sec);
-       btrfs_set_stack_timespec_nsec(&inode_item->otime,
-                                    BTRFS_I(inode)->i_otime.tv_nsec);
+       btrfs_set_stack_timespec_sec(&inode_item->otime, BTRFS_I(inode)->i_otime_sec);
+       btrfs_set_stack_timespec_nsec(&inode_item->otime, BTRFS_I(inode)->i_otime_nsec);
  }
  
  int btrfs_fill_inode(struct inode *inode, u32 *rdev)
Simple merge
diff --cc fs/btrfs/file.c
index 278a4ea651e1fdfd609fa30c3784e8bb3c267b58,92419cb8508ae4f88358afabd5badb1c664a5c80..f47731c45bb50497c6a3e5059eed67526bf95be2
@@@ -2474,10 -2476,9 +2477,10 @@@ int btrfs_replace_file_extents(struct b
                inode_inc_iversion(&inode->vfs_inode);
  
                if (!extent_info || extent_info->update_times)
 -                      inode->vfs_inode.i_mtime = inode_set_ctime_current(&inode->vfs_inode);
 +                      inode_set_mtime_to_ts(&inode->vfs_inode,
 +                                            inode_set_ctime_current(&inode->vfs_inode));
  
-               ret = btrfs_update_inode(trans, root, inode);
+               ret = btrfs_update_inode(trans, inode);
                if (ret)
                        break;
  
@@@ -2716,8 -2717,8 +2719,8 @@@ static int btrfs_punch_hole(struct fil
  
        ASSERT(trans != NULL);
        inode_inc_iversion(inode);
 -      inode->i_mtime = inode_set_ctime_current(inode);
 +      inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
-       ret = btrfs_update_inode(trans, root, BTRFS_I(inode));
+       ret = btrfs_update_inode(trans, BTRFS_I(inode));
        updated_inode = true;
        btrfs_end_transaction(trans);
        btrfs_btree_balance_dirty(fs_info);
index 6e3ce1aecb6e8371bb4fded39fdab97d1b06c23d,b388505c91cc185164019f46a7f8c6c2e9a0aa00..5e3fccddde0c618e19567ea3138cd5980a88758d
@@@ -3922,24 -3928,22 +3928,22 @@@ static void fill_inode_item(struct btrf
        btrfs_set_token_inode_nlink(&token, item, inode->i_nlink);
  
        btrfs_set_token_timespec_sec(&token, &item->atime,
 -                                   inode->i_atime.tv_sec);
 +                                   inode_get_atime_sec(inode));
        btrfs_set_token_timespec_nsec(&token, &item->atime,
 -                                    inode->i_atime.tv_nsec);
 +                                    inode_get_atime_nsec(inode));
  
        btrfs_set_token_timespec_sec(&token, &item->mtime,
 -                                   inode->i_mtime.tv_sec);
 +                                   inode_get_mtime_sec(inode));
        btrfs_set_token_timespec_nsec(&token, &item->mtime,
 -                                    inode->i_mtime.tv_nsec);
 +                                    inode_get_mtime_nsec(inode));
  
        btrfs_set_token_timespec_sec(&token, &item->ctime,
 -                                   inode_get_ctime(inode).tv_sec);
 +                                   inode_get_ctime_sec(inode));
        btrfs_set_token_timespec_nsec(&token, &item->ctime,
 -                                    inode_get_ctime(inode).tv_nsec);
 +                                    inode_get_ctime_nsec(inode));
  
-       btrfs_set_token_timespec_sec(&token, &item->otime,
-                                    BTRFS_I(inode)->i_otime.tv_sec);
-       btrfs_set_token_timespec_nsec(&token, &item->otime,
-                                     BTRFS_I(inode)->i_otime.tv_nsec);
+       btrfs_set_token_timespec_sec(&token, &item->otime, BTRFS_I(inode)->i_otime_sec);
+       btrfs_set_token_timespec_nsec(&token, &item->otime, BTRFS_I(inode)->i_otime_nsec);
  
        btrfs_set_token_inode_nbytes(&token, item, inode_get_bytes(inode));
        btrfs_set_token_inode_generation(&token, item,
@@@ -4132,8 -4135,9 +4135,8 @@@ err
        btrfs_i_size_write(dir, dir->vfs_inode.i_size - name->len * 2);
        inode_inc_iversion(&inode->vfs_inode);
        inode_inc_iversion(&dir->vfs_inode);
 -      inode_set_ctime_current(&inode->vfs_inode);
 -      dir->vfs_inode.i_mtime = inode_set_ctime_current(&dir->vfs_inode);
 +      inode_set_mtime_to_ts(&dir->vfs_inode, inode_set_ctime_current(&dir->vfs_inode));
-       ret = btrfs_update_inode(trans, root, dir);
+       ret = btrfs_update_inode(trans, dir);
  out:
        return ret;
  }
@@@ -4305,8 -4309,8 +4308,8 @@@ static int btrfs_unlink_subvol(struct b
  
        btrfs_i_size_write(dir, dir->vfs_inode.i_size - fname.disk_name.len * 2);
        inode_inc_iversion(&dir->vfs_inode);
 -      dir->vfs_inode.i_mtime = inode_set_ctime_current(&dir->vfs_inode);
 +      inode_set_mtime_to_ts(&dir->vfs_inode, inode_set_ctime_current(&dir->vfs_inode));
-       ret = btrfs_update_inode_fallback(trans, root, dir);
+       ret = btrfs_update_inode_fallback(trans, dir);
        if (ret)
                btrfs_abort_transaction(trans, ret);
  out:
@@@ -5582,6 -5585,6 +5585,7 @@@ static struct inode *new_simple_dir(str
                                    struct btrfs_key *key,
                                    struct btrfs_root *root)
  {
++      struct timespec64 ts;
        struct inode *inode = new_inode(dir->i_sb);
  
        if (!inode)
        inode->i_opflags &= ~IOP_XATTR;
        inode->i_fop = &simple_dir_operations;
        inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO;
-       inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
 -      inode->i_mtime = inode_set_ctime_current(inode);
 -      inode->i_atime = dir->i_atime;
 -      BTRFS_I(inode)->i_otime_sec = inode->i_mtime.tv_sec;
 -      BTRFS_I(inode)->i_otime_nsec = inode->i_mtime.tv_nsec;
++
++      ts = inode_set_ctime_current(inode);
++      inode_set_mtime_to_ts(inode, ts);
 +      inode_set_atime_to_ts(inode, inode_get_atime(dir));
-       BTRFS_I(inode)->i_otime = inode_get_mtime(inode);
++      BTRFS_I(inode)->i_otime_sec = ts.tv_sec;
++      BTRFS_I(inode)->i_otime_nsec = ts.tv_nsec;
++
        inode->i_uid = dir->i_uid;
        inode->i_gid = dir->i_gid;
  
@@@ -6160,6 -6164,6 +6168,7 @@@ static void btrfs_inherit_iflags(struc
  int btrfs_create_new_inode(struct btrfs_trans_handle *trans,
                           struct btrfs_new_inode_args *args)
  {
++      struct timespec64 ts;
        struct inode *dir = args->dir;
        struct inode *inode = args->inode;
        const struct fscrypt_str *name = args->orphan ? NULL : &args->fname.disk_name;
                goto discard;
        }
  
-       simple_inode_init_ts(inode);
-       BTRFS_I(inode)->i_otime = inode_get_mtime(inode);
 -      inode->i_mtime = inode_set_ctime_current(inode);
 -      inode->i_atime = inode->i_mtime;
 -      BTRFS_I(inode)->i_otime_sec = inode->i_mtime.tv_sec;
 -      BTRFS_I(inode)->i_otime_nsec = inode->i_mtime.tv_nsec;
++      ts = simple_inode_init_ts(inode);
++      BTRFS_I(inode)->i_otime_sec = ts.tv_sec;
++      BTRFS_I(inode)->i_otime_nsec = ts.tv_nsec;
  
        /*
         * We're going to fill the inode item now, so at this point the inode
@@@ -6443,10 -6449,10 +6453,10 @@@ int btrfs_add_link(struct btrfs_trans_h
         * values (the ones it had when the fsync was done).
         */
        if (!test_bit(BTRFS_FS_LOG_RECOVERING, &root->fs_info->flags))
 -              parent_inode->vfs_inode.i_mtime =
 -                      inode_set_ctime_current(&parent_inode->vfs_inode);
 +              inode_set_mtime_to_ts(&parent_inode->vfs_inode,
 +                                    inode_set_ctime_current(&parent_inode->vfs_inode));
  
-       ret = btrfs_update_inode(trans, root, parent_inode);
+       ret = btrfs_update_inode(trans, parent_inode);
        if (ret)
                btrfs_abort_transaction(trans, ret);
        return ret;
Simple merge
Simple merge
Simple merge
index 38a2775c5c7b59b992e5bea66f6eb7fda7313e25,9694a3ca17390914a9e7103356541a9f360aa0c1..6e63816dddcbea20f160a274cc8fa06f10ebd7a0
@@@ -1860,9 -1911,8 +1911,9 @@@ static noinline int create_pending_snap
  
        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, parent_root, BTRFS_I(parent_inode));
+       ret = btrfs_update_inode_fallback(trans, BTRFS_I(parent_inode));
        if (ret) {
                btrfs_abort_transaction(trans, ret);
                goto fail;
Simple merge
index 1f38affa4d9cba368edcbdfe0ca200cb48954c10,1fdfa9153e30c55d6813a50b7c8e3ff5d74be887..c87e18827a0a6cc411cd9d01411efe816a10c047
@@@ -457,86 -455,32 +455,34 @@@ static noinline struct btrfs_fs_device
        return NULL;
  }
  
- /*
-  * First check if the metadata_uuid is different from the fsid in the given
-  * fs_devices. Then check if the given fsid is the same as the metadata_uuid
-  * in the fs_devices. If it is, return true; otherwise, return false.
-  */
- static inline bool check_fsid_changed(const struct btrfs_fs_devices *fs_devices,
-                                     const u8 *fsid)
- {
-       return memcmp(fs_devices->fsid, fs_devices->metadata_uuid,
-                     BTRFS_FSID_SIZE) != 0 &&
-              memcmp(fs_devices->metadata_uuid, fsid, BTRFS_FSID_SIZE) == 0;
- }
- static struct btrfs_fs_devices *find_fsid_with_metadata_uuid(
-                               struct btrfs_super_block *disk_super)
- {
-       struct btrfs_fs_devices *fs_devices;
-       /*
-        * Handle scanned device having completed its fsid change but
-        * belonging to a fs_devices that was created by first scanning
-        * a device which didn't have its fsid/metadata_uuid changed
-        * at all and the CHANGING_FSID_V2 flag set.
-        */
-       list_for_each_entry(fs_devices, &fs_uuids, fs_list) {
-               if (!fs_devices->fsid_change)
-                       continue;
-               if (match_fsid_fs_devices(fs_devices, disk_super->metadata_uuid,
-                                         fs_devices->fsid))
-                       return fs_devices;
-       }
-       /*
-        * Handle scanned device having completed its fsid change but
-        * belonging to a fs_devices that was created by a device that
-        * has an outdated pair of fsid/metadata_uuid and
-        * CHANGING_FSID_V2 flag set.
-        */
-       list_for_each_entry(fs_devices, &fs_uuids, fs_list) {
-               if (!fs_devices->fsid_change)
-                       continue;
-               if (check_fsid_changed(fs_devices, disk_super->metadata_uuid))
-                       return fs_devices;
-       }
-       return find_fsid(disk_super->fsid, disk_super->metadata_uuid);
- }
  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;
        }
  
Simple merge
Simple merge