diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-04-28 15:29:42 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:02 -0400 |
commit | 788f20eb5affef584e75ea84bb80a4c3352a2c0e (patch) | |
tree | 8d803c865e8f0dd7fa14bdd1f2157b4c8649baa9 /fs/btrfs/volumes.c | |
parent | 8e7bf94fd5f44fa585e29fbe6a1bfabc04aea7cf (diff) |
Btrfs: Add new ioctl to add devices
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r-- | fs/btrfs/volumes.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index a2c56de1548a..b93c15aa17db 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/bio.h> | 19 | #include <linux/bio.h> |
20 | #include <linux/buffer_head.h> | 20 | #include <linux/buffer_head.h> |
21 | #include <linux/blkdev.h> | 21 | #include <linux/blkdev.h> |
22 | #include <linux/random.h> | ||
22 | #include <asm/div64.h> | 23 | #include <asm/div64.h> |
23 | #include "ctree.h" | 24 | #include "ctree.h" |
24 | #include "extent_map.h" | 25 | #include "extent_map.h" |
@@ -592,6 +593,80 @@ out: | |||
592 | return ret; | 593 | return ret; |
593 | } | 594 | } |
594 | 595 | ||
596 | int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | ||
597 | { | ||
598 | struct btrfs_trans_handle *trans; | ||
599 | struct btrfs_device *device; | ||
600 | struct block_device *bdev; | ||
601 | struct list_head *cur; | ||
602 | struct list_head *devices; | ||
603 | u64 total_bytes; | ||
604 | int ret = 0; | ||
605 | |||
606 | |||
607 | bdev = open_bdev_excl(device_path, 0, root->fs_info->bdev_holder); | ||
608 | if (!bdev) { | ||
609 | return -EIO; | ||
610 | } | ||
611 | mutex_lock(&root->fs_info->fs_mutex); | ||
612 | trans = btrfs_start_transaction(root, 1); | ||
613 | devices = &root->fs_info->fs_devices->devices; | ||
614 | list_for_each(cur, devices) { | ||
615 | device = list_entry(cur, struct btrfs_device, dev_list); | ||
616 | if (device->bdev == bdev) { | ||
617 | ret = -EEXIST; | ||
618 | goto out; | ||
619 | } | ||
620 | } | ||
621 | |||
622 | device = kzalloc(sizeof(*device), GFP_NOFS); | ||
623 | if (!device) { | ||
624 | /* we can safely leave the fs_devices entry around */ | ||
625 | ret = -ENOMEM; | ||
626 | goto out_close_bdev; | ||
627 | } | ||
628 | |||
629 | device->barriers = 1; | ||
630 | generate_random_uuid(device->uuid); | ||
631 | spin_lock_init(&device->io_lock); | ||
632 | device->name = kstrdup(device_path, GFP_NOFS); | ||
633 | if (!device->name) { | ||
634 | kfree(device); | ||
635 | goto out_close_bdev; | ||
636 | } | ||
637 | device->io_width = root->sectorsize; | ||
638 | device->io_align = root->sectorsize; | ||
639 | device->sector_size = root->sectorsize; | ||
640 | device->total_bytes = i_size_read(bdev->bd_inode); | ||
641 | device->dev_root = root->fs_info->dev_root; | ||
642 | device->bdev = bdev; | ||
643 | |||
644 | ret = btrfs_add_device(trans, root, device); | ||
645 | if (ret) | ||
646 | goto out_close_bdev; | ||
647 | |||
648 | total_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy); | ||
649 | btrfs_set_super_total_bytes(&root->fs_info->super_copy, | ||
650 | total_bytes + device->total_bytes); | ||
651 | |||
652 | total_bytes = btrfs_super_num_devices(&root->fs_info->super_copy); | ||
653 | btrfs_set_super_num_devices(&root->fs_info->super_copy, | ||
654 | total_bytes + 1); | ||
655 | |||
656 | list_add(&device->dev_list, &root->fs_info->fs_devices->devices); | ||
657 | list_add(&device->dev_alloc_list, | ||
658 | &root->fs_info->fs_devices->alloc_list); | ||
659 | root->fs_info->fs_devices->num_devices++; | ||
660 | out: | ||
661 | btrfs_end_transaction(trans, root); | ||
662 | mutex_unlock(&root->fs_info->fs_mutex); | ||
663 | return ret; | ||
664 | |||
665 | out_close_bdev: | ||
666 | close_bdev_excl(bdev); | ||
667 | goto out; | ||
668 | } | ||
669 | |||
595 | int btrfs_update_device(struct btrfs_trans_handle *trans, | 670 | int btrfs_update_device(struct btrfs_trans_handle *trans, |
596 | struct btrfs_device *device) | 671 | struct btrfs_device *device) |
597 | { | 672 | { |