diff options
Diffstat (limited to 'fs/btrfs/volumes.c')
| -rw-r--r-- | fs/btrfs/volumes.c | 34 | 
1 files changed, 21 insertions, 13 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 9df8e3f1ccab..d6e3af8be95b 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c  | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | */ | 17 | */ | 
| 18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> | 
| 19 | #include <linux/bio.h> | 19 | #include <linux/bio.h> | 
| 20 | #include <linux/slab.h> | ||
| 20 | #include <linux/buffer_head.h> | 21 | #include <linux/buffer_head.h> | 
| 21 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> | 
| 22 | #include <linux/random.h> | 23 | #include <linux/random.h> | 
| @@ -1096,7 +1097,7 @@ static int btrfs_rm_dev_item(struct btrfs_root *root, | |||
| 1096 | if (!path) | 1097 | if (!path) | 
| 1097 | return -ENOMEM; | 1098 | return -ENOMEM; | 
| 1098 | 1099 | ||
| 1099 | trans = btrfs_start_transaction(root, 1); | 1100 | trans = btrfs_start_transaction(root, 0); | 
| 1100 | key.objectid = BTRFS_DEV_ITEMS_OBJECTID; | 1101 | key.objectid = BTRFS_DEV_ITEMS_OBJECTID; | 
| 1101 | key.type = BTRFS_DEV_ITEM_KEY; | 1102 | key.type = BTRFS_DEV_ITEM_KEY; | 
| 1102 | key.offset = device->devid; | 1103 | key.offset = device->devid; | 
| @@ -1485,7 +1486,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
| 1485 | goto error; | 1486 | goto error; | 
| 1486 | } | 1487 | } | 
| 1487 | 1488 | ||
| 1488 | trans = btrfs_start_transaction(root, 1); | 1489 | trans = btrfs_start_transaction(root, 0); | 
| 1489 | lock_chunks(root); | 1490 | lock_chunks(root); | 
| 1490 | 1491 | ||
| 1491 | device->barriers = 1; | 1492 | device->barriers = 1; | 
| @@ -1750,9 +1751,10 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, | |||
| 1750 | 1751 | ||
| 1751 | /* step one, relocate all the extents inside this chunk */ | 1752 | /* step one, relocate all the extents inside this chunk */ | 
| 1752 | ret = btrfs_relocate_block_group(extent_root, chunk_offset); | 1753 | ret = btrfs_relocate_block_group(extent_root, chunk_offset); | 
| 1753 | BUG_ON(ret); | 1754 | if (ret) | 
| 1755 | return ret; | ||
| 1754 | 1756 | ||
| 1755 | trans = btrfs_start_transaction(root, 1); | 1757 | trans = btrfs_start_transaction(root, 0); | 
| 1756 | BUG_ON(!trans); | 1758 | BUG_ON(!trans); | 
| 1757 | 1759 | ||
| 1758 | lock_chunks(root); | 1760 | lock_chunks(root); | 
| @@ -1924,7 +1926,7 @@ int btrfs_balance(struct btrfs_root *dev_root) | |||
| 1924 | break; | 1926 | break; | 
| 1925 | BUG_ON(ret); | 1927 | BUG_ON(ret); | 
| 1926 | 1928 | ||
| 1927 | trans = btrfs_start_transaction(dev_root, 1); | 1929 | trans = btrfs_start_transaction(dev_root, 0); | 
| 1928 | BUG_ON(!trans); | 1930 | BUG_ON(!trans); | 
| 1929 | 1931 | ||
| 1930 | ret = btrfs_grow_device(trans, device, old_size); | 1932 | ret = btrfs_grow_device(trans, device, old_size); | 
| @@ -2093,11 +2095,7 @@ again: | |||
| 2093 | } | 2095 | } | 
| 2094 | 2096 | ||
| 2095 | /* Shrinking succeeded, else we would be at "done". */ | 2097 | /* Shrinking succeeded, else we would be at "done". */ | 
| 2096 | trans = btrfs_start_transaction(root, 1); | 2098 | trans = btrfs_start_transaction(root, 0); | 
| 2097 | if (!trans) { | ||
| 2098 | ret = -ENOMEM; | ||
| 2099 | goto done; | ||
| 2100 | } | ||
| 2101 | lock_chunks(root); | 2099 | lock_chunks(root); | 
| 2102 | 2100 | ||
| 2103 | device->disk_total_bytes = new_size; | 2101 | device->disk_total_bytes = new_size; | 
| @@ -2198,9 +2196,9 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, | |||
| 2198 | min_stripes = 2; | 2196 | min_stripes = 2; | 
| 2199 | } | 2197 | } | 
| 2200 | if (type & (BTRFS_BLOCK_GROUP_RAID1)) { | 2198 | if (type & (BTRFS_BLOCK_GROUP_RAID1)) { | 
| 2201 | num_stripes = min_t(u64, 2, fs_devices->rw_devices); | 2199 | if (fs_devices->rw_devices < 2) | 
| 2202 | if (num_stripes < 2) | ||
| 2203 | return -ENOSPC; | 2200 | return -ENOSPC; | 
| 2201 | num_stripes = 2; | ||
| 2204 | min_stripes = 2; | 2202 | min_stripes = 2; | 
| 2205 | } | 2203 | } | 
| 2206 | if (type & (BTRFS_BLOCK_GROUP_RAID10)) { | 2204 | if (type & (BTRFS_BLOCK_GROUP_RAID10)) { | 
| @@ -2244,8 +2242,16 @@ again: | |||
| 2244 | do_div(calc_size, stripe_len); | 2242 | do_div(calc_size, stripe_len); | 
| 2245 | calc_size *= stripe_len; | 2243 | calc_size *= stripe_len; | 
| 2246 | } | 2244 | } | 
| 2245 | |||
| 2247 | /* we don't want tiny stripes */ | 2246 | /* we don't want tiny stripes */ | 
| 2248 | calc_size = max_t(u64, min_stripe_size, calc_size); | 2247 | if (!looped) | 
| 2248 | calc_size = max_t(u64, min_stripe_size, calc_size); | ||
| 2249 | |||
| 2250 | /* | ||
| 2251 | * we're about to do_div by the stripe_len so lets make sure | ||
| 2252 | * we end up with something bigger than a stripe | ||
| 2253 | */ | ||
| 2254 | calc_size = max_t(u64, calc_size, stripe_len * 4); | ||
| 2249 | 2255 | ||
| 2250 | do_div(calc_size, stripe_len); | 2256 | do_div(calc_size, stripe_len); | 
| 2251 | calc_size *= stripe_len; | 2257 | calc_size *= stripe_len; | 
| @@ -3389,6 +3395,8 @@ int btrfs_read_chunk_tree(struct btrfs_root *root) | |||
| 3389 | key.type = 0; | 3395 | key.type = 0; | 
| 3390 | again: | 3396 | again: | 
| 3391 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 3397 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 
| 3398 | if (ret < 0) | ||
| 3399 | goto error; | ||
| 3392 | while (1) { | 3400 | while (1) { | 
| 3393 | leaf = path->nodes[0]; | 3401 | leaf = path->nodes[0]; | 
| 3394 | slot = path->slots[0]; | 3402 | slot = path->slots[0]; | 
