Btrfs: Add new ioctl to add devices

Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
Chris Mason
2008-04-28 15:29:42 -04:00
parent 8e7bf94fd5
commit 788f20eb5a
6 changed files with 108 additions and 0 deletions

View File

@@ -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"
@@ -592,6 +593,80 @@ out:
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)
{