Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2007 Oracle.  All rights reserved.
0004  */
0005 
0006 #include "ctree.h"
0007 #include "inode-item.h"
0008 #include "disk-io.h"
0009 #include "transaction.h"
0010 #include "print-tree.h"
0011 
0012 struct btrfs_inode_ref *btrfs_find_name_in_backref(struct extent_buffer *leaf,
0013                            int slot, const char *name,
0014                            int name_len)
0015 {
0016     struct btrfs_inode_ref *ref;
0017     unsigned long ptr;
0018     unsigned long name_ptr;
0019     u32 item_size;
0020     u32 cur_offset = 0;
0021     int len;
0022 
0023     item_size = btrfs_item_size(leaf, slot);
0024     ptr = btrfs_item_ptr_offset(leaf, slot);
0025     while (cur_offset < item_size) {
0026         ref = (struct btrfs_inode_ref *)(ptr + cur_offset);
0027         len = btrfs_inode_ref_name_len(leaf, ref);
0028         name_ptr = (unsigned long)(ref + 1);
0029         cur_offset += len + sizeof(*ref);
0030         if (len != name_len)
0031             continue;
0032         if (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0)
0033             return ref;
0034     }
0035     return NULL;
0036 }
0037 
0038 struct btrfs_inode_extref *btrfs_find_name_in_ext_backref(
0039         struct extent_buffer *leaf, int slot, u64 ref_objectid,
0040         const char *name, int name_len)
0041 {
0042     struct btrfs_inode_extref *extref;
0043     unsigned long ptr;
0044     unsigned long name_ptr;
0045     u32 item_size;
0046     u32 cur_offset = 0;
0047     int ref_name_len;
0048 
0049     item_size = btrfs_item_size(leaf, slot);
0050     ptr = btrfs_item_ptr_offset(leaf, slot);
0051 
0052     /*
0053      * Search all extended backrefs in this item. We're only
0054      * looking through any collisions so most of the time this is
0055      * just going to compare against one buffer. If all is well,
0056      * we'll return success and the inode ref object.
0057      */
0058     while (cur_offset < item_size) {
0059         extref = (struct btrfs_inode_extref *) (ptr + cur_offset);
0060         name_ptr = (unsigned long)(&extref->name);
0061         ref_name_len = btrfs_inode_extref_name_len(leaf, extref);
0062 
0063         if (ref_name_len == name_len &&
0064             btrfs_inode_extref_parent(leaf, extref) == ref_objectid &&
0065             (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0))
0066             return extref;
0067 
0068         cur_offset += ref_name_len + sizeof(*extref);
0069     }
0070     return NULL;
0071 }
0072 
0073 /* Returns NULL if no extref found */
0074 struct btrfs_inode_extref *
0075 btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
0076               struct btrfs_root *root,
0077               struct btrfs_path *path,
0078               const char *name, int name_len,
0079               u64 inode_objectid, u64 ref_objectid, int ins_len,
0080               int cow)
0081 {
0082     int ret;
0083     struct btrfs_key key;
0084 
0085     key.objectid = inode_objectid;
0086     key.type = BTRFS_INODE_EXTREF_KEY;
0087     key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
0088 
0089     ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
0090     if (ret < 0)
0091         return ERR_PTR(ret);
0092     if (ret > 0)
0093         return NULL;
0094     return btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0],
0095                           ref_objectid, name, name_len);
0096 
0097 }
0098 
0099 static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
0100                   struct btrfs_root *root,
0101                   const char *name, int name_len,
0102                   u64 inode_objectid, u64 ref_objectid,
0103                   u64 *index)
0104 {
0105     struct btrfs_path *path;
0106     struct btrfs_key key;
0107     struct btrfs_inode_extref *extref;
0108     struct extent_buffer *leaf;
0109     int ret;
0110     int del_len = name_len + sizeof(*extref);
0111     unsigned long ptr;
0112     unsigned long item_start;
0113     u32 item_size;
0114 
0115     key.objectid = inode_objectid;
0116     key.type = BTRFS_INODE_EXTREF_KEY;
0117     key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
0118 
0119     path = btrfs_alloc_path();
0120     if (!path)
0121         return -ENOMEM;
0122 
0123     ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
0124     if (ret > 0)
0125         ret = -ENOENT;
0126     if (ret < 0)
0127         goto out;
0128 
0129     /*
0130      * Sanity check - did we find the right item for this name?
0131      * This should always succeed so error here will make the FS
0132      * readonly.
0133      */
0134     extref = btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0],
0135                         ref_objectid, name, name_len);
0136     if (!extref) {
0137         btrfs_handle_fs_error(root->fs_info, -ENOENT, NULL);
0138         ret = -EROFS;
0139         goto out;
0140     }
0141 
0142     leaf = path->nodes[0];
0143     item_size = btrfs_item_size(leaf, path->slots[0]);
0144     if (index)
0145         *index = btrfs_inode_extref_index(leaf, extref);
0146 
0147     if (del_len == item_size) {
0148         /*
0149          * Common case only one ref in the item, remove the
0150          * whole item.
0151          */
0152         ret = btrfs_del_item(trans, root, path);
0153         goto out;
0154     }
0155 
0156     ptr = (unsigned long)extref;
0157     item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
0158 
0159     memmove_extent_buffer(leaf, ptr, ptr + del_len,
0160                   item_size - (ptr + del_len - item_start));
0161 
0162     btrfs_truncate_item(path, item_size - del_len, 1);
0163 
0164 out:
0165     btrfs_free_path(path);
0166 
0167     return ret;
0168 }
0169 
0170 int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
0171             struct btrfs_root *root,
0172             const char *name, int name_len,
0173             u64 inode_objectid, u64 ref_objectid, u64 *index)
0174 {
0175     struct btrfs_path *path;
0176     struct btrfs_key key;
0177     struct btrfs_inode_ref *ref;
0178     struct extent_buffer *leaf;
0179     unsigned long ptr;
0180     unsigned long item_start;
0181     u32 item_size;
0182     u32 sub_item_len;
0183     int ret;
0184     int search_ext_refs = 0;
0185     int del_len = name_len + sizeof(*ref);
0186 
0187     key.objectid = inode_objectid;
0188     key.offset = ref_objectid;
0189     key.type = BTRFS_INODE_REF_KEY;
0190 
0191     path = btrfs_alloc_path();
0192     if (!path)
0193         return -ENOMEM;
0194 
0195     ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
0196     if (ret > 0) {
0197         ret = -ENOENT;
0198         search_ext_refs = 1;
0199         goto out;
0200     } else if (ret < 0) {
0201         goto out;
0202     }
0203 
0204     ref = btrfs_find_name_in_backref(path->nodes[0], path->slots[0], name,
0205                      name_len);
0206     if (!ref) {
0207         ret = -ENOENT;
0208         search_ext_refs = 1;
0209         goto out;
0210     }
0211     leaf = path->nodes[0];
0212     item_size = btrfs_item_size(leaf, path->slots[0]);
0213 
0214     if (index)
0215         *index = btrfs_inode_ref_index(leaf, ref);
0216 
0217     if (del_len == item_size) {
0218         ret = btrfs_del_item(trans, root, path);
0219         goto out;
0220     }
0221     ptr = (unsigned long)ref;
0222     sub_item_len = name_len + sizeof(*ref);
0223     item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
0224     memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
0225                   item_size - (ptr + sub_item_len - item_start));
0226     btrfs_truncate_item(path, item_size - sub_item_len, 1);
0227 out:
0228     btrfs_free_path(path);
0229 
0230     if (search_ext_refs) {
0231         /*
0232          * No refs were found, or we could not find the
0233          * name in our ref array. Find and remove the extended
0234          * inode ref then.
0235          */
0236         return btrfs_del_inode_extref(trans, root, name, name_len,
0237                           inode_objectid, ref_objectid, index);
0238     }
0239 
0240     return ret;
0241 }
0242 
0243 /*
0244  * btrfs_insert_inode_extref() - Inserts an extended inode ref into a tree.
0245  *
0246  * The caller must have checked against BTRFS_LINK_MAX already.
0247  */
0248 static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans,
0249                      struct btrfs_root *root,
0250                      const char *name, int name_len,
0251                      u64 inode_objectid, u64 ref_objectid, u64 index)
0252 {
0253     struct btrfs_inode_extref *extref;
0254     int ret;
0255     int ins_len = name_len + sizeof(*extref);
0256     unsigned long ptr;
0257     struct btrfs_path *path;
0258     struct btrfs_key key;
0259     struct extent_buffer *leaf;
0260 
0261     key.objectid = inode_objectid;
0262     key.type = BTRFS_INODE_EXTREF_KEY;
0263     key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
0264 
0265     path = btrfs_alloc_path();
0266     if (!path)
0267         return -ENOMEM;
0268 
0269     ret = btrfs_insert_empty_item(trans, root, path, &key,
0270                       ins_len);
0271     if (ret == -EEXIST) {
0272         if (btrfs_find_name_in_ext_backref(path->nodes[0],
0273                            path->slots[0],
0274                            ref_objectid,
0275                            name, name_len))
0276             goto out;
0277 
0278         btrfs_extend_item(path, ins_len);
0279         ret = 0;
0280     }
0281     if (ret < 0)
0282         goto out;
0283 
0284     leaf = path->nodes[0];
0285     ptr = (unsigned long)btrfs_item_ptr(leaf, path->slots[0], char);
0286     ptr += btrfs_item_size(leaf, path->slots[0]) - ins_len;
0287     extref = (struct btrfs_inode_extref *)ptr;
0288 
0289     btrfs_set_inode_extref_name_len(path->nodes[0], extref, name_len);
0290     btrfs_set_inode_extref_index(path->nodes[0], extref, index);
0291     btrfs_set_inode_extref_parent(path->nodes[0], extref, ref_objectid);
0292 
0293     ptr = (unsigned long)&extref->name;
0294     write_extent_buffer(path->nodes[0], name, ptr, name_len);
0295     btrfs_mark_buffer_dirty(path->nodes[0]);
0296 
0297 out:
0298     btrfs_free_path(path);
0299     return ret;
0300 }
0301 
0302 /* Will return 0, -ENOMEM, -EMLINK, or -EEXIST or anything from the CoW path */
0303 int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
0304                struct btrfs_root *root,
0305                const char *name, int name_len,
0306                u64 inode_objectid, u64 ref_objectid, u64 index)
0307 {
0308     struct btrfs_fs_info *fs_info = root->fs_info;
0309     struct btrfs_path *path;
0310     struct btrfs_key key;
0311     struct btrfs_inode_ref *ref;
0312     unsigned long ptr;
0313     int ret;
0314     int ins_len = name_len + sizeof(*ref);
0315 
0316     key.objectid = inode_objectid;
0317     key.offset = ref_objectid;
0318     key.type = BTRFS_INODE_REF_KEY;
0319 
0320     path = btrfs_alloc_path();
0321     if (!path)
0322         return -ENOMEM;
0323 
0324     path->skip_release_on_error = 1;
0325     ret = btrfs_insert_empty_item(trans, root, path, &key,
0326                       ins_len);
0327     if (ret == -EEXIST) {
0328         u32 old_size;
0329         ref = btrfs_find_name_in_backref(path->nodes[0], path->slots[0],
0330                          name, name_len);
0331         if (ref)
0332             goto out;
0333 
0334         old_size = btrfs_item_size(path->nodes[0], path->slots[0]);
0335         btrfs_extend_item(path, ins_len);
0336         ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
0337                      struct btrfs_inode_ref);
0338         ref = (struct btrfs_inode_ref *)((unsigned long)ref + old_size);
0339         btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
0340         btrfs_set_inode_ref_index(path->nodes[0], ref, index);
0341         ptr = (unsigned long)(ref + 1);
0342         ret = 0;
0343     } else if (ret < 0) {
0344         if (ret == -EOVERFLOW) {
0345             if (btrfs_find_name_in_backref(path->nodes[0],
0346                                path->slots[0],
0347                                name, name_len))
0348                 ret = -EEXIST;
0349             else
0350                 ret = -EMLINK;
0351         }
0352         goto out;
0353     } else {
0354         ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
0355                      struct btrfs_inode_ref);
0356         btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
0357         btrfs_set_inode_ref_index(path->nodes[0], ref, index);
0358         ptr = (unsigned long)(ref + 1);
0359     }
0360     write_extent_buffer(path->nodes[0], name, ptr, name_len);
0361     btrfs_mark_buffer_dirty(path->nodes[0]);
0362 
0363 out:
0364     btrfs_free_path(path);
0365 
0366     if (ret == -EMLINK) {
0367         struct btrfs_super_block *disk_super = fs_info->super_copy;
0368         /* We ran out of space in the ref array. Need to
0369          * add an extended ref. */
0370         if (btrfs_super_incompat_flags(disk_super)
0371             & BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
0372             ret = btrfs_insert_inode_extref(trans, root, name,
0373                             name_len,
0374                             inode_objectid,
0375                             ref_objectid, index);
0376     }
0377 
0378     return ret;
0379 }
0380 
0381 int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans,
0382                  struct btrfs_root *root,
0383                  struct btrfs_path *path, u64 objectid)
0384 {
0385     struct btrfs_key key;
0386     int ret;
0387     key.objectid = objectid;
0388     key.type = BTRFS_INODE_ITEM_KEY;
0389     key.offset = 0;
0390 
0391     ret = btrfs_insert_empty_item(trans, root, path, &key,
0392                       sizeof(struct btrfs_inode_item));
0393     return ret;
0394 }
0395 
0396 int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
0397                *root, struct btrfs_path *path,
0398                struct btrfs_key *location, int mod)
0399 {
0400     int ins_len = mod < 0 ? -1 : 0;
0401     int cow = mod != 0;
0402     int ret;
0403     int slot;
0404     struct extent_buffer *leaf;
0405     struct btrfs_key found_key;
0406 
0407     ret = btrfs_search_slot(trans, root, location, path, ins_len, cow);
0408     if (ret > 0 && location->type == BTRFS_ROOT_ITEM_KEY &&
0409         location->offset == (u64)-1 && path->slots[0] != 0) {
0410         slot = path->slots[0] - 1;
0411         leaf = path->nodes[0];
0412         btrfs_item_key_to_cpu(leaf, &found_key, slot);
0413         if (found_key.objectid == location->objectid &&
0414             found_key.type == location->type) {
0415             path->slots[0]--;
0416             return 0;
0417         }
0418     }
0419     return ret;
0420 }
0421 
0422 static inline void btrfs_trace_truncate(struct btrfs_inode *inode,
0423                     struct extent_buffer *leaf,
0424                     struct btrfs_file_extent_item *fi,
0425                     u64 offset, int extent_type, int slot)
0426 {
0427     if (!inode)
0428         return;
0429     if (extent_type == BTRFS_FILE_EXTENT_INLINE)
0430         trace_btrfs_truncate_show_fi_inline(inode, leaf, fi, slot,
0431                             offset);
0432     else
0433         trace_btrfs_truncate_show_fi_regular(inode, leaf, fi, offset);
0434 }
0435 
0436 /*
0437  * Remove inode items from a given root.
0438  *
0439  * @trans:      A transaction handle.
0440  * @root:       The root from which to remove items.
0441  * @inode:      The inode whose items we want to remove.
0442  * @control:        The btrfs_truncate_control to control how and what we
0443  *          are truncating.
0444  *
0445  * Remove all keys associated with the inode from the given root that have a key
0446  * with a type greater than or equals to @min_type. When @min_type has a value of
0447  * BTRFS_EXTENT_DATA_KEY, only remove file extent items that have an offset value
0448  * greater than or equals to @new_size. If a file extent item that starts before
0449  * @new_size and ends after it is found, its length is adjusted.
0450  *
0451  * Returns: 0 on success, < 0 on error and NEED_TRUNCATE_BLOCK when @min_type is
0452  * BTRFS_EXTENT_DATA_KEY and the caller must truncate the last block.
0453  */
0454 int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
0455                    struct btrfs_root *root,
0456                    struct btrfs_truncate_control *control)
0457 {
0458     struct btrfs_fs_info *fs_info = root->fs_info;
0459     struct btrfs_path *path;
0460     struct extent_buffer *leaf;
0461     struct btrfs_file_extent_item *fi;
0462     struct btrfs_key key;
0463     struct btrfs_key found_key;
0464     u64 new_size = control->new_size;
0465     u64 extent_num_bytes = 0;
0466     u64 extent_offset = 0;
0467     u64 item_end = 0;
0468     u32 found_type = (u8)-1;
0469     int del_item;
0470     int pending_del_nr = 0;
0471     int pending_del_slot = 0;
0472     int extent_type = -1;
0473     int ret;
0474     u64 bytes_deleted = 0;
0475     bool be_nice = false;
0476 
0477     ASSERT(control->inode || !control->clear_extent_range);
0478     ASSERT(new_size == 0 || control->min_type == BTRFS_EXTENT_DATA_KEY);
0479 
0480     control->last_size = new_size;
0481     control->sub_bytes = 0;
0482 
0483     /*
0484      * For shareable roots we want to back off from time to time, this turns
0485      * out to be subvolume roots, reloc roots, and data reloc roots.
0486      */
0487     if (test_bit(BTRFS_ROOT_SHAREABLE, &root->state))
0488         be_nice = true;
0489 
0490     path = btrfs_alloc_path();
0491     if (!path)
0492         return -ENOMEM;
0493     path->reada = READA_BACK;
0494 
0495     key.objectid = control->ino;
0496     key.offset = (u64)-1;
0497     key.type = (u8)-1;
0498 
0499 search_again:
0500     /*
0501      * With a 16K leaf size and 128MiB extents, you can actually queue up a
0502      * huge file in a single leaf.  Most of the time that bytes_deleted is
0503      * > 0, it will be huge by the time we get here
0504      */
0505     if (be_nice && bytes_deleted > SZ_32M &&
0506         btrfs_should_end_transaction(trans)) {
0507         ret = -EAGAIN;
0508         goto out;
0509     }
0510 
0511     ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
0512     if (ret < 0)
0513         goto out;
0514 
0515     if (ret > 0) {
0516         ret = 0;
0517         /* There are no items in the tree for us to truncate, we're done */
0518         if (path->slots[0] == 0)
0519             goto out;
0520         path->slots[0]--;
0521     }
0522 
0523     while (1) {
0524         u64 clear_start = 0, clear_len = 0, extent_start = 0;
0525         bool should_throttle = false;
0526 
0527         fi = NULL;
0528         leaf = path->nodes[0];
0529         btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
0530         found_type = found_key.type;
0531 
0532         if (found_key.objectid != control->ino)
0533             break;
0534 
0535         if (found_type < control->min_type)
0536             break;
0537 
0538         item_end = found_key.offset;
0539         if (found_type == BTRFS_EXTENT_DATA_KEY) {
0540             fi = btrfs_item_ptr(leaf, path->slots[0],
0541                         struct btrfs_file_extent_item);
0542             extent_type = btrfs_file_extent_type(leaf, fi);
0543             if (extent_type != BTRFS_FILE_EXTENT_INLINE)
0544                 item_end +=
0545                     btrfs_file_extent_num_bytes(leaf, fi);
0546             else if (extent_type == BTRFS_FILE_EXTENT_INLINE)
0547                 item_end += btrfs_file_extent_ram_bytes(leaf, fi);
0548 
0549             btrfs_trace_truncate(control->inode, leaf, fi,
0550                          found_key.offset, extent_type,
0551                          path->slots[0]);
0552             item_end--;
0553         }
0554         if (found_type > control->min_type) {
0555             del_item = 1;
0556         } else {
0557             if (item_end < new_size)
0558                 break;
0559             if (found_key.offset >= new_size)
0560                 del_item = 1;
0561             else
0562                 del_item = 0;
0563         }
0564 
0565         /* FIXME, shrink the extent if the ref count is only 1 */
0566         if (found_type != BTRFS_EXTENT_DATA_KEY)
0567             goto delete;
0568 
0569         control->extents_found++;
0570 
0571         if (extent_type != BTRFS_FILE_EXTENT_INLINE) {
0572             u64 num_dec;
0573 
0574             clear_start = found_key.offset;
0575             extent_start = btrfs_file_extent_disk_bytenr(leaf, fi);
0576             if (!del_item) {
0577                 u64 orig_num_bytes =
0578                     btrfs_file_extent_num_bytes(leaf, fi);
0579                 extent_num_bytes = ALIGN(new_size -
0580                         found_key.offset,
0581                         fs_info->sectorsize);
0582                 clear_start = ALIGN(new_size, fs_info->sectorsize);
0583 
0584                 btrfs_set_file_extent_num_bytes(leaf, fi,
0585                              extent_num_bytes);
0586                 num_dec = (orig_num_bytes - extent_num_bytes);
0587                 if (extent_start != 0)
0588                     control->sub_bytes += num_dec;
0589                 btrfs_mark_buffer_dirty(leaf);
0590             } else {
0591                 extent_num_bytes =
0592                     btrfs_file_extent_disk_num_bytes(leaf, fi);
0593                 extent_offset = found_key.offset -
0594                     btrfs_file_extent_offset(leaf, fi);
0595 
0596                 /* FIXME blocksize != 4096 */
0597                 num_dec = btrfs_file_extent_num_bytes(leaf, fi);
0598                 if (extent_start != 0)
0599                     control->sub_bytes += num_dec;
0600             }
0601             clear_len = num_dec;
0602         } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
0603             /*
0604              * We can't truncate inline items that have had
0605              * special encodings
0606              */
0607             if (!del_item &&
0608                 btrfs_file_extent_encryption(leaf, fi) == 0 &&
0609                 btrfs_file_extent_other_encoding(leaf, fi) == 0 &&
0610                 btrfs_file_extent_compression(leaf, fi) == 0) {
0611                 u32 size = (u32)(new_size - found_key.offset);
0612 
0613                 btrfs_set_file_extent_ram_bytes(leaf, fi, size);
0614                 size = btrfs_file_extent_calc_inline_size(size);
0615                 btrfs_truncate_item(path, size, 1);
0616             } else if (!del_item) {
0617                 /*
0618                  * We have to bail so the last_size is set to
0619                  * just before this extent.
0620                  */
0621                 ret = BTRFS_NEED_TRUNCATE_BLOCK;
0622                 break;
0623             } else {
0624                 /*
0625                  * Inline extents are special, we just treat
0626                  * them as a full sector worth in the file
0627                  * extent tree just for simplicity sake.
0628                  */
0629                 clear_len = fs_info->sectorsize;
0630             }
0631 
0632             control->sub_bytes += item_end + 1 - new_size;
0633         }
0634 delete:
0635         /*
0636          * We only want to clear the file extent range if we're
0637          * modifying the actual inode's mapping, which is just the
0638          * normal truncate path.
0639          */
0640         if (control->clear_extent_range) {
0641             ret = btrfs_inode_clear_file_extent_range(control->inode,
0642                           clear_start, clear_len);
0643             if (ret) {
0644                 btrfs_abort_transaction(trans, ret);
0645                 break;
0646             }
0647         }
0648 
0649         if (del_item) {
0650             ASSERT(!pending_del_nr ||
0651                    ((path->slots[0] + 1) == pending_del_slot));
0652 
0653             control->last_size = found_key.offset;
0654             if (!pending_del_nr) {
0655                 /* No pending yet, add ourselves */
0656                 pending_del_slot = path->slots[0];
0657                 pending_del_nr = 1;
0658             } else if (pending_del_nr &&
0659                    path->slots[0] + 1 == pending_del_slot) {
0660                 /* Hop on the pending chunk */
0661                 pending_del_nr++;
0662                 pending_del_slot = path->slots[0];
0663             }
0664         } else {
0665             control->last_size = new_size;
0666             break;
0667         }
0668 
0669         if (del_item && extent_start != 0 && !control->skip_ref_updates) {
0670             struct btrfs_ref ref = { 0 };
0671 
0672             bytes_deleted += extent_num_bytes;
0673 
0674             btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF,
0675                     extent_start, extent_num_bytes, 0);
0676             btrfs_init_data_ref(&ref, btrfs_header_owner(leaf),
0677                     control->ino, extent_offset,
0678                     root->root_key.objectid, false);
0679             ret = btrfs_free_extent(trans, &ref);
0680             if (ret) {
0681                 btrfs_abort_transaction(trans, ret);
0682                 break;
0683             }
0684             if (be_nice) {
0685                 if (btrfs_should_throttle_delayed_refs(trans))
0686                     should_throttle = true;
0687             }
0688         }
0689 
0690         if (found_type == BTRFS_INODE_ITEM_KEY)
0691             break;
0692 
0693         if (path->slots[0] == 0 ||
0694             path->slots[0] != pending_del_slot ||
0695             should_throttle) {
0696             if (pending_del_nr) {
0697                 ret = btrfs_del_items(trans, root, path,
0698                         pending_del_slot,
0699                         pending_del_nr);
0700                 if (ret) {
0701                     btrfs_abort_transaction(trans, ret);
0702                     break;
0703                 }
0704                 pending_del_nr = 0;
0705             }
0706             btrfs_release_path(path);
0707 
0708             /*
0709              * We can generate a lot of delayed refs, so we need to
0710              * throttle every once and a while and make sure we're
0711              * adding enough space to keep up with the work we are
0712              * generating.  Since we hold a transaction here we
0713              * can't flush, and we don't want to FLUSH_LIMIT because
0714              * we could have generated too many delayed refs to
0715              * actually allocate, so just bail if we're short and
0716              * let the normal reservation dance happen higher up.
0717              */
0718             if (should_throttle) {
0719                 ret = btrfs_delayed_refs_rsv_refill(fs_info,
0720                             BTRFS_RESERVE_NO_FLUSH);
0721                 if (ret) {
0722                     ret = -EAGAIN;
0723                     break;
0724                 }
0725             }
0726             goto search_again;
0727         } else {
0728             path->slots[0]--;
0729         }
0730     }
0731 out:
0732     if (ret >= 0 && pending_del_nr) {
0733         int err;
0734 
0735         err = btrfs_del_items(trans, root, path, pending_del_slot,
0736                       pending_del_nr);
0737         if (err) {
0738             btrfs_abort_transaction(trans, err);
0739             ret = err;
0740         }
0741     }
0742 
0743     ASSERT(control->last_size >= new_size);
0744     if (!ret && control->last_size > new_size)
0745         control->last_size = new_size;
0746 
0747     btrfs_free_path(path);
0748     return ret;
0749 }