diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-03-24 15:02:07 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:01 -0400 |
commit | 8a4b83cc8bd75fca29ac68615896d9e92820e7c2 (patch) | |
tree | b7f99cf53c322665b78cca10742cc734ad070729 /fs/btrfs/super.c | |
parent | 239b14b32dc39232ebf9cce29ff77c4c564355fd (diff) |
Btrfs: Add support for device scanning and detection ioctls
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 67ed216df475..9624923a33dc 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include "ioctl.h" | 44 | #include "ioctl.h" |
45 | #include "print-tree.h" | 45 | #include "print-tree.h" |
46 | #include "xattr.h" | 46 | #include "xattr.h" |
47 | #include "volumes.h" | ||
47 | 48 | ||
48 | #define BTRFS_SUPER_MAGIC 0x9123683E | 49 | #define BTRFS_SUPER_MAGIC 0x9123683E |
49 | 50 | ||
@@ -216,7 +217,9 @@ static int parse_options (char * options, | |||
216 | return 1; | 217 | return 1; |
217 | } | 218 | } |
218 | 219 | ||
219 | static int btrfs_fill_super(struct super_block * sb, void * data, int silent) | 220 | static int btrfs_fill_super(struct super_block * sb, |
221 | struct btrfs_fs_devices *fs_devices, | ||
222 | void * data, int silent) | ||
220 | { | 223 | { |
221 | struct inode * inode; | 224 | struct inode * inode; |
222 | struct dentry * root_dentry; | 225 | struct dentry * root_dentry; |
@@ -231,7 +234,7 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent) | |||
231 | sb->s_xattr = btrfs_xattr_handlers; | 234 | sb->s_xattr = btrfs_xattr_handlers; |
232 | sb->s_time_gran = 1; | 235 | sb->s_time_gran = 1; |
233 | 236 | ||
234 | tree_root = open_ctree(sb); | 237 | tree_root = open_ctree(sb, fs_devices); |
235 | 238 | ||
236 | if (!tree_root || IS_ERR(tree_root)) { | 239 | if (!tree_root || IS_ERR(tree_root)) { |
237 | printk("btrfs: open_ctree failed\n"); | 240 | printk("btrfs: open_ctree failed\n"); |
@@ -334,18 +337,23 @@ static int test_bdev_super(struct super_block *s, void *data) | |||
334 | 337 | ||
335 | int btrfs_get_sb_bdev(struct file_system_type *fs_type, | 338 | int btrfs_get_sb_bdev(struct file_system_type *fs_type, |
336 | int flags, const char *dev_name, void *data, | 339 | int flags, const char *dev_name, void *data, |
337 | int (*fill_super)(struct super_block *, void *, int), | ||
338 | struct vfsmount *mnt, const char *subvol) | 340 | struct vfsmount *mnt, const char *subvol) |
339 | { | 341 | { |
340 | struct block_device *bdev = NULL; | 342 | struct block_device *bdev = NULL; |
341 | struct super_block *s; | 343 | struct super_block *s; |
342 | struct dentry *root; | 344 | struct dentry *root; |
345 | struct btrfs_fs_devices *fs_devices = NULL; | ||
343 | int error = 0; | 346 | int error = 0; |
344 | 347 | ||
345 | bdev = open_bdev_excl(dev_name, flags, fs_type); | 348 | error = btrfs_scan_one_device(dev_name, flags, fs_type, &fs_devices); |
346 | if (IS_ERR(bdev)) | 349 | if (error) |
347 | return PTR_ERR(bdev); | 350 | return error; |
348 | 351 | ||
352 | error = btrfs_open_devices(fs_devices, flags, fs_type); | ||
353 | if (error) | ||
354 | return error; | ||
355 | |||
356 | bdev = fs_devices->lowest_bdev; | ||
349 | /* | 357 | /* |
350 | * once the super is inserted into the list by sget, s_umount | 358 | * once the super is inserted into the list by sget, s_umount |
351 | * will protect the lockfs code from trying to start a snapshot | 359 | * will protect the lockfs code from trying to start a snapshot |
@@ -372,7 +380,8 @@ int btrfs_get_sb_bdev(struct file_system_type *fs_type, | |||
372 | s->s_flags = flags; | 380 | s->s_flags = flags; |
373 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); | 381 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); |
374 | sb_set_blocksize(s, block_size(bdev)); | 382 | sb_set_blocksize(s, block_size(bdev)); |
375 | error = fill_super(s, data, flags & MS_SILENT ? 1 : 0); | 383 | error = btrfs_fill_super(s, fs_devices, data, |
384 | flags & MS_SILENT ? 1 : 0); | ||
376 | if (error) { | 385 | if (error) { |
377 | up_write(&s->s_umount); | 386 | up_write(&s->s_umount); |
378 | deactivate_super(s); | 387 | deactivate_super(s); |
@@ -408,7 +417,7 @@ int btrfs_get_sb_bdev(struct file_system_type *fs_type, | |||
408 | error_s: | 417 | error_s: |
409 | error = PTR_ERR(s); | 418 | error = PTR_ERR(s); |
410 | error_bdev: | 419 | error_bdev: |
411 | close_bdev_excl(bdev); | 420 | btrfs_close_devices(fs_devices); |
412 | error: | 421 | error: |
413 | return error; | 422 | return error; |
414 | } | 423 | } |
@@ -421,8 +430,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, | |||
421 | char *subvol_name = NULL; | 430 | char *subvol_name = NULL; |
422 | 431 | ||
423 | parse_options((char *)data, NULL, &subvol_name); | 432 | parse_options((char *)data, NULL, &subvol_name); |
424 | ret = btrfs_get_sb_bdev(fs_type, flags, dev_name, data, | 433 | ret = btrfs_get_sb_bdev(fs_type, flags, dev_name, data, mnt, |
425 | btrfs_fill_super, mnt, | ||
426 | subvol_name ? subvol_name : "default"); | 434 | subvol_name ? subvol_name : "default"); |
427 | if (subvol_name) | 435 | if (subvol_name) |
428 | kfree(subvol_name); | 436 | kfree(subvol_name); |
@@ -445,13 +453,6 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
445 | return 0; | 453 | return 0; |
446 | } | 454 | } |
447 | 455 | ||
448 | static long btrfs_control_ioctl(struct file *file, unsigned int cmd, | ||
449 | unsigned long arg) | ||
450 | { | ||
451 | printk("btrfs control ioctl %d\n", cmd); | ||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | static struct file_system_type btrfs_fs_type = { | 456 | static struct file_system_type btrfs_fs_type = { |
456 | .owner = THIS_MODULE, | 457 | .owner = THIS_MODULE, |
457 | .name = "btrfs", | 458 | .name = "btrfs", |
@@ -460,6 +461,31 @@ static struct file_system_type btrfs_fs_type = { | |||
460 | .fs_flags = FS_REQUIRES_DEV, | 461 | .fs_flags = FS_REQUIRES_DEV, |
461 | }; | 462 | }; |
462 | 463 | ||
464 | static long btrfs_control_ioctl(struct file *file, unsigned int cmd, | ||
465 | unsigned long arg) | ||
466 | { | ||
467 | struct btrfs_ioctl_vol_args *vol; | ||
468 | struct btrfs_fs_devices *fs_devices; | ||
469 | int ret; | ||
470 | int len; | ||
471 | |||
472 | vol = kmalloc(sizeof(*vol), GFP_KERNEL); | ||
473 | if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) { | ||
474 | ret = -EFAULT; | ||
475 | goto out; | ||
476 | } | ||
477 | len = strnlen(vol->name, BTRFS_PATH_NAME_MAX); | ||
478 | switch (cmd) { | ||
479 | case BTRFS_IOC_SCAN_DEV: | ||
480 | ret = btrfs_scan_one_device(vol->name, MS_RDONLY, | ||
481 | &btrfs_fs_type, &fs_devices); | ||
482 | break; | ||
483 | } | ||
484 | out: | ||
485 | kfree(vol); | ||
486 | return 0; | ||
487 | } | ||
488 | |||
463 | static void btrfs_write_super_lockfs(struct super_block *sb) | 489 | static void btrfs_write_super_lockfs(struct super_block *sb) |
464 | { | 490 | { |
465 | struct btrfs_root *root = btrfs_sb(sb); | 491 | struct btrfs_root *root = btrfs_sb(sb); |
@@ -567,6 +593,7 @@ static void __exit exit_btrfs_fs(void) | |||
567 | btrfs_interface_exit(); | 593 | btrfs_interface_exit(); |
568 | unregister_filesystem(&btrfs_fs_type); | 594 | unregister_filesystem(&btrfs_fs_type); |
569 | btrfs_exit_sysfs(); | 595 | btrfs_exit_sysfs(); |
596 | btrfs_cleanup_fs_uuids(); | ||
570 | } | 597 | } |
571 | 598 | ||
572 | module_init(init_btrfs_fs) | 599 | module_init(init_btrfs_fs) |