[PATCH 15/17] btrfs: store pointer to superblock in bd_super

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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: linux-fsdevel@xxxxxxxxxxxxxxx
Cc: linux-btrfs@xxxxxxxxxxxxxxx
Cc: Josef Bacik <jbacik@xxxxxxxxxxxx>
Cc: Eric Sandeen <sandeen@xxxxxxxxxx>
Cc: Christoph Hellwig <hch@xxxxxxxxxxxxx>
Cc: Dave Chinner <dchinner@xxxxxxxxxx>
Cc: Jan Kara <jack@xxxxxxx>
Cc: Luiz Capitulino <lcapitulino@xxxxxxxxxx>
Cc: Chris Mason <chris.mason@xxxxxxxxxxxx>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@xxxxxxxxxxxxx>
---

diff -urNp linux-3.8-rc1-orig/fs/btrfs/super.c linux-3.8-rc1/fs/btrfs/super.c
--- linux-3.8-rc1-orig/fs/btrfs/super.c	2012-12-25 10:27:41.146737000 +0900
+++ linux-3.8-rc1/fs/btrfs/super.c	2012-12-25 16:38:35.880018000 +0900
@@ -854,6 +854,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:
@@ -1507,6 +1508,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);
 }
diff -urNp linux-3.8-rc1-orig/fs/btrfs/volumes.c linux-3.8-rc1/fs/btrfs/volumes.c
--- linux-3.8-rc1-orig/fs/btrfs/volumes.c	2012-12-25 10:27:41.150737000 +0900
+++ linux-3.8-rc1/fs/btrfs/volumes.c	2012-12-25 16:38:35.880018000 +0900
@@ -44,6 +44,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);
@@ -1497,6 +1499,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--;
@@ -1819,6 +1822,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;
@@ -1984,7 +2004,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)
@@ -1994,13 +2014,17 @@ int btrfs_init_new_device(struct btrfs_r
 				    "using the \"btrfs balance\" command.");
 		trans = btrfs_attach_transaction(root);
 		if (IS_ERR(trans)) {
-			if (PTR_ERR(trans) == -ENOENT)
-				return 0;
-			return PTR_ERR(trans);
+			ret = PTR_ERR(trans) == -ENOENT ? 0 : PTR_ERR(trans);
+			goto out;
 		}
 		ret = btrfs_commit_transaction(trans, root);
 	}
-
+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:
diff -urNp linux-3.8-rc1-orig/fs/btrfs/volumes.h linux-3.8-rc1/fs/btrfs/volumes.h
--- linux-3.8-rc1-orig/fs/btrfs/volumes.h	2012-12-25 10:27:41.166737000 +0900
+++ linux-3.8-rc1/fs/btrfs/volumes.h	2012-12-25 16:38:35.884018000 +0900
@@ -295,6 +295,8 @@ int btrfs_grow_device(struct btrfs_trans
 struct btrfs_device *btrfs_find_device(struct btrfs_fs_info *fs_info, 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_init_dev_replace_tgtdev(struct btrfs_root *root, char *device_path,
 				  struct btrfs_device **device_out);


--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux