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