]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
btrfs: allow read-write for 4K sectorsize on 64K page size systems
authorQu Wenruo <wqu@suse.com>
Mon, 26 Jul 2021 06:35:06 +0000 (14:35 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 23 Aug 2021 11:19:06 +0000 (13:19 +0200)
Since now we support data and metadata read-write for subpage, remove
the RO requirement for subpage mount.

There are some extra limitations though:

- For now, subpage RW mount is still considered experimental
  Thus that mount warning will still be there.

- No compression support
  There are still quite some PAGE_SIZE hard coded and quite some call
  sites use extent_clear_unlock_delalloc() to unlock locked_page.
  This will screw up subpage helpers.

  Now for subpage RW mount, no matter what mount option or inode attr is
  set, all writes will not be compressed.  Although reading compressed
  data has no problem.

- No defrag for subpage case
  The defrag support for subpage case will come in later patches, which
  will also rework the defrag workflow.

- No inline extent will be created
  This is mostly due to the fact that filemap_fdatawrite_range() will
  trigger more write than the range specified.
  In fallocate calls, this behavior can make us to writeback which can
  be inlined, before we enlarge the i_size.

  This is a very special corner case, and even current btrfs check won't
  report error on such inline extent + regular extent.
  But considering how much effort has been put to prevent such inline +
  regular, I'd prefer to cut off inline extent completely until we have
  a good solution.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/disk-io.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/super.c
fs/btrfs/sysfs.c

index b9ba244de1d11306ed132c56a5f6b24bf230a15f..2f9515dccce0b3452513737eb9d4cd81f0bfa0e5 100644 (file)
@@ -3392,15 +3392,10 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
                goto fail_alloc;
        }
 
-       /* For 4K sector size support, it's only read-only */
-       if (PAGE_SIZE == SZ_64K && sectorsize == SZ_4K) {
-               if (!sb_rdonly(sb) || btrfs_super_log_root(disk_super)) {
-                       btrfs_err(fs_info,
-       "subpage sectorsize %u only supported read-only for page size %lu",
-                               sectorsize, PAGE_SIZE);
-                       err = -EINVAL;
-                       goto fail_alloc;
-               }
+       if (sectorsize != PAGE_SIZE) {
+               btrfs_warn(fs_info,
+               "read-write for sector size %u with page size %lu is experimental",
+                          sectorsize, PAGE_SIZE);
        }
        if (sectorsize != PAGE_SIZE) {
                if (btrfs_super_incompat_flags(fs_info->super_copy) &
index 915f11462c7c1a8aad50cadea5ce6c87cac796bd..7e63b5c0a1dc5f664c4fe849d6d8de82ee29a70f 100644 (file)
@@ -489,6 +489,9 @@ static noinline int add_async_extent(struct async_chunk *cow,
  */
 static inline bool inode_can_compress(struct btrfs_inode *inode)
 {
+       /* Subpage doesn't support compression yet */
+       if (inode->root->fs_info->sectorsize < PAGE_SIZE)
+               return false;
        if (inode->flags & BTRFS_INODE_NODATACOW ||
            inode->flags & BTRFS_INODE_NODATASUM)
                return false;
index 0ba98e08a0290d2b8b494c37c6b58fd5bbdfa1bf..4d809899c07667f4c19171941a8b3186029c8a3f 100644 (file)
@@ -3115,6 +3115,12 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
                goto out;
        }
 
+       /* Subpage defrag will be supported in later commits */
+       if (root->fs_info->sectorsize < PAGE_SIZE) {
+               ret = -ENOTTY;
+               goto out;
+       }
+
        switch (inode->i_mode & S_IFMT) {
        case S_IFDIR:
                if (!capable(CAP_SYS_ADMIN)) {
index 35ff142ad242c9ad84ceee2bd1599206aef56f27..0d2e3ab2fc3144e037c025cd11e812255bd3b04f 100644 (file)
@@ -2041,13 +2041,6 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
                        ret = -EINVAL;
                        goto restore;
                }
-               if (fs_info->sectorsize < PAGE_SIZE) {
-                       btrfs_warn(fs_info,
-       "read-write mount is not yet allowed for sectorsize %u page size %lu",
-                                  fs_info->sectorsize, PAGE_SIZE);
-                       ret = -EINVAL;
-                       goto restore;
-               }
 
                /*
                 * NOTE: when remounting with a change that does writes, don't
index 9d1d140118fff201db239b64d91b222c0f32b83e..d9d53a255ef97546d00e9bb2f4cefc64d40fea42 100644 (file)
@@ -366,6 +366,10 @@ static ssize_t supported_sectorsizes_show(struct kobject *kobj,
 {
        ssize_t ret = 0;
 
+       /* 4K sector size is also supported with 64K page size */
+       if (PAGE_SIZE == SZ_64K)
+               ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%u ", SZ_4K);
+
        /* Only sectorsize == PAGE_SIZE is now supported */
        ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%lu\n", PAGE_SIZE);