brintos

brintos / linux-shallow public Read only

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