aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
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