summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-05-07 11:43:44 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:02 -0400
commita061fc8da7b990faa41ca503e66faef3ecdeead0 (patch)
tree0d3b5b6e4d2164d507d9a16d5b38d373592a5c8f /fs/btrfs/super.c
parent5d9cd9ecbf40b8bd5045a3c2f1feb35db6a12266 (diff)
Btrfs: Add support for online device removal
This required a few structural changes to the code that manages bdev pointers: The VFS super block now gets an anon-bdev instead of a pointer to the lowest bdev. This allows us to avoid swapping the super block bdev pointer around at run time. The code to read in the super block no longer goes through the extent buffer interface. Things got ugly keeping the mapping constant. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c35
1 files changed, 8 insertions, 27 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 7153dfaa340..020e5a83e31 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -315,24 +315,12 @@ static void btrfs_write_super(struct super_block *sb)
sb->s_dirt = 0;
}
-/*
- * This is almost a copy of get_sb_bdev in fs/super.c.
- * We need the local copy to allow direct mounting of
- * subvolumes, but this could be easily integrated back
- * into the generic version. --hch
- */
-
-/* start copy & paste */
-static int set_bdev_super(struct super_block *s, void *data)
+static int btrfs_test_super(struct super_block *s, void *data)
{
- s->s_bdev = data;
- s->s_dev = s->s_bdev->bd_dev;
- return 0;
-}
+ struct btrfs_fs_devices *test_fs_devices = data;
+ struct btrfs_root *root = btrfs_sb(s);
-static int test_bdev_super(struct super_block *s, void *data)
-{
- return (void *)s->s_bdev == data;
+ return root->fs_info->fs_devices == test_fs_devices;
}
int btrfs_get_sb_bdev(struct file_system_type *fs_type,
@@ -354,14 +342,9 @@ int btrfs_get_sb_bdev(struct file_system_type *fs_type,
return error;
bdev = fs_devices->lowest_bdev;
- /*
- * once the super is inserted into the list by sget, s_umount
- * will protect the lockfs code from trying to start a snapshot
- * while we are mounting
- */
- down(&bdev->bd_mount_sem);
- s = sget(fs_type, test_bdev_super, set_bdev_super, bdev);
- up(&bdev->bd_mount_sem);
+ btrfs_lock_volumes();
+ s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices);
+ btrfs_unlock_volumes();
if (IS_ERR(s))
goto error_s;
@@ -373,13 +356,11 @@ int btrfs_get_sb_bdev(struct file_system_type *fs_type,
goto error_bdev;
}
- close_bdev_excl(bdev);
} else {
char b[BDEVNAME_SIZE];
s->s_flags = flags;
strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
- sb_set_blocksize(s, block_size(bdev));
error = btrfs_fill_super(s, fs_devices, data,
flags & MS_SILENT ? 1 : 0);
if (error) {
@@ -458,7 +439,7 @@ static struct file_system_type btrfs_fs_type = {
.owner = THIS_MODULE,
.name = "btrfs",
.get_sb = btrfs_get_sb,
- .kill_sb = kill_block_super,
+ .kill_sb = kill_anon_super,
.fs_flags = FS_REQUIRES_DEV,
};