cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

inode-item.c (20310B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) 2007 Oracle.  All rights reserved.
      4 */
      5
      6#include "ctree.h"
      7#include "inode-item.h"
      8#include "disk-io.h"
      9#include "transaction.h"
     10#include "print-tree.h"
     11
     12struct btrfs_inode_ref *btrfs_find_name_in_backref(struct extent_buffer *leaf,
     13						   int slot, const char *name,
     14						   int name_len)
     15{
     16	struct btrfs_inode_ref *ref;
     17	unsigned long ptr;
     18	unsigned long name_ptr;
     19	u32 item_size;
     20	u32 cur_offset = 0;
     21	int len;
     22
     23	item_size = btrfs_item_size(leaf, slot);
     24	ptr = btrfs_item_ptr_offset(leaf, slot);
     25	while (cur_offset < item_size) {
     26		ref = (struct btrfs_inode_ref *)(ptr + cur_offset);
     27		len = btrfs_inode_ref_name_len(leaf, ref);
     28		name_ptr = (unsigned long)(ref + 1);
     29		cur_offset += len + sizeof(*ref);
     30		if (len != name_len)
     31			continue;
     32		if (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0)
     33			return ref;
     34	}
     35	return NULL;
     36}
     37
     38struct btrfs_inode_extref *btrfs_find_name_in_ext_backref(
     39		struct extent_buffer *leaf, int slot, u64 ref_objectid,
     40		const char *name, int name_len)
     41{
     42	struct btrfs_inode_extref *extref;
     43	unsigned long ptr;
     44	unsigned long name_ptr;
     45	u32 item_size;
     46	u32 cur_offset = 0;
     47	int ref_name_len;
     48
     49	item_size = btrfs_item_size(leaf, slot);
     50	ptr = btrfs_item_ptr_offset(leaf, slot);
     51
     52	/*
     53	 * Search all extended backrefs in this item. We're only
     54	 * looking through any collisions so most of the time this is
     55	 * just going to compare against one buffer. If all is well,
     56	 * we'll return success and the inode ref object.
     57	 */
     58	while (cur_offset < item_size) {
     59		extref = (struct btrfs_inode_extref *) (ptr + cur_offset);
     60		name_ptr = (unsigned long)(&extref->name);
     61		ref_name_len = btrfs_inode_extref_name_len(leaf, extref);
     62
     63		if (ref_name_len == name_len &&
     64		    btrfs_inode_extref_parent(leaf, extref) == ref_objectid &&
     65		    (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0))
     66			return extref;
     67
     68		cur_offset += ref_name_len + sizeof(*extref);
     69	}
     70	return NULL;
     71}
     72
     73/* Returns NULL if no extref found */
     74struct btrfs_inode_extref *
     75btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
     76			  struct btrfs_root *root,
     77			  struct btrfs_path *path,
     78			  const char *name, int name_len,
     79			  u64 inode_objectid, u64 ref_objectid, int ins_len,
     80			  int cow)
     81{
     82	int ret;
     83	struct btrfs_key key;
     84
     85	key.objectid = inode_objectid;
     86	key.type = BTRFS_INODE_EXTREF_KEY;
     87	key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
     88
     89	ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
     90	if (ret < 0)
     91		return ERR_PTR(ret);
     92	if (ret > 0)
     93		return NULL;
     94	return btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0],
     95					      ref_objectid, name, name_len);
     96
     97}
     98
     99static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
    100				  struct btrfs_root *root,
    101				  const char *name, int name_len,
    102				  u64 inode_objectid, u64 ref_objectid,
    103				  u64 *index)
    104{
    105	struct btrfs_path *path;
    106	struct btrfs_key key;
    107	struct btrfs_inode_extref *extref;
    108	struct extent_buffer *leaf;
    109	int ret;
    110	int del_len = name_len + sizeof(*extref);
    111	unsigned long ptr;
    112	unsigned long item_start;
    113	u32 item_size;
    114
    115	key.objectid = inode_objectid;
    116	key.type = BTRFS_INODE_EXTREF_KEY;
    117	key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
    118
    119	path = btrfs_alloc_path();
    120	if (!path)
    121		return -ENOMEM;
    122
    123	ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
    124	if (ret > 0)
    125		ret = -ENOENT;
    126	if (ret < 0)
    127		goto out;
    128
    129	/*
    130	 * Sanity check - did we find the right item for this name?
    131	 * This should always succeed so error here will make the FS
    132	 * readonly.
    133	 */
    134	extref = btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0],
    135						ref_objectid, name, name_len);
    136	if (!extref) {
    137		btrfs_handle_fs_error(root->fs_info, -ENOENT, NULL);
    138		ret = -EROFS;
    139		goto out;
    140	}
    141
    142	leaf = path->nodes[0];
    143	item_size = btrfs_item_size(leaf, path->slots[0]);
    144	if (index)
    145		*index = btrfs_inode_extref_index(leaf, extref);
    146
    147	if (del_len == item_size) {
    148		/*
    149		 * Common case only one ref in the item, remove the
    150		 * whole item.
    151		 */
    152		ret = btrfs_del_item(trans, root, path);
    153		goto out;
    154	}
    155
    156	ptr = (unsigned long)extref;
    157	item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
    158
    159	memmove_extent_buffer(leaf, ptr, ptr + del_len,
    160			      item_size - (ptr + del_len - item_start));
    161
    162	btrfs_truncate_item(path, item_size - del_len, 1);
    163
    164out:
    165	btrfs_free_path(path);
    166
    167	return ret;
    168}
    169
    170int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
    171			struct btrfs_root *root,
    172			const char *name, int name_len,
    173			u64 inode_objectid, u64 ref_objectid, u64 *index)
    174{
    175	struct btrfs_path *path;
    176	struct btrfs_key key;
    177	struct btrfs_inode_ref *ref;
    178	struct extent_buffer *leaf;
    179	unsigned long ptr;
    180	unsigned long item_start;
    181	u32 item_size;
    182	u32 sub_item_len;
    183	int ret;
    184	int search_ext_refs = 0;
    185	int del_len = name_len + sizeof(*ref);
    186
    187	key.objectid = inode_objectid;
    188	key.offset = ref_objectid;
    189	key.type = BTRFS_INODE_REF_KEY;
    190
    191	path = btrfs_alloc_path();
    192	if (!path)
    193		return -ENOMEM;
    194
    195	ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
    196	if (ret > 0) {
    197		ret = -ENOENT;
    198		search_ext_refs = 1;
    199		goto out;
    200	} else if (ret < 0) {
    201		goto out;
    202	}
    203
    204	ref = btrfs_find_name_in_backref(path->nodes[0], path->slots[0], name,
    205					 name_len);
    206	if (!ref) {
    207		ret = -ENOENT;
    208		search_ext_refs = 1;
    209		goto out;
    210	}
    211	leaf = path->nodes[0];
    212	item_size = btrfs_item_size(leaf, path->slots[0]);
    213
    214	if (index)
    215		*index = btrfs_inode_ref_index(leaf, ref);
    216
    217	if (del_len == item_size) {
    218		ret = btrfs_del_item(trans, root, path);
    219		goto out;
    220	}
    221	ptr = (unsigned long)ref;
    222	sub_item_len = name_len + sizeof(*ref);
    223	item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
    224	memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
    225			      item_size - (ptr + sub_item_len - item_start));
    226	btrfs_truncate_item(path, item_size - sub_item_len, 1);
    227out:
    228	btrfs_free_path(path);
    229
    230	if (search_ext_refs) {
    231		/*
    232		 * No refs were found, or we could not find the
    233		 * name in our ref array. Find and remove the extended
    234		 * inode ref then.
    235		 */
    236		return btrfs_del_inode_extref(trans, root, name, name_len,
    237					      inode_objectid, ref_objectid, index);
    238	}
    239
    240	return ret;
    241}
    242
    243/*
    244 * btrfs_insert_inode_extref() - Inserts an extended inode ref into a tree.
    245 *
    246 * The caller must have checked against BTRFS_LINK_MAX already.
    247 */
    248static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans,
    249				     struct btrfs_root *root,
    250				     const char *name, int name_len,
    251				     u64 inode_objectid, u64 ref_objectid, u64 index)
    252{
    253	struct btrfs_inode_extref *extref;
    254	int ret;
    255	int ins_len = name_len + sizeof(*extref);
    256	unsigned long ptr;
    257	struct btrfs_path *path;
    258	struct btrfs_key key;
    259	struct extent_buffer *leaf;
    260
    261	key.objectid = inode_objectid;
    262	key.type = BTRFS_INODE_EXTREF_KEY;
    263	key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
    264
    265	path = btrfs_alloc_path();
    266	if (!path)
    267		return -ENOMEM;
    268
    269	ret = btrfs_insert_empty_item(trans, root, path, &key,
    270				      ins_len);
    271	if (ret == -EEXIST) {
    272		if (btrfs_find_name_in_ext_backref(path->nodes[0],
    273						   path->slots[0],
    274						   ref_objectid,
    275						   name, name_len))
    276			goto out;
    277
    278		btrfs_extend_item(path, ins_len);
    279		ret = 0;
    280	}
    281	if (ret < 0)
    282		goto out;
    283
    284	leaf = path->nodes[0];
    285	ptr = (unsigned long)btrfs_item_ptr(leaf, path->slots[0], char);
    286	ptr += btrfs_item_size(leaf, path->slots[0]) - ins_len;
    287	extref = (struct btrfs_inode_extref *)ptr;
    288
    289	btrfs_set_inode_extref_name_len(path->nodes[0], extref, name_len);
    290	btrfs_set_inode_extref_index(path->nodes[0], extref, index);
    291	btrfs_set_inode_extref_parent(path->nodes[0], extref, ref_objectid);
    292
    293	ptr = (unsigned long)&extref->name;
    294	write_extent_buffer(path->nodes[0], name, ptr, name_len);
    295	btrfs_mark_buffer_dirty(path->nodes[0]);
    296
    297out:
    298	btrfs_free_path(path);
    299	return ret;
    300}
    301
    302/* Will return 0, -ENOMEM, -EMLINK, or -EEXIST or anything from the CoW path */
    303int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
    304			   struct btrfs_root *root,
    305			   const char *name, int name_len,
    306			   u64 inode_objectid, u64 ref_objectid, u64 index)
    307{
    308	struct btrfs_fs_info *fs_info = root->fs_info;
    309	struct btrfs_path *path;
    310	struct btrfs_key key;
    311	struct btrfs_inode_ref *ref;
    312	unsigned long ptr;
    313	int ret;
    314	int ins_len = name_len + sizeof(*ref);
    315
    316	key.objectid = inode_objectid;
    317	key.offset = ref_objectid;
    318	key.type = BTRFS_INODE_REF_KEY;
    319
    320	path = btrfs_alloc_path();
    321	if (!path)
    322		return -ENOMEM;
    323
    324	path->skip_release_on_error = 1;
    325	ret = btrfs_insert_empty_item(trans, root, path, &key,
    326				      ins_len);
    327	if (ret == -EEXIST) {
    328		u32 old_size;
    329		ref = btrfs_find_name_in_backref(path->nodes[0], path->slots[0],
    330						 name, name_len);
    331		if (ref)
    332			goto out;
    333
    334		old_size = btrfs_item_size(path->nodes[0], path->slots[0]);
    335		btrfs_extend_item(path, ins_len);
    336		ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
    337				     struct btrfs_inode_ref);
    338		ref = (struct btrfs_inode_ref *)((unsigned long)ref + old_size);
    339		btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
    340		btrfs_set_inode_ref_index(path->nodes[0], ref, index);
    341		ptr = (unsigned long)(ref + 1);
    342		ret = 0;
    343	} else if (ret < 0) {
    344		if (ret == -EOVERFLOW) {
    345			if (btrfs_find_name_in_backref(path->nodes[0],
    346						       path->slots[0],
    347						       name, name_len))
    348				ret = -EEXIST;
    349			else
    350				ret = -EMLINK;
    351		}
    352		goto out;
    353	} else {
    354		ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
    355				     struct btrfs_inode_ref);
    356		btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
    357		btrfs_set_inode_ref_index(path->nodes[0], ref, index);
    358		ptr = (unsigned long)(ref + 1);
    359	}
    360	write_extent_buffer(path->nodes[0], name, ptr, name_len);
    361	btrfs_mark_buffer_dirty(path->nodes[0]);
    362
    363out:
    364	btrfs_free_path(path);
    365
    366	if (ret == -EMLINK) {
    367		struct btrfs_super_block *disk_super = fs_info->super_copy;
    368		/* We ran out of space in the ref array. Need to
    369		 * add an extended ref. */
    370		if (btrfs_super_incompat_flags(disk_super)
    371		    & BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
    372			ret = btrfs_insert_inode_extref(trans, root, name,
    373							name_len,
    374							inode_objectid,
    375							ref_objectid, index);
    376	}
    377
    378	return ret;
    379}
    380
    381int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans,
    382			     struct btrfs_root *root,
    383			     struct btrfs_path *path, u64 objectid)
    384{
    385	struct btrfs_key key;
    386	int ret;
    387	key.objectid = objectid;
    388	key.type = BTRFS_INODE_ITEM_KEY;
    389	key.offset = 0;
    390
    391	ret = btrfs_insert_empty_item(trans, root, path, &key,
    392				      sizeof(struct btrfs_inode_item));
    393	return ret;
    394}
    395
    396int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
    397		       *root, struct btrfs_path *path,
    398		       struct btrfs_key *location, int mod)
    399{
    400	int ins_len = mod < 0 ? -1 : 0;
    401	int cow = mod != 0;
    402	int ret;
    403	int slot;
    404	struct extent_buffer *leaf;
    405	struct btrfs_key found_key;
    406
    407	ret = btrfs_search_slot(trans, root, location, path, ins_len, cow);
    408	if (ret > 0 && location->type == BTRFS_ROOT_ITEM_KEY &&
    409	    location->offset == (u64)-1 && path->slots[0] != 0) {
    410		slot = path->slots[0] - 1;
    411		leaf = path->nodes[0];
    412		btrfs_item_key_to_cpu(leaf, &found_key, slot);
    413		if (found_key.objectid == location->objectid &&
    414		    found_key.type == location->type) {
    415			path->slots[0]--;
    416			return 0;
    417		}
    418	}
    419	return ret;
    420}
    421
    422static inline void btrfs_trace_truncate(struct btrfs_inode *inode,
    423					struct extent_buffer *leaf,
    424					struct btrfs_file_extent_item *fi,
    425					u64 offset, int extent_type, int slot)
    426{
    427	if (!inode)
    428		return;
    429	if (extent_type == BTRFS_FILE_EXTENT_INLINE)
    430		trace_btrfs_truncate_show_fi_inline(inode, leaf, fi, slot,
    431						    offset);
    432	else
    433		trace_btrfs_truncate_show_fi_regular(inode, leaf, fi, offset);
    434}
    435
    436/*
    437 * Remove inode items from a given root.
    438 *
    439 * @trans:		A transaction handle.
    440 * @root:		The root from which to remove items.
    441 * @inode:		The inode whose items we want to remove.
    442 * @control:		The btrfs_truncate_control to control how and what we
    443 *			are truncating.
    444 *
    445 * Remove all keys associated with the inode from the given root that have a key
    446 * with a type greater than or equals to @min_type. When @min_type has a value of
    447 * BTRFS_EXTENT_DATA_KEY, only remove file extent items that have an offset value
    448 * greater than or equals to @new_size. If a file extent item that starts before
    449 * @new_size and ends after it is found, its length is adjusted.
    450 *
    451 * Returns: 0 on success, < 0 on error and NEED_TRUNCATE_BLOCK when @min_type is
    452 * BTRFS_EXTENT_DATA_KEY and the caller must truncate the last block.
    453 */
    454int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
    455			       struct btrfs_root *root,
    456			       struct btrfs_truncate_control *control)
    457{
    458	struct btrfs_fs_info *fs_info = root->fs_info;
    459	struct btrfs_path *path;
    460	struct extent_buffer *leaf;
    461	struct btrfs_file_extent_item *fi;
    462	struct btrfs_key key;
    463	struct btrfs_key found_key;
    464	u64 new_size = control->new_size;
    465	u64 extent_num_bytes = 0;
    466	u64 extent_offset = 0;
    467	u64 item_end = 0;
    468	u32 found_type = (u8)-1;
    469	int del_item;
    470	int pending_del_nr = 0;
    471	int pending_del_slot = 0;
    472	int extent_type = -1;
    473	int ret;
    474	u64 bytes_deleted = 0;
    475	bool be_nice = false;
    476
    477	ASSERT(control->inode || !control->clear_extent_range);
    478	ASSERT(new_size == 0 || control->min_type == BTRFS_EXTENT_DATA_KEY);
    479
    480	control->last_size = new_size;
    481	control->sub_bytes = 0;
    482
    483	/*
    484	 * For shareable roots we want to back off from time to time, this turns
    485	 * out to be subvolume roots, reloc roots, and data reloc roots.
    486	 */
    487	if (test_bit(BTRFS_ROOT_SHAREABLE, &root->state))
    488		be_nice = true;
    489
    490	path = btrfs_alloc_path();
    491	if (!path)
    492		return -ENOMEM;
    493	path->reada = READA_BACK;
    494
    495	key.objectid = control->ino;
    496	key.offset = (u64)-1;
    497	key.type = (u8)-1;
    498
    499search_again:
    500	/*
    501	 * With a 16K leaf size and 128MiB extents, you can actually queue up a
    502	 * huge file in a single leaf.  Most of the time that bytes_deleted is
    503	 * > 0, it will be huge by the time we get here
    504	 */
    505	if (be_nice && bytes_deleted > SZ_32M &&
    506	    btrfs_should_end_transaction(trans)) {
    507		ret = -EAGAIN;
    508		goto out;
    509	}
    510
    511	ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
    512	if (ret < 0)
    513		goto out;
    514
    515	if (ret > 0) {
    516		ret = 0;
    517		/* There are no items in the tree for us to truncate, we're done */
    518		if (path->slots[0] == 0)
    519			goto out;
    520		path->slots[0]--;
    521	}
    522
    523	while (1) {
    524		u64 clear_start = 0, clear_len = 0, extent_start = 0;
    525		bool should_throttle = false;
    526
    527		fi = NULL;
    528		leaf = path->nodes[0];
    529		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
    530		found_type = found_key.type;
    531
    532		if (found_key.objectid != control->ino)
    533			break;
    534
    535		if (found_type < control->min_type)
    536			break;
    537
    538		item_end = found_key.offset;
    539		if (found_type == BTRFS_EXTENT_DATA_KEY) {
    540			fi = btrfs_item_ptr(leaf, path->slots[0],
    541					    struct btrfs_file_extent_item);
    542			extent_type = btrfs_file_extent_type(leaf, fi);
    543			if (extent_type != BTRFS_FILE_EXTENT_INLINE)
    544				item_end +=
    545				    btrfs_file_extent_num_bytes(leaf, fi);
    546			else if (extent_type == BTRFS_FILE_EXTENT_INLINE)
    547				item_end += btrfs_file_extent_ram_bytes(leaf, fi);
    548
    549			btrfs_trace_truncate(control->inode, leaf, fi,
    550					     found_key.offset, extent_type,
    551					     path->slots[0]);
    552			item_end--;
    553		}
    554		if (found_type > control->min_type) {
    555			del_item = 1;
    556		} else {
    557			if (item_end < new_size)
    558				break;
    559			if (found_key.offset >= new_size)
    560				del_item = 1;
    561			else
    562				del_item = 0;
    563		}
    564
    565		/* FIXME, shrink the extent if the ref count is only 1 */
    566		if (found_type != BTRFS_EXTENT_DATA_KEY)
    567			goto delete;
    568
    569		control->extents_found++;
    570
    571		if (extent_type != BTRFS_FILE_EXTENT_INLINE) {
    572			u64 num_dec;
    573
    574			clear_start = found_key.offset;
    575			extent_start = btrfs_file_extent_disk_bytenr(leaf, fi);
    576			if (!del_item) {
    577				u64 orig_num_bytes =
    578					btrfs_file_extent_num_bytes(leaf, fi);
    579				extent_num_bytes = ALIGN(new_size -
    580						found_key.offset,
    581						fs_info->sectorsize);
    582				clear_start = ALIGN(new_size, fs_info->sectorsize);
    583
    584				btrfs_set_file_extent_num_bytes(leaf, fi,
    585							 extent_num_bytes);
    586				num_dec = (orig_num_bytes - extent_num_bytes);
    587				if (extent_start != 0)
    588					control->sub_bytes += num_dec;
    589				btrfs_mark_buffer_dirty(leaf);
    590			} else {
    591				extent_num_bytes =
    592					btrfs_file_extent_disk_num_bytes(leaf, fi);
    593				extent_offset = found_key.offset -
    594					btrfs_file_extent_offset(leaf, fi);
    595
    596				/* FIXME blocksize != 4096 */
    597				num_dec = btrfs_file_extent_num_bytes(leaf, fi);
    598				if (extent_start != 0)
    599					control->sub_bytes += num_dec;
    600			}
    601			clear_len = num_dec;
    602		} else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
    603			/*
    604			 * We can't truncate inline items that have had
    605			 * special encodings
    606			 */
    607			if (!del_item &&
    608			    btrfs_file_extent_encryption(leaf, fi) == 0 &&
    609			    btrfs_file_extent_other_encoding(leaf, fi) == 0 &&
    610			    btrfs_file_extent_compression(leaf, fi) == 0) {
    611				u32 size = (u32)(new_size - found_key.offset);
    612
    613				btrfs_set_file_extent_ram_bytes(leaf, fi, size);
    614				size = btrfs_file_extent_calc_inline_size(size);
    615				btrfs_truncate_item(path, size, 1);
    616			} else if (!del_item) {
    617				/*
    618				 * We have to bail so the last_size is set to
    619				 * just before this extent.
    620				 */
    621				ret = BTRFS_NEED_TRUNCATE_BLOCK;
    622				break;
    623			} else {
    624				/*
    625				 * Inline extents are special, we just treat
    626				 * them as a full sector worth in the file
    627				 * extent tree just for simplicity sake.
    628				 */
    629				clear_len = fs_info->sectorsize;
    630			}
    631
    632			control->sub_bytes += item_end + 1 - new_size;
    633		}
    634delete:
    635		/*
    636		 * We only want to clear the file extent range if we're
    637		 * modifying the actual inode's mapping, which is just the
    638		 * normal truncate path.
    639		 */
    640		if (control->clear_extent_range) {
    641			ret = btrfs_inode_clear_file_extent_range(control->inode,
    642						  clear_start, clear_len);
    643			if (ret) {
    644				btrfs_abort_transaction(trans, ret);
    645				break;
    646			}
    647		}
    648
    649		if (del_item) {
    650			ASSERT(!pending_del_nr ||
    651			       ((path->slots[0] + 1) == pending_del_slot));
    652
    653			control->last_size = found_key.offset;
    654			if (!pending_del_nr) {
    655				/* No pending yet, add ourselves */
    656				pending_del_slot = path->slots[0];
    657				pending_del_nr = 1;
    658			} else if (pending_del_nr &&
    659				   path->slots[0] + 1 == pending_del_slot) {
    660				/* Hop on the pending chunk */
    661				pending_del_nr++;
    662				pending_del_slot = path->slots[0];
    663			}
    664		} else {
    665			control->last_size = new_size;
    666			break;
    667		}
    668
    669		if (del_item && extent_start != 0 && !control->skip_ref_updates) {
    670			struct btrfs_ref ref = { 0 };
    671
    672			bytes_deleted += extent_num_bytes;
    673
    674			btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF,
    675					extent_start, extent_num_bytes, 0);
    676			btrfs_init_data_ref(&ref, btrfs_header_owner(leaf),
    677					control->ino, extent_offset,
    678					root->root_key.objectid, false);
    679			ret = btrfs_free_extent(trans, &ref);
    680			if (ret) {
    681				btrfs_abort_transaction(trans, ret);
    682				break;
    683			}
    684			if (be_nice) {
    685				if (btrfs_should_throttle_delayed_refs(trans))
    686					should_throttle = true;
    687			}
    688		}
    689
    690		if (found_type == BTRFS_INODE_ITEM_KEY)
    691			break;
    692
    693		if (path->slots[0] == 0 ||
    694		    path->slots[0] != pending_del_slot ||
    695		    should_throttle) {
    696			if (pending_del_nr) {
    697				ret = btrfs_del_items(trans, root, path,
    698						pending_del_slot,
    699						pending_del_nr);
    700				if (ret) {
    701					btrfs_abort_transaction(trans, ret);
    702					break;
    703				}
    704				pending_del_nr = 0;
    705			}
    706			btrfs_release_path(path);
    707
    708			/*
    709			 * We can generate a lot of delayed refs, so we need to
    710			 * throttle every once and a while and make sure we're
    711			 * adding enough space to keep up with the work we are
    712			 * generating.  Since we hold a transaction here we
    713			 * can't flush, and we don't want to FLUSH_LIMIT because
    714			 * we could have generated too many delayed refs to
    715			 * actually allocate, so just bail if we're short and
    716			 * let the normal reservation dance happen higher up.
    717			 */
    718			if (should_throttle) {
    719				ret = btrfs_delayed_refs_rsv_refill(fs_info,
    720							BTRFS_RESERVE_NO_FLUSH);
    721				if (ret) {
    722					ret = -EAGAIN;
    723					break;
    724				}
    725			}
    726			goto search_again;
    727		} else {
    728			path->slots[0]--;
    729		}
    730	}
    731out:
    732	if (ret >= 0 && pending_del_nr) {
    733		int err;
    734
    735		err = btrfs_del_items(trans, root, path, pending_del_slot,
    736				      pending_del_nr);
    737		if (err) {
    738			btrfs_abort_transaction(trans, err);
    739			ret = err;
    740		}
    741	}
    742
    743	ASSERT(control->last_size >= new_size);
    744	if (!ret && control->last_size > new_size)
    745		control->last_size = new_size;
    746
    747	btrfs_free_path(path);
    748	return ret;
    749}