Loading fs/btrfs/ctree.h +2 −0 Original line number Diff line number Diff line Loading @@ -551,6 +551,8 @@ struct btrfs_fs_info { u64 data_alloc_profile; u64 metadata_alloc_profile; u64 system_alloc_profile; void *bdev_holder; }; /* Loading fs/btrfs/inode.c +23 −0 Original line number Diff line number Diff line Loading @@ -3070,6 +3070,27 @@ static int btrfs_ioctl_defrag(struct file *file) return 0; } long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg) { struct btrfs_ioctl_vol_args *vol_args; int ret; vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); if (!vol_args) return -ENOMEM; if (copy_from_user(vol_args, arg, sizeof(*vol_args))) { ret = -EFAULT; goto out; } ret = btrfs_init_new_device(root, vol_args->name); out: kfree(vol_args); return ret; } long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { Loading @@ -3082,6 +3103,8 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_defrag(file); case BTRFS_IOC_RESIZE: return btrfs_ioctl_resize(root, (void __user *)arg); case BTRFS_IOC_ADD_DEV: return btrfs_ioctl_add_dev(root, (void __user *)arg); } return -ENOTTY; Loading fs/btrfs/ioctl.h +6 −0 Original line number Diff line number Diff line Loading @@ -36,4 +36,10 @@ struct btrfs_ioctl_vol_args { struct btrfs_ioctl_vol_args) #define BTRFS_IOC_SCAN_DEV _IOW(BTRFS_IOCTL_MAGIC, 4, \ struct btrfs_ioctl_vol_args) #define BTRFS_IOC_ADD_DEV _IOW(BTRFS_IOCTL_MAGIC, 10, \ struct btrfs_ioctl_vol_args) #define BTRFS_IOC_RM_DEV _IOW(BTRFS_IOCTL_MAGIC, 11, \ struct btrfs_ioctl_vol_args) #define BTRFS_IOC_BALANCE _IOW(BTRFS_IOCTL_MAGIC, 12, \ struct btrfs_ioctl_vol_args) #endif fs/btrfs/super.c +1 −0 Original line number Diff line number Diff line Loading @@ -388,6 +388,7 @@ int btrfs_get_sb_bdev(struct file_system_type *fs_type, goto error; } btrfs_sb(s)->fs_info->bdev_holder = fs_type; s->s_flags |= MS_ACTIVE; } Loading fs/btrfs/volumes.c +75 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <linux/bio.h> #include <linux/buffer_head.h> #include <linux/blkdev.h> #include <linux/random.h> #include <asm/div64.h> #include "ctree.h" #include "extent_map.h" Loading Loading @@ -592,6 +593,80 @@ int btrfs_add_device(struct btrfs_trans_handle *trans, return ret; } int btrfs_init_new_device(struct btrfs_root *root, char *device_path) { struct btrfs_trans_handle *trans; struct btrfs_device *device; struct block_device *bdev; struct list_head *cur; struct list_head *devices; u64 total_bytes; int ret = 0; bdev = open_bdev_excl(device_path, 0, root->fs_info->bdev_holder); if (!bdev) { return -EIO; } mutex_lock(&root->fs_info->fs_mutex); trans = btrfs_start_transaction(root, 1); devices = &root->fs_info->fs_devices->devices; list_for_each(cur, devices) { device = list_entry(cur, struct btrfs_device, dev_list); if (device->bdev == bdev) { ret = -EEXIST; goto out; } } device = kzalloc(sizeof(*device), GFP_NOFS); if (!device) { /* we can safely leave the fs_devices entry around */ ret = -ENOMEM; goto out_close_bdev; } device->barriers = 1; generate_random_uuid(device->uuid); spin_lock_init(&device->io_lock); device->name = kstrdup(device_path, GFP_NOFS); if (!device->name) { kfree(device); goto out_close_bdev; } device->io_width = root->sectorsize; device->io_align = root->sectorsize; device->sector_size = root->sectorsize; device->total_bytes = i_size_read(bdev->bd_inode); device->dev_root = root->fs_info->dev_root; device->bdev = bdev; ret = btrfs_add_device(trans, root, device); if (ret) goto out_close_bdev; total_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy); btrfs_set_super_total_bytes(&root->fs_info->super_copy, total_bytes + device->total_bytes); total_bytes = btrfs_super_num_devices(&root->fs_info->super_copy); btrfs_set_super_num_devices(&root->fs_info->super_copy, total_bytes + 1); list_add(&device->dev_list, &root->fs_info->fs_devices->devices); list_add(&device->dev_alloc_list, &root->fs_info->fs_devices->alloc_list); root->fs_info->fs_devices->num_devices++; out: btrfs_end_transaction(trans, root); mutex_unlock(&root->fs_info->fs_mutex); return ret; out_close_bdev: close_bdev_excl(bdev); goto out; } int btrfs_update_device(struct btrfs_trans_handle *trans, struct btrfs_device *device) { Loading Loading
fs/btrfs/ctree.h +2 −0 Original line number Diff line number Diff line Loading @@ -551,6 +551,8 @@ struct btrfs_fs_info { u64 data_alloc_profile; u64 metadata_alloc_profile; u64 system_alloc_profile; void *bdev_holder; }; /* Loading
fs/btrfs/inode.c +23 −0 Original line number Diff line number Diff line Loading @@ -3070,6 +3070,27 @@ static int btrfs_ioctl_defrag(struct file *file) return 0; } long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg) { struct btrfs_ioctl_vol_args *vol_args; int ret; vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); if (!vol_args) return -ENOMEM; if (copy_from_user(vol_args, arg, sizeof(*vol_args))) { ret = -EFAULT; goto out; } ret = btrfs_init_new_device(root, vol_args->name); out: kfree(vol_args); return ret; } long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { Loading @@ -3082,6 +3103,8 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_defrag(file); case BTRFS_IOC_RESIZE: return btrfs_ioctl_resize(root, (void __user *)arg); case BTRFS_IOC_ADD_DEV: return btrfs_ioctl_add_dev(root, (void __user *)arg); } return -ENOTTY; Loading
fs/btrfs/ioctl.h +6 −0 Original line number Diff line number Diff line Loading @@ -36,4 +36,10 @@ struct btrfs_ioctl_vol_args { struct btrfs_ioctl_vol_args) #define BTRFS_IOC_SCAN_DEV _IOW(BTRFS_IOCTL_MAGIC, 4, \ struct btrfs_ioctl_vol_args) #define BTRFS_IOC_ADD_DEV _IOW(BTRFS_IOCTL_MAGIC, 10, \ struct btrfs_ioctl_vol_args) #define BTRFS_IOC_RM_DEV _IOW(BTRFS_IOCTL_MAGIC, 11, \ struct btrfs_ioctl_vol_args) #define BTRFS_IOC_BALANCE _IOW(BTRFS_IOCTL_MAGIC, 12, \ struct btrfs_ioctl_vol_args) #endif
fs/btrfs/super.c +1 −0 Original line number Diff line number Diff line Loading @@ -388,6 +388,7 @@ int btrfs_get_sb_bdev(struct file_system_type *fs_type, goto error; } btrfs_sb(s)->fs_info->bdev_holder = fs_type; s->s_flags |= MS_ACTIVE; } Loading
fs/btrfs/volumes.c +75 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <linux/bio.h> #include <linux/buffer_head.h> #include <linux/blkdev.h> #include <linux/random.h> #include <asm/div64.h> #include "ctree.h" #include "extent_map.h" Loading Loading @@ -592,6 +593,80 @@ int btrfs_add_device(struct btrfs_trans_handle *trans, return ret; } int btrfs_init_new_device(struct btrfs_root *root, char *device_path) { struct btrfs_trans_handle *trans; struct btrfs_device *device; struct block_device *bdev; struct list_head *cur; struct list_head *devices; u64 total_bytes; int ret = 0; bdev = open_bdev_excl(device_path, 0, root->fs_info->bdev_holder); if (!bdev) { return -EIO; } mutex_lock(&root->fs_info->fs_mutex); trans = btrfs_start_transaction(root, 1); devices = &root->fs_info->fs_devices->devices; list_for_each(cur, devices) { device = list_entry(cur, struct btrfs_device, dev_list); if (device->bdev == bdev) { ret = -EEXIST; goto out; } } device = kzalloc(sizeof(*device), GFP_NOFS); if (!device) { /* we can safely leave the fs_devices entry around */ ret = -ENOMEM; goto out_close_bdev; } device->barriers = 1; generate_random_uuid(device->uuid); spin_lock_init(&device->io_lock); device->name = kstrdup(device_path, GFP_NOFS); if (!device->name) { kfree(device); goto out_close_bdev; } device->io_width = root->sectorsize; device->io_align = root->sectorsize; device->sector_size = root->sectorsize; device->total_bytes = i_size_read(bdev->bd_inode); device->dev_root = root->fs_info->dev_root; device->bdev = bdev; ret = btrfs_add_device(trans, root, device); if (ret) goto out_close_bdev; total_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy); btrfs_set_super_total_bytes(&root->fs_info->super_copy, total_bytes + device->total_bytes); total_bytes = btrfs_super_num_devices(&root->fs_info->super_copy); btrfs_set_super_num_devices(&root->fs_info->super_copy, total_bytes + 1); list_add(&device->dev_list, &root->fs_info->fs_devices->devices); list_add(&device->dev_alloc_list, &root->fs_info->fs_devices->alloc_list); root->fs_info->fs_devices->num_devices++; out: btrfs_end_transaction(trans, root); mutex_unlock(&root->fs_info->fs_mutex); return ret; out_close_bdev: close_bdev_excl(bdev); goto out; } int btrfs_update_device(struct btrfs_trans_handle *trans, struct btrfs_device *device) { Loading