aboutsummaryrefslogtreecommitdiffstats
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 7153dfaa3404..020e5a83e31f 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -315,24 +315,12 @@ static void btrfs_write_super(struct super_block *sb)
315 sb->s_dirt = 0; 315 sb->s_dirt = 0;
316} 316}
317 317
318/* 318static int btrfs_test_super(struct super_block *s, void *data)
319 * This is almost a copy of get_sb_bdev in fs/super.c.
320 * We need the local copy to allow direct mounting of
321 * subvolumes, but this could be easily integrated back
322 * into the generic version. --hch
323 */
324
325/* start copy & paste */
326static int set_bdev_super(struct super_block *s, void *data)
327{ 319{
328 s->s_bdev = data; 320 struct btrfs_fs_devices *test_fs_devices = data;
329 s->s_dev = s->s_bdev->bd_dev; 321 struct btrfs_root *root = btrfs_sb(s);
330 return 0;
331}
332 322
333static int test_bdev_super(struct super_block *s, void *data) 323 return root->fs_info->fs_devices == test_fs_devices;
334{
335 return (void *)s->s_bdev == data;
336} 324}
337 325
338int btrfs_get_sb_bdev(struct file_system_type *fs_type, 326int 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,
354 return error; 342 return error;
355 343
356 bdev = fs_devices->lowest_bdev; 344 bdev = fs_devices->lowest_bdev;
357 /* 345 btrfs_lock_volumes();
358 * once the super is inserted into the list by sget, s_umount 346 s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices);
359 * will protect the lockfs code from trying to start a snapshot 347 btrfs_unlock_volumes();
360 * while we are mounting
361 */
362 down(&bdev->bd_mount_sem);
363 s = sget(fs_type, test_bdev_super, set_bdev_super, bdev);
364 up(&bdev->bd_mount_sem);
365 if (IS_ERR(s)) 348 if (IS_ERR(s))
366 goto error_s; 349 goto error_s;
367 350
@@ -373,13 +356,11 @@ int btrfs_get_sb_bdev(struct file_system_type *fs_type,
373 goto error_bdev; 356 goto error_bdev;
374 } 357 }
375 358
376 close_bdev_excl(bdev);
377 } else { 359 } else {
378 char b[BDEVNAME_SIZE]; 360 char b[BDEVNAME_SIZE];
379 361
380 s->s_flags = flags; 362 s->s_flags = flags;
381 strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); 363 strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
382 sb_set_blocksize(s, block_size(bdev));
383 error = btrfs_fill_super(s, fs_devices, data, 364 error = btrfs_fill_super(s, fs_devices, data,
384 flags & MS_SILENT ? 1 : 0); 365 flags & MS_SILENT ? 1 : 0);
385 if (error) { 366 if (error) {
@@ -458,7 +439,7 @@ static struct file_system_type btrfs_fs_type = {
458 .owner = THIS_MODULE, 439 .owner = THIS_MODULE,
459 .name = "btrfs", 440 .name = "btrfs",
460 .get_sb = btrfs_get_sb, 441 .get_sb = btrfs_get_sb,
461 .kill_sb = kill_block_super, 442 .kill_sb = kill_anon_super,
462 .fs_flags = FS_REQUIRES_DEV, 443 .fs_flags = FS_REQUIRES_DEV,
463}; 444};
464 445