xref: /openbmc/linux/fs/btrfs/backref.c (revision 740c3d226cbba6cd6a32adfb66809c94938f3e57)
1a542ad1bSJan Schmidt /*
2a542ad1bSJan Schmidt  * Copyright (C) 2011 STRATO.  All rights reserved.
3a542ad1bSJan Schmidt  *
4a542ad1bSJan Schmidt  * This program is free software; you can redistribute it and/or
5a542ad1bSJan Schmidt  * modify it under the terms of the GNU General Public
6a542ad1bSJan Schmidt  * License v2 as published by the Free Software Foundation.
7a542ad1bSJan Schmidt  *
8a542ad1bSJan Schmidt  * This program is distributed in the hope that it will be useful,
9a542ad1bSJan Schmidt  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10a542ad1bSJan Schmidt  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11a542ad1bSJan Schmidt  * General Public License for more details.
12a542ad1bSJan Schmidt  *
13a542ad1bSJan Schmidt  * You should have received a copy of the GNU General Public
14a542ad1bSJan Schmidt  * License along with this program; if not, write to the
15a542ad1bSJan Schmidt  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16a542ad1bSJan Schmidt  * Boston, MA 021110-1307, USA.
17a542ad1bSJan Schmidt  */
18a542ad1bSJan Schmidt 
19a542ad1bSJan Schmidt #include "ctree.h"
20a542ad1bSJan Schmidt #include "disk-io.h"
21a542ad1bSJan Schmidt #include "backref.h"
22a542ad1bSJan Schmidt 
23a542ad1bSJan Schmidt struct __data_ref {
24a542ad1bSJan Schmidt 	struct list_head list;
25a542ad1bSJan Schmidt 	u64 inum;
26a542ad1bSJan Schmidt 	u64 root;
27a542ad1bSJan Schmidt 	u64 extent_data_item_offset;
28a542ad1bSJan Schmidt };
29a542ad1bSJan Schmidt 
30a542ad1bSJan Schmidt struct __shared_ref {
31a542ad1bSJan Schmidt 	struct list_head list;
32a542ad1bSJan Schmidt 	u64 disk_byte;
33a542ad1bSJan Schmidt };
34a542ad1bSJan Schmidt 
35a542ad1bSJan Schmidt static int __inode_info(u64 inum, u64 ioff, u8 key_type,
36a542ad1bSJan Schmidt 			struct btrfs_root *fs_root, struct btrfs_path *path,
37a542ad1bSJan Schmidt 			struct btrfs_key *found_key)
38a542ad1bSJan Schmidt {
39a542ad1bSJan Schmidt 	int ret;
40a542ad1bSJan Schmidt 	struct btrfs_key key;
41a542ad1bSJan Schmidt 	struct extent_buffer *eb;
42a542ad1bSJan Schmidt 
43a542ad1bSJan Schmidt 	key.type = key_type;
44a542ad1bSJan Schmidt 	key.objectid = inum;
45a542ad1bSJan Schmidt 	key.offset = ioff;
46a542ad1bSJan Schmidt 
47a542ad1bSJan Schmidt 	ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0);
48a542ad1bSJan Schmidt 	if (ret < 0)
49a542ad1bSJan Schmidt 		return ret;
50a542ad1bSJan Schmidt 
51a542ad1bSJan Schmidt 	eb = path->nodes[0];
52a542ad1bSJan Schmidt 	if (ret && path->slots[0] >= btrfs_header_nritems(eb)) {
53a542ad1bSJan Schmidt 		ret = btrfs_next_leaf(fs_root, path);
54a542ad1bSJan Schmidt 		if (ret)
55a542ad1bSJan Schmidt 			return ret;
56a542ad1bSJan Schmidt 		eb = path->nodes[0];
57a542ad1bSJan Schmidt 	}
58a542ad1bSJan Schmidt 
59a542ad1bSJan Schmidt 	btrfs_item_key_to_cpu(eb, found_key, path->slots[0]);
60a542ad1bSJan Schmidt 	if (found_key->type != key.type || found_key->objectid != key.objectid)
61a542ad1bSJan Schmidt 		return 1;
62a542ad1bSJan Schmidt 
63a542ad1bSJan Schmidt 	return 0;
64a542ad1bSJan Schmidt }
65a542ad1bSJan Schmidt 
66a542ad1bSJan Schmidt /*
67a542ad1bSJan Schmidt  * this makes the path point to (inum INODE_ITEM ioff)
68a542ad1bSJan Schmidt  */
69a542ad1bSJan Schmidt int inode_item_info(u64 inum, u64 ioff, struct btrfs_root *fs_root,
70a542ad1bSJan Schmidt 			struct btrfs_path *path)
71a542ad1bSJan Schmidt {
72a542ad1bSJan Schmidt 	struct btrfs_key key;
73a542ad1bSJan Schmidt 	return __inode_info(inum, ioff, BTRFS_INODE_ITEM_KEY, fs_root, path,
74a542ad1bSJan Schmidt 				&key);
75a542ad1bSJan Schmidt }
76a542ad1bSJan Schmidt 
77a542ad1bSJan Schmidt static int inode_ref_info(u64 inum, u64 ioff, struct btrfs_root *fs_root,
78a542ad1bSJan Schmidt 				struct btrfs_path *path,
79a542ad1bSJan Schmidt 				struct btrfs_key *found_key)
80a542ad1bSJan Schmidt {
81a542ad1bSJan Schmidt 	return __inode_info(inum, ioff, BTRFS_INODE_REF_KEY, fs_root, path,
82a542ad1bSJan Schmidt 				found_key);
83a542ad1bSJan Schmidt }
84a542ad1bSJan Schmidt 
85a542ad1bSJan Schmidt /*
86a542ad1bSJan Schmidt  * this iterates to turn a btrfs_inode_ref into a full filesystem path. elements
87a542ad1bSJan Schmidt  * of the path are separated by '/' and the path is guaranteed to be
88a542ad1bSJan Schmidt  * 0-terminated. the path is only given within the current file system.
89a542ad1bSJan Schmidt  * Therefore, it never starts with a '/'. the caller is responsible to provide
90a542ad1bSJan Schmidt  * "size" bytes in "dest". the dest buffer will be filled backwards. finally,
91a542ad1bSJan Schmidt  * the start point of the resulting string is returned. this pointer is within
92a542ad1bSJan Schmidt  * dest, normally.
93a542ad1bSJan Schmidt  * in case the path buffer would overflow, the pointer is decremented further
94a542ad1bSJan Schmidt  * as if output was written to the buffer, though no more output is actually
95a542ad1bSJan Schmidt  * generated. that way, the caller can determine how much space would be
96a542ad1bSJan Schmidt  * required for the path to fit into the buffer. in that case, the returned
97a542ad1bSJan Schmidt  * value will be smaller than dest. callers must check this!
98a542ad1bSJan Schmidt  */
99a542ad1bSJan Schmidt static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
100a542ad1bSJan Schmidt 				struct btrfs_inode_ref *iref,
101a542ad1bSJan Schmidt 				struct extent_buffer *eb_in, u64 parent,
102a542ad1bSJan Schmidt 				char *dest, u32 size)
103a542ad1bSJan Schmidt {
104a542ad1bSJan Schmidt 	u32 len;
105a542ad1bSJan Schmidt 	int slot;
106a542ad1bSJan Schmidt 	u64 next_inum;
107a542ad1bSJan Schmidt 	int ret;
108a542ad1bSJan Schmidt 	s64 bytes_left = size - 1;
109a542ad1bSJan Schmidt 	struct extent_buffer *eb = eb_in;
110a542ad1bSJan Schmidt 	struct btrfs_key found_key;
111a542ad1bSJan Schmidt 
112a542ad1bSJan Schmidt 	if (bytes_left >= 0)
113a542ad1bSJan Schmidt 		dest[bytes_left] = '\0';
114a542ad1bSJan Schmidt 
115a542ad1bSJan Schmidt 	while (1) {
116a542ad1bSJan Schmidt 		len = btrfs_inode_ref_name_len(eb, iref);
117a542ad1bSJan Schmidt 		bytes_left -= len;
118a542ad1bSJan Schmidt 		if (bytes_left >= 0)
119a542ad1bSJan Schmidt 			read_extent_buffer(eb, dest + bytes_left,
120a542ad1bSJan Schmidt 						(unsigned long)(iref + 1), len);
121a542ad1bSJan Schmidt 		if (eb != eb_in)
122a542ad1bSJan Schmidt 			free_extent_buffer(eb);
123a542ad1bSJan Schmidt 		ret = inode_ref_info(parent, 0, fs_root, path, &found_key);
124a542ad1bSJan Schmidt 		if (ret)
125a542ad1bSJan Schmidt 			break;
126a542ad1bSJan Schmidt 		next_inum = found_key.offset;
127a542ad1bSJan Schmidt 
128a542ad1bSJan Schmidt 		/* regular exit ahead */
129a542ad1bSJan Schmidt 		if (parent == next_inum)
130a542ad1bSJan Schmidt 			break;
131a542ad1bSJan Schmidt 
132a542ad1bSJan Schmidt 		slot = path->slots[0];
133a542ad1bSJan Schmidt 		eb = path->nodes[0];
134a542ad1bSJan Schmidt 		/* make sure we can use eb after releasing the path */
135a542ad1bSJan Schmidt 		if (eb != eb_in)
136a542ad1bSJan Schmidt 			atomic_inc(&eb->refs);
137a542ad1bSJan Schmidt 		btrfs_release_path(path);
138a542ad1bSJan Schmidt 
139a542ad1bSJan Schmidt 		iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref);
140a542ad1bSJan Schmidt 		parent = next_inum;
141a542ad1bSJan Schmidt 		--bytes_left;
142a542ad1bSJan Schmidt 		if (bytes_left >= 0)
143a542ad1bSJan Schmidt 			dest[bytes_left] = '/';
144a542ad1bSJan Schmidt 	}
145a542ad1bSJan Schmidt 
146a542ad1bSJan Schmidt 	btrfs_release_path(path);
147a542ad1bSJan Schmidt 
148a542ad1bSJan Schmidt 	if (ret)
149a542ad1bSJan Schmidt 		return ERR_PTR(ret);
150a542ad1bSJan Schmidt 
151a542ad1bSJan Schmidt 	return dest + bytes_left;
152a542ad1bSJan Schmidt }
153a542ad1bSJan Schmidt 
154a542ad1bSJan Schmidt /*
155a542ad1bSJan Schmidt  * this makes the path point to (logical EXTENT_ITEM *)
156a542ad1bSJan Schmidt  * returns BTRFS_EXTENT_FLAG_DATA for data, BTRFS_EXTENT_FLAG_TREE_BLOCK for
157a542ad1bSJan Schmidt  * tree blocks and <0 on error.
158a542ad1bSJan Schmidt  */
159a542ad1bSJan Schmidt int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
160a542ad1bSJan Schmidt 			struct btrfs_path *path, struct btrfs_key *found_key)
161a542ad1bSJan Schmidt {
162a542ad1bSJan Schmidt 	int ret;
163a542ad1bSJan Schmidt 	u64 flags;
164a542ad1bSJan Schmidt 	u32 item_size;
165a542ad1bSJan Schmidt 	struct extent_buffer *eb;
166a542ad1bSJan Schmidt 	struct btrfs_extent_item *ei;
167a542ad1bSJan Schmidt 	struct btrfs_key key;
168a542ad1bSJan Schmidt 
169a542ad1bSJan Schmidt 	key.type = BTRFS_EXTENT_ITEM_KEY;
170a542ad1bSJan Schmidt 	key.objectid = logical;
171a542ad1bSJan Schmidt 	key.offset = (u64)-1;
172a542ad1bSJan Schmidt 
173a542ad1bSJan Schmidt 	ret = btrfs_search_slot(NULL, fs_info->extent_root, &key, path, 0, 0);
174a542ad1bSJan Schmidt 	if (ret < 0)
175a542ad1bSJan Schmidt 		return ret;
176a542ad1bSJan Schmidt 	ret = btrfs_previous_item(fs_info->extent_root, path,
177a542ad1bSJan Schmidt 					0, BTRFS_EXTENT_ITEM_KEY);
178a542ad1bSJan Schmidt 	if (ret < 0)
179a542ad1bSJan Schmidt 		return ret;
180a542ad1bSJan Schmidt 
181a542ad1bSJan Schmidt 	btrfs_item_key_to_cpu(path->nodes[0], found_key, path->slots[0]);
182a542ad1bSJan Schmidt 	if (found_key->type != BTRFS_EXTENT_ITEM_KEY ||
183a542ad1bSJan Schmidt 	    found_key->objectid > logical ||
184a542ad1bSJan Schmidt 	    found_key->objectid + found_key->offset <= logical)
185a542ad1bSJan Schmidt 		return -ENOENT;
186a542ad1bSJan Schmidt 
187a542ad1bSJan Schmidt 	eb = path->nodes[0];
188a542ad1bSJan Schmidt 	item_size = btrfs_item_size_nr(eb, path->slots[0]);
189a542ad1bSJan Schmidt 	BUG_ON(item_size < sizeof(*ei));
190a542ad1bSJan Schmidt 
191a542ad1bSJan Schmidt 	ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item);
192a542ad1bSJan Schmidt 	flags = btrfs_extent_flags(eb, ei);
193a542ad1bSJan Schmidt 
194a542ad1bSJan Schmidt 	if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK)
195a542ad1bSJan Schmidt 		return BTRFS_EXTENT_FLAG_TREE_BLOCK;
196a542ad1bSJan Schmidt 	if (flags & BTRFS_EXTENT_FLAG_DATA)
197a542ad1bSJan Schmidt 		return BTRFS_EXTENT_FLAG_DATA;
198a542ad1bSJan Schmidt 
199a542ad1bSJan Schmidt 	return -EIO;
200a542ad1bSJan Schmidt }
201a542ad1bSJan Schmidt 
202a542ad1bSJan Schmidt /*
203a542ad1bSJan Schmidt  * helper function to iterate extent inline refs. ptr must point to a 0 value
204a542ad1bSJan Schmidt  * for the first call and may be modified. it is used to track state.
205a542ad1bSJan Schmidt  * if more refs exist, 0 is returned and the next call to
206a542ad1bSJan Schmidt  * __get_extent_inline_ref must pass the modified ptr parameter to get the
207a542ad1bSJan Schmidt  * next ref. after the last ref was processed, 1 is returned.
208a542ad1bSJan Schmidt  * returns <0 on error
209a542ad1bSJan Schmidt  */
210a542ad1bSJan Schmidt static int __get_extent_inline_ref(unsigned long *ptr, struct extent_buffer *eb,
211a542ad1bSJan Schmidt 				struct btrfs_extent_item *ei, u32 item_size,
212a542ad1bSJan Schmidt 				struct btrfs_extent_inline_ref **out_eiref,
213a542ad1bSJan Schmidt 				int *out_type)
214a542ad1bSJan Schmidt {
215a542ad1bSJan Schmidt 	unsigned long end;
216a542ad1bSJan Schmidt 	u64 flags;
217a542ad1bSJan Schmidt 	struct btrfs_tree_block_info *info;
218a542ad1bSJan Schmidt 
219a542ad1bSJan Schmidt 	if (!*ptr) {
220a542ad1bSJan Schmidt 		/* first call */
221a542ad1bSJan Schmidt 		flags = btrfs_extent_flags(eb, ei);
222a542ad1bSJan Schmidt 		if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
223a542ad1bSJan Schmidt 			info = (struct btrfs_tree_block_info *)(ei + 1);
224a542ad1bSJan Schmidt 			*out_eiref =
225a542ad1bSJan Schmidt 				(struct btrfs_extent_inline_ref *)(info + 1);
226a542ad1bSJan Schmidt 		} else {
227a542ad1bSJan Schmidt 			*out_eiref = (struct btrfs_extent_inline_ref *)(ei + 1);
228a542ad1bSJan Schmidt 		}
229a542ad1bSJan Schmidt 		*ptr = (unsigned long)*out_eiref;
230a542ad1bSJan Schmidt 		if ((void *)*ptr >= (void *)ei + item_size)
231a542ad1bSJan Schmidt 			return -ENOENT;
232a542ad1bSJan Schmidt 	}
233a542ad1bSJan Schmidt 
234a542ad1bSJan Schmidt 	end = (unsigned long)ei + item_size;
235a542ad1bSJan Schmidt 	*out_eiref = (struct btrfs_extent_inline_ref *)*ptr;
236a542ad1bSJan Schmidt 	*out_type = btrfs_extent_inline_ref_type(eb, *out_eiref);
237a542ad1bSJan Schmidt 
238a542ad1bSJan Schmidt 	*ptr += btrfs_extent_inline_ref_size(*out_type);
239a542ad1bSJan Schmidt 	WARN_ON(*ptr > end);
240a542ad1bSJan Schmidt 	if (*ptr == end)
241a542ad1bSJan Schmidt 		return 1; /* last */
242a542ad1bSJan Schmidt 
243a542ad1bSJan Schmidt 	return 0;
244a542ad1bSJan Schmidt }
245a542ad1bSJan Schmidt 
246a542ad1bSJan Schmidt /*
247a542ad1bSJan Schmidt  * reads the tree block backref for an extent. tree level and root are returned
248a542ad1bSJan Schmidt  * through out_level and out_root. ptr must point to a 0 value for the first
249a542ad1bSJan Schmidt  * call and may be modified (see __get_extent_inline_ref comment).
250a542ad1bSJan Schmidt  * returns 0 if data was provided, 1 if there was no more data to provide or
251a542ad1bSJan Schmidt  * <0 on error.
252a542ad1bSJan Schmidt  */
253a542ad1bSJan Schmidt int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb,
254a542ad1bSJan Schmidt 				struct btrfs_extent_item *ei, u32 item_size,
255a542ad1bSJan Schmidt 				u64 *out_root, u8 *out_level)
256a542ad1bSJan Schmidt {
257a542ad1bSJan Schmidt 	int ret;
258a542ad1bSJan Schmidt 	int type;
259a542ad1bSJan Schmidt 	struct btrfs_tree_block_info *info;
260a542ad1bSJan Schmidt 	struct btrfs_extent_inline_ref *eiref;
261a542ad1bSJan Schmidt 
262a542ad1bSJan Schmidt 	if (*ptr == (unsigned long)-1)
263a542ad1bSJan Schmidt 		return 1;
264a542ad1bSJan Schmidt 
265a542ad1bSJan Schmidt 	while (1) {
266a542ad1bSJan Schmidt 		ret = __get_extent_inline_ref(ptr, eb, ei, item_size,
267a542ad1bSJan Schmidt 						&eiref, &type);
268a542ad1bSJan Schmidt 		if (ret < 0)
269a542ad1bSJan Schmidt 			return ret;
270a542ad1bSJan Schmidt 
271a542ad1bSJan Schmidt 		if (type == BTRFS_TREE_BLOCK_REF_KEY ||
272a542ad1bSJan Schmidt 		    type == BTRFS_SHARED_BLOCK_REF_KEY)
273a542ad1bSJan Schmidt 			break;
274a542ad1bSJan Schmidt 
275a542ad1bSJan Schmidt 		if (ret == 1)
276a542ad1bSJan Schmidt 			return 1;
277a542ad1bSJan Schmidt 	}
278a542ad1bSJan Schmidt 
279a542ad1bSJan Schmidt 	/* we can treat both ref types equally here */
280a542ad1bSJan Schmidt 	info = (struct btrfs_tree_block_info *)(ei + 1);
281a542ad1bSJan Schmidt 	*out_root = btrfs_extent_inline_ref_offset(eb, eiref);
282a542ad1bSJan Schmidt 	*out_level = btrfs_tree_block_level(eb, info);
283a542ad1bSJan Schmidt 
284a542ad1bSJan Schmidt 	if (ret == 1)
285a542ad1bSJan Schmidt 		*ptr = (unsigned long)-1;
286a542ad1bSJan Schmidt 
287a542ad1bSJan Schmidt 	return 0;
288a542ad1bSJan Schmidt }
289a542ad1bSJan Schmidt 
290a542ad1bSJan Schmidt static int __data_list_add(struct list_head *head, u64 inum,
291a542ad1bSJan Schmidt 				u64 extent_data_item_offset, u64 root)
292a542ad1bSJan Schmidt {
293a542ad1bSJan Schmidt 	struct __data_ref *ref;
294a542ad1bSJan Schmidt 
295a542ad1bSJan Schmidt 	ref = kmalloc(sizeof(*ref), GFP_NOFS);
296a542ad1bSJan Schmidt 	if (!ref)
297a542ad1bSJan Schmidt 		return -ENOMEM;
298a542ad1bSJan Schmidt 
299a542ad1bSJan Schmidt 	ref->inum = inum;
300a542ad1bSJan Schmidt 	ref->extent_data_item_offset = extent_data_item_offset;
301a542ad1bSJan Schmidt 	ref->root = root;
302a542ad1bSJan Schmidt 	list_add_tail(&ref->list, head);
303a542ad1bSJan Schmidt 
304a542ad1bSJan Schmidt 	return 0;
305a542ad1bSJan Schmidt }
306a542ad1bSJan Schmidt 
307a542ad1bSJan Schmidt static int __data_list_add_eb(struct list_head *head, struct extent_buffer *eb,
308a542ad1bSJan Schmidt 				struct btrfs_extent_data_ref *dref)
309a542ad1bSJan Schmidt {
310a542ad1bSJan Schmidt 	return __data_list_add(head, btrfs_extent_data_ref_objectid(eb, dref),
311a542ad1bSJan Schmidt 				btrfs_extent_data_ref_offset(eb, dref),
312a542ad1bSJan Schmidt 				btrfs_extent_data_ref_root(eb, dref));
313a542ad1bSJan Schmidt }
314a542ad1bSJan Schmidt 
315a542ad1bSJan Schmidt static int __shared_list_add(struct list_head *head, u64 disk_byte)
316a542ad1bSJan Schmidt {
317a542ad1bSJan Schmidt 	struct __shared_ref *ref;
318a542ad1bSJan Schmidt 
319a542ad1bSJan Schmidt 	ref = kmalloc(sizeof(*ref), GFP_NOFS);
320a542ad1bSJan Schmidt 	if (!ref)
321a542ad1bSJan Schmidt 		return -ENOMEM;
322a542ad1bSJan Schmidt 
323a542ad1bSJan Schmidt 	ref->disk_byte = disk_byte;
324a542ad1bSJan Schmidt 	list_add_tail(&ref->list, head);
325a542ad1bSJan Schmidt 
326a542ad1bSJan Schmidt 	return 0;
327a542ad1bSJan Schmidt }
328a542ad1bSJan Schmidt 
329a542ad1bSJan Schmidt static int __iter_shared_inline_ref_inodes(struct btrfs_fs_info *fs_info,
330a542ad1bSJan Schmidt 					   u64 logical, u64 inum,
331a542ad1bSJan Schmidt 					   u64 extent_data_item_offset,
332a542ad1bSJan Schmidt 					   u64 extent_offset,
333a542ad1bSJan Schmidt 					   struct btrfs_path *path,
334a542ad1bSJan Schmidt 					   struct list_head *data_refs,
335a542ad1bSJan Schmidt 					   iterate_extent_inodes_t *iterate,
336a542ad1bSJan Schmidt 					   void *ctx)
337a542ad1bSJan Schmidt {
338a542ad1bSJan Schmidt 	u64 ref_root;
339a542ad1bSJan Schmidt 	u32 item_size;
340a542ad1bSJan Schmidt 	struct btrfs_key key;
341a542ad1bSJan Schmidt 	struct extent_buffer *eb;
342a542ad1bSJan Schmidt 	struct btrfs_extent_item *ei;
343a542ad1bSJan Schmidt 	struct btrfs_extent_inline_ref *eiref;
344a542ad1bSJan Schmidt 	struct __data_ref *ref;
345a542ad1bSJan Schmidt 	int ret;
346a542ad1bSJan Schmidt 	int type;
347a542ad1bSJan Schmidt 	int last;
348a542ad1bSJan Schmidt 	unsigned long ptr = 0;
349a542ad1bSJan Schmidt 
350a542ad1bSJan Schmidt 	WARN_ON(!list_empty(data_refs));
351a542ad1bSJan Schmidt 	ret = extent_from_logical(fs_info, logical, path, &key);
352a542ad1bSJan Schmidt 	if (ret & BTRFS_EXTENT_FLAG_DATA)
353a542ad1bSJan Schmidt 		ret = -EIO;
354a542ad1bSJan Schmidt 	if (ret < 0)
355a542ad1bSJan Schmidt 		goto out;
356a542ad1bSJan Schmidt 
357a542ad1bSJan Schmidt 	eb = path->nodes[0];
358a542ad1bSJan Schmidt 	ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item);
359a542ad1bSJan Schmidt 	item_size = btrfs_item_size_nr(eb, path->slots[0]);
360a542ad1bSJan Schmidt 
361a542ad1bSJan Schmidt 	ret = 0;
362a542ad1bSJan Schmidt 	ref_root = 0;
363a542ad1bSJan Schmidt 	/*
364a542ad1bSJan Schmidt 	 * as done in iterate_extent_inodes, we first build a list of refs to
365a542ad1bSJan Schmidt 	 * iterate, then free the path and then iterate them to avoid deadlocks.
366a542ad1bSJan Schmidt 	 */
367a542ad1bSJan Schmidt 	do {
368a542ad1bSJan Schmidt 		last = __get_extent_inline_ref(&ptr, eb, ei, item_size,
369a542ad1bSJan Schmidt 						&eiref, &type);
370a542ad1bSJan Schmidt 		if (last < 0) {
371a542ad1bSJan Schmidt 			ret = last;
372a542ad1bSJan Schmidt 			goto out;
373a542ad1bSJan Schmidt 		}
374a542ad1bSJan Schmidt 		if (type == BTRFS_TREE_BLOCK_REF_KEY ||
375a542ad1bSJan Schmidt 		    type == BTRFS_SHARED_BLOCK_REF_KEY) {
376a542ad1bSJan Schmidt 			ref_root = btrfs_extent_inline_ref_offset(eb, eiref);
377a542ad1bSJan Schmidt 			ret = __data_list_add(data_refs, inum,
378a542ad1bSJan Schmidt 						extent_data_item_offset,
379a542ad1bSJan Schmidt 						ref_root);
380a542ad1bSJan Schmidt 		}
381a542ad1bSJan Schmidt 	} while (!ret && !last);
382a542ad1bSJan Schmidt 
383a542ad1bSJan Schmidt 	btrfs_release_path(path);
384a542ad1bSJan Schmidt 
385a542ad1bSJan Schmidt 	if (ref_root == 0) {
386a542ad1bSJan Schmidt 		printk(KERN_ERR "btrfs: failed to find tree block ref "
387a542ad1bSJan Schmidt 			"for shared data backref %llu\n", logical);
388a542ad1bSJan Schmidt 		WARN_ON(1);
389a542ad1bSJan Schmidt 		ret = -EIO;
390a542ad1bSJan Schmidt 	}
391a542ad1bSJan Schmidt 
392a542ad1bSJan Schmidt out:
393a542ad1bSJan Schmidt 	while (!list_empty(data_refs)) {
394a542ad1bSJan Schmidt 		ref = list_first_entry(data_refs, struct __data_ref, list);
395a542ad1bSJan Schmidt 		list_del(&ref->list);
396a542ad1bSJan Schmidt 		if (!ret)
397a542ad1bSJan Schmidt 			ret = iterate(ref->inum, extent_offset +
398a542ad1bSJan Schmidt 					ref->extent_data_item_offset,
399a542ad1bSJan Schmidt 					ref->root, ctx);
400a542ad1bSJan Schmidt 		kfree(ref);
401a542ad1bSJan Schmidt 	}
402a542ad1bSJan Schmidt 
403a542ad1bSJan Schmidt 	return ret;
404a542ad1bSJan Schmidt }
405a542ad1bSJan Schmidt 
406a542ad1bSJan Schmidt static int __iter_shared_inline_ref(struct btrfs_fs_info *fs_info,
407a542ad1bSJan Schmidt 				    u64 logical, u64 orig_extent_item_objectid,
408a542ad1bSJan Schmidt 				    u64 extent_offset, struct btrfs_path *path,
409a542ad1bSJan Schmidt 				    struct list_head *data_refs,
410a542ad1bSJan Schmidt 				    iterate_extent_inodes_t *iterate,
411a542ad1bSJan Schmidt 				    void *ctx)
412a542ad1bSJan Schmidt {
413a542ad1bSJan Schmidt 	u64 disk_byte;
414a542ad1bSJan Schmidt 	struct btrfs_key key;
415a542ad1bSJan Schmidt 	struct btrfs_file_extent_item *fi;
416a542ad1bSJan Schmidt 	struct extent_buffer *eb;
417a542ad1bSJan Schmidt 	int slot;
418a542ad1bSJan Schmidt 	int nritems;
419a542ad1bSJan Schmidt 	int ret;
420a542ad1bSJan Schmidt 	int found = 0;
421a542ad1bSJan Schmidt 
422a542ad1bSJan Schmidt 	eb = read_tree_block(fs_info->tree_root, logical,
423a542ad1bSJan Schmidt 				fs_info->tree_root->leafsize, 0);
424a542ad1bSJan Schmidt 	if (!eb)
425a542ad1bSJan Schmidt 		return -EIO;
426a542ad1bSJan Schmidt 
427a542ad1bSJan Schmidt 	/*
428a542ad1bSJan Schmidt 	 * from the shared data ref, we only have the leaf but we need
429a542ad1bSJan Schmidt 	 * the key. thus, we must look into all items and see that we
430a542ad1bSJan Schmidt 	 * find one (some) with a reference to our extent item.
431a542ad1bSJan Schmidt 	 */
432a542ad1bSJan Schmidt 	nritems = btrfs_header_nritems(eb);
433a542ad1bSJan Schmidt 	for (slot = 0; slot < nritems; ++slot) {
434a542ad1bSJan Schmidt 		btrfs_item_key_to_cpu(eb, &key, slot);
435a542ad1bSJan Schmidt 		if (key.type != BTRFS_EXTENT_DATA_KEY)
436a542ad1bSJan Schmidt 			continue;
437a542ad1bSJan Schmidt 		fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
438a542ad1bSJan Schmidt 		if (!fi) {
439a542ad1bSJan Schmidt 			free_extent_buffer(eb);
440a542ad1bSJan Schmidt 			return -EIO;
441a542ad1bSJan Schmidt 		}
442a542ad1bSJan Schmidt 		disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
443a542ad1bSJan Schmidt 		if (disk_byte != orig_extent_item_objectid) {
444a542ad1bSJan Schmidt 			if (found)
445a542ad1bSJan Schmidt 				break;
446a542ad1bSJan Schmidt 			else
447a542ad1bSJan Schmidt 				continue;
448a542ad1bSJan Schmidt 		}
449a542ad1bSJan Schmidt 		++found;
450a542ad1bSJan Schmidt 		ret = __iter_shared_inline_ref_inodes(fs_info, logical,
451a542ad1bSJan Schmidt 							key.objectid,
452a542ad1bSJan Schmidt 							key.offset,
453a542ad1bSJan Schmidt 							extent_offset, path,
454a542ad1bSJan Schmidt 							data_refs,
455a542ad1bSJan Schmidt 							iterate, ctx);
456a542ad1bSJan Schmidt 		if (ret)
457a542ad1bSJan Schmidt 			break;
458a542ad1bSJan Schmidt 	}
459a542ad1bSJan Schmidt 
460a542ad1bSJan Schmidt 	if (!found) {
461a542ad1bSJan Schmidt 		printk(KERN_ERR "btrfs: failed to follow shared data backref "
462a542ad1bSJan Schmidt 			"to parent %llu\n", logical);
463a542ad1bSJan Schmidt 		WARN_ON(1);
464a542ad1bSJan Schmidt 		ret = -EIO;
465a542ad1bSJan Schmidt 	}
466a542ad1bSJan Schmidt 
467a542ad1bSJan Schmidt 	free_extent_buffer(eb);
468a542ad1bSJan Schmidt 	return ret;
469a542ad1bSJan Schmidt }
470a542ad1bSJan Schmidt 
471a542ad1bSJan Schmidt /*
472a542ad1bSJan Schmidt  * calls iterate() for every inode that references the extent identified by
473a542ad1bSJan Schmidt  * the given parameters. will use the path given as a parameter and return it
474a542ad1bSJan Schmidt  * released.
475a542ad1bSJan Schmidt  * when the iterator function returns a non-zero value, iteration stops.
476a542ad1bSJan Schmidt  */
477a542ad1bSJan Schmidt int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
478a542ad1bSJan Schmidt 				struct btrfs_path *path,
479a542ad1bSJan Schmidt 				u64 extent_item_objectid,
480a542ad1bSJan Schmidt 				u64 extent_offset,
481a542ad1bSJan Schmidt 				iterate_extent_inodes_t *iterate, void *ctx)
482a542ad1bSJan Schmidt {
483a542ad1bSJan Schmidt 	unsigned long ptr = 0;
484a542ad1bSJan Schmidt 	int last;
485a542ad1bSJan Schmidt 	int ret;
486a542ad1bSJan Schmidt 	int type;
487a542ad1bSJan Schmidt 	u64 logical;
488a542ad1bSJan Schmidt 	u32 item_size;
489a542ad1bSJan Schmidt 	struct btrfs_extent_inline_ref *eiref;
490a542ad1bSJan Schmidt 	struct btrfs_extent_data_ref *dref;
491a542ad1bSJan Schmidt 	struct extent_buffer *eb;
492a542ad1bSJan Schmidt 	struct btrfs_extent_item *ei;
493a542ad1bSJan Schmidt 	struct btrfs_key key;
494a542ad1bSJan Schmidt 	struct list_head data_refs = LIST_HEAD_INIT(data_refs);
495a542ad1bSJan Schmidt 	struct list_head shared_refs = LIST_HEAD_INIT(shared_refs);
496a542ad1bSJan Schmidt 	struct __data_ref *ref_d;
497a542ad1bSJan Schmidt 	struct __shared_ref *ref_s;
498a542ad1bSJan Schmidt 
499a542ad1bSJan Schmidt 	eb = path->nodes[0];
500a542ad1bSJan Schmidt 	ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item);
501a542ad1bSJan Schmidt 	item_size = btrfs_item_size_nr(eb, path->slots[0]);
502a542ad1bSJan Schmidt 
503a542ad1bSJan Schmidt 	/* first we iterate the inline refs, ... */
504a542ad1bSJan Schmidt 	do {
505a542ad1bSJan Schmidt 		last = __get_extent_inline_ref(&ptr, eb, ei, item_size,
506a542ad1bSJan Schmidt 						&eiref, &type);
507a542ad1bSJan Schmidt 		if (last == -ENOENT) {
508a542ad1bSJan Schmidt 			ret = 0;
509a542ad1bSJan Schmidt 			break;
510a542ad1bSJan Schmidt 		}
511a542ad1bSJan Schmidt 		if (last < 0) {
512a542ad1bSJan Schmidt 			ret = last;
513a542ad1bSJan Schmidt 			break;
514a542ad1bSJan Schmidt 		}
515a542ad1bSJan Schmidt 
516a542ad1bSJan Schmidt 		if (type == BTRFS_EXTENT_DATA_REF_KEY) {
517a542ad1bSJan Schmidt 			dref = (struct btrfs_extent_data_ref *)(&eiref->offset);
518a542ad1bSJan Schmidt 			ret = __data_list_add_eb(&data_refs, eb, dref);
519a542ad1bSJan Schmidt 		} else if (type == BTRFS_SHARED_DATA_REF_KEY) {
520a542ad1bSJan Schmidt 			logical = btrfs_extent_inline_ref_offset(eb, eiref);
521a542ad1bSJan Schmidt 			ret = __shared_list_add(&shared_refs, logical);
522a542ad1bSJan Schmidt 		}
523a542ad1bSJan Schmidt 	} while (!ret && !last);
524a542ad1bSJan Schmidt 
525a542ad1bSJan Schmidt 	/* ... then we proceed to in-tree references and ... */
526a542ad1bSJan Schmidt 	while (!ret) {
527a542ad1bSJan Schmidt 		++path->slots[0];
528a542ad1bSJan Schmidt 		if (path->slots[0] > btrfs_header_nritems(eb)) {
529a542ad1bSJan Schmidt 			ret = btrfs_next_leaf(fs_info->extent_root, path);
530a542ad1bSJan Schmidt 			if (ret) {
531a542ad1bSJan Schmidt 				if (ret == 1)
532a542ad1bSJan Schmidt 					ret = 0; /* we're done */
533a542ad1bSJan Schmidt 				break;
534a542ad1bSJan Schmidt 			}
535a542ad1bSJan Schmidt 			eb = path->nodes[0];
536a542ad1bSJan Schmidt 		}
537a542ad1bSJan Schmidt 		btrfs_item_key_to_cpu(eb, &key, path->slots[0]);
538a542ad1bSJan Schmidt 		if (key.objectid != extent_item_objectid)
539a542ad1bSJan Schmidt 			break;
540a542ad1bSJan Schmidt 		if (key.type == BTRFS_EXTENT_DATA_REF_KEY) {
541a542ad1bSJan Schmidt 			dref = btrfs_item_ptr(eb, path->slots[0],
542a542ad1bSJan Schmidt 						struct btrfs_extent_data_ref);
543a542ad1bSJan Schmidt 			ret = __data_list_add_eb(&data_refs, eb, dref);
544a542ad1bSJan Schmidt 		} else if (key.type == BTRFS_SHARED_DATA_REF_KEY) {
545a542ad1bSJan Schmidt 			ret = __shared_list_add(&shared_refs, key.offset);
546a542ad1bSJan Schmidt 		}
547a542ad1bSJan Schmidt 	}
548a542ad1bSJan Schmidt 
549a542ad1bSJan Schmidt 	btrfs_release_path(path);
550a542ad1bSJan Schmidt 
551a542ad1bSJan Schmidt 	/*
552a542ad1bSJan Schmidt 	 * ... only at the very end we can process the refs we found. this is
553a542ad1bSJan Schmidt 	 * because the iterator function we call is allowed to make tree lookups
554a542ad1bSJan Schmidt 	 * and we have to avoid deadlocks. additionally, we need more tree
555a542ad1bSJan Schmidt 	 * lookups ourselves for shared data refs.
556a542ad1bSJan Schmidt 	 */
557a542ad1bSJan Schmidt 	while (!list_empty(&data_refs)) {
558a542ad1bSJan Schmidt 		ref_d = list_first_entry(&data_refs, struct __data_ref, list);
559a542ad1bSJan Schmidt 		list_del(&ref_d->list);
560a542ad1bSJan Schmidt 		if (!ret)
561a542ad1bSJan Schmidt 			ret = iterate(ref_d->inum, extent_offset +
562a542ad1bSJan Schmidt 					ref_d->extent_data_item_offset,
563a542ad1bSJan Schmidt 					ref_d->root, ctx);
564a542ad1bSJan Schmidt 		kfree(ref_d);
565a542ad1bSJan Schmidt 	}
566a542ad1bSJan Schmidt 
567a542ad1bSJan Schmidt 	while (!list_empty(&shared_refs)) {
568a542ad1bSJan Schmidt 		ref_s = list_first_entry(&shared_refs, struct __shared_ref,
569a542ad1bSJan Schmidt 					list);
570a542ad1bSJan Schmidt 		list_del(&ref_s->list);
571a542ad1bSJan Schmidt 		if (!ret)
572a542ad1bSJan Schmidt 			ret = __iter_shared_inline_ref(fs_info,
573a542ad1bSJan Schmidt 							ref_s->disk_byte,
574a542ad1bSJan Schmidt 							extent_item_objectid,
575a542ad1bSJan Schmidt 							extent_offset, path,
576a542ad1bSJan Schmidt 							&data_refs,
577a542ad1bSJan Schmidt 							iterate, ctx);
578a542ad1bSJan Schmidt 		kfree(ref_s);
579a542ad1bSJan Schmidt 	}
580a542ad1bSJan Schmidt 
581a542ad1bSJan Schmidt 	return ret;
582a542ad1bSJan Schmidt }
583a542ad1bSJan Schmidt 
584a542ad1bSJan Schmidt int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info,
585a542ad1bSJan Schmidt 				struct btrfs_path *path,
586a542ad1bSJan Schmidt 				iterate_extent_inodes_t *iterate, void *ctx)
587a542ad1bSJan Schmidt {
588a542ad1bSJan Schmidt 	int ret;
589a542ad1bSJan Schmidt 	u64 offset;
590a542ad1bSJan Schmidt 	struct btrfs_key found_key;
591a542ad1bSJan Schmidt 
592a542ad1bSJan Schmidt 	ret = extent_from_logical(fs_info, logical, path,
593a542ad1bSJan Schmidt 					&found_key);
594a542ad1bSJan Schmidt 	if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK)
595a542ad1bSJan Schmidt 		ret = -EINVAL;
596a542ad1bSJan Schmidt 	if (ret < 0)
597a542ad1bSJan Schmidt 		return ret;
598a542ad1bSJan Schmidt 
599a542ad1bSJan Schmidt 	offset = logical - found_key.objectid;
600a542ad1bSJan Schmidt 	ret = iterate_extent_inodes(fs_info, path, found_key.objectid,
601a542ad1bSJan Schmidt 					offset, iterate, ctx);
602a542ad1bSJan Schmidt 
603a542ad1bSJan Schmidt 	return ret;
604a542ad1bSJan Schmidt }
605a542ad1bSJan Schmidt 
606a542ad1bSJan Schmidt static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,
607a542ad1bSJan Schmidt 				struct btrfs_path *path,
608a542ad1bSJan Schmidt 				iterate_irefs_t *iterate, void *ctx)
609a542ad1bSJan Schmidt {
610a542ad1bSJan Schmidt 	int ret;
611a542ad1bSJan Schmidt 	int slot;
612a542ad1bSJan Schmidt 	u32 cur;
613a542ad1bSJan Schmidt 	u32 len;
614a542ad1bSJan Schmidt 	u32 name_len;
615a542ad1bSJan Schmidt 	u64 parent = 0;
616a542ad1bSJan Schmidt 	int found = 0;
617a542ad1bSJan Schmidt 	struct extent_buffer *eb;
618a542ad1bSJan Schmidt 	struct btrfs_item *item;
619a542ad1bSJan Schmidt 	struct btrfs_inode_ref *iref;
620a542ad1bSJan Schmidt 	struct btrfs_key found_key;
621a542ad1bSJan Schmidt 
622a542ad1bSJan Schmidt 	while (1) {
623a542ad1bSJan Schmidt 		ret = inode_ref_info(inum, parent ? parent+1 : 0, fs_root, path,
624a542ad1bSJan Schmidt 					&found_key);
625a542ad1bSJan Schmidt 		if (ret < 0)
626a542ad1bSJan Schmidt 			break;
627a542ad1bSJan Schmidt 		if (ret) {
628a542ad1bSJan Schmidt 			ret = found ? 0 : -ENOENT;
629a542ad1bSJan Schmidt 			break;
630a542ad1bSJan Schmidt 		}
631a542ad1bSJan Schmidt 		++found;
632a542ad1bSJan Schmidt 
633a542ad1bSJan Schmidt 		parent = found_key.offset;
634a542ad1bSJan Schmidt 		slot = path->slots[0];
635a542ad1bSJan Schmidt 		eb = path->nodes[0];
636a542ad1bSJan Schmidt 		/* make sure we can use eb after releasing the path */
637a542ad1bSJan Schmidt 		atomic_inc(&eb->refs);
638a542ad1bSJan Schmidt 		btrfs_release_path(path);
639a542ad1bSJan Schmidt 
640a542ad1bSJan Schmidt 		item = btrfs_item_nr(eb, slot);
641a542ad1bSJan Schmidt 		iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref);
642a542ad1bSJan Schmidt 
643a542ad1bSJan Schmidt 		for (cur = 0; cur < btrfs_item_size(eb, item); cur += len) {
644a542ad1bSJan Schmidt 			name_len = btrfs_inode_ref_name_len(eb, iref);
645a542ad1bSJan Schmidt 			/* path must be released before calling iterate()! */
646a542ad1bSJan Schmidt 			ret = iterate(parent, iref, eb, ctx);
647a542ad1bSJan Schmidt 			if (ret) {
648a542ad1bSJan Schmidt 				free_extent_buffer(eb);
649a542ad1bSJan Schmidt 				break;
650a542ad1bSJan Schmidt 			}
651a542ad1bSJan Schmidt 			len = sizeof(*iref) + name_len;
652a542ad1bSJan Schmidt 			iref = (struct btrfs_inode_ref *)((char *)iref + len);
653a542ad1bSJan Schmidt 		}
654a542ad1bSJan Schmidt 		free_extent_buffer(eb);
655a542ad1bSJan Schmidt 	}
656a542ad1bSJan Schmidt 
657a542ad1bSJan Schmidt 	btrfs_release_path(path);
658a542ad1bSJan Schmidt 
659a542ad1bSJan Schmidt 	return ret;
660a542ad1bSJan Schmidt }
661a542ad1bSJan Schmidt 
662a542ad1bSJan Schmidt /*
663a542ad1bSJan Schmidt  * returns 0 if the path could be dumped (probably truncated)
664a542ad1bSJan Schmidt  * returns <0 in case of an error
665a542ad1bSJan Schmidt  */
666a542ad1bSJan Schmidt static int inode_to_path(u64 inum, struct btrfs_inode_ref *iref,
667a542ad1bSJan Schmidt 				struct extent_buffer *eb, void *ctx)
668a542ad1bSJan Schmidt {
669a542ad1bSJan Schmidt 	struct inode_fs_paths *ipath = ctx;
670a542ad1bSJan Schmidt 	char *fspath;
671a542ad1bSJan Schmidt 	char *fspath_min;
672a542ad1bSJan Schmidt 	int i = ipath->fspath->elem_cnt;
673a542ad1bSJan Schmidt 	const int s_ptr = sizeof(char *);
674a542ad1bSJan Schmidt 	u32 bytes_left;
675a542ad1bSJan Schmidt 
676a542ad1bSJan Schmidt 	bytes_left = ipath->fspath->bytes_left > s_ptr ?
677a542ad1bSJan Schmidt 					ipath->fspath->bytes_left - s_ptr : 0;
678a542ad1bSJan Schmidt 
679*740c3d22SChris Mason 	fspath_min = (char *)ipath->fspath->val + (i + 1) * s_ptr;
680a542ad1bSJan Schmidt 	fspath = iref_to_path(ipath->fs_root, ipath->btrfs_path, iref, eb,
681a542ad1bSJan Schmidt 				inum, fspath_min, bytes_left);
682a542ad1bSJan Schmidt 	if (IS_ERR(fspath))
683a542ad1bSJan Schmidt 		return PTR_ERR(fspath);
684a542ad1bSJan Schmidt 
685a542ad1bSJan Schmidt 	if (fspath > fspath_min) {
686*740c3d22SChris Mason 		ipath->fspath->val[i] = (u64)fspath;
687a542ad1bSJan Schmidt 		++ipath->fspath->elem_cnt;
688a542ad1bSJan Schmidt 		ipath->fspath->bytes_left = fspath - fspath_min;
689a542ad1bSJan Schmidt 	} else {
690a542ad1bSJan Schmidt 		++ipath->fspath->elem_missed;
691a542ad1bSJan Schmidt 		ipath->fspath->bytes_missing += fspath_min - fspath;
692a542ad1bSJan Schmidt 		ipath->fspath->bytes_left = 0;
693a542ad1bSJan Schmidt 	}
694a542ad1bSJan Schmidt 
695a542ad1bSJan Schmidt 	return 0;
696a542ad1bSJan Schmidt }
697a542ad1bSJan Schmidt 
698a542ad1bSJan Schmidt /*
699a542ad1bSJan Schmidt  * this dumps all file system paths to the inode into the ipath struct, provided
700a542ad1bSJan Schmidt  * is has been created large enough. each path is zero-terminated and accessed
701*740c3d22SChris Mason  * from ipath->fspath->val[i].
702a542ad1bSJan Schmidt  * when it returns, there are ipath->fspath->elem_cnt number of paths available
703*740c3d22SChris Mason  * in ipath->fspath->val[]. when the allocated space wasn't sufficient, the
704a542ad1bSJan Schmidt  * number of missed paths in recored in ipath->fspath->elem_missed, otherwise,
705a542ad1bSJan Schmidt  * it's zero. ipath->fspath->bytes_missing holds the number of bytes that would
706a542ad1bSJan Schmidt  * have been needed to return all paths.
707a542ad1bSJan Schmidt  */
708a542ad1bSJan Schmidt int paths_from_inode(u64 inum, struct inode_fs_paths *ipath)
709a542ad1bSJan Schmidt {
710a542ad1bSJan Schmidt 	return iterate_irefs(inum, ipath->fs_root, ipath->btrfs_path,
711a542ad1bSJan Schmidt 				inode_to_path, ipath);
712a542ad1bSJan Schmidt }
713a542ad1bSJan Schmidt 
714a542ad1bSJan Schmidt /*
715a542ad1bSJan Schmidt  * allocates space to return multiple file system paths for an inode.
716a542ad1bSJan Schmidt  * total_bytes to allocate are passed, note that space usable for actual path
717a542ad1bSJan Schmidt  * information will be total_bytes - sizeof(struct inode_fs_paths).
718a542ad1bSJan Schmidt  * the returned pointer must be freed with free_ipath() in the end.
719a542ad1bSJan Schmidt  */
720a542ad1bSJan Schmidt struct btrfs_data_container *init_data_container(u32 total_bytes)
721a542ad1bSJan Schmidt {
722a542ad1bSJan Schmidt 	struct btrfs_data_container *data;
723a542ad1bSJan Schmidt 	size_t alloc_bytes;
724a542ad1bSJan Schmidt 
725a542ad1bSJan Schmidt 	alloc_bytes = max_t(size_t, total_bytes, sizeof(*data));
726a542ad1bSJan Schmidt 	data = kmalloc(alloc_bytes, GFP_NOFS);
727a542ad1bSJan Schmidt 	if (!data)
728a542ad1bSJan Schmidt 		return ERR_PTR(-ENOMEM);
729a542ad1bSJan Schmidt 
730a542ad1bSJan Schmidt 	if (total_bytes >= sizeof(*data)) {
731a542ad1bSJan Schmidt 		data->bytes_left = total_bytes - sizeof(*data);
732a542ad1bSJan Schmidt 		data->bytes_missing = 0;
733a542ad1bSJan Schmidt 	} else {
734a542ad1bSJan Schmidt 		data->bytes_missing = sizeof(*data) - total_bytes;
735a542ad1bSJan Schmidt 		data->bytes_left = 0;
736a542ad1bSJan Schmidt 	}
737a542ad1bSJan Schmidt 
738a542ad1bSJan Schmidt 	data->elem_cnt = 0;
739a542ad1bSJan Schmidt 	data->elem_missed = 0;
740a542ad1bSJan Schmidt 
741a542ad1bSJan Schmidt 	return data;
742a542ad1bSJan Schmidt }
743a542ad1bSJan Schmidt 
744a542ad1bSJan Schmidt /*
745a542ad1bSJan Schmidt  * allocates space to return multiple file system paths for an inode.
746a542ad1bSJan Schmidt  * total_bytes to allocate are passed, note that space usable for actual path
747a542ad1bSJan Schmidt  * information will be total_bytes - sizeof(struct inode_fs_paths).
748a542ad1bSJan Schmidt  * the returned pointer must be freed with free_ipath() in the end.
749a542ad1bSJan Schmidt  */
750a542ad1bSJan Schmidt struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root,
751a542ad1bSJan Schmidt 					struct btrfs_path *path)
752a542ad1bSJan Schmidt {
753a542ad1bSJan Schmidt 	struct inode_fs_paths *ifp;
754a542ad1bSJan Schmidt 	struct btrfs_data_container *fspath;
755a542ad1bSJan Schmidt 
756a542ad1bSJan Schmidt 	fspath = init_data_container(total_bytes);
757a542ad1bSJan Schmidt 	if (IS_ERR(fspath))
758a542ad1bSJan Schmidt 		return (void *)fspath;
759a542ad1bSJan Schmidt 
760a542ad1bSJan Schmidt 	ifp = kmalloc(sizeof(*ifp), GFP_NOFS);
761a542ad1bSJan Schmidt 	if (!ifp) {
762a542ad1bSJan Schmidt 		kfree(fspath);
763a542ad1bSJan Schmidt 		return ERR_PTR(-ENOMEM);
764a542ad1bSJan Schmidt 	}
765a542ad1bSJan Schmidt 
766a542ad1bSJan Schmidt 	ifp->btrfs_path = path;
767a542ad1bSJan Schmidt 	ifp->fspath = fspath;
768a542ad1bSJan Schmidt 	ifp->fs_root = fs_root;
769a542ad1bSJan Schmidt 
770a542ad1bSJan Schmidt 	return ifp;
771a542ad1bSJan Schmidt }
772a542ad1bSJan Schmidt 
773a542ad1bSJan Schmidt void free_ipath(struct inode_fs_paths *ipath)
774a542ad1bSJan Schmidt {
775a542ad1bSJan Schmidt 	kfree(ipath);
776a542ad1bSJan Schmidt }
777