Commit | Line | Data |
---|---|---|
c1d7c514 | 1 | // SPDX-License-Identifier: GPL-2.0 |
6cbd5570 CM |
2 | /* |
3 | * Copyright (C) 2007 Oracle. All rights reserved. | |
6cbd5570 CM |
4 | */ |
5 | ||
581bb050 LZ |
6 | #include <linux/kthread.h> |
7 | #include <linux/pagemap.h> | |
8 | ||
9f5fae2f CM |
9 | #include "ctree.h" |
10 | #include "disk-io.h" | |
581bb050 LZ |
11 | #include "free-space-cache.h" |
12 | #include "inode-map.h" | |
9f5fae2f CM |
13 | #include "transaction.h" |
14 | ||
581bb050 LZ |
15 | static int caching_kthread(void *data) |
16 | { | |
17 | struct btrfs_root *root = data; | |
18 | struct btrfs_fs_info *fs_info = root->fs_info; | |
19 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; | |
20 | struct btrfs_key key; | |
21 | struct btrfs_path *path; | |
22 | struct extent_buffer *leaf; | |
23 | u64 last = (u64)-1; | |
24 | int slot; | |
25 | int ret; | |
26 | ||
0b246afa | 27 | if (!btrfs_test_opt(fs_info, INODE_MAP_CACHE)) |
4b9465cb CM |
28 | return 0; |
29 | ||
581bb050 LZ |
30 | path = btrfs_alloc_path(); |
31 | if (!path) | |
32 | return -ENOMEM; | |
33 | ||
34 | /* Since the commit root is read-only, we can safely skip locking. */ | |
35 | path->skip_locking = 1; | |
36 | path->search_commit_root = 1; | |
e4058b54 | 37 | path->reada = READA_FORWARD; |
581bb050 LZ |
38 | |
39 | key.objectid = BTRFS_FIRST_FREE_OBJECTID; | |
40 | key.offset = 0; | |
41 | key.type = BTRFS_INODE_ITEM_KEY; | |
42 | again: | |
43 | /* need to make sure the commit_root doesn't disappear */ | |
9e351cc8 | 44 | down_read(&fs_info->commit_root_sem); |
581bb050 LZ |
45 | |
46 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | |
47 | if (ret < 0) | |
48 | goto out; | |
49 | ||
50 | while (1) { | |
7841cb28 | 51 | if (btrfs_fs_closing(fs_info)) |
581bb050 LZ |
52 | goto out; |
53 | ||
54 | leaf = path->nodes[0]; | |
55 | slot = path->slots[0]; | |
a47d6b70 | 56 | if (slot >= btrfs_header_nritems(leaf)) { |
581bb050 LZ |
57 | ret = btrfs_next_leaf(root, path); |
58 | if (ret < 0) | |
59 | goto out; | |
60 | else if (ret > 0) | |
61 | break; | |
62 | ||
63 | if (need_resched() || | |
64 | btrfs_transaction_in_commit(fs_info)) { | |
65 | leaf = path->nodes[0]; | |
66 | ||
fae7f21c | 67 | if (WARN_ON(btrfs_header_nritems(leaf) == 0)) |
581bb050 | 68 | break; |
581bb050 LZ |
69 | |
70 | /* | |
71 | * Save the key so we can advances forward | |
72 | * in the next search. | |
73 | */ | |
74 | btrfs_item_key_to_cpu(leaf, &key, 0); | |
945d8962 | 75 | btrfs_release_path(path); |
57cdc8db | 76 | root->ino_cache_progress = last; |
9e351cc8 | 77 | up_read(&fs_info->commit_root_sem); |
581bb050 LZ |
78 | schedule_timeout(1); |
79 | goto again; | |
80 | } else | |
81 | continue; | |
82 | } | |
83 | ||
84 | btrfs_item_key_to_cpu(leaf, &key, slot); | |
85 | ||
86 | if (key.type != BTRFS_INODE_ITEM_KEY) | |
87 | goto next; | |
88 | ||
a47d6b70 | 89 | if (key.objectid >= root->highest_objectid) |
581bb050 LZ |
90 | break; |
91 | ||
92 | if (last != (u64)-1 && last + 1 != key.objectid) { | |
ab8d0fc4 | 93 | __btrfs_add_free_space(fs_info, ctl, last + 1, |
581bb050 | 94 | key.objectid - last - 1); |
57cdc8db | 95 | wake_up(&root->ino_cache_wait); |
581bb050 LZ |
96 | } |
97 | ||
98 | last = key.objectid; | |
99 | next: | |
100 | path->slots[0]++; | |
101 | } | |
102 | ||
a47d6b70 | 103 | if (last < root->highest_objectid - 1) { |
ab8d0fc4 | 104 | __btrfs_add_free_space(fs_info, ctl, last + 1, |
a47d6b70 | 105 | root->highest_objectid - last - 1); |
581bb050 LZ |
106 | } |
107 | ||
57cdc8db DS |
108 | spin_lock(&root->ino_cache_lock); |
109 | root->ino_cache_state = BTRFS_CACHE_FINISHED; | |
110 | spin_unlock(&root->ino_cache_lock); | |
581bb050 | 111 | |
57cdc8db | 112 | root->ino_cache_progress = (u64)-1; |
581bb050 LZ |
113 | btrfs_unpin_free_ino(root); |
114 | out: | |
57cdc8db | 115 | wake_up(&root->ino_cache_wait); |
9e351cc8 | 116 | up_read(&fs_info->commit_root_sem); |
581bb050 LZ |
117 | |
118 | btrfs_free_path(path); | |
119 | ||
120 | return ret; | |
121 | } | |
122 | ||
123 | static void start_caching(struct btrfs_root *root) | |
124 | { | |
ab8d0fc4 | 125 | struct btrfs_fs_info *fs_info = root->fs_info; |
a47d6b70 | 126 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; |
581bb050 | 127 | struct task_struct *tsk; |
82d5902d | 128 | int ret; |
a47d6b70 | 129 | u64 objectid; |
581bb050 | 130 | |
ab8d0fc4 | 131 | if (!btrfs_test_opt(fs_info, INODE_MAP_CACHE)) |
4b9465cb CM |
132 | return; |
133 | ||
57cdc8db DS |
134 | spin_lock(&root->ino_cache_lock); |
135 | if (root->ino_cache_state != BTRFS_CACHE_NO) { | |
136 | spin_unlock(&root->ino_cache_lock); | |
581bb050 LZ |
137 | return; |
138 | } | |
139 | ||
57cdc8db DS |
140 | root->ino_cache_state = BTRFS_CACHE_STARTED; |
141 | spin_unlock(&root->ino_cache_lock); | |
581bb050 | 142 | |
ab8d0fc4 | 143 | ret = load_free_ino_cache(fs_info, root); |
82d5902d | 144 | if (ret == 1) { |
57cdc8db DS |
145 | spin_lock(&root->ino_cache_lock); |
146 | root->ino_cache_state = BTRFS_CACHE_FINISHED; | |
147 | spin_unlock(&root->ino_cache_lock); | |
82d5902d LZ |
148 | return; |
149 | } | |
150 | ||
a47d6b70 LZ |
151 | /* |
152 | * It can be quite time-consuming to fill the cache by searching | |
153 | * through the extent tree, and this can keep ino allocation path | |
154 | * waiting. Therefore at start we quickly find out the highest | |
155 | * inode number and we know we can use inode numbers which fall in | |
156 | * [highest_ino + 1, BTRFS_LAST_FREE_OBJECTID]. | |
157 | */ | |
158 | ret = btrfs_find_free_objectid(root, &objectid); | |
159 | if (!ret && objectid <= BTRFS_LAST_FREE_OBJECTID) { | |
ab8d0fc4 | 160 | __btrfs_add_free_space(fs_info, ctl, objectid, |
a47d6b70 LZ |
161 | BTRFS_LAST_FREE_OBJECTID - objectid + 1); |
162 | } | |
163 | ||
67a77eb1 | 164 | tsk = kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu", |
581bb050 | 165 | root->root_key.objectid); |
e60efa84 | 166 | if (IS_ERR(tsk)) { |
ab8d0fc4 JM |
167 | btrfs_warn(fs_info, "failed to start inode caching task"); |
168 | btrfs_clear_pending_and_info(fs_info, INODE_MAP_CACHE, | |
0b246afa | 169 | "disabling inode map caching"); |
e60efa84 | 170 | } |
581bb050 LZ |
171 | } |
172 | ||
173 | int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid) | |
174 | { | |
3cdde224 | 175 | if (!btrfs_test_opt(root->fs_info, INODE_MAP_CACHE)) |
4b9465cb CM |
176 | return btrfs_find_free_objectid(root, objectid); |
177 | ||
581bb050 LZ |
178 | again: |
179 | *objectid = btrfs_find_ino_for_alloc(root); | |
180 | ||
181 | if (*objectid != 0) | |
182 | return 0; | |
183 | ||
184 | start_caching(root); | |
185 | ||
57cdc8db DS |
186 | wait_event(root->ino_cache_wait, |
187 | root->ino_cache_state == BTRFS_CACHE_FINISHED || | |
581bb050 LZ |
188 | root->free_ino_ctl->free_space > 0); |
189 | ||
57cdc8db | 190 | if (root->ino_cache_state == BTRFS_CACHE_FINISHED && |
581bb050 LZ |
191 | root->free_ino_ctl->free_space == 0) |
192 | return -ENOSPC; | |
193 | else | |
194 | goto again; | |
195 | } | |
196 | ||
197 | void btrfs_return_ino(struct btrfs_root *root, u64 objectid) | |
198 | { | |
ab8d0fc4 | 199 | struct btrfs_fs_info *fs_info = root->fs_info; |
581bb050 | 200 | struct btrfs_free_space_ctl *pinned = root->free_ino_pinned; |
4b9465cb | 201 | |
ab8d0fc4 | 202 | if (!btrfs_test_opt(fs_info, INODE_MAP_CACHE)) |
4b9465cb | 203 | return; |
581bb050 | 204 | again: |
57cdc8db | 205 | if (root->ino_cache_state == BTRFS_CACHE_FINISHED) { |
ab8d0fc4 | 206 | __btrfs_add_free_space(fs_info, pinned, objectid, 1); |
581bb050 | 207 | } else { |
ab8d0fc4 | 208 | down_write(&fs_info->commit_root_sem); |
57cdc8db DS |
209 | spin_lock(&root->ino_cache_lock); |
210 | if (root->ino_cache_state == BTRFS_CACHE_FINISHED) { | |
211 | spin_unlock(&root->ino_cache_lock); | |
ab8d0fc4 | 212 | up_write(&fs_info->commit_root_sem); |
581bb050 LZ |
213 | goto again; |
214 | } | |
57cdc8db | 215 | spin_unlock(&root->ino_cache_lock); |
581bb050 LZ |
216 | |
217 | start_caching(root); | |
218 | ||
ab8d0fc4 | 219 | __btrfs_add_free_space(fs_info, pinned, objectid, 1); |
581bb050 | 220 | |
ab8d0fc4 | 221 | up_write(&fs_info->commit_root_sem); |
581bb050 LZ |
222 | } |
223 | } | |
224 | ||
225 | /* | |
57cdc8db DS |
226 | * When a transaction is committed, we'll move those inode numbers which are |
227 | * smaller than root->ino_cache_progress from pinned tree to free_ino tree, and | |
228 | * others will just be dropped, because the commit root we were searching has | |
229 | * changed. | |
581bb050 | 230 | * |
9e351cc8 | 231 | * Must be called with root->fs_info->commit_root_sem held |
581bb050 LZ |
232 | */ |
233 | void btrfs_unpin_free_ino(struct btrfs_root *root) | |
234 | { | |
235 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; | |
236 | struct rb_root *rbroot = &root->free_ino_pinned->free_space_offset; | |
ae9d8f17 | 237 | spinlock_t *rbroot_lock = &root->free_ino_pinned->tree_lock; |
581bb050 LZ |
238 | struct btrfs_free_space *info; |
239 | struct rb_node *n; | |
240 | u64 count; | |
241 | ||
3cdde224 | 242 | if (!btrfs_test_opt(root->fs_info, INODE_MAP_CACHE)) |
4b9465cb CM |
243 | return; |
244 | ||
581bb050 | 245 | while (1) { |
ae9d8f17 | 246 | spin_lock(rbroot_lock); |
581bb050 | 247 | n = rb_first(rbroot); |
ae9d8f17 FM |
248 | if (!n) { |
249 | spin_unlock(rbroot_lock); | |
581bb050 | 250 | break; |
ae9d8f17 | 251 | } |
581bb050 LZ |
252 | |
253 | info = rb_entry(n, struct btrfs_free_space, offset_index); | |
79787eaa | 254 | BUG_ON(info->bitmap); /* Logic error */ |
581bb050 | 255 | |
57cdc8db | 256 | if (info->offset > root->ino_cache_progress) |
bc931c0e | 257 | count = 0; |
581bb050 | 258 | else |
bc931c0e GU |
259 | count = min(root->ino_cache_progress - info->offset + 1, |
260 | info->bytes); | |
581bb050 | 261 | |
581bb050 | 262 | rb_erase(&info->offset_index, rbroot); |
ae9d8f17 | 263 | spin_unlock(rbroot_lock); |
bc931c0e | 264 | if (count) |
ab8d0fc4 JM |
265 | __btrfs_add_free_space(root->fs_info, ctl, |
266 | info->offset, count); | |
c3f4a168 | 267 | kmem_cache_free(btrfs_free_space_cachep, info); |
581bb050 LZ |
268 | } |
269 | } | |
270 | ||
ee22184b | 271 | #define INIT_THRESHOLD ((SZ_32K / 2) / sizeof(struct btrfs_free_space)) |
09cbfeaf | 272 | #define INODES_PER_BITMAP (PAGE_SIZE * 8) |
581bb050 LZ |
273 | |
274 | /* | |
275 | * The goal is to keep the memory used by the free_ino tree won't | |
276 | * exceed the memory if we use bitmaps only. | |
277 | */ | |
278 | static void recalculate_thresholds(struct btrfs_free_space_ctl *ctl) | |
279 | { | |
280 | struct btrfs_free_space *info; | |
281 | struct rb_node *n; | |
282 | int max_ino; | |
283 | int max_bitmaps; | |
284 | ||
285 | n = rb_last(&ctl->free_space_offset); | |
286 | if (!n) { | |
287 | ctl->extents_thresh = INIT_THRESHOLD; | |
288 | return; | |
289 | } | |
290 | info = rb_entry(n, struct btrfs_free_space, offset_index); | |
291 | ||
292 | /* | |
293 | * Find the maximum inode number in the filesystem. Note we | |
294 | * ignore the fact that this can be a bitmap, because we are | |
295 | * not doing precise calculation. | |
296 | */ | |
297 | max_ino = info->bytes - 1; | |
298 | ||
299 | max_bitmaps = ALIGN(max_ino, INODES_PER_BITMAP) / INODES_PER_BITMAP; | |
300 | if (max_bitmaps <= ctl->total_bitmaps) { | |
301 | ctl->extents_thresh = 0; | |
302 | return; | |
303 | } | |
304 | ||
305 | ctl->extents_thresh = (max_bitmaps - ctl->total_bitmaps) * | |
09cbfeaf | 306 | PAGE_SIZE / sizeof(*info); |
581bb050 LZ |
307 | } |
308 | ||
309 | /* | |
310 | * We don't fall back to bitmap, if we are below the extents threshold | |
311 | * or this chunk of inode numbers is a big one. | |
312 | */ | |
313 | static bool use_bitmap(struct btrfs_free_space_ctl *ctl, | |
314 | struct btrfs_free_space *info) | |
315 | { | |
316 | if (ctl->free_extents < ctl->extents_thresh || | |
317 | info->bytes > INODES_PER_BITMAP / 10) | |
318 | return false; | |
319 | ||
320 | return true; | |
321 | } | |
322 | ||
20e5506b | 323 | static const struct btrfs_free_space_op free_ino_op = { |
581bb050 LZ |
324 | .recalc_thresholds = recalculate_thresholds, |
325 | .use_bitmap = use_bitmap, | |
326 | }; | |
327 | ||
328 | static void pinned_recalc_thresholds(struct btrfs_free_space_ctl *ctl) | |
329 | { | |
330 | } | |
331 | ||
332 | static bool pinned_use_bitmap(struct btrfs_free_space_ctl *ctl, | |
333 | struct btrfs_free_space *info) | |
334 | { | |
335 | /* | |
336 | * We always use extents for two reasons: | |
337 | * | |
338 | * - The pinned tree is only used during the process of caching | |
339 | * work. | |
340 | * - Make code simpler. See btrfs_unpin_free_ino(). | |
341 | */ | |
342 | return false; | |
343 | } | |
344 | ||
20e5506b | 345 | static const struct btrfs_free_space_op pinned_free_ino_op = { |
581bb050 LZ |
346 | .recalc_thresholds = pinned_recalc_thresholds, |
347 | .use_bitmap = pinned_use_bitmap, | |
348 | }; | |
349 | ||
350 | void btrfs_init_free_ino_ctl(struct btrfs_root *root) | |
351 | { | |
352 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; | |
353 | struct btrfs_free_space_ctl *pinned = root->free_ino_pinned; | |
354 | ||
355 | spin_lock_init(&ctl->tree_lock); | |
356 | ctl->unit = 1; | |
357 | ctl->start = 0; | |
358 | ctl->private = NULL; | |
359 | ctl->op = &free_ino_op; | |
55507ce3 FM |
360 | INIT_LIST_HEAD(&ctl->trimming_ranges); |
361 | mutex_init(&ctl->cache_writeout_mutex); | |
581bb050 LZ |
362 | |
363 | /* | |
364 | * Initially we allow to use 16K of ram to cache chunks of | |
365 | * inode numbers before we resort to bitmaps. This is somewhat | |
366 | * arbitrary, but it will be adjusted in runtime. | |
367 | */ | |
368 | ctl->extents_thresh = INIT_THRESHOLD; | |
369 | ||
370 | spin_lock_init(&pinned->tree_lock); | |
371 | pinned->unit = 1; | |
372 | pinned->start = 0; | |
373 | pinned->private = NULL; | |
374 | pinned->extents_thresh = 0; | |
375 | pinned->op = &pinned_free_ino_op; | |
376 | } | |
377 | ||
82d5902d LZ |
378 | int btrfs_save_ino_cache(struct btrfs_root *root, |
379 | struct btrfs_trans_handle *trans) | |
380 | { | |
0b246afa | 381 | struct btrfs_fs_info *fs_info = root->fs_info; |
82d5902d LZ |
382 | struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; |
383 | struct btrfs_path *path; | |
384 | struct inode *inode; | |
ba38eb4d | 385 | struct btrfs_block_rsv *rsv; |
364ecf36 | 386 | struct extent_changeset *data_reserved = NULL; |
ba38eb4d | 387 | u64 num_bytes; |
82d5902d LZ |
388 | u64 alloc_hint = 0; |
389 | int ret; | |
390 | int prealloc; | |
391 | bool retry = false; | |
392 | ||
ca456ae2 | 393 | /* only fs tree and subvol/snap needs ino cache */ |
394 | if (root->root_key.objectid != BTRFS_FS_TREE_OBJECTID && | |
395 | (root->root_key.objectid < BTRFS_FIRST_FREE_OBJECTID || | |
396 | root->root_key.objectid > BTRFS_LAST_FREE_OBJECTID)) | |
397 | return 0; | |
398 | ||
d132a538 | 399 | /* Don't save inode cache if we are deleting this root */ |
69e9c6c6 | 400 | if (btrfs_root_refs(&root->root_item) == 0) |
d132a538 JB |
401 | return 0; |
402 | ||
0b246afa | 403 | if (!btrfs_test_opt(fs_info, INODE_MAP_CACHE)) |
4b9465cb CM |
404 | return 0; |
405 | ||
82d5902d LZ |
406 | path = btrfs_alloc_path(); |
407 | if (!path) | |
408 | return -ENOMEM; | |
4b9465cb | 409 | |
ba38eb4d | 410 | rsv = trans->block_rsv; |
0b246afa | 411 | trans->block_rsv = &fs_info->trans_block_rsv; |
ba38eb4d MX |
412 | |
413 | num_bytes = trans->bytes_reserved; | |
414 | /* | |
415 | * 1 item for inode item insertion if need | |
7b61cd92 MX |
416 | * 4 items for inode item update (in the worst case) |
417 | * 1 items for slack space if we need do truncation | |
ba38eb4d MX |
418 | * 1 item for free space object |
419 | * 3 items for pre-allocation | |
420 | */ | |
0b246afa | 421 | trans->bytes_reserved = btrfs_calc_trans_metadata_size(fs_info, 10); |
08e007d2 MX |
422 | ret = btrfs_block_rsv_add(root, trans->block_rsv, |
423 | trans->bytes_reserved, | |
424 | BTRFS_RESERVE_NO_FLUSH); | |
ba38eb4d MX |
425 | if (ret) |
426 | goto out; | |
0b246afa JM |
427 | trace_btrfs_space_reservation(fs_info, "ino_cache", trans->transid, |
428 | trans->bytes_reserved, 1); | |
82d5902d LZ |
429 | again: |
430 | inode = lookup_free_ino_inode(root, path); | |
79787eaa | 431 | if (IS_ERR(inode) && (PTR_ERR(inode) != -ENOENT || retry)) { |
82d5902d | 432 | ret = PTR_ERR(inode); |
ba38eb4d | 433 | goto out_release; |
82d5902d LZ |
434 | } |
435 | ||
436 | if (IS_ERR(inode)) { | |
79787eaa | 437 | BUG_ON(retry); /* Logic error */ |
82d5902d LZ |
438 | retry = true; |
439 | ||
440 | ret = create_free_ino_inode(root, trans, path); | |
441 | if (ret) | |
ba38eb4d | 442 | goto out_release; |
82d5902d LZ |
443 | goto again; |
444 | } | |
445 | ||
446 | BTRFS_I(inode)->generation = 0; | |
447 | ret = btrfs_update_inode(trans, root, inode); | |
79787eaa | 448 | if (ret) { |
66642832 | 449 | btrfs_abort_transaction(trans, ret); |
79787eaa JM |
450 | goto out_put; |
451 | } | |
82d5902d LZ |
452 | |
453 | if (i_size_read(inode) > 0) { | |
77ab86bf | 454 | ret = btrfs_truncate_free_space_cache(trans, NULL, inode); |
79787eaa | 455 | if (ret) { |
7cfa9e51 | 456 | if (ret != -ENOSPC) |
66642832 | 457 | btrfs_abort_transaction(trans, ret); |
82d5902d | 458 | goto out_put; |
79787eaa | 459 | } |
82d5902d LZ |
460 | } |
461 | ||
57cdc8db DS |
462 | spin_lock(&root->ino_cache_lock); |
463 | if (root->ino_cache_state != BTRFS_CACHE_FINISHED) { | |
82d5902d | 464 | ret = -1; |
57cdc8db | 465 | spin_unlock(&root->ino_cache_lock); |
82d5902d LZ |
466 | goto out_put; |
467 | } | |
57cdc8db | 468 | spin_unlock(&root->ino_cache_lock); |
82d5902d LZ |
469 | |
470 | spin_lock(&ctl->tree_lock); | |
471 | prealloc = sizeof(struct btrfs_free_space) * ctl->free_extents; | |
09cbfeaf KS |
472 | prealloc = ALIGN(prealloc, PAGE_SIZE); |
473 | prealloc += ctl->total_bitmaps * PAGE_SIZE; | |
82d5902d LZ |
474 | spin_unlock(&ctl->tree_lock); |
475 | ||
476 | /* Just to make sure we have enough space */ | |
09cbfeaf | 477 | prealloc += 8 * PAGE_SIZE; |
82d5902d | 478 | |
364ecf36 | 479 | ret = btrfs_delalloc_reserve_space(inode, &data_reserved, 0, prealloc); |
82d5902d LZ |
480 | if (ret) |
481 | goto out_put; | |
482 | ||
483 | ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, prealloc, | |
484 | prealloc, prealloc, &alloc_hint); | |
c09544e0 | 485 | if (ret) { |
43b18595 | 486 | btrfs_delalloc_release_extents(BTRFS_I(inode), prealloc, true); |
82d5902d | 487 | goto out_put; |
c09544e0 | 488 | } |
82d5902d | 489 | |
53645a91 | 490 | ret = btrfs_write_out_ino_cache(root, trans, path, inode); |
43b18595 | 491 | btrfs_delalloc_release_extents(BTRFS_I(inode), prealloc, false); |
82d5902d LZ |
492 | out_put: |
493 | iput(inode); | |
ba38eb4d | 494 | out_release: |
0b246afa JM |
495 | trace_btrfs_space_reservation(fs_info, "ino_cache", trans->transid, |
496 | trans->bytes_reserved, 0); | |
2ff7e61e JM |
497 | btrfs_block_rsv_release(fs_info, trans->block_rsv, |
498 | trans->bytes_reserved); | |
82d5902d | 499 | out: |
ba38eb4d MX |
500 | trans->block_rsv = rsv; |
501 | trans->bytes_reserved = num_bytes; | |
82d5902d LZ |
502 | |
503 | btrfs_free_path(path); | |
364ecf36 | 504 | extent_changeset_free(data_reserved); |
82d5902d LZ |
505 | return ret; |
506 | } | |
507 | ||
f32e48e9 | 508 | int btrfs_find_highest_objectid(struct btrfs_root *root, u64 *objectid) |
5be6f7f1 CM |
509 | { |
510 | struct btrfs_path *path; | |
511 | int ret; | |
5f39d397 | 512 | struct extent_buffer *l; |
5be6f7f1 | 513 | struct btrfs_key search_key; |
5f39d397 | 514 | struct btrfs_key found_key; |
5be6f7f1 CM |
515 | int slot; |
516 | ||
517 | path = btrfs_alloc_path(); | |
db5b493a TI |
518 | if (!path) |
519 | return -ENOMEM; | |
5be6f7f1 | 520 | |
6527cdbe ZY |
521 | search_key.objectid = BTRFS_LAST_FREE_OBJECTID; |
522 | search_key.type = -1; | |
5be6f7f1 CM |
523 | search_key.offset = (u64)-1; |
524 | ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); | |
525 | if (ret < 0) | |
526 | goto error; | |
79787eaa | 527 | BUG_ON(ret == 0); /* Corruption */ |
5be6f7f1 CM |
528 | if (path->slots[0] > 0) { |
529 | slot = path->slots[0] - 1; | |
5f39d397 CM |
530 | l = path->nodes[0]; |
531 | btrfs_item_key_to_cpu(l, &found_key, slot); | |
13a8a7c8 YZ |
532 | *objectid = max_t(u64, found_key.objectid, |
533 | BTRFS_FIRST_FREE_OBJECTID - 1); | |
5be6f7f1 | 534 | } else { |
13a8a7c8 | 535 | *objectid = BTRFS_FIRST_FREE_OBJECTID - 1; |
5be6f7f1 CM |
536 | } |
537 | ret = 0; | |
538 | error: | |
539 | btrfs_free_path(path); | |
540 | return ret; | |
541 | } | |
542 | ||
581bb050 | 543 | int btrfs_find_free_objectid(struct btrfs_root *root, u64 *objectid) |
9f5fae2f | 544 | { |
9f5fae2f | 545 | int ret; |
a2135011 | 546 | mutex_lock(&root->objectid_mutex); |
9f5fae2f | 547 | |
13a8a7c8 | 548 | if (unlikely(root->highest_objectid >= BTRFS_LAST_FREE_OBJECTID)) { |
3c1d84b7 ST |
549 | btrfs_warn(root->fs_info, |
550 | "the objectid of root %llu reaches its highest value", | |
551 | root->root_key.objectid); | |
13a8a7c8 YZ |
552 | ret = -ENOSPC; |
553 | goto out; | |
9f5fae2f | 554 | } |
13a8a7c8 YZ |
555 | |
556 | *objectid = ++root->highest_objectid; | |
557 | ret = 0; | |
558 | out: | |
a2135011 | 559 | mutex_unlock(&root->objectid_mutex); |
9f5fae2f CM |
560 | return ret; |
561 | } |