Merge tag 'for-5.9-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 13 Aug 2020 19:26:18 +0000 (12:26 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 13 Aug 2020 19:26:18 +0000 (12:26 -0700)
Pull more btrfs updates from David Sterba:
 "One minor update, the rest are fixes that have arrived a bit late for
  the first batch. There are also some recent fixes for bugs that were
  discovered during the merge window and pop up during testing.

  User visible change:

   - show correct subvolume path in /proc/mounts for bind mounts

  Fixes:

   - fix compression messages when remounting with different level or
     compression algorithm

   - tree-log: fix some memory leaks on error handling paths

   - restore I_VERSION on remount

   - fix return values and error code mixups

   - fix umount crash with quotas enabled when removing sysfs files

   - fix trim range on a shrunk device"

* tag 'for-5.9-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: trim: fix underflow in trim length to prevent access beyond device boundary
  btrfs: fix return value mixup in btrfs_get_extent
  btrfs: sysfs: fix NULL pointer dereference at btrfs_sysfs_del_qgroups()
  btrfs: check correct variable after allocation in btrfs_backref_iter_alloc
  btrfs: make sure SB_I_VERSION doesn't get unset by remount
  btrfs: fix memory leaks after failure to lookup checksums during inode logging
  btrfs: don't show full path of bind mounts in subvol=
  btrfs: fix messages after changing compression level by remount
  btrfs: only search for left_info if there is no right_info in try_merge_free_space
  btrfs: inode: fix NULL pointer dereference if inode doesn't need compression

fs/btrfs/backref.c
fs/btrfs/extent-io-tree.h
fs/btrfs/extent-tree.c
fs/btrfs/free-space-cache.c
fs/btrfs/inode.c
fs/btrfs/super.c
fs/btrfs/sysfs.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.c

index ea10f7bc99abf7590b89c1fa888cf8d135aac620..ea1c28ccb44ff95f9cf1a8769af6580d156f4173 100644 (file)
@@ -2303,7 +2303,7 @@ struct btrfs_backref_iter *btrfs_backref_iter_alloc(
                return NULL;
 
        ret->path = btrfs_alloc_path();
-       if (!ret) {
+       if (!ret->path) {
                kfree(ret);
                return NULL;
        }
index f39d47a2d01a677d276e7b4cfc39dd6dde90a3c3..219a09a2b7340a90dd3a75a2beb2eb9ca5a98615 100644 (file)
@@ -34,6 +34,8 @@ struct io_failure_record;
  */
 #define CHUNK_ALLOCATED                                EXTENT_DIRTY
 #define CHUNK_TRIMMED                          EXTENT_DEFRAG
+#define CHUNK_STATE_MASK                       (CHUNK_ALLOCATED |              \
+                                                CHUNK_TRIMMED)
 
 enum {
        IO_TREE_FS_PINNED_EXTENTS,
index 61ede335f6c3743a09fa88f0f5fa0483b250620a..de6fe176fdfb3400c4b0786c9b032f972069d20e 100644 (file)
@@ -33,6 +33,7 @@
 #include "delalloc-space.h"
 #include "block-group.h"
 #include "discard.h"
+#include "rcu-string.h"
 
 #undef SCRAMBLE_DELAYED_REFS
 
@@ -5668,6 +5669,19 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, u64 *trimmed)
                                            &start, &end,
                                            CHUNK_TRIMMED | CHUNK_ALLOCATED);
 
+               /* Check if there are any CHUNK_* bits left */
+               if (start > device->total_bytes) {
+                       WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG));
+                       btrfs_warn_in_rcu(fs_info,
+"ignoring attempt to trim beyond device size: offset %llu length %llu device %s device size %llu",
+                                         start, end - start + 1,
+                                         rcu_str_deref(device->name),
+                                         device->total_bytes);
+                       mutex_unlock(&fs_info->chunk_mutex);
+                       ret = 0;
+                       break;
+               }
+
                /* Ensure we skip the reserved area in the first 1M */
                start = max_t(u64, start, SZ_1M);
 
index 6d961e11639e3aa960957a966e3d1c5511f581b5..ef0fd7afb0b1e8f45674bfd94044aef24a7a2c57 100644 (file)
@@ -2282,7 +2282,7 @@ out:
 static bool try_merge_free_space(struct btrfs_free_space_ctl *ctl,
                          struct btrfs_free_space *info, bool update_stat)
 {
-       struct btrfs_free_space *left_info;
+       struct btrfs_free_space *left_info = NULL;
        struct btrfs_free_space *right_info;
        bool merged = false;
        u64 offset = info->offset;
@@ -2298,7 +2298,7 @@ static bool try_merge_free_space(struct btrfs_free_space_ctl *ctl,
        if (right_info && rb_prev(&right_info->offset_index))
                left_info = rb_entry(rb_prev(&right_info->offset_index),
                                     struct btrfs_free_space, offset_index);
-       else
+       else if (!right_info)
                left_info = tree_search_offset(ctl, offset - 1, 0, 0);
 
        /* See try_merge_free_space() comment. */
index 6dc03bab0c9d1b51c3f8572d046c8ac4b49560c3..51fcd82d41c0ebec1fceb671dc23e40492941e6f 100644 (file)
@@ -654,12 +654,18 @@ cont:
                                                     page_error_op |
                                                     PAGE_END_WRITEBACK);
 
-                       for (i = 0; i < nr_pages; i++) {
-                               WARN_ON(pages[i]->mapping);
-                               put_page(pages[i]);
+                       /*
+                        * Ensure we only free the compressed pages if we have
+                        * them allocated, as we can still reach here with
+                        * inode_need_compress() == false.
+                        */
+                       if (pages) {
+                               for (i = 0; i < nr_pages; i++) {
+                                       WARN_ON(pages[i]->mapping);
+                                       put_page(pages[i]);
+                               }
+                               kfree(pages);
                        }
-                       kfree(pages);
-
                        return 0;
                }
        }
@@ -6622,7 +6628,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
            extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
                /* Only regular file could have regular/prealloc extent */
                if (!S_ISREG(inode->vfs_inode.i_mode)) {
-                       ret = -EUCLEAN;
+                       err = -EUCLEAN;
                        btrfs_crit(fs_info,
                "regular/prealloc extent found for non-regular inode %llu",
                                   btrfs_ino(inode));
index 5a9dc31d95c9836cb77822ecdadcb90a7f850854..e529ddb35b87f32bbc2363111f4dd19ade19d347 100644 (file)
@@ -517,6 +517,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
        char *compress_type;
        bool compress_force = false;
        enum btrfs_compression_type saved_compress_type;
+       int saved_compress_level;
        bool saved_compress_force;
        int no_compress = 0;
 
@@ -598,6 +599,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
                                info->compress_type : BTRFS_COMPRESS_NONE;
                        saved_compress_force =
                                btrfs_test_opt(info, FORCE_COMPRESS);
+                       saved_compress_level = info->compress_level;
                        if (token == Opt_compress ||
                            token == Opt_compress_force ||
                            strncmp(args[0].from, "zlib", 4) == 0) {
@@ -642,6 +644,8 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
                                no_compress = 0;
                        } else if (strncmp(args[0].from, "no", 2) == 0) {
                                compress_type = "no";
+                               info->compress_level = 0;
+                               info->compress_type = 0;
                                btrfs_clear_opt(info->mount_opt, COMPRESS);
                                btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
                                compress_force = false;
@@ -662,11 +666,11 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
                                 */
                                btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
                        }
-                       if ((btrfs_test_opt(info, COMPRESS) &&
-                            (info->compress_type != saved_compress_type ||
-                             compress_force != saved_compress_force)) ||
-                           (!btrfs_test_opt(info, COMPRESS) &&
-                            no_compress == 1)) {
+                       if (no_compress == 1) {
+                               btrfs_info(info, "use no compression");
+                       } else if ((info->compress_type != saved_compress_type) ||
+                                  (compress_force != saved_compress_force) ||
+                                  (info->compress_level != saved_compress_level)) {
                                btrfs_info(info, "%s %s compression, level %d",
                                           (compress_force) ? "force" : "use",
                                           compress_type, info->compress_level);
@@ -1382,6 +1386,7 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
 {
        struct btrfs_fs_info *info = btrfs_sb(dentry->d_sb);
        const char *compress_type;
+       const char *subvol_name;
 
        if (btrfs_test_opt(info, DEGRADED))
                seq_puts(seq, ",degraded");
@@ -1468,8 +1473,13 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
                seq_puts(seq, ",ref_verify");
        seq_printf(seq, ",subvolid=%llu",
                  BTRFS_I(d_inode(dentry))->root->root_key.objectid);
-       seq_puts(seq, ",subvol=");
-       seq_dentry(seq, dentry, " \t\n\\");
+       subvol_name = btrfs_get_subvol_name_from_objectid(info,
+                       BTRFS_I(d_inode(dentry))->root->root_key.objectid);
+       if (!IS_ERR(subvol_name)) {
+               seq_puts(seq, ",subvol=");
+               seq_escape(seq, subvol_name, " \t\n\\");
+               kfree(subvol_name);
+       }
        return 0;
 }
 
@@ -1950,6 +1960,12 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
                set_bit(BTRFS_FS_OPEN, &fs_info->flags);
        }
 out:
+       /*
+        * We need to set SB_I_VERSION here otherwise it'll get cleared by VFS,
+        * since the absence of the flag means it can be toggled off by remount.
+        */
+       *flags |= SB_I_VERSION;
+
        wake_up_process(fs_info->transaction_kthread);
        btrfs_remount_cleanup(fs_info, old_opts);
        clear_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state);
index 104c80caaa744acc8adec42235e0c0be988fa216..c8df2edafd8558ece7ca334a39812f4b10243510 100644 (file)
@@ -1565,9 +1565,11 @@ void btrfs_sysfs_del_qgroups(struct btrfs_fs_info *fs_info)
        rbtree_postorder_for_each_entry_safe(qgroup, next,
                                             &fs_info->qgroup_tree, node)
                btrfs_sysfs_del_one_qgroup(fs_info, qgroup);
-       kobject_del(fs_info->qgroups_kobj);
-       kobject_put(fs_info->qgroups_kobj);
-       fs_info->qgroups_kobj = NULL;
+       if (fs_info->qgroups_kobj) {
+               kobject_del(fs_info->qgroups_kobj);
+               kobject_put(fs_info->qgroups_kobj);
+               fs_info->qgroups_kobj = NULL;
+       }
 }
 
 /* Called when qgroups get initialized, thus there is no need for locking */
index ea8136dcf71f8f90627315285d5fdff3eac6892b..696dd861cc3c63324a7488fcf31491ad42e46aac 100644 (file)
@@ -4036,11 +4036,8 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
                                                fs_info->csum_root,
                                                ds + cs, ds + cs + cl - 1,
                                                &ordered_sums, 0);
-                               if (ret) {
-                                       btrfs_release_path(dst_path);
-                                       kfree(ins_data);
-                                       return ret;
-                               }
+                               if (ret)
+                                       break;
                        }
                }
        }
@@ -4053,7 +4050,6 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
         * we have to do this after the loop above to avoid changing the
         * log tree while trying to change the log tree.
         */
-       ret = 0;
        while (!list_empty(&ordered_sums)) {
                struct btrfs_ordered_sum *sums = list_entry(ordered_sums.next,
                                                   struct btrfs_ordered_sum,
index d7670e2a9f39320ab13667e7ba03be34819b734a..ee96c5869f57e2aa2945325446e58e7002ca6341 100644 (file)
@@ -4720,6 +4720,10 @@ again:
        }
 
        mutex_lock(&fs_info->chunk_mutex);
+       /* Clear all state bits beyond the shrunk device size */
+       clear_extent_bits(&device->alloc_state, new_size, (u64)-1,
+                         CHUNK_STATE_MASK);
+
        btrfs_device_set_disk_total_bytes(device, new_size);
        if (list_empty(&device->post_commit_list))
                list_add_tail(&device->post_commit_list,