Merge tag 'for-4.15-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 29 Nov 2017 22:26:50 +0000 (14:26 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 29 Nov 2017 22:26:50 +0000 (14:26 -0800)
Pull btrfs fixes from David Sterba:
 "We've collected some fixes in since the pre-merge window freeze.

  There's technically only one regression fix for 4.15, but the rest
  seems important and candidates for stable.

   - fix missing flush bio puts in error cases (is serious, but rarely
     happens)

   - fix reporting stat::st_blocks for buffered append writes

   - fix space cache invalidation

   - fix out of bound memory access when setting zlib level

   - fix potential memory corruption when fsync fails in the middle

   - fix crash in integrity checker

   - incremetnal send fix, path mixup for certain unlink/rename
     combination

   - pass flags to writeback so compressed writes can be throttled
     properly

   - error handling fixes"

* tag 'for-4.15-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  Btrfs: incremental send, fix wrong unlink path after renaming file
  btrfs: tree-checker: Fix false panic for sanity test
  Btrfs: fix list_add corruption and soft lockups in fsync
  btrfs: Fix wild memory access in compression level parser
  btrfs: fix deadlock when writing out space cache
  btrfs: clear space cache inode generation always
  Btrfs: fix reported number of inode blocks after buffered append writes
  Btrfs: move definition of the function btrfs_find_new_delalloc_bytes
  Btrfs: bail out gracefully rather than BUG_ON
  btrfs: dev_alloc_list is not protected by RCU, use normal list_del
  btrfs: add missing device::flush_bio puts
  btrfs: Fix transaction abort during failure in btrfs_rm_dev_item
  Btrfs: add write_flags for compression bio

1  2 
fs/btrfs/ctree.h
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h
fs/btrfs/super.c
fs/btrfs/volumes.c

diff --combined fs/btrfs/ctree.h
index 51477a537c837146100ae3ab6cf62ece7ee7e357,72dcbf19f6cef12b2650ae0ce410aa70cf99935b..13c260b525a1282aded755e5bb0141458ec52452
@@@ -2957,7 -2957,7 +2957,7 @@@ static inline int btrfs_fs_closing(stru
   */
  static inline int btrfs_need_cleaner_sleep(struct btrfs_fs_info *fs_info)
  {
 -      return fs_info->sb->s_flags & MS_RDONLY || btrfs_fs_closing(fs_info);
 +      return fs_info->sb->s_flags & SB_RDONLY || btrfs_fs_closing(fs_info);
  }
  
  static inline void free_fs_info(struct btrfs_fs_info *fs_info)
@@@ -3180,6 -3180,7 +3180,7 @@@ int btrfs_start_delalloc_inodes(struct 
  int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, int delay_iput,
                               int nr);
  int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
+                             unsigned int extra_bits,
                              struct extent_state **cached_state, int dedupe);
  int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
                             struct btrfs_root *new_root,
diff --combined fs/btrfs/extent-tree.c
index 7208ecef70889833ac2caa7d3d5d8b4b634a4ee0,784d41e95ed9534b1f120d3e4895e9d4b8da38e3..4497f937e8fb7ce608f8ef7cc8db1c7a51bcd2a3
@@@ -3502,13 -3502,6 +3502,6 @@@ again
                goto again;
        }
  
-       /* We've already setup this transaction, go ahead and exit */
-       if (block_group->cache_generation == trans->transid &&
-           i_size_read(inode)) {
-               dcs = BTRFS_DC_SETUP;
-               goto out_put;
-       }
        /*
         * We want to set the generation to 0, that way if anything goes wrong
         * from here on out we know not to trust this cache when we load up next
        }
        WARN_ON(ret);
  
+       /* We've already setup this transaction, go ahead and exit */
+       if (block_group->cache_generation == trans->transid &&
+           i_size_read(inode)) {
+               dcs = BTRFS_DC_SETUP;
+               goto out_put;
+       }
        if (i_size_read(inode) > 0) {
                ret = btrfs_check_trunc_cache_free_space(fs_info,
                                        &fs_info->global_block_rsv);
@@@ -3992,9 -3992,16 +3992,9 @@@ void btrfs_dec_nocow_writers(struct btr
        btrfs_put_block_group(bg);
  }
  
 -static int btrfs_wait_nocow_writers_atomic_t(atomic_t *a)
 -{
 -      schedule();
 -      return 0;
 -}
 -
  void btrfs_wait_nocow_writers(struct btrfs_block_group_cache *bg)
  {
 -      wait_on_atomic_t(&bg->nocow_writers,
 -                       btrfs_wait_nocow_writers_atomic_t,
 +      wait_on_atomic_t(&bg->nocow_writers, atomic_t_wait,
                         TASK_UNINTERRUPTIBLE);
  }
  
@@@ -6523,6 -6530,12 +6523,6 @@@ void btrfs_dec_block_group_reservations
        btrfs_put_block_group(bg);
  }
  
 -static int btrfs_wait_bg_reservations_atomic_t(atomic_t *a)
 -{
 -      schedule();
 -      return 0;
 -}
 -
  void btrfs_wait_block_group_reservations(struct btrfs_block_group_cache *bg)
  {
        struct btrfs_space_info *space_info = bg->space_info;
        down_write(&space_info->groups_sem);
        up_write(&space_info->groups_sem);
  
 -      wait_on_atomic_t(&bg->reservations,
 -                       btrfs_wait_bg_reservations_atomic_t,
 +      wait_on_atomic_t(&bg->reservations, atomic_t_wait,
                         TASK_UNINTERRUPTIBLE);
  }
  
@@@ -11045,6 -11059,12 +11045,6 @@@ int btrfs_start_write_no_snapshotting(s
        return 1;
  }
  
 -static int wait_snapshotting_atomic_t(atomic_t *a)
 -{
 -      schedule();
 -      return 0;
 -}
 -
  void btrfs_wait_for_snapshot_creation(struct btrfs_root *root)
  {
        while (true) {
                ret = btrfs_start_write_no_snapshotting(root);
                if (ret)
                        break;
 -              wait_on_atomic_t(&root->will_be_snapshotted,
 -                               wait_snapshotting_atomic_t,
 +              wait_on_atomic_t(&root->will_be_snapshotted, atomic_t_wait,
                                 TASK_UNINTERRUPTIBLE);
        }
  }
diff --combined fs/btrfs/extent_io.c
index f9e9f721efe22d50c45b39e498429255bcd5f436,1dfd14678db86daa915b992e846e4180509dfb54..012d63870b99acfc180ef0cd05fb337e39730959
@@@ -1,4 -1,3 +1,4 @@@
 +// SPDX-License-Identifier: GPL-2.0
  #include <linux/bitops.h>
  #include <linux/slab.h>
  #include <linux/bio.h>
@@@ -1984,7 -1983,7 +1984,7 @@@ int repair_io_failure(struct btrfs_fs_i
        struct btrfs_bio *bbio = NULL;
        int ret;
  
 -      ASSERT(!(fs_info->sb->s_flags & MS_RDONLY));
 +      ASSERT(!(fs_info->sb->s_flags & SB_RDONLY));
        BUG_ON(!mirror_num);
  
        bio = btrfs_io_bio_alloc(1);
@@@ -3253,7 -3252,7 +3253,7 @@@ static noinline_for_stack int writepage
                                               delalloc_start,
                                               delalloc_end,
                                               &page_started,
-                                              nr_written);
+                                              nr_written, wbc);
                /* File system has been set read-only */
                if (ret) {
                        SetPageError(page);
@@@ -3797,7 -3796,7 +3797,7 @@@ int btree_write_cache_pages(struct addr
        int scanned = 0;
        int tag;
  
 -      pagevec_init(&pvec, 0);
 +      pagevec_init(&pvec);
        if (wbc->range_cyclic) {
                index = mapping->writeback_index; /* Start from prev offset */
                end = -1;
@@@ -3814,8 -3813,8 +3814,8 @@@ retry
        if (wbc->sync_mode == WB_SYNC_ALL)
                tag_pages_for_writeback(mapping, index, end);
        while (!done && !nr_to_write_done && (index <= end) &&
 -             (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
 -                      min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
 +             (nr_pages = pagevec_lookup_range_tag(&pvec, mapping, &index, end,
 +                      tag))) {
                unsigned i;
  
                scanned = 1;
                        if (!PagePrivate(page))
                                continue;
  
 -                      if (!wbc->range_cyclic && page->index > end) {
 -                              done = 1;
 -                              break;
 -                      }
 -
                        spin_lock(&mapping->private_lock);
                        if (!PagePrivate(page)) {
                                spin_unlock(&mapping->private_lock);
@@@ -3936,7 -3940,7 +3936,7 @@@ static int extent_write_cache_pages(str
        if (!igrab(inode))
                return 0;
  
 -      pagevec_init(&pvec, 0);
 +      pagevec_init(&pvec);
        if (wbc->range_cyclic) {
                index = mapping->writeback_index; /* Start from prev offset */
                end = -1;
@@@ -3956,8 -3960,8 +3956,8 @@@ retry
                tag_pages_for_writeback(mapping, index, end);
        done_index = index;
        while (!done && !nr_to_write_done && (index <= end) &&
 -             (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
 -                      min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
 +                      (nr_pages = pagevec_lookup_range_tag(&pvec, mapping,
 +                                              &index, end, tag))) {
                unsigned i;
  
                scanned = 1;
                                continue;
                        }
  
 -                      if (!wbc->range_cyclic && page->index > end) {
 -                              done = 1;
 -                              unlock_page(page);
 -                              continue;
 -                      }
 -
                        if (wbc->sync_mode != WB_SYNC_NONE) {
                                if (PageWriteback(page))
                                        flush_fn(data);
diff --combined fs/btrfs/extent_io.h
index 4a8861379d3ef23ef49dfc1b418bbd22243402de,2ef824b58e3c73bc6dad79ca77cda5b54ab4ff7c..93dcae0c3183009c3668dfa34b449051c7576719
@@@ -1,4 -1,3 +1,4 @@@
 +/* SPDX-License-Identifier: GPL-2.0 */
  #ifndef __EXTENTIO__
  #define __EXTENTIO__
  
@@@ -116,7 -115,8 +116,8 @@@ struct extent_io_ops 
         */
        int (*fill_delalloc)(void *private_data, struct page *locked_page,
                             u64 start, u64 end, int *page_started,
-                            unsigned long *nr_written);
+                            unsigned long *nr_written,
+                            struct writeback_control *wbc);
  
        int (*writepage_start_hook)(struct page *page, u64 start, u64 end);
        void (*writepage_end_io_hook)(struct page *page, u64 start, u64 end,
@@@ -365,10 -365,11 +366,11 @@@ int convert_extent_bit(struct extent_io
                       struct extent_state **cached_state);
  
  static inline int set_extent_delalloc(struct extent_io_tree *tree, u64 start,
-               u64 end, struct extent_state **cached_state)
+                                     u64 end, unsigned int extra_bits,
+                                     struct extent_state **cached_state)
  {
        return set_extent_bit(tree, start, end,
-                             EXTENT_DELALLOC | EXTENT_UPTODATE,
+                             EXTENT_DELALLOC | EXTENT_UPTODATE | extra_bits,
                              NULL, cached_state, GFP_NOFS);
  }
  
diff --combined fs/btrfs/super.c
index 305cae7444a071aad914e65de89f3217d8632f5c,ff3545e526f5d8a9376b9d396e114c5e80b3c93f..3a4dce1536455416a4f609f99ec416b61811f592
@@@ -107,7 -107,7 +107,7 @@@ static void btrfs_handle_error(struct b
                return;
  
        if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
 -              sb->s_flags |= MS_RDONLY;
 +              sb->s_flags |= SB_RDONLY;
                btrfs_info(fs_info, "forced readonly");
                /*
                 * Note that a running device replace operation is not
@@@ -137,7 -137,7 +137,7 @@@ void __btrfs_handle_fs_error(struct btr
  
        /*
         * Special case: if the error is EROFS, and we're already
 -       * under MS_RDONLY, then it is safe here.
 +       * under SB_RDONLY, then it is safe here.
         */
        if (errno == -EROFS && sb_rdonly(sb))
                return;
        set_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state);
  
        /* Don't go through full error handling during mount */
 -      if (sb->s_flags & MS_BORN)
 +      if (sb->s_flags & SB_BORN)
                btrfs_handle_error(fs_info);
  }
  
@@@ -507,9 -507,18 +507,18 @@@ int btrfs_parse_options(struct btrfs_fs
                            token == Opt_compress_force ||
                            strncmp(args[0].from, "zlib", 4) == 0) {
                                compress_type = "zlib";
                                info->compress_type = BTRFS_COMPRESS_ZLIB;
-                               info->compress_level =
-                                       btrfs_compress_str2level(args[0].from);
+                               info->compress_level = BTRFS_ZLIB_DEFAULT_LEVEL;
+                               /*
+                                * args[0] contains uninitialized data since
+                                * for these tokens we don't expect any
+                                * parameter.
+                                */
+                               if (token != Opt_compress &&
+                                   token != Opt_compress_force)
+                                       info->compress_level =
+                                         btrfs_compress_str2level(args[0].from);
                                btrfs_set_opt(info->mount_opt, COMPRESS);
                                btrfs_clear_opt(info->mount_opt, NODATACOW);
                                btrfs_clear_opt(info->mount_opt, NODATASUM);
                        break;
                case Opt_acl:
  #ifdef CONFIG_BTRFS_FS_POSIX_ACL
 -                      info->sb->s_flags |= MS_POSIXACL;
 +                      info->sb->s_flags |= SB_POSIXACL;
                        break;
  #else
                        btrfs_err(info, "support for ACL not compiled in!");
                        goto out;
  #endif
                case Opt_noacl:
 -                      info->sb->s_flags &= ~MS_POSIXACL;
 +                      info->sb->s_flags &= ~SB_POSIXACL;
                        break;
                case Opt_notreelog:
                        btrfs_set_and_info(info, NOTREELOG,
@@@ -851,7 -860,7 +860,7 @@@ check
        /*
         * Extra check for current option against current flag
         */
 -      if (btrfs_test_opt(info, NOLOGREPLAY) && !(new_flags & MS_RDONLY)) {
 +      if (btrfs_test_opt(info, NOLOGREPLAY) && !(new_flags & SB_RDONLY)) {
                btrfs_err(info,
                          "nologreplay must be used with ro mount option");
                ret = -EINVAL;
@@@ -1147,7 -1156,7 +1156,7 @@@ static int btrfs_fill_super(struct supe
        sb->s_xattr = btrfs_xattr_handlers;
        sb->s_time_gran = 1;
  #ifdef CONFIG_BTRFS_FS_POSIX_ACL
 -      sb->s_flags |= MS_POSIXACL;
 +      sb->s_flags |= SB_POSIXACL;
  #endif
        sb->s_flags |= SB_I_VERSION;
        sb->s_iflags |= SB_I_CGROUPWB;
        }
  
        cleancache_init_fs(sb);
 -      sb->s_flags |= MS_ACTIVE;
 +      sb->s_flags |= SB_ACTIVE;
        return 0;
  
  fail_close:
@@@ -1277,7 -1286,7 +1286,7 @@@ static int btrfs_show_options(struct se
                seq_puts(seq, ",flushoncommit");
        if (btrfs_test_opt(info, DISCARD))
                seq_puts(seq, ",discard");
 -      if (!(info->sb->s_flags & MS_POSIXACL))
 +      if (!(info->sb->s_flags & SB_POSIXACL))
                seq_puts(seq, ",noacl");
        if (btrfs_test_opt(info, SPACE_CACHE))
                seq_puts(seq, ",space_cache");
@@@ -1409,11 -1418,11 +1418,11 @@@ static struct dentry *mount_subvol(cons
  
        mnt = vfs_kern_mount(&btrfs_fs_type, flags, device_name, newargs);
        if (PTR_ERR_OR_ZERO(mnt) == -EBUSY) {
 -              if (flags & MS_RDONLY) {
 -                      mnt = vfs_kern_mount(&btrfs_fs_type, flags & ~MS_RDONLY,
 +              if (flags & SB_RDONLY) {
 +                      mnt = vfs_kern_mount(&btrfs_fs_type, flags & ~SB_RDONLY,
                                             device_name, newargs);
                } else {
 -                      mnt = vfs_kern_mount(&btrfs_fs_type, flags | MS_RDONLY,
 +                      mnt = vfs_kern_mount(&btrfs_fs_type, flags | SB_RDONLY,
                                             device_name, newargs);
                        if (IS_ERR(mnt)) {
                                root = ERR_CAST(mnt);
@@@ -1565,7 -1574,7 +1574,7 @@@ static struct dentry *btrfs_mount(struc
        u64 subvol_objectid = 0;
        int error = 0;
  
 -      if (!(flags & MS_RDONLY))
 +      if (!(flags & SB_RDONLY))
                mode |= FMODE_WRITE;
  
        error = btrfs_parse_early_options(data, mode, fs_type,
        if (error)
                goto error_fs_info;
  
 -      if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) {
 +      if (!(flags & SB_RDONLY) && fs_devices->rw_devices == 0) {
                error = -EACCES;
                goto error_close_devices;
        }
  
        bdev = fs_devices->latest_bdev;
 -      s = sget(fs_type, btrfs_test_super, btrfs_set_super, flags | MS_NOSEC,
 +      s = sget(fs_type, btrfs_test_super, btrfs_set_super, flags | SB_NOSEC,
                 fs_info);
        if (IS_ERR(s)) {
                error = PTR_ERR(s);
        if (s->s_root) {
                btrfs_close_devices(fs_devices);
                free_fs_info(fs_info);
 -              if ((flags ^ s->s_flags) & MS_RDONLY)
 +              if ((flags ^ s->s_flags) & SB_RDONLY)
                        error = -EBUSY;
        } else {
                snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev);
@@@ -1702,11 -1711,11 +1711,11 @@@ static inline void btrfs_remount_begin(
  {
        if (btrfs_raw_test_opt(old_opts, AUTO_DEFRAG) &&
            (!btrfs_raw_test_opt(fs_info->mount_opt, AUTO_DEFRAG) ||
 -           (flags & MS_RDONLY))) {
 +           (flags & SB_RDONLY))) {
                /* wait for any defraggers to finish */
                wait_event(fs_info->transaction_wait,
                           (atomic_read(&fs_info->defrag_running) == 0));
 -              if (flags & MS_RDONLY)
 +              if (flags & SB_RDONLY)
                        sync_filesystem(fs_info->sb);
        }
  }
@@@ -1766,10 -1775,10 +1775,10 @@@ static int btrfs_remount(struct super_b
        btrfs_resize_thread_pool(fs_info,
                fs_info->thread_pool_size, old_thread_pool_size);
  
 -      if ((bool)(*flags & MS_RDONLY) == sb_rdonly(sb))
 +      if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb))
                goto out;
  
 -      if (*flags & MS_RDONLY) {
 +      if (*flags & SB_RDONLY) {
                /*
                 * this also happens on 'umount -rf' or on shutdown, when
                 * the filesystem is busy.
                /* avoid complains from lockdep et al. */
                up(&fs_info->uuid_tree_rescan_sem);
  
 -              sb->s_flags |= MS_RDONLY;
 +              sb->s_flags |= SB_RDONLY;
  
                /*
 -               * Setting MS_RDONLY will put the cleaner thread to
 +               * Setting SB_RDONLY will put the cleaner thread to
                 * sleep at the next loop if it's already active.
                 * If it's already asleep, we'll leave unused block
                 * groups on disk until we're mounted read-write again
                                goto restore;
                        }
                }
 -              sb->s_flags &= ~MS_RDONLY;
 +              sb->s_flags &= ~SB_RDONLY;
  
                set_bit(BTRFS_FS_OPEN, &fs_info->flags);
        }
@@@ -1866,9 -1875,9 +1875,9 @@@ out
        return 0;
  
  restore:
 -      /* We've hit an error - don't reset MS_RDONLY */
 +      /* We've hit an error - don't reset SB_RDONLY */
        if (sb_rdonly(sb))
 -              old_flags |= MS_RDONLY;
 +              old_flags |= SB_RDONLY;
        sb->s_flags = old_flags;
        fs_info->mount_opt = old_opts;
        fs_info->compress_type = old_compress_type;
diff --combined fs/btrfs/volumes.c
index 925070b9ce030c32e9d5f8976e4197e87271703e,d48b24e54366f3c2c6892d6a7bb0f286c02cb8c2..49810b70afd3941721246497d94c754ec2120619
@@@ -189,6 -189,7 +189,7 @@@ static void free_fs_devices(struct btrf
                                    struct btrfs_device, dev_list);
                list_del(&device->dev_list);
                rcu_string_free(device->name);
+               bio_put(device->flush_bio);
                kfree(device);
        }
        kfree(fs_devices);
@@@ -578,6 -579,7 +579,7 @@@ static void btrfs_free_stale_device(str
                                fs_devs->num_devices--;
                                list_del(&dev->dev_list);
                                rcu_string_free(dev->name);
+                               bio_put(dev->flush_bio);
                                kfree(dev);
                        }
                        break;
@@@ -630,6 -632,7 +632,7 @@@ static noinline int device_list_add(con
  
                name = rcu_string_strdup(path, GFP_NOFS);
                if (!name) {
+                       bio_put(device->flush_bio);
                        kfree(device);
                        return -ENOMEM;
                }
@@@ -742,6 -745,7 +745,7 @@@ static struct btrfs_fs_devices *clone_f
                        name = rcu_string_strdup(orig_dev->name->str,
                                        GFP_KERNEL);
                        if (!name) {
+                               bio_put(device->flush_bio);
                                kfree(device);
                                goto error;
                        }
@@@ -807,6 -811,7 +811,7 @@@ again
                list_del_init(&device->dev_list);
                fs_devices->num_devices--;
                rcu_string_free(device->name);
+               bio_put(device->flush_bio);
                kfree(device);
        }
  
@@@ -1750,20 -1755,24 +1755,24 @@@ static int btrfs_rm_dev_item(struct btr
        key.offset = device->devid;
  
        ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
-       if (ret < 0)
-               goto out;
-       if (ret > 0) {
-               ret = -ENOENT;
+       if (ret) {
+               if (ret > 0)
+                       ret = -ENOENT;
+               btrfs_abort_transaction(trans, ret);
+               btrfs_end_transaction(trans);
                goto out;
        }
  
        ret = btrfs_del_item(trans, root, path);
-       if (ret)
-               goto out;
+       if (ret) {
+               btrfs_abort_transaction(trans, ret);
+               btrfs_end_transaction(trans);
+       }
  out:
        btrfs_free_path(path);
-       btrfs_commit_transaction(trans);
+       if (!ret)
+               ret = btrfs_commit_transaction(trans);
        return ret;
  }
  
@@@ -1993,7 -2002,7 +2002,7 @@@ void btrfs_rm_dev_replace_remove_srcdev
        fs_devices = srcdev->fs_devices;
  
        list_del_rcu(&srcdev->dev_list);
-       list_del_rcu(&srcdev->dev_alloc_list);
+       list_del(&srcdev->dev_alloc_list);
        fs_devices->num_devices--;
        if (srcdev->missing)
                fs_devices->missing_devices--;
@@@ -2349,6 -2358,7 +2358,7 @@@ int btrfs_init_new_device(struct btrfs_
  
        name = rcu_string_strdup(device_path, GFP_KERNEL);
        if (!name) {
+               bio_put(device->flush_bio);
                kfree(device);
                ret = -ENOMEM;
                goto error;
        trans = btrfs_start_transaction(root, 0);
        if (IS_ERR(trans)) {
                rcu_string_free(device->name);
+               bio_put(device->flush_bio);
                kfree(device);
                ret = PTR_ERR(trans);
                goto error;
        set_blocksize(device->bdev, BTRFS_BDEV_BLOCKSIZE);
  
        if (seeding_dev) {
 -              sb->s_flags &= ~MS_RDONLY;
 +              sb->s_flags &= ~SB_RDONLY;
                ret = btrfs_prepare_sprout(fs_info);
                if (ret) {
                        btrfs_abort_transaction(trans, ret);
@@@ -2497,10 -2508,11 +2508,11 @@@ error_sysfs
        btrfs_sysfs_rm_device_link(fs_info->fs_devices, device);
  error_trans:
        if (seeding_dev)
 -              sb->s_flags |= MS_RDONLY;
 +              sb->s_flags |= SB_RDONLY;
        if (trans)
                btrfs_end_transaction(trans);
        rcu_string_free(device->name);
+       bio_put(device->flush_bio);
        kfree(device);
  error:
        blkdev_put(bdev, FMODE_EXCL);
@@@ -2567,6 -2579,7 +2579,7 @@@ int btrfs_init_dev_replace_tgtdev(struc
  
        name = rcu_string_strdup(device_path, GFP_KERNEL);
        if (!name) {
+               bio_put(device->flush_bio);
                kfree(device);
                ret = -ENOMEM;
                goto error;
@@@ -6284,6 -6297,7 +6297,7 @@@ struct btrfs_device *btrfs_alloc_device
  
                ret = find_next_devid(fs_info, &tmp);
                if (ret) {
+                       bio_put(dev->flush_bio);
                        kfree(dev);
                        return ERR_PTR(ret);
                }