@@ -826,6 +826,7 @@ static int btrfs_fill_super(struct super
save_mount_options(sb, data);
cleancache_init_fs(sb);
sb->s_flags |= MS_ACTIVE;
+ btrfs_set_super_devices(fs_devices, sb);
return 0;
fail_close:
@@ -1459,6 +1460,7 @@ static int btrfs_statfs(struct dentry *d
static void btrfs_kill_super(struct super_block *sb)
{
struct btrfs_fs_info *fs_info = btrfs_sb(sb);
+ btrfs_set_super_devices(fs_info->fs_devices, NULL);
kill_anon_super(sb);
free_fs_info(fs_info);
}
@@ -43,6 +43,8 @@ static int init_first_rw_device(struct b
static int btrfs_relocate_sys_chunks(struct btrfs_root *root);
static void __btrfs_reset_dev_stats(struct btrfs_device *dev);
static void btrfs_dev_stat_print_on_load(struct btrfs_device *device);
+static void btrfs_set_super_device(struct btrfs_device *device,
+ struct super_block *sb);
static DEFINE_MUTEX(uuid_mutex);
static LIST_HEAD(fs_uuids);
@@ -1435,6 +1437,7 @@ int btrfs_rm_device(struct btrfs_root *r
cur_devices = device->fs_devices;
mutex_lock(&root->fs_info->fs_devices->device_list_mutex);
+ btrfs_set_super_device(device, NULL);
list_del_rcu(&device->dev_list);
device->fs_devices->num_devices--;
@@ -1645,6 +1648,23 @@ error:
return ret;
}
+static void btrfs_set_super_device(struct btrfs_device *device,
+ struct super_block *sb)
+{
+ if (device->bdev)
+ device->bdev->bd_super = sb;
+}
+
+void btrfs_set_super_devices(struct btrfs_fs_devices *fs_devices,
+ struct super_block *sb)
+{
+ struct btrfs_device *device;
+ mutex_lock(&fs_devices->device_list_mutex);
+ list_for_each_entry(device, &fs_devices->devices, dev_list)
+ btrfs_set_super_device(device, sb);
+ mutex_unlock(&fs_devices->device_list_mutex);
+}
+
int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
{
struct request_queue *q;
@@ -1800,7 +1820,7 @@ int btrfs_init_new_device(struct btrfs_r
up_write(&sb->s_umount);
if (ret) /* transaction commit */
- return ret;
+ goto out;
ret = btrfs_relocate_sys_chunks(root);
if (ret < 0)
@@ -1809,7 +1829,12 @@ int btrfs_init_new_device(struct btrfs_r
"device initialization. This can be fixed "
"using the \"btrfs balance\" command.");
}
-
+out:
+ /*
+ * The device was successfully added to the filesystem, so we store a
+ * pointer to the superblock in ->bd_super.
+ */
+ btrfs_set_super_device(device, sb);
return ret;
error_trans:
@@ -279,6 +279,8 @@ int btrfs_grow_device(struct btrfs_trans
struct btrfs_device *btrfs_find_device(struct btrfs_root *root, u64 devid,
u8 *uuid, u8 *fsid);
int btrfs_shrink_device(struct btrfs_device *device, u64 new_size);
+void btrfs_set_super_devices(struct btrfs_fs_devices *fs_devices,
+ struct super_block *sb);
int btrfs_init_new_device(struct btrfs_root *root, char *path);
int btrfs_balance(struct btrfs_balance_control *bctl,
struct btrfs_ioctl_balance_args *bargs);
Subject: btrfs: store pointer to superblock in bd_super This is needed to get get_active_super and, by extension, thaw_bdev initiated freezes working. Thanks go to Josef Bacik and Christoph Hellwig for initiating this effort to fix btrfs and for suggesting the solution implemented here, respectively. Cc: Josef Bacik <jbacik@fusionio.com> Cc: Christoph Hellwig <hch@infradead.org> Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp> --- -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html