error = -ENOMEM;
                                goto out;
                        }
-                       device = btrfs_scan_one_device(device_name, flags);
+                       device = btrfs_scan_one_device(device_name, flags, false);
                        kfree(device_name);
                        if (IS_ERR(device)) {
                                error = PTR_ERR(device);
                goto error_fs_info;
        }
 
-       device = btrfs_scan_one_device(device_name, mode);
+       /*
+        * With 'true' passed to btrfs_scan_one_device() (mount time) we expect
+        * either a valid device or an error.
+        */
+       device = btrfs_scan_one_device(device_name, mode, true);
+       ASSERT(device != NULL);
        if (IS_ERR(device)) {
                mutex_unlock(&uuid_mutex);
                error = PTR_ERR(device);
        switch (cmd) {
        case BTRFS_IOC_SCAN_DEV:
                mutex_lock(&uuid_mutex);
-               device = btrfs_scan_one_device(vol->name, BLK_OPEN_READ);
+               /*
+                * Scanning outside of mount can return NULL which would turn
+                * into 0 error code.
+                */
+               device = btrfs_scan_one_device(vol->name, BLK_OPEN_READ, false);
                ret = PTR_ERR_OR_ZERO(device);
                mutex_unlock(&uuid_mutex);
                break;
                break;
        case BTRFS_IOC_DEVICES_READY:
                mutex_lock(&uuid_mutex);
-               device = btrfs_scan_one_device(vol->name, BLK_OPEN_READ);
-               if (IS_ERR(device)) {
+               /*
+                * Scanning outside of mount can return NULL which would turn
+                * into 0 error code.
+                */
+               device = btrfs_scan_one_device(vol->name, BLK_OPEN_READ, false);
+               if (IS_ERR_OR_NULL(device)) {
                        mutex_unlock(&uuid_mutex);
                        ret = PTR_ERR(device);
                        break;
 
 {
        struct btrfs_fs_devices *fs_devices, *tmp_fs_devices;
        struct btrfs_device *device, *tmp_device;
-       int ret = 0;
+       int ret;
+       bool freed = false;
 
        lockdep_assert_held(&uuid_mutex);
 
-       if (devt)
-               ret = -ENOENT;
-
+       /* Return good status if there is no instance of devt. */
+       ret = 0;
        list_for_each_entry_safe(fs_devices, tmp_fs_devices, &fs_uuids, fs_list) {
 
                mutex_lock(&fs_devices->device_list_mutex);
                        if (devt && devt != device->devt)
                                continue;
                        if (fs_devices->opened) {
-                               /* for an already deleted device return 0 */
-                               if (devt && ret != 0)
+                               if (devt)
                                        ret = -EBUSY;
                                break;
                        }
                        list_del(&device->dev_list);
                        btrfs_free_device(device);
 
-                       ret = 0;
+                       freed = true;
                }
                mutex_unlock(&fs_devices->device_list_mutex);
 
                }
        }
 
+       /* If there is at least one freed device return 0. */
+       if (freed)
+               return 0;
+
        return ret;
 }
 
 /*
  * Look for a btrfs signature on a device. This may be called out of the mount path
  * and we are not allowed to call set_blocksize during the scan. The superblock
- * is read via pagecache
+ * is read via pagecache.
+ *
+ * With @mount_arg_dev it's a scan during mount time that will always register
+ * the device or return an error. Multi-device and seeding devices are registered
+ * in both cases.
  */
-struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags)
+struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,
+                                          bool mount_arg_dev)
 {
        struct btrfs_super_block *disk_super;
        bool new_device_added = false;
                goto error_bdev_put;
        }
 
+       if (!mount_arg_dev && btrfs_super_num_devices(disk_super) == 1 &&
+           !(btrfs_super_flags(disk_super) & BTRFS_SUPER_FLAG_SEEDING)) {
+               dev_t devt;
+
+               ret = lookup_bdev(path, &devt);
+               if (ret)
+                       btrfs_warn(NULL, "lookup bdev failed for path %s: %d",
+                                  path, ret);
+               else
+                       btrfs_free_stale_devices(devt, NULL);
+
+               pr_debug("BTRFS: skip registering single non-seed device %s\n", path);
+               device = NULL;
+               goto free_disk_super;
+       }
+
        device = device_list_add(path, disk_super, &new_device_added);
        if (!IS_ERR(device) && new_device_added)
                btrfs_free_stale_devices(device->devt, device);
 
+free_disk_super:
        btrfs_release_disk_super(disk_super);
 
 error_bdev_put:
 
 void btrfs_mapping_tree_free(struct extent_map_tree *tree);
 int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
                       blk_mode_t flags, void *holder);
-struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags);
+struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,
+                                          bool mount_arg_dev);
 int btrfs_forget_devices(dev_t devt);
 void btrfs_close_devices(struct btrfs_fs_devices *fs_devices);
 void btrfs_free_extra_devids(struct btrfs_fs_devices *fs_devices);