xref: /openbmc/linux/fs/btrfs/inode-item.c (revision d5e09e38)
1c1d7c514SDavid Sterba // SPDX-License-Identifier: GPL-2.0
26cbd5570SChris Mason /*
36cbd5570SChris Mason  * Copyright (C) 2007 Oracle.  All rights reserved.
46cbd5570SChris Mason  */
56cbd5570SChris Mason 
61e1d2701SChris Mason #include "ctree.h"
7ec8eb376SJosef Bacik #include "fs.h"
8ec8eb376SJosef Bacik #include "messages.h"
926c2c454SJosef Bacik #include "inode-item.h"
101e1d2701SChris Mason #include "disk-io.h"
11e089f05cSChris Mason #include "transaction.h"
12727011e0SChris Mason #include "print-tree.h"
13f1e5c618SJosef Bacik #include "space-info.h"
1407e81dc9SJosef Bacik #include "accessors.h"
15a0231804SJosef Bacik #include "extent-tree.h"
167c8ede16SJosef Bacik #include "file-item.h"
171e1d2701SChris Mason 
btrfs_find_name_in_backref(struct extent_buffer * leaf,int slot,const struct fscrypt_str * name)189bb8407fSNikolay Borisov struct btrfs_inode_ref *btrfs_find_name_in_backref(struct extent_buffer *leaf,
19e43eec81SSweet Tea Dorminy 						   int slot,
206db75318SSweet Tea Dorminy 						   const struct fscrypt_str *name)
213954401fSChris Mason {
223954401fSChris Mason 	struct btrfs_inode_ref *ref;
233954401fSChris Mason 	unsigned long ptr;
243954401fSChris Mason 	unsigned long name_ptr;
253954401fSChris Mason 	u32 item_size;
263954401fSChris Mason 	u32 cur_offset = 0;
273954401fSChris Mason 	int len;
283954401fSChris Mason 
293212fa14SJosef Bacik 	item_size = btrfs_item_size(leaf, slot);
301f250e92SFilipe Manana 	ptr = btrfs_item_ptr_offset(leaf, slot);
313954401fSChris Mason 	while (cur_offset < item_size) {
323954401fSChris Mason 		ref = (struct btrfs_inode_ref *)(ptr + cur_offset);
333954401fSChris Mason 		len = btrfs_inode_ref_name_len(leaf, ref);
343954401fSChris Mason 		name_ptr = (unsigned long)(ref + 1);
353954401fSChris Mason 		cur_offset += len + sizeof(*ref);
36e43eec81SSweet Tea Dorminy 		if (len != name->len)
373954401fSChris Mason 			continue;
38e43eec81SSweet Tea Dorminy 		if (memcmp_extent_buffer(leaf, name->name, name_ptr,
39e43eec81SSweet Tea Dorminy 					 name->len) == 0)
409bb8407fSNikolay Borisov 			return ref;
413954401fSChris Mason 	}
429bb8407fSNikolay Borisov 	return NULL;
433954401fSChris Mason }
443954401fSChris Mason 
btrfs_find_name_in_ext_backref(struct extent_buffer * leaf,int slot,u64 ref_objectid,const struct fscrypt_str * name)456ff49c6aSNikolay Borisov struct btrfs_inode_extref *btrfs_find_name_in_ext_backref(
466ff49c6aSNikolay Borisov 		struct extent_buffer *leaf, int slot, u64 ref_objectid,
476db75318SSweet Tea Dorminy 		const struct fscrypt_str *name)
48f186373fSMark Fasheh {
49f186373fSMark Fasheh 	struct btrfs_inode_extref *extref;
50f186373fSMark Fasheh 	unsigned long ptr;
51f186373fSMark Fasheh 	unsigned long name_ptr;
52f186373fSMark Fasheh 	u32 item_size;
53f186373fSMark Fasheh 	u32 cur_offset = 0;
54f186373fSMark Fasheh 	int ref_name_len;
55f186373fSMark Fasheh 
563212fa14SJosef Bacik 	item_size = btrfs_item_size(leaf, slot);
571f250e92SFilipe Manana 	ptr = btrfs_item_ptr_offset(leaf, slot);
58f186373fSMark Fasheh 
59f186373fSMark Fasheh 	/*
60f186373fSMark Fasheh 	 * Search all extended backrefs in this item. We're only
61f186373fSMark Fasheh 	 * looking through any collisions so most of the time this is
62f186373fSMark Fasheh 	 * just going to compare against one buffer. If all is well,
63f186373fSMark Fasheh 	 * we'll return success and the inode ref object.
64f186373fSMark Fasheh 	 */
65f186373fSMark Fasheh 	while (cur_offset < item_size) {
66f186373fSMark Fasheh 		extref = (struct btrfs_inode_extref *) (ptr + cur_offset);
67f186373fSMark Fasheh 		name_ptr = (unsigned long)(&extref->name);
68f186373fSMark Fasheh 		ref_name_len = btrfs_inode_extref_name_len(leaf, extref);
69f186373fSMark Fasheh 
70e43eec81SSweet Tea Dorminy 		if (ref_name_len == name->len &&
71f186373fSMark Fasheh 		    btrfs_inode_extref_parent(leaf, extref) == ref_objectid &&
72e43eec81SSweet Tea Dorminy 		    (memcmp_extent_buffer(leaf, name->name, name_ptr,
73e43eec81SSweet Tea Dorminy 					  name->len) == 0))
746ff49c6aSNikolay Borisov 			return extref;
75f186373fSMark Fasheh 
76f186373fSMark Fasheh 		cur_offset += ref_name_len + sizeof(*extref);
77f186373fSMark Fasheh 	}
786ff49c6aSNikolay Borisov 	return NULL;
79f186373fSMark Fasheh }
80f186373fSMark Fasheh 
81f186373fSMark Fasheh /* Returns NULL if no extref found */
82f186373fSMark Fasheh struct btrfs_inode_extref *
btrfs_lookup_inode_extref(struct btrfs_trans_handle * trans,struct btrfs_root * root,struct btrfs_path * path,const struct fscrypt_str * name,u64 inode_objectid,u64 ref_objectid,int ins_len,int cow)83f186373fSMark Fasheh btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
84f186373fSMark Fasheh 			  struct btrfs_root *root,
85f186373fSMark Fasheh 			  struct btrfs_path *path,
866db75318SSweet Tea Dorminy 			  const struct fscrypt_str *name,
87f186373fSMark Fasheh 			  u64 inode_objectid, u64 ref_objectid, int ins_len,
88f186373fSMark Fasheh 			  int cow)
89f186373fSMark Fasheh {
90f186373fSMark Fasheh 	int ret;
91f186373fSMark Fasheh 	struct btrfs_key key;
92f186373fSMark Fasheh 
93f186373fSMark Fasheh 	key.objectid = inode_objectid;
94f186373fSMark Fasheh 	key.type = BTRFS_INODE_EXTREF_KEY;
95e43eec81SSweet Tea Dorminy 	key.offset = btrfs_extref_hash(ref_objectid, name->name, name->len);
96f186373fSMark Fasheh 
97f186373fSMark Fasheh 	ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
98f186373fSMark Fasheh 	if (ret < 0)
99f186373fSMark Fasheh 		return ERR_PTR(ret);
100f186373fSMark Fasheh 	if (ret > 0)
101f186373fSMark Fasheh 		return NULL;
1026ff49c6aSNikolay Borisov 	return btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0],
103e43eec81SSweet Tea Dorminy 					      ref_objectid, name);
1046ff49c6aSNikolay Borisov 
105f186373fSMark Fasheh }
106f186373fSMark Fasheh 
btrfs_del_inode_extref(struct btrfs_trans_handle * trans,struct btrfs_root * root,const struct fscrypt_str * name,u64 inode_objectid,u64 ref_objectid,u64 * index)10748a3b636SEric Sandeen static int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
108f186373fSMark Fasheh 				  struct btrfs_root *root,
1096db75318SSweet Tea Dorminy 				  const struct fscrypt_str *name,
11048a3b636SEric Sandeen 				  u64 inode_objectid, u64 ref_objectid,
11148a3b636SEric Sandeen 				  u64 *index)
112f186373fSMark Fasheh {
113f186373fSMark Fasheh 	struct btrfs_path *path;
114f186373fSMark Fasheh 	struct btrfs_key key;
115f186373fSMark Fasheh 	struct btrfs_inode_extref *extref;
116f186373fSMark Fasheh 	struct extent_buffer *leaf;
117f186373fSMark Fasheh 	int ret;
118e43eec81SSweet Tea Dorminy 	int del_len = name->len + sizeof(*extref);
119f186373fSMark Fasheh 	unsigned long ptr;
120f186373fSMark Fasheh 	unsigned long item_start;
121f186373fSMark Fasheh 	u32 item_size;
122f186373fSMark Fasheh 
123f186373fSMark Fasheh 	key.objectid = inode_objectid;
124962a298fSDavid Sterba 	key.type = BTRFS_INODE_EXTREF_KEY;
125e43eec81SSweet Tea Dorminy 	key.offset = btrfs_extref_hash(ref_objectid, name->name, name->len);
126f186373fSMark Fasheh 
127f186373fSMark Fasheh 	path = btrfs_alloc_path();
128f186373fSMark Fasheh 	if (!path)
129f186373fSMark Fasheh 		return -ENOMEM;
130f186373fSMark Fasheh 
131f186373fSMark Fasheh 	ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
132f186373fSMark Fasheh 	if (ret > 0)
133f186373fSMark Fasheh 		ret = -ENOENT;
134f186373fSMark Fasheh 	if (ret < 0)
135f186373fSMark Fasheh 		goto out;
136f186373fSMark Fasheh 
137f186373fSMark Fasheh 	/*
138f186373fSMark Fasheh 	 * Sanity check - did we find the right item for this name?
139f186373fSMark Fasheh 	 * This should always succeed so error here will make the FS
140f186373fSMark Fasheh 	 * readonly.
141f186373fSMark Fasheh 	 */
1426ff49c6aSNikolay Borisov 	extref = btrfs_find_name_in_ext_backref(path->nodes[0], path->slots[0],
143e43eec81SSweet Tea Dorminy 						ref_objectid, name);
1446ff49c6aSNikolay Borisov 	if (!extref) {
14534d97007SAnand Jain 		btrfs_handle_fs_error(root->fs_info, -ENOENT, NULL);
146f186373fSMark Fasheh 		ret = -EROFS;
147f186373fSMark Fasheh 		goto out;
148f186373fSMark Fasheh 	}
149f186373fSMark Fasheh 
150f186373fSMark Fasheh 	leaf = path->nodes[0];
1513212fa14SJosef Bacik 	item_size = btrfs_item_size(leaf, path->slots[0]);
152f186373fSMark Fasheh 	if (index)
153f186373fSMark Fasheh 		*index = btrfs_inode_extref_index(leaf, extref);
154f186373fSMark Fasheh 
155f186373fSMark Fasheh 	if (del_len == item_size) {
156f186373fSMark Fasheh 		/*
157f186373fSMark Fasheh 		 * Common case only one ref in the item, remove the
158f186373fSMark Fasheh 		 * whole item.
159f186373fSMark Fasheh 		 */
160f186373fSMark Fasheh 		ret = btrfs_del_item(trans, root, path);
161f186373fSMark Fasheh 		goto out;
162f186373fSMark Fasheh 	}
163f186373fSMark Fasheh 
164f186373fSMark Fasheh 	ptr = (unsigned long)extref;
165f186373fSMark Fasheh 	item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
166f186373fSMark Fasheh 
167f186373fSMark Fasheh 	memmove_extent_buffer(leaf, ptr, ptr + del_len,
168f186373fSMark Fasheh 			      item_size - (ptr + del_len - item_start));
169f186373fSMark Fasheh 
170*d5e09e38SFilipe Manana 	btrfs_truncate_item(trans, path, item_size - del_len, 1);
171f186373fSMark Fasheh 
172f186373fSMark Fasheh out:
173f186373fSMark Fasheh 	btrfs_free_path(path);
174f186373fSMark Fasheh 
175f186373fSMark Fasheh 	return ret;
176f186373fSMark Fasheh }
177f186373fSMark Fasheh 
btrfs_del_inode_ref(struct btrfs_trans_handle * trans,struct btrfs_root * root,const struct fscrypt_str * name,u64 inode_objectid,u64 ref_objectid,u64 * index)1783954401fSChris Mason int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
1796db75318SSweet Tea Dorminy 			struct btrfs_root *root, const struct fscrypt_str *name,
180aec7477bSJosef Bacik 			u64 inode_objectid, u64 ref_objectid, u64 *index)
1813954401fSChris Mason {
1823954401fSChris Mason 	struct btrfs_path *path;
1833954401fSChris Mason 	struct btrfs_key key;
1843954401fSChris Mason 	struct btrfs_inode_ref *ref;
1853954401fSChris Mason 	struct extent_buffer *leaf;
1863954401fSChris Mason 	unsigned long ptr;
1873954401fSChris Mason 	unsigned long item_start;
1883954401fSChris Mason 	u32 item_size;
1893954401fSChris Mason 	u32 sub_item_len;
1903954401fSChris Mason 	int ret;
191f186373fSMark Fasheh 	int search_ext_refs = 0;
192e43eec81SSweet Tea Dorminy 	int del_len = name->len + sizeof(*ref);
1933954401fSChris Mason 
1943954401fSChris Mason 	key.objectid = inode_objectid;
1953954401fSChris Mason 	key.offset = ref_objectid;
196962a298fSDavid Sterba 	key.type = BTRFS_INODE_REF_KEY;
1973954401fSChris Mason 
1983954401fSChris Mason 	path = btrfs_alloc_path();
1993954401fSChris Mason 	if (!path)
2003954401fSChris Mason 		return -ENOMEM;
2013954401fSChris Mason 
2023954401fSChris Mason 	ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
2033954401fSChris Mason 	if (ret > 0) {
2043954401fSChris Mason 		ret = -ENOENT;
205f186373fSMark Fasheh 		search_ext_refs = 1;
2063954401fSChris Mason 		goto out;
2073954401fSChris Mason 	} else if (ret < 0) {
2083954401fSChris Mason 		goto out;
2093954401fSChris Mason 	}
2109bb8407fSNikolay Borisov 
211e43eec81SSweet Tea Dorminy 	ref = btrfs_find_name_in_backref(path->nodes[0], path->slots[0], name);
2129bb8407fSNikolay Borisov 	if (!ref) {
2133954401fSChris Mason 		ret = -ENOENT;
214f186373fSMark Fasheh 		search_ext_refs = 1;
2153954401fSChris Mason 		goto out;
2163954401fSChris Mason 	}
2173954401fSChris Mason 	leaf = path->nodes[0];
2183212fa14SJosef Bacik 	item_size = btrfs_item_size(leaf, path->slots[0]);
219aec7477bSJosef Bacik 
220aec7477bSJosef Bacik 	if (index)
221aec7477bSJosef Bacik 		*index = btrfs_inode_ref_index(leaf, ref);
222aec7477bSJosef Bacik 
2233954401fSChris Mason 	if (del_len == item_size) {
2243954401fSChris Mason 		ret = btrfs_del_item(trans, root, path);
2253954401fSChris Mason 		goto out;
2263954401fSChris Mason 	}
2273954401fSChris Mason 	ptr = (unsigned long)ref;
228e43eec81SSweet Tea Dorminy 	sub_item_len = name->len + sizeof(*ref);
2293954401fSChris Mason 	item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
2303954401fSChris Mason 	memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
2313954401fSChris Mason 			      item_size - (ptr + sub_item_len - item_start));
232*d5e09e38SFilipe Manana 	btrfs_truncate_item(trans, path, item_size - sub_item_len, 1);
233f186373fSMark Fasheh out:
234f186373fSMark Fasheh 	btrfs_free_path(path);
235f186373fSMark Fasheh 
236f186373fSMark Fasheh 	if (search_ext_refs) {
237f186373fSMark Fasheh 		/*
238f186373fSMark Fasheh 		 * No refs were found, or we could not find the
239f186373fSMark Fasheh 		 * name in our ref array. Find and remove the extended
240f186373fSMark Fasheh 		 * inode ref then.
241f186373fSMark Fasheh 		 */
242e43eec81SSweet Tea Dorminy 		return btrfs_del_inode_extref(trans, root, name,
243f186373fSMark Fasheh 					      inode_objectid, ref_objectid, index);
244f186373fSMark Fasheh 	}
245f186373fSMark Fasheh 
246f186373fSMark Fasheh 	return ret;
247f186373fSMark Fasheh }
248f186373fSMark Fasheh 
249f186373fSMark Fasheh /*
250f186373fSMark Fasheh  * btrfs_insert_inode_extref() - Inserts an extended inode ref into a tree.
251f186373fSMark Fasheh  *
252f186373fSMark Fasheh  * The caller must have checked against BTRFS_LINK_MAX already.
253f186373fSMark Fasheh  */
btrfs_insert_inode_extref(struct btrfs_trans_handle * trans,struct btrfs_root * root,const struct fscrypt_str * name,u64 inode_objectid,u64 ref_objectid,u64 index)254f186373fSMark Fasheh static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans,
255f186373fSMark Fasheh 				     struct btrfs_root *root,
2566db75318SSweet Tea Dorminy 				     const struct fscrypt_str *name,
257e43eec81SSweet Tea Dorminy 				     u64 inode_objectid, u64 ref_objectid,
258e43eec81SSweet Tea Dorminy 				     u64 index)
259f186373fSMark Fasheh {
260f186373fSMark Fasheh 	struct btrfs_inode_extref *extref;
261f186373fSMark Fasheh 	int ret;
262e43eec81SSweet Tea Dorminy 	int ins_len = name->len + sizeof(*extref);
263f186373fSMark Fasheh 	unsigned long ptr;
264f186373fSMark Fasheh 	struct btrfs_path *path;
265f186373fSMark Fasheh 	struct btrfs_key key;
266f186373fSMark Fasheh 	struct extent_buffer *leaf;
267f186373fSMark Fasheh 
268f186373fSMark Fasheh 	key.objectid = inode_objectid;
269f186373fSMark Fasheh 	key.type = BTRFS_INODE_EXTREF_KEY;
270e43eec81SSweet Tea Dorminy 	key.offset = btrfs_extref_hash(ref_objectid, name->name, name->len);
271f186373fSMark Fasheh 
272f186373fSMark Fasheh 	path = btrfs_alloc_path();
273f186373fSMark Fasheh 	if (!path)
274f186373fSMark Fasheh 		return -ENOMEM;
275f186373fSMark Fasheh 
276f186373fSMark Fasheh 	ret = btrfs_insert_empty_item(trans, root, path, &key,
277f186373fSMark Fasheh 				      ins_len);
278f186373fSMark Fasheh 	if (ret == -EEXIST) {
2791f250e92SFilipe Manana 		if (btrfs_find_name_in_ext_backref(path->nodes[0],
2801f250e92SFilipe Manana 						   path->slots[0],
2811f250e92SFilipe Manana 						   ref_objectid,
282e43eec81SSweet Tea Dorminy 						   name))
283f186373fSMark Fasheh 			goto out;
284f186373fSMark Fasheh 
285*d5e09e38SFilipe Manana 		btrfs_extend_item(trans, path, ins_len);
286f186373fSMark Fasheh 		ret = 0;
287f186373fSMark Fasheh 	}
288f186373fSMark Fasheh 	if (ret < 0)
289f186373fSMark Fasheh 		goto out;
290f186373fSMark Fasheh 
291f186373fSMark Fasheh 	leaf = path->nodes[0];
292f186373fSMark Fasheh 	ptr = (unsigned long)btrfs_item_ptr(leaf, path->slots[0], char);
2933212fa14SJosef Bacik 	ptr += btrfs_item_size(leaf, path->slots[0]) - ins_len;
294f186373fSMark Fasheh 	extref = (struct btrfs_inode_extref *)ptr;
295f186373fSMark Fasheh 
296e43eec81SSweet Tea Dorminy 	btrfs_set_inode_extref_name_len(path->nodes[0], extref, name->len);
297f186373fSMark Fasheh 	btrfs_set_inode_extref_index(path->nodes[0], extref, index);
298f186373fSMark Fasheh 	btrfs_set_inode_extref_parent(path->nodes[0], extref, ref_objectid);
299f186373fSMark Fasheh 
300f186373fSMark Fasheh 	ptr = (unsigned long)&extref->name;
301e43eec81SSweet Tea Dorminy 	write_extent_buffer(path->nodes[0], name->name, ptr, name->len);
302*d5e09e38SFilipe Manana 	btrfs_mark_buffer_dirty(trans, path->nodes[0]);
303f186373fSMark Fasheh 
3043954401fSChris Mason out:
3053954401fSChris Mason 	btrfs_free_path(path);
3063954401fSChris Mason 	return ret;
3073954401fSChris Mason }
3083954401fSChris Mason 
30979787eaaSJeff Mahoney /* Will return 0, -ENOMEM, -EMLINK, or -EEXIST or anything from the CoW path */
btrfs_insert_inode_ref(struct btrfs_trans_handle * trans,struct btrfs_root * root,const struct fscrypt_str * name,u64 inode_objectid,u64 ref_objectid,u64 index)3103954401fSChris Mason int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
3116db75318SSweet Tea Dorminy 			   struct btrfs_root *root, const struct fscrypt_str *name,
312aec7477bSJosef Bacik 			   u64 inode_objectid, u64 ref_objectid, u64 index)
3133954401fSChris Mason {
3140b246afaSJeff Mahoney 	struct btrfs_fs_info *fs_info = root->fs_info;
3153954401fSChris Mason 	struct btrfs_path *path;
3163954401fSChris Mason 	struct btrfs_key key;
3173954401fSChris Mason 	struct btrfs_inode_ref *ref;
3183954401fSChris Mason 	unsigned long ptr;
3193954401fSChris Mason 	int ret;
320e43eec81SSweet Tea Dorminy 	int ins_len = name->len + sizeof(*ref);
3213954401fSChris Mason 
3223954401fSChris Mason 	key.objectid = inode_objectid;
3233954401fSChris Mason 	key.offset = ref_objectid;
324962a298fSDavid Sterba 	key.type = BTRFS_INODE_REF_KEY;
3253954401fSChris Mason 
3263954401fSChris Mason 	path = btrfs_alloc_path();
3273954401fSChris Mason 	if (!path)
3283954401fSChris Mason 		return -ENOMEM;
3293954401fSChris Mason 
330df8d116fSFilipe Manana 	path->skip_release_on_error = 1;
3313954401fSChris Mason 	ret = btrfs_insert_empty_item(trans, root, path, &key,
3323954401fSChris Mason 				      ins_len);
3333954401fSChris Mason 	if (ret == -EEXIST) {
3343954401fSChris Mason 		u32 old_size;
3359bb8407fSNikolay Borisov 		ref = btrfs_find_name_in_backref(path->nodes[0], path->slots[0],
336e43eec81SSweet Tea Dorminy 						 name);
3379bb8407fSNikolay Borisov 		if (ref)
3383954401fSChris Mason 			goto out;
3393954401fSChris Mason 
3403212fa14SJosef Bacik 		old_size = btrfs_item_size(path->nodes[0], path->slots[0]);
341*d5e09e38SFilipe Manana 		btrfs_extend_item(trans, path, ins_len);
3423954401fSChris Mason 		ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
3433954401fSChris Mason 				     struct btrfs_inode_ref);
3443954401fSChris Mason 		ref = (struct btrfs_inode_ref *)((unsigned long)ref + old_size);
345e43eec81SSweet Tea Dorminy 		btrfs_set_inode_ref_name_len(path->nodes[0], ref, name->len);
346aec7477bSJosef Bacik 		btrfs_set_inode_ref_index(path->nodes[0], ref, index);
3473954401fSChris Mason 		ptr = (unsigned long)(ref + 1);
3483954401fSChris Mason 		ret = 0;
3493954401fSChris Mason 	} else if (ret < 0) {
350df8d116fSFilipe Manana 		if (ret == -EOVERFLOW) {
3511f250e92SFilipe Manana 			if (btrfs_find_name_in_backref(path->nodes[0],
3521f250e92SFilipe Manana 						       path->slots[0],
353e43eec81SSweet Tea Dorminy 						       name))
354df8d116fSFilipe Manana 				ret = -EEXIST;
355df8d116fSFilipe Manana 			else
356a5719521SYan, Zheng 				ret = -EMLINK;
357df8d116fSFilipe Manana 		}
3583954401fSChris Mason 		goto out;
3593954401fSChris Mason 	} else {
3603954401fSChris Mason 		ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
3613954401fSChris Mason 				     struct btrfs_inode_ref);
362e43eec81SSweet Tea Dorminy 		btrfs_set_inode_ref_name_len(path->nodes[0], ref, name->len);
363aec7477bSJosef Bacik 		btrfs_set_inode_ref_index(path->nodes[0], ref, index);
3643954401fSChris Mason 		ptr = (unsigned long)(ref + 1);
3653954401fSChris Mason 	}
366e43eec81SSweet Tea Dorminy 	write_extent_buffer(path->nodes[0], name->name, ptr, name->len);
367*d5e09e38SFilipe Manana 	btrfs_mark_buffer_dirty(trans, path->nodes[0]);
3683954401fSChris Mason 
3693954401fSChris Mason out:
3703954401fSChris Mason 	btrfs_free_path(path);
371f186373fSMark Fasheh 
372f186373fSMark Fasheh 	if (ret == -EMLINK) {
3730b246afaSJeff Mahoney 		struct btrfs_super_block *disk_super = fs_info->super_copy;
374f186373fSMark Fasheh 		/* We ran out of space in the ref array. Need to
375f186373fSMark Fasheh 		 * add an extended ref. */
376f186373fSMark Fasheh 		if (btrfs_super_incompat_flags(disk_super)
377f186373fSMark Fasheh 		    & BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
378f186373fSMark Fasheh 			ret = btrfs_insert_inode_extref(trans, root, name,
379f186373fSMark Fasheh 							inode_objectid,
380f186373fSMark Fasheh 							ref_objectid, index);
381f186373fSMark Fasheh 	}
382f186373fSMark Fasheh 
3833954401fSChris Mason 	return ret;
3843954401fSChris Mason }
3853954401fSChris Mason 
btrfs_insert_empty_inode(struct btrfs_trans_handle * trans,struct btrfs_root * root,struct btrfs_path * path,u64 objectid)3865f39d397SChris Mason int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans,
3875f39d397SChris Mason 			     struct btrfs_root *root,
3885f39d397SChris Mason 			     struct btrfs_path *path, u64 objectid)
3891e1d2701SChris Mason {
3901e1d2701SChris Mason 	struct btrfs_key key;
3911e1d2701SChris Mason 	int ret;
3921e1d2701SChris Mason 	key.objectid = objectid;
393962a298fSDavid Sterba 	key.type = BTRFS_INODE_ITEM_KEY;
3941e1d2701SChris Mason 	key.offset = 0;
3951e1d2701SChris Mason 
3965f39d397SChris Mason 	ret = btrfs_insert_empty_item(trans, root, path, &key,
3975f39d397SChris Mason 				      sizeof(struct btrfs_inode_item));
3981e1d2701SChris Mason 	return ret;
3991e1d2701SChris Mason }
4001e1d2701SChris Mason 
btrfs_lookup_inode(struct btrfs_trans_handle * trans,struct btrfs_root * root,struct btrfs_path * path,struct btrfs_key * location,int mod)401e089f05cSChris Mason int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
402d6e4a428SChris Mason 		       *root, struct btrfs_path *path,
403d6e4a428SChris Mason 		       struct btrfs_key *location, int mod)
4041e1d2701SChris Mason {
4051e1d2701SChris Mason 	int ins_len = mod < 0 ? -1 : 0;
4061e1d2701SChris Mason 	int cow = mod != 0;
407d6e4a428SChris Mason 	int ret;
408d6e4a428SChris Mason 	int slot;
4095f39d397SChris Mason 	struct extent_buffer *leaf;
410d6e4a428SChris Mason 	struct btrfs_key found_key;
4111e1d2701SChris Mason 
412d6e4a428SChris Mason 	ret = btrfs_search_slot(trans, root, location, path, ins_len, cow);
413962a298fSDavid Sterba 	if (ret > 0 && location->type == BTRFS_ROOT_ITEM_KEY &&
414d6e4a428SChris Mason 	    location->offset == (u64)-1 && path->slots[0] != 0) {
415d6e4a428SChris Mason 		slot = path->slots[0] - 1;
4165f39d397SChris Mason 		leaf = path->nodes[0];
4175f39d397SChris Mason 		btrfs_item_key_to_cpu(leaf, &found_key, slot);
418d6e4a428SChris Mason 		if (found_key.objectid == location->objectid &&
419962a298fSDavid Sterba 		    found_key.type == location->type) {
420d6e4a428SChris Mason 			path->slots[0]--;
421d6e4a428SChris Mason 			return 0;
422d6e4a428SChris Mason 		}
423d6e4a428SChris Mason 	}
424d6e4a428SChris Mason 	return ret;
4251e1d2701SChris Mason }
42654f03ab1SJosef Bacik 
btrfs_trace_truncate(struct btrfs_inode * inode,struct extent_buffer * leaf,struct btrfs_file_extent_item * fi,u64 offset,int extent_type,int slot)42771d18b53SJosef Bacik static inline void btrfs_trace_truncate(struct btrfs_inode *inode,
42871d18b53SJosef Bacik 					struct extent_buffer *leaf,
42971d18b53SJosef Bacik 					struct btrfs_file_extent_item *fi,
43071d18b53SJosef Bacik 					u64 offset, int extent_type, int slot)
43171d18b53SJosef Bacik {
43271d18b53SJosef Bacik 	if (!inode)
43371d18b53SJosef Bacik 		return;
43471d18b53SJosef Bacik 	if (extent_type == BTRFS_FILE_EXTENT_INLINE)
43571d18b53SJosef Bacik 		trace_btrfs_truncate_show_fi_inline(inode, leaf, fi, slot,
43671d18b53SJosef Bacik 						    offset);
43771d18b53SJosef Bacik 	else
43871d18b53SJosef Bacik 		trace_btrfs_truncate_show_fi_regular(inode, leaf, fi, offset);
43971d18b53SJosef Bacik }
44071d18b53SJosef Bacik 
44154f03ab1SJosef Bacik /*
44254f03ab1SJosef Bacik  * Remove inode items from a given root.
44354f03ab1SJosef Bacik  *
44454f03ab1SJosef Bacik  * @trans:		A transaction handle.
44554f03ab1SJosef Bacik  * @root:		The root from which to remove items.
44654f03ab1SJosef Bacik  * @inode:		The inode whose items we want to remove.
447d9ac19c3SJosef Bacik  * @control:		The btrfs_truncate_control to control how and what we
448d9ac19c3SJosef Bacik  *			are truncating.
44954f03ab1SJosef Bacik  *
45054f03ab1SJosef Bacik  * Remove all keys associated with the inode from the given root that have a key
45154f03ab1SJosef Bacik  * with a type greater than or equals to @min_type. When @min_type has a value of
45254f03ab1SJosef Bacik  * BTRFS_EXTENT_DATA_KEY, only remove file extent items that have an offset value
45354f03ab1SJosef Bacik  * greater than or equals to @new_size. If a file extent item that starts before
45454f03ab1SJosef Bacik  * @new_size and ends after it is found, its length is adjusted.
45554f03ab1SJosef Bacik  *
45654f03ab1SJosef Bacik  * Returns: 0 on success, < 0 on error and NEED_TRUNCATE_BLOCK when @min_type is
45754f03ab1SJosef Bacik  * BTRFS_EXTENT_DATA_KEY and the caller must truncate the last block.
45854f03ab1SJosef Bacik  */
btrfs_truncate_inode_items(struct btrfs_trans_handle * trans,struct btrfs_root * root,struct btrfs_truncate_control * control)45954f03ab1SJosef Bacik int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
46054f03ab1SJosef Bacik 			       struct btrfs_root *root,
461d9ac19c3SJosef Bacik 			       struct btrfs_truncate_control *control)
46254f03ab1SJosef Bacik {
46354f03ab1SJosef Bacik 	struct btrfs_fs_info *fs_info = root->fs_info;
46454f03ab1SJosef Bacik 	struct btrfs_path *path;
46554f03ab1SJosef Bacik 	struct extent_buffer *leaf;
46654f03ab1SJosef Bacik 	struct btrfs_file_extent_item *fi;
46754f03ab1SJosef Bacik 	struct btrfs_key key;
46854f03ab1SJosef Bacik 	struct btrfs_key found_key;
469d9ac19c3SJosef Bacik 	u64 new_size = control->new_size;
47054f03ab1SJosef Bacik 	u64 extent_num_bytes = 0;
47154f03ab1SJosef Bacik 	u64 extent_offset = 0;
47254f03ab1SJosef Bacik 	u64 item_end = 0;
47354f03ab1SJosef Bacik 	u32 found_type = (u8)-1;
47454f03ab1SJosef Bacik 	int del_item;
47554f03ab1SJosef Bacik 	int pending_del_nr = 0;
47654f03ab1SJosef Bacik 	int pending_del_slot = 0;
47754f03ab1SJosef Bacik 	int extent_type = -1;
47854f03ab1SJosef Bacik 	int ret;
47954f03ab1SJosef Bacik 	u64 bytes_deleted = 0;
48054f03ab1SJosef Bacik 	bool be_nice = false;
48154f03ab1SJosef Bacik 
48271d18b53SJosef Bacik 	ASSERT(control->inode || !control->clear_extent_range);
48356e1edb0SJosef Bacik 	ASSERT(new_size == 0 || control->min_type == BTRFS_EXTENT_DATA_KEY);
48454f03ab1SJosef Bacik 
485c2ddb612SJosef Bacik 	control->last_size = new_size;
486462b728eSJosef Bacik 	control->sub_bytes = 0;
487c2ddb612SJosef Bacik 
48854f03ab1SJosef Bacik 	/*
489275312a0SJosef Bacik 	 * For shareable roots we want to back off from time to time, this turns
490275312a0SJosef Bacik 	 * out to be subvolume roots, reloc roots, and data reloc roots.
49154f03ab1SJosef Bacik 	 */
492275312a0SJosef Bacik 	if (test_bit(BTRFS_ROOT_SHAREABLE, &root->state))
49354f03ab1SJosef Bacik 		be_nice = true;
49454f03ab1SJosef Bacik 
49554f03ab1SJosef Bacik 	path = btrfs_alloc_path();
49654f03ab1SJosef Bacik 	if (!path)
49754f03ab1SJosef Bacik 		return -ENOMEM;
49854f03ab1SJosef Bacik 	path->reada = READA_BACK;
49954f03ab1SJosef Bacik 
500487e81d2SJosef Bacik 	key.objectid = control->ino;
50154f03ab1SJosef Bacik 	key.offset = (u64)-1;
50254f03ab1SJosef Bacik 	key.type = (u8)-1;
50354f03ab1SJosef Bacik 
50454f03ab1SJosef Bacik search_again:
50554f03ab1SJosef Bacik 	/*
50654f03ab1SJosef Bacik 	 * With a 16K leaf size and 128MiB extents, you can actually queue up a
50754f03ab1SJosef Bacik 	 * huge file in a single leaf.  Most of the time that bytes_deleted is
50854f03ab1SJosef Bacik 	 * > 0, it will be huge by the time we get here
50954f03ab1SJosef Bacik 	 */
51054f03ab1SJosef Bacik 	if (be_nice && bytes_deleted > SZ_32M &&
51154f03ab1SJosef Bacik 	    btrfs_should_end_transaction(trans)) {
51254f03ab1SJosef Bacik 		ret = -EAGAIN;
51354f03ab1SJosef Bacik 		goto out;
51454f03ab1SJosef Bacik 	}
51554f03ab1SJosef Bacik 
51654f03ab1SJosef Bacik 	ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
51754f03ab1SJosef Bacik 	if (ret < 0)
51854f03ab1SJosef Bacik 		goto out;
51954f03ab1SJosef Bacik 
52054f03ab1SJosef Bacik 	if (ret > 0) {
52154f03ab1SJosef Bacik 		ret = 0;
52254f03ab1SJosef Bacik 		/* There are no items in the tree for us to truncate, we're done */
52354f03ab1SJosef Bacik 		if (path->slots[0] == 0)
52454f03ab1SJosef Bacik 			goto out;
52554f03ab1SJosef Bacik 		path->slots[0]--;
52654f03ab1SJosef Bacik 	}
52754f03ab1SJosef Bacik 
52854f03ab1SJosef Bacik 	while (1) {
5297097a941SJosef Bacik 		u64 clear_start = 0, clear_len = 0, extent_start = 0;
530a8fdc051SFilipe Manana 		bool refill_delayed_refs_rsv = false;
53154f03ab1SJosef Bacik 
53254f03ab1SJosef Bacik 		fi = NULL;
53354f03ab1SJosef Bacik 		leaf = path->nodes[0];
53454f03ab1SJosef Bacik 		btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
53554f03ab1SJosef Bacik 		found_type = found_key.type;
53654f03ab1SJosef Bacik 
537487e81d2SJosef Bacik 		if (found_key.objectid != control->ino)
53854f03ab1SJosef Bacik 			break;
53954f03ab1SJosef Bacik 
540d9ac19c3SJosef Bacik 		if (found_type < control->min_type)
54154f03ab1SJosef Bacik 			break;
54254f03ab1SJosef Bacik 
54354f03ab1SJosef Bacik 		item_end = found_key.offset;
54454f03ab1SJosef Bacik 		if (found_type == BTRFS_EXTENT_DATA_KEY) {
54554f03ab1SJosef Bacik 			fi = btrfs_item_ptr(leaf, path->slots[0],
54654f03ab1SJosef Bacik 					    struct btrfs_file_extent_item);
54754f03ab1SJosef Bacik 			extent_type = btrfs_file_extent_type(leaf, fi);
54871d18b53SJosef Bacik 			if (extent_type != BTRFS_FILE_EXTENT_INLINE)
54954f03ab1SJosef Bacik 				item_end +=
55054f03ab1SJosef Bacik 				    btrfs_file_extent_num_bytes(leaf, fi);
55171d18b53SJosef Bacik 			else if (extent_type == BTRFS_FILE_EXTENT_INLINE)
55254f03ab1SJosef Bacik 				item_end += btrfs_file_extent_ram_bytes(leaf, fi);
55354f03ab1SJosef Bacik 
55471d18b53SJosef Bacik 			btrfs_trace_truncate(control->inode, leaf, fi,
55571d18b53SJosef Bacik 					     found_key.offset, extent_type,
55671d18b53SJosef Bacik 					     path->slots[0]);
55754f03ab1SJosef Bacik 			item_end--;
55854f03ab1SJosef Bacik 		}
559d9ac19c3SJosef Bacik 		if (found_type > control->min_type) {
56054f03ab1SJosef Bacik 			del_item = 1;
56154f03ab1SJosef Bacik 		} else {
56254f03ab1SJosef Bacik 			if (item_end < new_size)
56354f03ab1SJosef Bacik 				break;
56454f03ab1SJosef Bacik 			if (found_key.offset >= new_size)
56554f03ab1SJosef Bacik 				del_item = 1;
56654f03ab1SJosef Bacik 			else
56754f03ab1SJosef Bacik 				del_item = 0;
56854f03ab1SJosef Bacik 		}
5697097a941SJosef Bacik 
57054f03ab1SJosef Bacik 		/* FIXME, shrink the extent if the ref count is only 1 */
57154f03ab1SJosef Bacik 		if (found_type != BTRFS_EXTENT_DATA_KEY)
57254f03ab1SJosef Bacik 			goto delete;
57354f03ab1SJosef Bacik 
574d9ac19c3SJosef Bacik 		control->extents_found++;
57554f03ab1SJosef Bacik 
57654f03ab1SJosef Bacik 		if (extent_type != BTRFS_FILE_EXTENT_INLINE) {
57754f03ab1SJosef Bacik 			u64 num_dec;
57854f03ab1SJosef Bacik 
57954f03ab1SJosef Bacik 			clear_start = found_key.offset;
58054f03ab1SJosef Bacik 			extent_start = btrfs_file_extent_disk_bytenr(leaf, fi);
58154f03ab1SJosef Bacik 			if (!del_item) {
58254f03ab1SJosef Bacik 				u64 orig_num_bytes =
58354f03ab1SJosef Bacik 					btrfs_file_extent_num_bytes(leaf, fi);
58454f03ab1SJosef Bacik 				extent_num_bytes = ALIGN(new_size -
58554f03ab1SJosef Bacik 						found_key.offset,
58654f03ab1SJosef Bacik 						fs_info->sectorsize);
58754f03ab1SJosef Bacik 				clear_start = ALIGN(new_size, fs_info->sectorsize);
58854f03ab1SJosef Bacik 
58954f03ab1SJosef Bacik 				btrfs_set_file_extent_num_bytes(leaf, fi,
59054f03ab1SJosef Bacik 							 extent_num_bytes);
59154f03ab1SJosef Bacik 				num_dec = (orig_num_bytes - extent_num_bytes);
592462b728eSJosef Bacik 				if (extent_start != 0)
593462b728eSJosef Bacik 					control->sub_bytes += num_dec;
594*d5e09e38SFilipe Manana 				btrfs_mark_buffer_dirty(trans, leaf);
59554f03ab1SJosef Bacik 			} else {
59654f03ab1SJosef Bacik 				extent_num_bytes =
59754f03ab1SJosef Bacik 					btrfs_file_extent_disk_num_bytes(leaf, fi);
59854f03ab1SJosef Bacik 				extent_offset = found_key.offset -
59954f03ab1SJosef Bacik 					btrfs_file_extent_offset(leaf, fi);
60054f03ab1SJosef Bacik 
60154f03ab1SJosef Bacik 				/* FIXME blocksize != 4096 */
60254f03ab1SJosef Bacik 				num_dec = btrfs_file_extent_num_bytes(leaf, fi);
603462b728eSJosef Bacik 				if (extent_start != 0)
604462b728eSJosef Bacik 					control->sub_bytes += num_dec;
60554f03ab1SJosef Bacik 			}
60654f03ab1SJosef Bacik 			clear_len = num_dec;
60754f03ab1SJosef Bacik 		} else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
60854f03ab1SJosef Bacik 			/*
60954f03ab1SJosef Bacik 			 * We can't truncate inline items that have had
61054f03ab1SJosef Bacik 			 * special encodings
61154f03ab1SJosef Bacik 			 */
61254f03ab1SJosef Bacik 			if (!del_item &&
61354f03ab1SJosef Bacik 			    btrfs_file_extent_encryption(leaf, fi) == 0 &&
61454f03ab1SJosef Bacik 			    btrfs_file_extent_other_encoding(leaf, fi) == 0 &&
61554f03ab1SJosef Bacik 			    btrfs_file_extent_compression(leaf, fi) == 0) {
61654f03ab1SJosef Bacik 				u32 size = (u32)(new_size - found_key.offset);
61754f03ab1SJosef Bacik 
61854f03ab1SJosef Bacik 				btrfs_set_file_extent_ram_bytes(leaf, fi, size);
61954f03ab1SJosef Bacik 				size = btrfs_file_extent_calc_inline_size(size);
620*d5e09e38SFilipe Manana 				btrfs_truncate_item(trans, path, size, 1);
62154f03ab1SJosef Bacik 			} else if (!del_item) {
62254f03ab1SJosef Bacik 				/*
62354f03ab1SJosef Bacik 				 * We have to bail so the last_size is set to
62454f03ab1SJosef Bacik 				 * just before this extent.
62554f03ab1SJosef Bacik 				 */
62654f03ab1SJosef Bacik 				ret = BTRFS_NEED_TRUNCATE_BLOCK;
62754f03ab1SJosef Bacik 				break;
62854f03ab1SJosef Bacik 			} else {
62954f03ab1SJosef Bacik 				/*
63054f03ab1SJosef Bacik 				 * Inline extents are special, we just treat
63154f03ab1SJosef Bacik 				 * them as a full sector worth in the file
63254f03ab1SJosef Bacik 				 * extent tree just for simplicity sake.
63354f03ab1SJosef Bacik 				 */
63454f03ab1SJosef Bacik 				clear_len = fs_info->sectorsize;
63554f03ab1SJosef Bacik 			}
63654f03ab1SJosef Bacik 
637462b728eSJosef Bacik 			control->sub_bytes += item_end + 1 - new_size;
63854f03ab1SJosef Bacik 		}
63954f03ab1SJosef Bacik delete:
64054f03ab1SJosef Bacik 		/*
641655807b8SJosef Bacik 		 * We only want to clear the file extent range if we're
642655807b8SJosef Bacik 		 * modifying the actual inode's mapping, which is just the
643655807b8SJosef Bacik 		 * normal truncate path.
64454f03ab1SJosef Bacik 		 */
645655807b8SJosef Bacik 		if (control->clear_extent_range) {
64671d18b53SJosef Bacik 			ret = btrfs_inode_clear_file_extent_range(control->inode,
64754f03ab1SJosef Bacik 						  clear_start, clear_len);
64854f03ab1SJosef Bacik 			if (ret) {
64954f03ab1SJosef Bacik 				btrfs_abort_transaction(trans, ret);
65054f03ab1SJosef Bacik 				break;
65154f03ab1SJosef Bacik 			}
65254f03ab1SJosef Bacik 		}
65354f03ab1SJosef Bacik 
65454f03ab1SJosef Bacik 		if (del_item) {
655376b91d5SJosef Bacik 			ASSERT(!pending_del_nr ||
656376b91d5SJosef Bacik 			       ((path->slots[0] + 1) == pending_del_slot));
657376b91d5SJosef Bacik 
6580adbc619SJosef Bacik 			control->last_size = found_key.offset;
65954f03ab1SJosef Bacik 			if (!pending_del_nr) {
66054f03ab1SJosef Bacik 				/* No pending yet, add ourselves */
66154f03ab1SJosef Bacik 				pending_del_slot = path->slots[0];
66254f03ab1SJosef Bacik 				pending_del_nr = 1;
6634a6f5ccaSFilipe Manana 			} else if (path->slots[0] + 1 == pending_del_slot) {
66454f03ab1SJosef Bacik 				/* Hop on the pending chunk */
66554f03ab1SJosef Bacik 				pending_del_nr++;
66654f03ab1SJosef Bacik 				pending_del_slot = path->slots[0];
66754f03ab1SJosef Bacik 			}
66854f03ab1SJosef Bacik 		} else {
6690adbc619SJosef Bacik 			control->last_size = new_size;
67054f03ab1SJosef Bacik 			break;
67154f03ab1SJosef Bacik 		}
67254f03ab1SJosef Bacik 
6735caa490eSJosef Bacik 		if (del_item && extent_start != 0 && !control->skip_ref_updates) {
67454f03ab1SJosef Bacik 			struct btrfs_ref ref = { 0 };
67554f03ab1SJosef Bacik 
67654f03ab1SJosef Bacik 			bytes_deleted += extent_num_bytes;
67754f03ab1SJosef Bacik 
67854f03ab1SJosef Bacik 			btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF,
67954f03ab1SJosef Bacik 					extent_start, extent_num_bytes, 0);
68054f03ab1SJosef Bacik 			btrfs_init_data_ref(&ref, btrfs_header_owner(leaf),
681487e81d2SJosef Bacik 					control->ino, extent_offset,
68254f03ab1SJosef Bacik 					root->root_key.objectid, false);
68354f03ab1SJosef Bacik 			ret = btrfs_free_extent(trans, &ref);
68454f03ab1SJosef Bacik 			if (ret) {
68554f03ab1SJosef Bacik 				btrfs_abort_transaction(trans, ret);
68654f03ab1SJosef Bacik 				break;
68754f03ab1SJosef Bacik 			}
688a8fdc051SFilipe Manana 			if (be_nice && btrfs_check_space_for_delayed_refs(fs_info))
689a8fdc051SFilipe Manana 				refill_delayed_refs_rsv = true;
69054f03ab1SJosef Bacik 		}
69154f03ab1SJosef Bacik 
69254f03ab1SJosef Bacik 		if (found_type == BTRFS_INODE_ITEM_KEY)
69354f03ab1SJosef Bacik 			break;
69454f03ab1SJosef Bacik 
69554f03ab1SJosef Bacik 		if (path->slots[0] == 0 ||
69654f03ab1SJosef Bacik 		    path->slots[0] != pending_del_slot ||
697a8fdc051SFilipe Manana 		    refill_delayed_refs_rsv) {
69854f03ab1SJosef Bacik 			if (pending_del_nr) {
69954f03ab1SJosef Bacik 				ret = btrfs_del_items(trans, root, path,
70054f03ab1SJosef Bacik 						pending_del_slot,
70154f03ab1SJosef Bacik 						pending_del_nr);
70254f03ab1SJosef Bacik 				if (ret) {
70354f03ab1SJosef Bacik 					btrfs_abort_transaction(trans, ret);
70454f03ab1SJosef Bacik 					break;
70554f03ab1SJosef Bacik 				}
70654f03ab1SJosef Bacik 				pending_del_nr = 0;
70754f03ab1SJosef Bacik 			}
70854f03ab1SJosef Bacik 			btrfs_release_path(path);
70954f03ab1SJosef Bacik 
71054f03ab1SJosef Bacik 			/*
71154f03ab1SJosef Bacik 			 * We can generate a lot of delayed refs, so we need to
71254f03ab1SJosef Bacik 			 * throttle every once and a while and make sure we're
71354f03ab1SJosef Bacik 			 * adding enough space to keep up with the work we are
71454f03ab1SJosef Bacik 			 * generating.  Since we hold a transaction here we
71554f03ab1SJosef Bacik 			 * can't flush, and we don't want to FLUSH_LIMIT because
71654f03ab1SJosef Bacik 			 * we could have generated too many delayed refs to
71754f03ab1SJosef Bacik 			 * actually allocate, so just bail if we're short and
71854f03ab1SJosef Bacik 			 * let the normal reservation dance happen higher up.
71954f03ab1SJosef Bacik 			 */
720a8fdc051SFilipe Manana 			if (refill_delayed_refs_rsv) {
72154f03ab1SJosef Bacik 				ret = btrfs_delayed_refs_rsv_refill(fs_info,
72254f03ab1SJosef Bacik 							BTRFS_RESERVE_NO_FLUSH);
72354f03ab1SJosef Bacik 				if (ret) {
72454f03ab1SJosef Bacik 					ret = -EAGAIN;
72554f03ab1SJosef Bacik 					break;
72654f03ab1SJosef Bacik 				}
72754f03ab1SJosef Bacik 			}
72854f03ab1SJosef Bacik 			goto search_again;
72954f03ab1SJosef Bacik 		} else {
73054f03ab1SJosef Bacik 			path->slots[0]--;
73154f03ab1SJosef Bacik 		}
73254f03ab1SJosef Bacik 	}
73354f03ab1SJosef Bacik out:
73454f03ab1SJosef Bacik 	if (ret >= 0 && pending_del_nr) {
73554f03ab1SJosef Bacik 		int err;
73654f03ab1SJosef Bacik 
73754f03ab1SJosef Bacik 		err = btrfs_del_items(trans, root, path, pending_del_slot,
73854f03ab1SJosef Bacik 				      pending_del_nr);
73954f03ab1SJosef Bacik 		if (err) {
74054f03ab1SJosef Bacik 			btrfs_abort_transaction(trans, err);
74154f03ab1SJosef Bacik 			ret = err;
74254f03ab1SJosef Bacik 		}
74354f03ab1SJosef Bacik 	}
744c2ddb612SJosef Bacik 
745c2ddb612SJosef Bacik 	ASSERT(control->last_size >= new_size);
746c2ddb612SJosef Bacik 	if (!ret && control->last_size > new_size)
747c2ddb612SJosef Bacik 		control->last_size = new_size;
74854f03ab1SJosef Bacik 
74954f03ab1SJosef Bacik 	btrfs_free_path(path);
75054f03ab1SJosef Bacik 	return ret;
75154f03ab1SJosef Bacik }
752