~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/btrfs/root-tree.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * Copyright (C) 2007 Oracle.  All rights reserved.
  4  */
  5 
  6 #include <linux/err.h>
  7 #include <linux/uuid.h>
  8 #include "ctree.h"
  9 #include "fs.h"
 10 #include "messages.h"
 11 #include "transaction.h"
 12 #include "disk-io.h"
 13 #include "qgroup.h"
 14 #include "space-info.h"
 15 #include "accessors.h"
 16 #include "root-tree.h"
 17 #include "orphan.h"
 18 
 19 /*
 20  * Read a root item from the tree. In case we detect a root item smaller then
 21  * sizeof(root_item), we know it's an old version of the root structure and
 22  * initialize all new fields to zero. The same happens if we detect mismatching
 23  * generation numbers as then we know the root was once mounted with an older
 24  * kernel that was not aware of the root item structure change.
 25  */
 26 static void btrfs_read_root_item(struct extent_buffer *eb, int slot,
 27                                 struct btrfs_root_item *item)
 28 {
 29         u32 len;
 30         int need_reset = 0;
 31 
 32         len = btrfs_item_size(eb, slot);
 33         read_extent_buffer(eb, item, btrfs_item_ptr_offset(eb, slot),
 34                            min_t(u32, len, sizeof(*item)));
 35         if (len < sizeof(*item))
 36                 need_reset = 1;
 37         if (!need_reset && btrfs_root_generation(item)
 38                 != btrfs_root_generation_v2(item)) {
 39                 if (btrfs_root_generation_v2(item) != 0) {
 40                         btrfs_warn(eb->fs_info,
 41                                         "mismatching generation and generation_v2 found in root item. This root was probably mounted with an older kernel. Resetting all new fields.");
 42                 }
 43                 need_reset = 1;
 44         }
 45         if (need_reset) {
 46                 /* Clear all members from generation_v2 onwards. */
 47                 memset_startat(item, 0, generation_v2);
 48                 generate_random_guid(item->uuid);
 49         }
 50 }
 51 
 52 /*
 53  * Lookup the root by the key.
 54  *
 55  * root: the root of the root tree
 56  * search_key: the key to search
 57  * path: the path we search
 58  * root_item: the root item of the tree we look for
 59  * root_key: the root key of the tree we look for
 60  *
 61  * If ->offset of 'search_key' is -1ULL, it means we are not sure the offset
 62  * of the search key, just lookup the root with the highest offset for a
 63  * given objectid.
 64  *
 65  * If we find something return 0, otherwise > 0, < 0 on error.
 66  */
 67 int btrfs_find_root(struct btrfs_root *root, const struct btrfs_key *search_key,
 68                     struct btrfs_path *path, struct btrfs_root_item *root_item,
 69                     struct btrfs_key *root_key)
 70 {
 71         struct btrfs_key found_key;
 72         struct extent_buffer *l;
 73         int ret;
 74         int slot;
 75 
 76         ret = btrfs_search_slot(NULL, root, search_key, path, 0, 0);
 77         if (ret < 0)
 78                 return ret;
 79 
 80         if (search_key->offset != -1ULL) {      /* the search key is exact */
 81                 if (ret > 0)
 82                         goto out;
 83         } else {
 84                 /*
 85                  * Key with offset -1 found, there would have to exist a root
 86                  * with such id, but this is out of the valid range.
 87                  */
 88                 if (ret == 0) {
 89                         ret = -EUCLEAN;
 90                         goto out;
 91                 }
 92                 if (path->slots[0] == 0)
 93                         goto out;
 94                 path->slots[0]--;
 95                 ret = 0;
 96         }
 97 
 98         l = path->nodes[0];
 99         slot = path->slots[0];
100 
101         btrfs_item_key_to_cpu(l, &found_key, slot);
102         if (found_key.objectid != search_key->objectid ||
103             found_key.type != BTRFS_ROOT_ITEM_KEY) {
104                 ret = 1;
105                 goto out;
106         }
107 
108         if (root_item)
109                 btrfs_read_root_item(l, slot, root_item);
110         if (root_key)
111                 memcpy(root_key, &found_key, sizeof(found_key));
112 out:
113         btrfs_release_path(path);
114         return ret;
115 }
116 
117 void btrfs_set_root_node(struct btrfs_root_item *item,
118                          struct extent_buffer *node)
119 {
120         btrfs_set_root_bytenr(item, node->start);
121         btrfs_set_root_level(item, btrfs_header_level(node));
122         btrfs_set_root_generation(item, btrfs_header_generation(node));
123 }
124 
125 /*
126  * copy the data in 'item' into the btree
127  */
128 int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
129                       *root, struct btrfs_key *key, struct btrfs_root_item
130                       *item)
131 {
132         struct btrfs_fs_info *fs_info = root->fs_info;
133         struct btrfs_path *path;
134         struct extent_buffer *l;
135         int ret;
136         int slot;
137         unsigned long ptr;
138         u32 old_len;
139 
140         path = btrfs_alloc_path();
141         if (!path)
142                 return -ENOMEM;
143 
144         ret = btrfs_search_slot(trans, root, key, path, 0, 1);
145         if (ret < 0)
146                 goto out;
147 
148         if (ret > 0) {
149                 btrfs_crit(fs_info,
150                         "unable to find root key (%llu %u %llu) in tree %llu",
151                         key->objectid, key->type, key->offset, btrfs_root_id(root));
152                 ret = -EUCLEAN;
153                 btrfs_abort_transaction(trans, ret);
154                 goto out;
155         }
156 
157         l = path->nodes[0];
158         slot = path->slots[0];
159         ptr = btrfs_item_ptr_offset(l, slot);
160         old_len = btrfs_item_size(l, slot);
161 
162         /*
163          * If this is the first time we update the root item which originated
164          * from an older kernel, we need to enlarge the item size to make room
165          * for the added fields.
166          */
167         if (old_len < sizeof(*item)) {
168                 btrfs_release_path(path);
169                 ret = btrfs_search_slot(trans, root, key, path,
170                                 -1, 1);
171                 if (ret < 0) {
172                         btrfs_abort_transaction(trans, ret);
173                         goto out;
174                 }
175 
176                 ret = btrfs_del_item(trans, root, path);
177                 if (ret < 0) {
178                         btrfs_abort_transaction(trans, ret);
179                         goto out;
180                 }
181                 btrfs_release_path(path);
182                 ret = btrfs_insert_empty_item(trans, root, path,
183                                 key, sizeof(*item));
184                 if (ret < 0) {
185                         btrfs_abort_transaction(trans, ret);
186                         goto out;
187                 }
188                 l = path->nodes[0];
189                 slot = path->slots[0];
190                 ptr = btrfs_item_ptr_offset(l, slot);
191         }
192 
193         /*
194          * Update generation_v2 so at the next mount we know the new root
195          * fields are valid.
196          */
197         btrfs_set_root_generation_v2(item, btrfs_root_generation(item));
198 
199         write_extent_buffer(l, item, ptr, sizeof(*item));
200         btrfs_mark_buffer_dirty(trans, path->nodes[0]);
201 out:
202         btrfs_free_path(path);
203         return ret;
204 }
205 
206 int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
207                       const struct btrfs_key *key, struct btrfs_root_item *item)
208 {
209         /*
210          * Make sure generation v1 and v2 match. See update_root for details.
211          */
212         btrfs_set_root_generation_v2(item, btrfs_root_generation(item));
213         return btrfs_insert_item(trans, root, key, item, sizeof(*item));
214 }
215 
216 int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info)
217 {
218         struct btrfs_root *tree_root = fs_info->tree_root;
219         struct extent_buffer *leaf;
220         struct btrfs_path *path;
221         struct btrfs_key key;
222         struct btrfs_root *root;
223         int err = 0;
224         int ret;
225 
226         path = btrfs_alloc_path();
227         if (!path)
228                 return -ENOMEM;
229 
230         key.objectid = BTRFS_ORPHAN_OBJECTID;
231         key.type = BTRFS_ORPHAN_ITEM_KEY;
232         key.offset = 0;
233 
234         while (1) {
235                 u64 root_objectid;
236 
237                 ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0);
238                 if (ret < 0) {
239                         err = ret;
240                         break;
241                 }
242 
243                 leaf = path->nodes[0];
244                 if (path->slots[0] >= btrfs_header_nritems(leaf)) {
245                         ret = btrfs_next_leaf(tree_root, path);
246                         if (ret < 0)
247                                 err = ret;
248                         if (ret != 0)
249                                 break;
250                         leaf = path->nodes[0];
251                 }
252 
253                 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
254                 btrfs_release_path(path);
255 
256                 if (key.objectid != BTRFS_ORPHAN_OBJECTID ||
257                     key.type != BTRFS_ORPHAN_ITEM_KEY)
258                         break;
259 
260                 root_objectid = key.offset;
261                 key.offset++;
262 
263                 root = btrfs_get_fs_root(fs_info, root_objectid, false);
264                 err = PTR_ERR_OR_ZERO(root);
265                 if (err && err != -ENOENT) {
266                         break;
267                 } else if (err == -ENOENT) {
268                         struct btrfs_trans_handle *trans;
269 
270                         btrfs_release_path(path);
271 
272                         trans = btrfs_join_transaction(tree_root);
273                         if (IS_ERR(trans)) {
274                                 err = PTR_ERR(trans);
275                                 btrfs_handle_fs_error(fs_info, err,
276                                             "Failed to start trans to delete orphan item");
277                                 break;
278                         }
279                         err = btrfs_del_orphan_item(trans, tree_root,
280                                                     root_objectid);
281                         btrfs_end_transaction(trans);
282                         if (err) {
283                                 btrfs_handle_fs_error(fs_info, err,
284                                             "Failed to delete root orphan item");
285                                 break;
286                         }
287                         continue;
288                 }
289 
290                 WARN_ON(!test_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state));
291                 if (btrfs_root_refs(&root->root_item) == 0) {
292                         struct btrfs_key drop_key;
293 
294                         btrfs_disk_key_to_cpu(&drop_key, &root->root_item.drop_progress);
295                         /*
296                          * If we have a non-zero drop_progress then we know we
297                          * made it partly through deleting this snapshot, and
298                          * thus we need to make sure we block any balance from
299                          * happening until this snapshot is completely dropped.
300                          */
301                         if (drop_key.objectid != 0 || drop_key.type != 0 ||
302                             drop_key.offset != 0) {
303                                 set_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags);
304                                 set_bit(BTRFS_ROOT_UNFINISHED_DROP, &root->state);
305                         }
306 
307                         set_bit(BTRFS_ROOT_DEAD_TREE, &root->state);
308                         btrfs_add_dead_root(root);
309                 }
310                 btrfs_put_root(root);
311         }
312 
313         btrfs_free_path(path);
314         return err;
315 }
316 
317 /* drop the root item for 'key' from the tree root */
318 int btrfs_del_root(struct btrfs_trans_handle *trans,
319                    const struct btrfs_key *key)
320 {
321         struct btrfs_root *root = trans->fs_info->tree_root;
322         struct btrfs_path *path;
323         int ret;
324 
325         path = btrfs_alloc_path();
326         if (!path)
327                 return -ENOMEM;
328         ret = btrfs_search_slot(trans, root, key, path, -1, 1);
329         if (ret < 0)
330                 goto out;
331         if (ret != 0) {
332                 /* The root must exist but we did not find it by the key. */
333                 ret = -EUCLEAN;
334                 goto out;
335         }
336 
337         ret = btrfs_del_item(trans, root, path);
338 out:
339         btrfs_free_path(path);
340         return ret;
341 }
342 
343 int btrfs_del_root_ref(struct btrfs_trans_handle *trans, u64 root_id,
344                        u64 ref_id, u64 dirid, u64 *sequence,
345                        const struct fscrypt_str *name)
346 {
347         struct btrfs_root *tree_root = trans->fs_info->tree_root;
348         struct btrfs_path *path;
349         struct btrfs_root_ref *ref;
350         struct extent_buffer *leaf;
351         struct btrfs_key key;
352         unsigned long ptr;
353         int ret;
354 
355         path = btrfs_alloc_path();
356         if (!path)
357                 return -ENOMEM;
358 
359         key.objectid = root_id;
360         key.type = BTRFS_ROOT_BACKREF_KEY;
361         key.offset = ref_id;
362 again:
363         ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1);
364         if (ret < 0) {
365                 goto out;
366         } else if (ret == 0) {
367                 leaf = path->nodes[0];
368                 ref = btrfs_item_ptr(leaf, path->slots[0],
369                                      struct btrfs_root_ref);
370                 ptr = (unsigned long)(ref + 1);
371                 if ((btrfs_root_ref_dirid(leaf, ref) != dirid) ||
372                     (btrfs_root_ref_name_len(leaf, ref) != name->len) ||
373                     memcmp_extent_buffer(leaf, name->name, ptr, name->len)) {
374                         ret = -ENOENT;
375                         goto out;
376                 }
377                 *sequence = btrfs_root_ref_sequence(leaf, ref);
378 
379                 ret = btrfs_del_item(trans, tree_root, path);
380                 if (ret)
381                         goto out;
382         } else {
383                 ret = -ENOENT;
384                 goto out;
385         }
386 
387         if (key.type == BTRFS_ROOT_BACKREF_KEY) {
388                 btrfs_release_path(path);
389                 key.objectid = ref_id;
390                 key.type = BTRFS_ROOT_REF_KEY;
391                 key.offset = root_id;
392                 goto again;
393         }
394 
395 out:
396         btrfs_free_path(path);
397         return ret;
398 }
399 
400 /*
401  * add a btrfs_root_ref item.  type is either BTRFS_ROOT_REF_KEY
402  * or BTRFS_ROOT_BACKREF_KEY.
403  *
404  * The dirid, sequence, name and name_len refer to the directory entry
405  * that is referencing the root.
406  *
407  * For a forward ref, the root_id is the id of the tree referencing
408  * the root and ref_id is the id of the subvol  or snapshot.
409  *
410  * For a back ref the root_id is the id of the subvol or snapshot and
411  * ref_id is the id of the tree referencing it.
412  *
413  * Will return 0, -ENOMEM, or anything from the CoW path
414  */
415 int btrfs_add_root_ref(struct btrfs_trans_handle *trans, u64 root_id,
416                        u64 ref_id, u64 dirid, u64 sequence,
417                        const struct fscrypt_str *name)
418 {
419         struct btrfs_root *tree_root = trans->fs_info->tree_root;
420         struct btrfs_key key;
421         int ret;
422         struct btrfs_path *path;
423         struct btrfs_root_ref *ref;
424         struct extent_buffer *leaf;
425         unsigned long ptr;
426 
427         path = btrfs_alloc_path();
428         if (!path)
429                 return -ENOMEM;
430 
431         key.objectid = root_id;
432         key.type = BTRFS_ROOT_BACKREF_KEY;
433         key.offset = ref_id;
434 again:
435         ret = btrfs_insert_empty_item(trans, tree_root, path, &key,
436                                       sizeof(*ref) + name->len);
437         if (ret) {
438                 btrfs_abort_transaction(trans, ret);
439                 btrfs_free_path(path);
440                 return ret;
441         }
442 
443         leaf = path->nodes[0];
444         ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref);
445         btrfs_set_root_ref_dirid(leaf, ref, dirid);
446         btrfs_set_root_ref_sequence(leaf, ref, sequence);
447         btrfs_set_root_ref_name_len(leaf, ref, name->len);
448         ptr = (unsigned long)(ref + 1);
449         write_extent_buffer(leaf, name->name, ptr, name->len);
450         btrfs_mark_buffer_dirty(trans, leaf);
451 
452         if (key.type == BTRFS_ROOT_BACKREF_KEY) {
453                 btrfs_release_path(path);
454                 key.objectid = ref_id;
455                 key.type = BTRFS_ROOT_REF_KEY;
456                 key.offset = root_id;
457                 goto again;
458         }
459 
460         btrfs_free_path(path);
461         return 0;
462 }
463 
464 /*
465  * Old btrfs forgets to init root_item->flags and root_item->byte_limit
466  * for subvolumes. To work around this problem, we steal a bit from
467  * root_item->inode_item->flags, and use it to indicate if those fields
468  * have been properly initialized.
469  */
470 void btrfs_check_and_init_root_item(struct btrfs_root_item *root_item)
471 {
472         u64 inode_flags = btrfs_stack_inode_flags(&root_item->inode);
473 
474         if (!(inode_flags & BTRFS_INODE_ROOT_ITEM_INIT)) {
475                 inode_flags |= BTRFS_INODE_ROOT_ITEM_INIT;
476                 btrfs_set_stack_inode_flags(&root_item->inode, inode_flags);
477                 btrfs_set_root_flags(root_item, 0);
478                 btrfs_set_root_limit(root_item, 0);
479         }
480 }
481 
482 void btrfs_update_root_times(struct btrfs_trans_handle *trans,
483                              struct btrfs_root *root)
484 {
485         struct btrfs_root_item *item = &root->root_item;
486         struct timespec64 ct;
487 
488         ktime_get_real_ts64(&ct);
489         spin_lock(&root->root_item_lock);
490         btrfs_set_root_ctransid(item, trans->transid);
491         btrfs_set_stack_timespec_sec(&item->ctime, ct.tv_sec);
492         btrfs_set_stack_timespec_nsec(&item->ctime, ct.tv_nsec);
493         spin_unlock(&root->root_item_lock);
494 }
495 
496 /*
497  * Reserve space for subvolume operation.
498  *
499  * root: the root of the parent directory
500  * rsv: block reservation
501  * items: the number of items that we need do reservation
502  * use_global_rsv: allow fallback to the global block reservation
503  *
504  * This function is used to reserve the space for snapshot/subvolume
505  * creation and deletion. Those operations are different with the
506  * common file/directory operations, they change two fs/file trees
507  * and root tree, the number of items that the qgroup reserves is
508  * different with the free space reservation. So we can not use
509  * the space reservation mechanism in start_transaction().
510  */
511 int btrfs_subvolume_reserve_metadata(struct btrfs_root *root,
512                                      struct btrfs_block_rsv *rsv, int items,
513                                      bool use_global_rsv)
514 {
515         u64 qgroup_num_bytes = 0;
516         u64 num_bytes;
517         int ret;
518         struct btrfs_fs_info *fs_info = root->fs_info;
519         struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv;
520 
521         if (btrfs_qgroup_enabled(fs_info)) {
522                 /* One for parent inode, two for dir entries */
523                 qgroup_num_bytes = 3 * fs_info->nodesize;
524                 ret = btrfs_qgroup_reserve_meta_prealloc(root,
525                                                          qgroup_num_bytes, true,
526                                                          false);
527                 if (ret)
528                         return ret;
529         }
530 
531         num_bytes = btrfs_calc_insert_metadata_size(fs_info, items);
532         rsv->space_info = btrfs_find_space_info(fs_info,
533                                             BTRFS_BLOCK_GROUP_METADATA);
534         ret = btrfs_block_rsv_add(fs_info, rsv, num_bytes,
535                                   BTRFS_RESERVE_FLUSH_ALL);
536 
537         if (ret == -ENOSPC && use_global_rsv)
538                 ret = btrfs_block_rsv_migrate(global_rsv, rsv, num_bytes, true);
539 
540         if (ret && qgroup_num_bytes)
541                 btrfs_qgroup_free_meta_prealloc(root, qgroup_num_bytes);
542 
543         if (!ret) {
544                 spin_lock(&rsv->lock);
545                 rsv->qgroup_rsv_reserved += qgroup_num_bytes;
546                 spin_unlock(&rsv->lock);
547         }
548         return ret;
549 }
550 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php