xref: /linux/fs/xfs/xfs_handle.c (revision c5288cda69ee2d8607f5026bd599a5cebf0ee783)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4  * Copyright (c) 2022-2024 Oracle.
5  * All rights reserved.
6  */
7 #include "xfs.h"
8 #include "xfs_fs.h"
9 #include "xfs_format.h"
10 #include "xfs_log_format.h"
11 #include "xfs_shared.h"
12 #include "xfs_trans_resv.h"
13 #include "xfs_mount.h"
14 #include "xfs_bmap_btree.h"
15 #include "xfs_inode.h"
16 #include "xfs_error.h"
17 #include "xfs_trace.h"
18 #include "xfs_trans.h"
19 #include "xfs_da_format.h"
20 #include "xfs_da_btree.h"
21 #include "xfs_attr.h"
22 #include "xfs_ioctl.h"
23 #include "xfs_parent.h"
24 #include "xfs_da_btree.h"
25 #include "xfs_handle.h"
26 #include "xfs_health.h"
27 #include "xfs_icache.h"
28 #include "xfs_export.h"
29 #include "xfs_xattr.h"
30 #include "xfs_acl.h"
31 
32 #include <linux/namei.h>
33 
34 static inline size_t
35 xfs_filehandle_fid_len(void)
36 {
37 	struct xfs_handle	*handle = NULL;
38 
39 	return sizeof(struct xfs_fid) - sizeof(handle->ha_fid.fid_len);
40 }
41 
42 static inline size_t
43 xfs_filehandle_init(
44 	struct xfs_mount	*mp,
45 	xfs_ino_t		ino,
46 	uint32_t		gen,
47 	struct xfs_handle	*handle)
48 {
49 	memcpy(&handle->ha_fsid, mp->m_fixedfsid, sizeof(struct xfs_fsid));
50 
51 	handle->ha_fid.fid_len = xfs_filehandle_fid_len();
52 	handle->ha_fid.fid_pad = 0;
53 	handle->ha_fid.fid_gen = gen;
54 	handle->ha_fid.fid_ino = ino;
55 
56 	return sizeof(struct xfs_handle);
57 }
58 
59 static inline size_t
60 xfs_fshandle_init(
61 	struct xfs_mount	*mp,
62 	struct xfs_handle	*handle)
63 {
64 	memcpy(&handle->ha_fsid, mp->m_fixedfsid, sizeof(struct xfs_fsid));
65 	memset(&handle->ha_fid, 0, sizeof(handle->ha_fid));
66 
67 	return sizeof(struct xfs_fsid);
68 }
69 
70 /*
71  * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to
72  * a file or fs handle.
73  *
74  * XFS_IOC_PATH_TO_FSHANDLE
75  *    returns fs handle for a mount point or path within that mount point
76  * XFS_IOC_FD_TO_HANDLE
77  *    returns full handle for a FD opened in user space
78  * XFS_IOC_PATH_TO_HANDLE
79  *    returns full handle for a path
80  */
81 int
82 xfs_find_handle(
83 	unsigned int		cmd,
84 	xfs_fsop_handlereq_t	*hreq)
85 {
86 	int			hsize;
87 	xfs_handle_t		handle;
88 	struct inode		*inode;
89 	struct fd		f = {NULL};
90 	struct path		path;
91 	int			error;
92 	struct xfs_inode	*ip;
93 
94 	if (cmd == XFS_IOC_FD_TO_HANDLE) {
95 		f = fdget(hreq->fd);
96 		if (!f.file)
97 			return -EBADF;
98 		inode = file_inode(f.file);
99 	} else {
100 		error = user_path_at(AT_FDCWD, hreq->path, 0, &path);
101 		if (error)
102 			return error;
103 		inode = d_inode(path.dentry);
104 	}
105 	ip = XFS_I(inode);
106 
107 	/*
108 	 * We can only generate handles for inodes residing on a XFS filesystem,
109 	 * and only for regular files, directories or symbolic links.
110 	 */
111 	error = -EINVAL;
112 	if (inode->i_sb->s_magic != XFS_SB_MAGIC)
113 		goto out_put;
114 
115 	error = -EBADF;
116 	if (!S_ISREG(inode->i_mode) &&
117 	    !S_ISDIR(inode->i_mode) &&
118 	    !S_ISLNK(inode->i_mode))
119 		goto out_put;
120 
121 
122 	memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
123 
124 	if (cmd == XFS_IOC_PATH_TO_FSHANDLE)
125 		hsize = xfs_fshandle_init(ip->i_mount, &handle);
126 	else
127 		hsize = xfs_filehandle_init(ip->i_mount, ip->i_ino,
128 				inode->i_generation, &handle);
129 
130 	error = -EFAULT;
131 	if (copy_to_user(hreq->ohandle, &handle, hsize) ||
132 	    copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
133 		goto out_put;
134 
135 	error = 0;
136 
137  out_put:
138 	if (cmd == XFS_IOC_FD_TO_HANDLE)
139 		fdput(f);
140 	else
141 		path_put(&path);
142 	return error;
143 }
144 
145 /*
146  * No need to do permission checks on the various pathname components
147  * as the handle operations are privileged.
148  */
149 STATIC int
150 xfs_handle_acceptable(
151 	void			*context,
152 	struct dentry		*dentry)
153 {
154 	return 1;
155 }
156 
157 /* Convert handle already copied to kernel space into a dentry. */
158 static struct dentry *
159 xfs_khandle_to_dentry(
160 	struct file		*file,
161 	struct xfs_handle	*handle)
162 {
163 	struct xfs_fid64        fid = {
164 		.ino		= handle->ha_fid.fid_ino,
165 		.gen		= handle->ha_fid.fid_gen,
166 	};
167 
168 	/*
169 	 * Only allow handle opens under a directory.
170 	 */
171 	if (!S_ISDIR(file_inode(file)->i_mode))
172 		return ERR_PTR(-ENOTDIR);
173 
174 	if (handle->ha_fid.fid_len != xfs_filehandle_fid_len())
175 		return ERR_PTR(-EINVAL);
176 
177 	return exportfs_decode_fh(file->f_path.mnt, (struct fid *)&fid, 3,
178 			FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG,
179 			xfs_handle_acceptable, NULL);
180 }
181 
182 /* Convert handle already copied to kernel space into an xfs_inode. */
183 static struct xfs_inode *
184 xfs_khandle_to_inode(
185 	struct file		*file,
186 	struct xfs_handle	*handle)
187 {
188 	struct xfs_inode	*ip = XFS_I(file_inode(file));
189 	struct xfs_mount	*mp = ip->i_mount;
190 	struct inode		*inode;
191 
192 	if (!S_ISDIR(VFS_I(ip)->i_mode))
193 		return ERR_PTR(-ENOTDIR);
194 
195 	if (handle->ha_fid.fid_len != xfs_filehandle_fid_len())
196 		return ERR_PTR(-EINVAL);
197 
198 	inode = xfs_nfs_get_inode(mp->m_super, handle->ha_fid.fid_ino,
199 			handle->ha_fid.fid_gen);
200 	if (IS_ERR(inode))
201 		return ERR_CAST(inode);
202 
203 	return XFS_I(inode);
204 }
205 
206 /*
207  * Convert userspace handle data into a dentry.
208  */
209 struct dentry *
210 xfs_handle_to_dentry(
211 	struct file		*parfilp,
212 	void __user		*uhandle,
213 	u32			hlen)
214 {
215 	xfs_handle_t		handle;
216 
217 	if (hlen != sizeof(xfs_handle_t))
218 		return ERR_PTR(-EINVAL);
219 	if (copy_from_user(&handle, uhandle, hlen))
220 		return ERR_PTR(-EFAULT);
221 
222 	return xfs_khandle_to_dentry(parfilp, &handle);
223 }
224 
225 STATIC struct dentry *
226 xfs_handlereq_to_dentry(
227 	struct file		*parfilp,
228 	xfs_fsop_handlereq_t	*hreq)
229 {
230 	return xfs_handle_to_dentry(parfilp, hreq->ihandle, hreq->ihandlen);
231 }
232 
233 int
234 xfs_open_by_handle(
235 	struct file		*parfilp,
236 	xfs_fsop_handlereq_t	*hreq)
237 {
238 	const struct cred	*cred = current_cred();
239 	int			error;
240 	int			fd;
241 	int			permflag;
242 	struct file		*filp;
243 	struct inode		*inode;
244 	struct dentry		*dentry;
245 	fmode_t			fmode;
246 	struct path		path;
247 
248 	if (!capable(CAP_SYS_ADMIN))
249 		return -EPERM;
250 
251 	dentry = xfs_handlereq_to_dentry(parfilp, hreq);
252 	if (IS_ERR(dentry))
253 		return PTR_ERR(dentry);
254 	inode = d_inode(dentry);
255 
256 	/* Restrict xfs_open_by_handle to directories & regular files. */
257 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
258 		error = -EPERM;
259 		goto out_dput;
260 	}
261 
262 #if BITS_PER_LONG != 32
263 	hreq->oflags |= O_LARGEFILE;
264 #endif
265 
266 	permflag = hreq->oflags;
267 	fmode = OPEN_FMODE(permflag);
268 	if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
269 	    (fmode & FMODE_WRITE) && IS_APPEND(inode)) {
270 		error = -EPERM;
271 		goto out_dput;
272 	}
273 
274 	if ((fmode & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
275 		error = -EPERM;
276 		goto out_dput;
277 	}
278 
279 	/* Can't write directories. */
280 	if (S_ISDIR(inode->i_mode) && (fmode & FMODE_WRITE)) {
281 		error = -EISDIR;
282 		goto out_dput;
283 	}
284 
285 	fd = get_unused_fd_flags(0);
286 	if (fd < 0) {
287 		error = fd;
288 		goto out_dput;
289 	}
290 
291 	path.mnt = parfilp->f_path.mnt;
292 	path.dentry = dentry;
293 	filp = dentry_open(&path, hreq->oflags, cred);
294 	dput(dentry);
295 	if (IS_ERR(filp)) {
296 		put_unused_fd(fd);
297 		return PTR_ERR(filp);
298 	}
299 
300 	if (S_ISREG(inode->i_mode)) {
301 		filp->f_flags |= O_NOATIME;
302 		filp->f_mode |= FMODE_NOCMTIME;
303 	}
304 
305 	fd_install(fd, filp);
306 	return fd;
307 
308  out_dput:
309 	dput(dentry);
310 	return error;
311 }
312 
313 int
314 xfs_readlink_by_handle(
315 	struct file		*parfilp,
316 	xfs_fsop_handlereq_t	*hreq)
317 {
318 	struct dentry		*dentry;
319 	__u32			olen;
320 	int			error;
321 
322 	if (!capable(CAP_SYS_ADMIN))
323 		return -EPERM;
324 
325 	dentry = xfs_handlereq_to_dentry(parfilp, hreq);
326 	if (IS_ERR(dentry))
327 		return PTR_ERR(dentry);
328 
329 	/* Restrict this handle operation to symlinks only. */
330 	if (!d_is_symlink(dentry)) {
331 		error = -EINVAL;
332 		goto out_dput;
333 	}
334 
335 	if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) {
336 		error = -EFAULT;
337 		goto out_dput;
338 	}
339 
340 	error = vfs_readlink(dentry, hreq->ohandle, olen);
341 
342  out_dput:
343 	dput(dentry);
344 	return error;
345 }
346 
347 /*
348  * Format an attribute and copy it out to the user's buffer.
349  * Take care to check values and protect against them changing later,
350  * we may be reading them directly out of a user buffer.
351  */
352 static void
353 xfs_ioc_attr_put_listent(
354 	struct xfs_attr_list_context *context,
355 	int			flags,
356 	unsigned char		*name,
357 	int			namelen,
358 	void			*value,
359 	int			valuelen)
360 {
361 	struct xfs_attrlist	*alist = context->buffer;
362 	struct xfs_attrlist_ent	*aep;
363 	int			arraytop;
364 
365 	ASSERT(!context->seen_enough);
366 	ASSERT(context->count >= 0);
367 	ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
368 	ASSERT(context->firstu >= sizeof(*alist));
369 	ASSERT(context->firstu <= context->bufsize);
370 
371 	/*
372 	 * Only list entries in the right namespace.
373 	 */
374 	if (context->attr_filter != (flags & XFS_ATTR_NSP_ONDISK_MASK))
375 		return;
376 
377 	arraytop = sizeof(*alist) +
378 			context->count * sizeof(alist->al_offset[0]);
379 
380 	/* decrement by the actual bytes used by the attr */
381 	context->firstu -= round_up(offsetof(struct xfs_attrlist_ent, a_name) +
382 			namelen + 1, sizeof(uint32_t));
383 	if (context->firstu < arraytop) {
384 		trace_xfs_attr_list_full(context);
385 		alist->al_more = 1;
386 		context->seen_enough = 1;
387 		return;
388 	}
389 
390 	aep = context->buffer + context->firstu;
391 	aep->a_valuelen = valuelen;
392 	memcpy(aep->a_name, name, namelen);
393 	aep->a_name[namelen] = 0;
394 	alist->al_offset[context->count++] = context->firstu;
395 	alist->al_count = context->count;
396 	trace_xfs_attr_list_add(context);
397 }
398 
399 static unsigned int
400 xfs_attr_filter(
401 	u32			ioc_flags)
402 {
403 	if (ioc_flags & XFS_IOC_ATTR_ROOT)
404 		return XFS_ATTR_ROOT;
405 	if (ioc_flags & XFS_IOC_ATTR_SECURE)
406 		return XFS_ATTR_SECURE;
407 	return 0;
408 }
409 
410 static inline enum xfs_attr_update
411 xfs_xattr_flags(
412 	u32			ioc_flags,
413 	void			*value)
414 {
415 	if (!value)
416 		return XFS_ATTRUPDATE_REMOVE;
417 	if (ioc_flags & XFS_IOC_ATTR_CREATE)
418 		return XFS_ATTRUPDATE_CREATE;
419 	if (ioc_flags & XFS_IOC_ATTR_REPLACE)
420 		return XFS_ATTRUPDATE_REPLACE;
421 	return XFS_ATTRUPDATE_UPSERT;
422 }
423 
424 int
425 xfs_ioc_attr_list(
426 	struct xfs_inode		*dp,
427 	void __user			*ubuf,
428 	size_t				bufsize,
429 	int				flags,
430 	struct xfs_attrlist_cursor __user *ucursor)
431 {
432 	struct xfs_attr_list_context	context = { };
433 	struct xfs_attrlist		*alist;
434 	void				*buffer;
435 	int				error;
436 
437 	if (bufsize < sizeof(struct xfs_attrlist) ||
438 	    bufsize > XFS_XATTR_LIST_MAX)
439 		return -EINVAL;
440 
441 	/*
442 	 * Reject flags, only allow namespaces.
443 	 */
444 	if (flags & ~(XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
445 		return -EINVAL;
446 	if (flags == (XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
447 		return -EINVAL;
448 
449 	/*
450 	 * Validate the cursor.
451 	 */
452 	if (copy_from_user(&context.cursor, ucursor, sizeof(context.cursor)))
453 		return -EFAULT;
454 	if (context.cursor.pad1 || context.cursor.pad2)
455 		return -EINVAL;
456 	if (!context.cursor.initted &&
457 	    (context.cursor.hashval || context.cursor.blkno ||
458 	     context.cursor.offset))
459 		return -EINVAL;
460 
461 	buffer = kvzalloc(bufsize, GFP_KERNEL);
462 	if (!buffer)
463 		return -ENOMEM;
464 
465 	/*
466 	 * Initialize the output buffer.
467 	 */
468 	context.dp = dp;
469 	context.resynch = 1;
470 	context.attr_filter = xfs_attr_filter(flags);
471 	context.buffer = buffer;
472 	context.bufsize = round_down(bufsize, sizeof(uint32_t));
473 	context.firstu = context.bufsize;
474 	context.put_listent = xfs_ioc_attr_put_listent;
475 
476 	alist = context.buffer;
477 	alist->al_count = 0;
478 	alist->al_more = 0;
479 	alist->al_offset[0] = context.bufsize;
480 
481 	error = xfs_attr_list(&context);
482 	if (error)
483 		goto out_free;
484 
485 	if (copy_to_user(ubuf, buffer, bufsize) ||
486 	    copy_to_user(ucursor, &context.cursor, sizeof(context.cursor)))
487 		error = -EFAULT;
488 out_free:
489 	kvfree(buffer);
490 	return error;
491 }
492 
493 int
494 xfs_attrlist_by_handle(
495 	struct file		*parfilp,
496 	struct xfs_fsop_attrlist_handlereq __user *p)
497 {
498 	struct xfs_fsop_attrlist_handlereq al_hreq;
499 	struct dentry		*dentry;
500 	int			error = -ENOMEM;
501 
502 	if (!capable(CAP_SYS_ADMIN))
503 		return -EPERM;
504 	if (copy_from_user(&al_hreq, p, sizeof(al_hreq)))
505 		return -EFAULT;
506 
507 	dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
508 	if (IS_ERR(dentry))
509 		return PTR_ERR(dentry);
510 
511 	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), al_hreq.buffer,
512 				  al_hreq.buflen, al_hreq.flags, &p->pos);
513 	dput(dentry);
514 	return error;
515 }
516 
517 static int
518 xfs_attrmulti_attr_get(
519 	struct inode		*inode,
520 	unsigned char		*name,
521 	unsigned char		__user *ubuf,
522 	uint32_t		*len,
523 	uint32_t		flags)
524 {
525 	struct xfs_da_args	args = {
526 		.dp		= XFS_I(inode),
527 		.attr_filter	= xfs_attr_filter(flags),
528 		.name		= name,
529 		.namelen	= strlen(name),
530 		.valuelen	= *len,
531 	};
532 	int			error;
533 
534 	if (*len > XFS_XATTR_SIZE_MAX)
535 		return -EINVAL;
536 
537 	error = xfs_attr_get(&args);
538 	if (error)
539 		goto out_kfree;
540 
541 	*len = args.valuelen;
542 	if (copy_to_user(ubuf, args.value, args.valuelen))
543 		error = -EFAULT;
544 
545 out_kfree:
546 	kvfree(args.value);
547 	return error;
548 }
549 
550 static int
551 xfs_attrmulti_attr_set(
552 	struct inode		*inode,
553 	unsigned char		*name,
554 	const unsigned char	__user *ubuf,
555 	uint32_t		len,
556 	uint32_t		flags)
557 {
558 	struct xfs_da_args	args = {
559 		.dp		= XFS_I(inode),
560 		.attr_filter	= xfs_attr_filter(flags),
561 		.name		= name,
562 		.namelen	= strlen(name),
563 	};
564 	int			error;
565 
566 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
567 		return -EPERM;
568 
569 	if (ubuf) {
570 		if (len > XFS_XATTR_SIZE_MAX)
571 			return -EINVAL;
572 		args.value = memdup_user(ubuf, len);
573 		if (IS_ERR(args.value))
574 			return PTR_ERR(args.value);
575 		args.valuelen = len;
576 	}
577 
578 	error = xfs_attr_change(&args, xfs_xattr_flags(flags, args.value));
579 	if (!error && (flags & XFS_IOC_ATTR_ROOT))
580 		xfs_forget_acl(inode, name);
581 	kfree(args.value);
582 	return error;
583 }
584 
585 int
586 xfs_ioc_attrmulti_one(
587 	struct file		*parfilp,
588 	struct inode		*inode,
589 	uint32_t		opcode,
590 	void __user		*uname,
591 	void __user		*value,
592 	uint32_t		*len,
593 	uint32_t		flags)
594 {
595 	unsigned char		*name;
596 	int			error;
597 
598 	if ((flags & XFS_IOC_ATTR_ROOT) && (flags & XFS_IOC_ATTR_SECURE))
599 		return -EINVAL;
600 
601 	name = strndup_user(uname, MAXNAMELEN);
602 	if (IS_ERR(name))
603 		return PTR_ERR(name);
604 
605 	switch (opcode) {
606 	case ATTR_OP_GET:
607 		error = xfs_attrmulti_attr_get(inode, name, value, len, flags);
608 		break;
609 	case ATTR_OP_REMOVE:
610 		value = NULL;
611 		*len = 0;
612 		fallthrough;
613 	case ATTR_OP_SET:
614 		error = mnt_want_write_file(parfilp);
615 		if (error)
616 			break;
617 		error = xfs_attrmulti_attr_set(inode, name, value, *len, flags);
618 		mnt_drop_write_file(parfilp);
619 		break;
620 	default:
621 		error = -EINVAL;
622 		break;
623 	}
624 
625 	kfree(name);
626 	return error;
627 }
628 
629 int
630 xfs_attrmulti_by_handle(
631 	struct file		*parfilp,
632 	void			__user *arg)
633 {
634 	int			error;
635 	xfs_attr_multiop_t	*ops;
636 	xfs_fsop_attrmulti_handlereq_t am_hreq;
637 	struct dentry		*dentry;
638 	unsigned int		i, size;
639 
640 	if (!capable(CAP_SYS_ADMIN))
641 		return -EPERM;
642 	if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t)))
643 		return -EFAULT;
644 
645 	/* overflow check */
646 	if (am_hreq.opcount >= INT_MAX / sizeof(xfs_attr_multiop_t))
647 		return -E2BIG;
648 
649 	dentry = xfs_handlereq_to_dentry(parfilp, &am_hreq.hreq);
650 	if (IS_ERR(dentry))
651 		return PTR_ERR(dentry);
652 
653 	error = -E2BIG;
654 	size = am_hreq.opcount * sizeof(xfs_attr_multiop_t);
655 	if (!size || size > 16 * PAGE_SIZE)
656 		goto out_dput;
657 
658 	ops = memdup_user(am_hreq.ops, size);
659 	if (IS_ERR(ops)) {
660 		error = PTR_ERR(ops);
661 		goto out_dput;
662 	}
663 
664 	error = 0;
665 	for (i = 0; i < am_hreq.opcount; i++) {
666 		ops[i].am_error = xfs_ioc_attrmulti_one(parfilp,
667 				d_inode(dentry), ops[i].am_opcode,
668 				ops[i].am_attrname, ops[i].am_attrvalue,
669 				&ops[i].am_length, ops[i].am_flags);
670 	}
671 
672 	if (copy_to_user(am_hreq.ops, ops, size))
673 		error = -EFAULT;
674 
675 	kfree(ops);
676  out_dput:
677 	dput(dentry);
678 	return error;
679 }
680 
681 struct xfs_getparents_ctx {
682 	struct xfs_attr_list_context	context;
683 	struct xfs_getparents_by_handle	gph;
684 
685 	/* File to target */
686 	struct xfs_inode		*ip;
687 
688 	/* Internal buffer where we format records */
689 	void				*krecords;
690 
691 	/* Last record filled out */
692 	struct xfs_getparents_rec	*lastrec;
693 
694 	unsigned int			count;
695 };
696 
697 static inline unsigned int
698 xfs_getparents_rec_sizeof(
699 	unsigned int		namelen)
700 {
701 	return round_up(sizeof(struct xfs_getparents_rec) + namelen + 1,
702 			sizeof(uint64_t));
703 }
704 
705 static void
706 xfs_getparents_put_listent(
707 	struct xfs_attr_list_context	*context,
708 	int				flags,
709 	unsigned char			*name,
710 	int				namelen,
711 	void				*value,
712 	int				valuelen)
713 {
714 	struct xfs_getparents_ctx	*gpx =
715 		container_of(context, struct xfs_getparents_ctx, context);
716 	struct xfs_inode		*ip = context->dp;
717 	struct xfs_mount		*mp = ip->i_mount;
718 	struct xfs_getparents		*gp = &gpx->gph.gph_request;
719 	struct xfs_getparents_rec	*gpr = gpx->krecords + context->firstu;
720 	unsigned short			reclen =
721 		xfs_getparents_rec_sizeof(namelen);
722 	xfs_ino_t			ino;
723 	uint32_t			gen;
724 	int				error;
725 
726 	if (!(flags & XFS_ATTR_PARENT))
727 		return;
728 
729 	error = xfs_parent_from_attr(mp, flags, name, namelen, value, valuelen,
730 			&ino, &gen);
731 	if (error) {
732 		xfs_inode_mark_sick(ip, XFS_SICK_INO_PARENT);
733 		context->seen_enough = -EFSCORRUPTED;
734 		return;
735 	}
736 
737 	/*
738 	 * We found a parent pointer, but we've filled up the buffer.  Signal
739 	 * to the caller that we did /not/ reach the end of the parent pointer
740 	 * recordset.
741 	 */
742 	if (context->firstu > context->bufsize - reclen) {
743 		context->seen_enough = 1;
744 		return;
745 	}
746 
747 	/* Format the parent pointer directly into the caller buffer. */
748 	gpr->gpr_reclen = reclen;
749 	xfs_filehandle_init(mp, ino, gen, &gpr->gpr_parent);
750 	memcpy(gpr->gpr_name, name, namelen);
751 	gpr->gpr_name[namelen] = 0;
752 
753 	trace_xfs_getparents_put_listent(ip, gp, context, gpr);
754 
755 	context->firstu += reclen;
756 	gpx->count++;
757 	gpx->lastrec = gpr;
758 }
759 
760 /* Expand the last record to fill the rest of the caller's buffer. */
761 static inline void
762 xfs_getparents_expand_lastrec(
763 	struct xfs_getparents_ctx	*gpx)
764 {
765 	struct xfs_getparents		*gp = &gpx->gph.gph_request;
766 	struct xfs_getparents_rec	*gpr = gpx->lastrec;
767 
768 	if (!gpx->lastrec)
769 		gpr = gpx->krecords;
770 
771 	gpr->gpr_reclen = gp->gp_bufsize - ((void *)gpr - gpx->krecords);
772 
773 	trace_xfs_getparents_expand_lastrec(gpx->ip, gp, &gpx->context, gpr);
774 }
775 
776 static inline void __user *u64_to_uptr(u64 val)
777 {
778 	return (void __user *)(uintptr_t)val;
779 }
780 
781 /* Retrieve the parent pointers for a given inode. */
782 STATIC int
783 xfs_getparents(
784 	struct xfs_getparents_ctx	*gpx)
785 {
786 	struct xfs_getparents		*gp = &gpx->gph.gph_request;
787 	struct xfs_inode		*ip = gpx->ip;
788 	struct xfs_mount		*mp = ip->i_mount;
789 	size_t				bufsize;
790 	int				error;
791 
792 	/* Check size of buffer requested by user */
793 	if (gp->gp_bufsize > XFS_XATTR_LIST_MAX)
794 		return -ENOMEM;
795 	if (gp->gp_bufsize < xfs_getparents_rec_sizeof(1))
796 		return -EINVAL;
797 
798 	if (gp->gp_iflags & ~XFS_GETPARENTS_IFLAGS_ALL)
799 		return -EINVAL;
800 	if (gp->gp_reserved)
801 		return -EINVAL;
802 
803 	bufsize = round_down(gp->gp_bufsize, sizeof(uint64_t));
804 	gpx->krecords = kvzalloc(bufsize, GFP_KERNEL);
805 	if (!gpx->krecords) {
806 		bufsize = min(bufsize, PAGE_SIZE);
807 		gpx->krecords = kvzalloc(bufsize, GFP_KERNEL);
808 		if (!gpx->krecords)
809 			return -ENOMEM;
810 	}
811 
812 	gpx->context.dp = ip;
813 	gpx->context.resynch = 1;
814 	gpx->context.put_listent = xfs_getparents_put_listent;
815 	gpx->context.bufsize = bufsize;
816 	/* firstu is used to track the bytes filled in the buffer */
817 	gpx->context.firstu = 0;
818 
819 	/* Copy the cursor provided by caller */
820 	memcpy(&gpx->context.cursor, &gp->gp_cursor,
821 			sizeof(struct xfs_attrlist_cursor));
822 	gpx->count = 0;
823 	gp->gp_oflags = 0;
824 
825 	trace_xfs_getparents_begin(ip, gp, &gpx->context.cursor);
826 
827 	error = xfs_attr_list(&gpx->context);
828 	if (error)
829 		goto out_free_buf;
830 	if (gpx->context.seen_enough < 0) {
831 		error = gpx->context.seen_enough;
832 		goto out_free_buf;
833 	}
834 	xfs_getparents_expand_lastrec(gpx);
835 
836 	/* Update the caller with the current cursor position */
837 	memcpy(&gp->gp_cursor, &gpx->context.cursor,
838 			sizeof(struct xfs_attrlist_cursor));
839 
840 	/* Is this the root directory? */
841 	if (ip->i_ino == mp->m_sb.sb_rootino)
842 		gp->gp_oflags |= XFS_GETPARENTS_OFLAG_ROOT;
843 
844 	if (gpx->context.seen_enough == 0) {
845 		/*
846 		 * If we did not run out of buffer space, then we reached the
847 		 * end of the pptr recordset, so set the DONE flag.
848 		 */
849 		gp->gp_oflags |= XFS_GETPARENTS_OFLAG_DONE;
850 	} else if (gpx->count == 0) {
851 		/*
852 		 * If we ran out of buffer space before copying any parent
853 		 * pointers at all, the caller's buffer was too short.  Tell
854 		 * userspace that, erm, the message is too long.
855 		 */
856 		error = -EMSGSIZE;
857 		goto out_free_buf;
858 	}
859 
860 	trace_xfs_getparents_end(ip, gp, &gpx->context.cursor);
861 
862 	ASSERT(gpx->context.firstu <= gpx->gph.gph_request.gp_bufsize);
863 
864 	/* Copy the records to userspace. */
865 	if (copy_to_user(u64_to_uptr(gpx->gph.gph_request.gp_buffer),
866 				gpx->krecords, gpx->context.firstu))
867 		error = -EFAULT;
868 
869 out_free_buf:
870 	kvfree(gpx->krecords);
871 	gpx->krecords = NULL;
872 	return error;
873 }
874 
875 /* Retrieve the parents of this file and pass them back to userspace. */
876 int
877 xfs_ioc_getparents(
878 	struct file			*file,
879 	struct xfs_getparents __user	*ureq)
880 {
881 	struct xfs_getparents_ctx	gpx = {
882 		.ip			= XFS_I(file_inode(file)),
883 	};
884 	struct xfs_getparents		*kreq = &gpx.gph.gph_request;
885 	struct xfs_mount		*mp = gpx.ip->i_mount;
886 	int				error;
887 
888 	if (!capable(CAP_SYS_ADMIN))
889 		return -EPERM;
890 	if (!xfs_has_parent(mp))
891 		return -EOPNOTSUPP;
892 	if (copy_from_user(kreq, ureq, sizeof(*kreq)))
893 		return -EFAULT;
894 
895 	error = xfs_getparents(&gpx);
896 	if (error)
897 		return error;
898 
899 	if (copy_to_user(ureq, kreq, sizeof(*kreq)))
900 		return -EFAULT;
901 
902 	return 0;
903 }
904 
905 /* Retrieve the parents of this file handle and pass them back to userspace. */
906 int
907 xfs_ioc_getparents_by_handle(
908 	struct file			*file,
909 	struct xfs_getparents_by_handle __user	*ureq)
910 {
911 	struct xfs_getparents_ctx	gpx = { };
912 	struct xfs_inode		*ip = XFS_I(file_inode(file));
913 	struct xfs_mount		*mp = ip->i_mount;
914 	struct xfs_getparents_by_handle	*kreq = &gpx.gph;
915 	struct xfs_handle		*handle = &kreq->gph_handle;
916 	int				error;
917 
918 	if (!capable(CAP_SYS_ADMIN))
919 		return -EPERM;
920 	if (!xfs_has_parent(mp))
921 		return -EOPNOTSUPP;
922 	if (copy_from_user(kreq, ureq, sizeof(*kreq)))
923 		return -EFAULT;
924 
925 	/*
926 	 * We don't use exportfs_decode_fh because it does too much work here.
927 	 * If the handle refers to a directory, the exportfs code will walk
928 	 * upwards through the directory tree to connect the dentries to the
929 	 * root directory dentry.  For GETPARENTS we don't care about that
930 	 * because we're not actually going to open a file descriptor; we only
931 	 * want to open an inode and read its parent pointers.
932 	 *
933 	 * Note that xfs_scrub uses GETPARENTS to log that it will try to fix a
934 	 * corrupted file's metadata.  For this usecase we would really rather
935 	 * userspace single-step the path reconstruction to avoid loops or
936 	 * other strange things if the directory tree is corrupt.
937 	 */
938 	gpx.ip = xfs_khandle_to_inode(file, handle);
939 	if (IS_ERR(gpx.ip))
940 		return PTR_ERR(gpx.ip);
941 
942 	error = xfs_getparents(&gpx);
943 	if (error)
944 		goto out_rele;
945 
946 	if (copy_to_user(ureq, kreq, sizeof(*kreq)))
947 		error = -EFAULT;
948 
949 out_rele:
950 	xfs_irele(gpx.ip);
951 	return error;
952 }
953