aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c63
1 files changed, 39 insertions, 24 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 88e2fe931bde..7c84a8122c37 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1116,15 +1116,18 @@ out:
1116 return ret; 1116 return ret;
1117} 1117}
1118 1118
1119static int contains_pending_extent(struct btrfs_trans_handle *trans, 1119static int contains_pending_extent(struct btrfs_transaction *transaction,
1120 struct btrfs_device *device, 1120 struct btrfs_device *device,
1121 u64 *start, u64 len) 1121 u64 *start, u64 len)
1122{ 1122{
1123 struct btrfs_fs_info *fs_info = device->dev_root->fs_info;
1123 struct extent_map *em; 1124 struct extent_map *em;
1124 struct list_head *search_list = &trans->transaction->pending_chunks; 1125 struct list_head *search_list = &fs_info->pinned_chunks;
1125 int ret = 0; 1126 int ret = 0;
1126 u64 physical_start = *start; 1127 u64 physical_start = *start;
1127 1128
1129 if (transaction)
1130 search_list = &transaction->pending_chunks;
1128again: 1131again:
1129 list_for_each_entry(em, search_list, list) { 1132 list_for_each_entry(em, search_list, list) {
1130 struct map_lookup *map; 1133 struct map_lookup *map;
@@ -1159,8 +1162,8 @@ again:
1159 } 1162 }
1160 } 1163 }
1161 } 1164 }
1162 if (search_list == &trans->transaction->pending_chunks) { 1165 if (search_list != &fs_info->pinned_chunks) {
1163 search_list = &trans->root->fs_info->pinned_chunks; 1166 search_list = &fs_info->pinned_chunks;
1164 goto again; 1167 goto again;
1165 } 1168 }
1166 1169
@@ -1169,12 +1172,13 @@ again:
1169 1172
1170 1173
1171/* 1174/*
1172 * find_free_dev_extent - find free space in the specified device 1175 * find_free_dev_extent_start - find free space in the specified device
1173 * @device: the device which we search the free space in 1176 * @device: the device which we search the free space in
1174 * @num_bytes: the size of the free space that we need 1177 * @num_bytes: the size of the free space that we need
1175 * @start: store the start of the free space. 1178 * @search_start: the position from which to begin the search
1176 * @len: the size of the free space. that we find, or the size of the max 1179 * @start: store the start of the free space.
1177 * free space if we don't find suitable free space 1180 * @len: the size of the free space. that we find, or the size
1181 * of the max free space if we don't find suitable free space
1178 * 1182 *
1179 * this uses a pretty simple search, the expectation is that it is 1183 * this uses a pretty simple search, the expectation is that it is
1180 * called very infrequently and that a given device has a small number 1184 * called very infrequently and that a given device has a small number
@@ -1188,9 +1192,9 @@ again:
1188 * But if we don't find suitable free space, it is used to store the size of 1192 * But if we don't find suitable free space, it is used to store the size of
1189 * the max free space. 1193 * the max free space.
1190 */ 1194 */
1191int find_free_dev_extent(struct btrfs_trans_handle *trans, 1195int find_free_dev_extent_start(struct btrfs_transaction *transaction,
1192 struct btrfs_device *device, u64 num_bytes, 1196 struct btrfs_device *device, u64 num_bytes,
1193 u64 *start, u64 *len) 1197 u64 search_start, u64 *start, u64 *len)
1194{ 1198{
1195 struct btrfs_key key; 1199 struct btrfs_key key;
1196 struct btrfs_root *root = device->dev_root; 1200 struct btrfs_root *root = device->dev_root;
@@ -1200,19 +1204,11 @@ int find_free_dev_extent(struct btrfs_trans_handle *trans,
1200 u64 max_hole_start; 1204 u64 max_hole_start;
1201 u64 max_hole_size; 1205 u64 max_hole_size;
1202 u64 extent_end; 1206 u64 extent_end;
1203 u64 search_start;
1204 u64 search_end = device->total_bytes; 1207 u64 search_end = device->total_bytes;
1205 int ret; 1208 int ret;
1206 int slot; 1209 int slot;
1207 struct extent_buffer *l; 1210 struct extent_buffer *l;
1208 1211
1209 /* FIXME use last free of some kind */
1210
1211 /* we don't want to overwrite the superblock on the drive,
1212 * so we make sure to start at an offset of at least 1MB
1213 */
1214 search_start = max(root->fs_info->alloc_start, 1024ull * 1024);
1215
1216 path = btrfs_alloc_path(); 1212 path = btrfs_alloc_path();
1217 if (!path) 1213 if (!path)
1218 return -ENOMEM; 1214 return -ENOMEM;
@@ -1273,7 +1269,7 @@ again:
1273 * Have to check before we set max_hole_start, otherwise 1269 * Have to check before we set max_hole_start, otherwise
1274 * we could end up sending back this offset anyway. 1270 * we could end up sending back this offset anyway.
1275 */ 1271 */
1276 if (contains_pending_extent(trans, device, 1272 if (contains_pending_extent(transaction, device,
1277 &search_start, 1273 &search_start,
1278 hole_size)) { 1274 hole_size)) {
1279 if (key.offset >= search_start) { 1275 if (key.offset >= search_start) {
@@ -1322,7 +1318,7 @@ next:
1322 if (search_end > search_start) { 1318 if (search_end > search_start) {
1323 hole_size = search_end - search_start; 1319 hole_size = search_end - search_start;
1324 1320
1325 if (contains_pending_extent(trans, device, &search_start, 1321 if (contains_pending_extent(transaction, device, &search_start,
1326 hole_size)) { 1322 hole_size)) {
1327 btrfs_release_path(path); 1323 btrfs_release_path(path);
1328 goto again; 1324 goto again;
@@ -1348,6 +1344,24 @@ out:
1348 return ret; 1344 return ret;
1349} 1345}
1350 1346
1347int find_free_dev_extent(struct btrfs_trans_handle *trans,
1348 struct btrfs_device *device, u64 num_bytes,
1349 u64 *start, u64 *len)
1350{
1351 struct btrfs_root *root = device->dev_root;
1352 u64 search_start;
1353
1354 /* FIXME use last free of some kind */
1355
1356 /*
1357 * we don't want to overwrite the superblock on the drive,
1358 * so we make sure to start at an offset of at least 1MB
1359 */
1360 search_start = max(root->fs_info->alloc_start, 1024ull * 1024);
1361 return find_free_dev_extent_start(trans->transaction, device,
1362 num_bytes, search_start, start, len);
1363}
1364
1351static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans, 1365static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans,
1352 struct btrfs_device *device, 1366 struct btrfs_device *device,
1353 u64 start, u64 *dev_extent_len) 1367 u64 start, u64 *dev_extent_len)
@@ -4196,7 +4210,8 @@ again:
4196 u64 start = new_size; 4210 u64 start = new_size;
4197 u64 len = old_size - new_size; 4211 u64 len = old_size - new_size;
4198 4212
4199 if (contains_pending_extent(trans, device, &start, len)) { 4213 if (contains_pending_extent(trans->transaction, device,
4214 &start, len)) {
4200 unlock_chunks(root); 4215 unlock_chunks(root);
4201 checked_pending_chunks = true; 4216 checked_pending_chunks = true;
4202 failed = 0; 4217 failed = 0;