mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-11-20 08:38:24 +08:00
Btrfs: Add new ioctl to add devices
Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
8e7bf94fd5
commit
788f20eb5a
@ -551,6 +551,8 @@ struct btrfs_fs_info {
|
|||||||
u64 data_alloc_profile;
|
u64 data_alloc_profile;
|
||||||
u64 metadata_alloc_profile;
|
u64 metadata_alloc_profile;
|
||||||
u64 system_alloc_profile;
|
u64 system_alloc_profile;
|
||||||
|
|
||||||
|
void *bdev_holder;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3070,6 +3070,27 @@ static int btrfs_ioctl_defrag(struct file *file)
|
|||||||
return 0;
|
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
|
long btrfs_ioctl(struct file *file, unsigned int
|
||||||
cmd, unsigned long arg)
|
cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
@ -3082,6 +3103,8 @@ long btrfs_ioctl(struct file *file, unsigned int
|
|||||||
return btrfs_ioctl_defrag(file);
|
return btrfs_ioctl_defrag(file);
|
||||||
case BTRFS_IOC_RESIZE:
|
case BTRFS_IOC_RESIZE:
|
||||||
return btrfs_ioctl_resize(root, (void __user *)arg);
|
return btrfs_ioctl_resize(root, (void __user *)arg);
|
||||||
|
case BTRFS_IOC_ADD_DEV:
|
||||||
|
return btrfs_ioctl_add_dev(root, (void __user *)arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
|
@ -36,4 +36,10 @@ struct btrfs_ioctl_vol_args {
|
|||||||
struct btrfs_ioctl_vol_args)
|
struct btrfs_ioctl_vol_args)
|
||||||
#define BTRFS_IOC_SCAN_DEV _IOW(BTRFS_IOCTL_MAGIC, 4, \
|
#define BTRFS_IOC_SCAN_DEV _IOW(BTRFS_IOCTL_MAGIC, 4, \
|
||||||
struct btrfs_ioctl_vol_args)
|
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
|
#endif
|
||||||
|
@ -388,6 +388,7 @@ int btrfs_get_sb_bdev(struct file_system_type *fs_type,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
btrfs_sb(s)->fs_info->bdev_holder = fs_type;
|
||||||
s->s_flags |= MS_ACTIVE;
|
s->s_flags |= MS_ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <linux/bio.h>
|
#include <linux/bio.h>
|
||||||
#include <linux/buffer_head.h>
|
#include <linux/buffer_head.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
|
#include <linux/random.h>
|
||||||
#include <asm/div64.h>
|
#include <asm/div64.h>
|
||||||
#include "ctree.h"
|
#include "ctree.h"
|
||||||
#include "extent_map.h"
|
#include "extent_map.h"
|
||||||
@ -592,6 +593,80 @@ out:
|
|||||||
return ret;
|
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,
|
int btrfs_update_device(struct btrfs_trans_handle *trans,
|
||||||
struct btrfs_device *device)
|
struct btrfs_device *device)
|
||||||
{
|
{
|
||||||
|
@ -133,4 +133,5 @@ int btrfs_grow_device(struct btrfs_trans_handle *trans,
|
|||||||
struct btrfs_device *btrfs_find_device(struct btrfs_root *root, u64 devid,
|
struct btrfs_device *btrfs_find_device(struct btrfs_root *root, u64 devid,
|
||||||
u8 *uuid);
|
u8 *uuid);
|
||||||
int btrfs_shrink_device(struct btrfs_device *device, u64 new_size);
|
int btrfs_shrink_device(struct btrfs_device *device, u64 new_size);
|
||||||
|
int btrfs_init_new_device(struct btrfs_root *root, char *path);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user