diff options
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 35 |
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 | /* | 318 | static 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 */ | ||
326 | static 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 | ||
333 | static 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 | ||
338 | int btrfs_get_sb_bdev(struct file_system_type *fs_type, | 326 | 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, | |||
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 | ||