X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=volumes.c;h=9ebe52a4d547f01631a4d309d4c1eca8dc3d1947;hb=4c7094e046dc7875af2e7f65eb80b256b6232fd7;hp=2e1fb4a46465e75c35988d606fe41604f7dd2fd3;hpb=8075fd4da1a5c759261413461a4bd7f9af81722c;p=platform%2Fupstream%2Fbtrfs-progs.git diff --git a/volumes.c b/volumes.c index 2e1fb4a..9ebe52a 100644 --- a/volumes.c +++ b/volumes.c @@ -30,6 +30,72 @@ #include "utils.h" #include "kernel-lib/raid56.h" +const struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES] = { + [BTRFS_RAID_RAID10] = { + .sub_stripes = 2, + .dev_stripes = 1, + .devs_max = 0, /* 0 == as many as possible */ + .devs_min = 4, + .tolerated_failures = 1, + .devs_increment = 2, + .ncopies = 2, + }, + [BTRFS_RAID_RAID1] = { + .sub_stripes = 1, + .dev_stripes = 1, + .devs_max = 2, + .devs_min = 2, + .tolerated_failures = 1, + .devs_increment = 2, + .ncopies = 2, + }, + [BTRFS_RAID_DUP] = { + .sub_stripes = 1, + .dev_stripes = 2, + .devs_max = 1, + .devs_min = 1, + .tolerated_failures = 0, + .devs_increment = 1, + .ncopies = 2, + }, + [BTRFS_RAID_RAID0] = { + .sub_stripes = 1, + .dev_stripes = 1, + .devs_max = 0, + .devs_min = 2, + .tolerated_failures = 0, + .devs_increment = 1, + .ncopies = 1, + }, + [BTRFS_RAID_SINGLE] = { + .sub_stripes = 1, + .dev_stripes = 1, + .devs_max = 1, + .devs_min = 1, + .tolerated_failures = 0, + .devs_increment = 1, + .ncopies = 1, + }, + [BTRFS_RAID_RAID5] = { + .sub_stripes = 1, + .dev_stripes = 1, + .devs_max = 0, + .devs_min = 2, + .tolerated_failures = 1, + .devs_increment = 1, + .ncopies = 2, + }, + [BTRFS_RAID_RAID6] = { + .sub_stripes = 1, + .dev_stripes = 1, + .devs_max = 0, + .devs_min = 3, + .tolerated_failures = 2, + .devs_increment = 1, + .ncopies = 3, + }, +}; + struct stripe { struct btrfs_device *dev; u64 physical; @@ -181,8 +247,8 @@ again: struct btrfs_device, dev_list); if (device->fd != -1) { if (fsync(device->fd) == -1) { - warning("fsync on device %llu failed: %s", - device->devid, strerror(errno)); + warning("fsync on device %llu failed: %m", + device->devid); ret = -errno; } if (posix_fadvise(device->fd, 0, 0, POSIX_FADV_DONTNEED)) @@ -242,8 +308,7 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices, int flags) fd = open(device->name, flags); if (fd < 0) { ret = -errno; - error("cannot open device '%s': %s", device->name, - strerror(errno)); + error("cannot open device '%s': %m", device->name); goto fail; } @@ -309,9 +374,9 @@ int btrfs_scan_one_device(int fd, const char *path, * But if we don't find suitable free space, it is used to store the size of * the max free space. */ -static int find_free_dev_extent_start(struct btrfs_trans_handle *trans, - struct btrfs_device *device, u64 num_bytes, - u64 search_start, u64 *start, u64 *len) +static int find_free_dev_extent_start(struct btrfs_device *device, + u64 num_bytes, u64 search_start, + u64 *start, u64 *len) { struct btrfs_key key; struct btrfs_root *root = device->dev_root; @@ -450,20 +515,17 @@ out: return ret; } -int find_free_dev_extent(struct btrfs_trans_handle *trans, - struct btrfs_device *device, u64 num_bytes, - u64 *start) +static int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes, + u64 *start, u64 *len) { /* FIXME use last free of some kind */ - return find_free_dev_extent_start(trans, device, - num_bytes, 0, start, NULL); + return find_free_dev_extent_start(device, num_bytes, 0, start, len); } static int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans, struct btrfs_device *device, - u64 chunk_tree, u64 chunk_objectid, - u64 chunk_offset, - u64 num_bytes, u64 *start, int convert) + u64 chunk_offset, u64 num_bytes, u64 *start, + int convert) { int ret; struct btrfs_path *path; @@ -481,8 +543,7 @@ static int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans, * is responsible to make sure it's free. */ if (!convert) { - ret = find_free_dev_extent(trans, device, num_bytes, - start); + ret = find_free_dev_extent(device, num_bytes, start, NULL); if (ret) goto err; } @@ -497,8 +558,9 @@ static int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans, leaf = path->nodes[0]; extent = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dev_extent); - btrfs_set_dev_extent_chunk_tree(leaf, extent, chunk_tree); - btrfs_set_dev_extent_chunk_objectid(leaf, extent, chunk_objectid); + btrfs_set_dev_extent_chunk_tree(leaf, extent, BTRFS_CHUNK_TREE_OBJECTID); + btrfs_set_dev_extent_chunk_objectid(leaf, extent, + BTRFS_FIRST_CHUNK_TREE_OBJECTID); btrfs_set_dev_extent_chunk_offset(leaf, extent, chunk_offset); write_extent_buffer(leaf, root->fs_info->chunk_tree_uuid, @@ -830,7 +892,7 @@ error: return ret; } -#define BTRFS_MAX_DEVS(r) ((BTRFS_LEAF_DATA_SIZE(r) \ +#define BTRFS_MAX_DEVS(info) ((BTRFS_LEAF_DATA_SIZE(info) \ - sizeof(struct btrfs_item) \ - sizeof(struct btrfs_chunk)) \ / sizeof(struct btrfs_stripe) + 1) @@ -886,12 +948,12 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, calc_size = SZ_1G; max_chunk_size = 10 * calc_size; min_stripe_size = SZ_64M; - max_stripes = BTRFS_MAX_DEVS(chunk_root); + max_stripes = BTRFS_MAX_DEVS(info); } else if (type & BTRFS_BLOCK_GROUP_METADATA) { calc_size = SZ_1G; max_chunk_size = 4 * calc_size; min_stripe_size = SZ_32M; - max_stripes = BTRFS_MAX_DEVS(chunk_root); + max_stripes = BTRFS_MAX_DEVS(info); } } if (type & BTRFS_BLOCK_GROUP_RAID1) { @@ -1035,9 +1097,7 @@ again: (index == num_stripes - 1)) list_move_tail(&device->dev_list, dev_list); - ret = btrfs_alloc_dev_extent(trans, device, - info->chunk_root->root_key.objectid, - BTRFS_FIRST_CHUNK_TREE_OBJECTID, key.offset, + ret = btrfs_alloc_dev_extent(trans, device, key.offset, calc_size, &dev_offset, 0); if (ret < 0) goto out_chunk_map; @@ -1172,9 +1232,7 @@ int btrfs_alloc_data_chunk(struct btrfs_trans_handle *trans, while (index < num_stripes) { struct btrfs_stripe *stripe; - ret = btrfs_alloc_dev_extent(trans, device, - info->chunk_root->root_key.objectid, - BTRFS_FIRST_CHUNK_TREE_OBJECTID, key.offset, + ret = btrfs_alloc_dev_extent(trans, device, key.offset, calc_size, &dev_offset, convert); BUG_ON(ret);