// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
 * Copyright (c) 2022-2024 Oracle.
 * All rights reserved.
 */
#include "xfs.h"
#include "xfs_fs.h"
#include "xfs_format.h"
#include "xfs_log_format.h"
#include "xfs_shared.h"
#include "xfs_trans_resv.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_inode.h"
#include "xfs_error.h"
#include "xfs_trace.h"
#include "xfs_trans.h"
#include "xfs_da_format.h"
#include "xfs_da_btree.h"
#include "xfs_attr.h"
#include "xfs_ioctl.h"
#include "xfs_parent.h"
#include "xfs_handle.h"
#include "xfs_health.h"
#include "xfs_icache.h"
#include "xfs_export.h"
#include "xfs_xattr.h"
#include "xfs_acl.h"

#include <linux/namei.h>

static inline size_t
xfs_filehandle_fid_len(void)
{
	struct xfs_handle	*handle = NULL;

	return sizeof(struct xfs_fid) - sizeof(handle->ha_fid.fid_len);
}

static inline size_t
xfs_filehandle_init(
	struct xfs_mount	*mp,
	xfs_ino_t		ino,
	uint32_t		gen,
	struct xfs_handle	*handle)
{
	memcpy(&handle->ha_fsid, mp->m_fixedfsid, sizeof(struct xfs_fsid));

	handle->ha_fid.fid_len = xfs_filehandle_fid_len();
	handle->ha_fid.fid_pad = 0;
	handle->ha_fid.fid_gen = gen;
	handle->ha_fid.fid_ino = ino;

	return sizeof(struct xfs_handle);
}

static inline size_t
xfs_fshandle_init(
	struct xfs_mount	*mp,
	struct xfs_handle	*handle)
{
	memcpy(&handle->ha_fsid, mp->m_fixedfsid, sizeof(struct xfs_fsid));
	memset(&handle->ha_fid, 0, sizeof(handle->ha_fid));

	return sizeof(struct xfs_fsid);
}

/*
 * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to
 * a file or fs handle.
 *
 * XFS_IOC_PATH_TO_FSHANDLE
 *    returns fs handle for a mount point or path within that mount point
 * XFS_IOC_FD_TO_HANDLE
 *    returns full handle for a FD opened in user space
 * XFS_IOC_PATH_TO_HANDLE
 *    returns full handle for a path
 */
int
xfs_find_handle(
	unsigned int		cmd,
	xfs_fsop_handlereq_t	*hreq)
{
	int			hsize;
	xfs_handle_t		handle;
	struct inode		*inode;
	struct fd		f = {NULL};
	struct path		path;
	int			error;
	struct xfs_inode	*ip;

	if (cmd == XFS_IOC_FD_TO_HANDLE) {
		f = fdget(hreq->fd);
		if (!f.file)
			return -EBADF;
		inode = file_inode(f.file);
	} else {
		error = user_path_at(AT_FDCWD, hreq->path, 0, &path);
		if (error)
			return error;
		inode = d_inode(path.dentry);
	}
	ip = XFS_I(inode);

	/*
	 * We can only generate handles for inodes residing on a XFS filesystem,
	 * and only for regular files, directories or symbolic links.
	 */
	error = -EINVAL;
	if (inode->i_sb->s_magic != XFS_SB_MAGIC)
		goto out_put;

	error = -EBADF;
	if (!S_ISREG(inode->i_mode) &&
	    !S_ISDIR(inode->i_mode) &&
	    !S_ISLNK(inode->i_mode))
		goto out_put;


	memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));

	if (cmd == XFS_IOC_PATH_TO_FSHANDLE)
		hsize = xfs_fshandle_init(ip->i_mount, &handle);
	else
		hsize = xfs_filehandle_init(ip->i_mount, ip->i_ino,
				inode->i_generation, &handle);

	error = -EFAULT;
	if (copy_to_user(hreq->ohandle, &handle, hsize) ||
	    copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
		goto out_put;

	error = 0;

 out_put:
	if (cmd == XFS_IOC_FD_TO_HANDLE)
		fdput(f);
	else
		path_put(&path);
	return error;
}

/*
 * No need to do permission checks on the various pathname components
 * as the handle operations are privileged.
 */
STATIC int
xfs_handle_acceptable(
	void			*context,
	struct dentry		*dentry)
{
	return 1;
}

/* Convert handle already copied to kernel space into a dentry. */
static struct dentry *
xfs_khandle_to_dentry(
	struct file		*file,
	struct xfs_handle	*handle)
{
	struct xfs_fid64        fid = {
		.ino		= handle->ha_fid.fid_ino,
		.gen		= handle->ha_fid.fid_gen,
	};

	/*
	 * Only allow handle opens under a directory.
	 */
	if (!S_ISDIR(file_inode(file)->i_mode))
		return ERR_PTR(-ENOTDIR);

	if (handle->ha_fid.fid_len != xfs_filehandle_fid_len())
		return ERR_PTR(-EINVAL);

	return exportfs_decode_fh(file->f_path.mnt, (struct fid *)&fid, 3,
			FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG,
			xfs_handle_acceptable, NULL);
}

/* Convert handle already copied to kernel space into an xfs_inode. */
static struct xfs_inode *
xfs_khandle_to_inode(
	struct file		*file,
	struct xfs_handle	*handle)
{
	struct xfs_inode	*ip = XFS_I(file_inode(file));
	struct xfs_mount	*mp = ip->i_mount;
	struct inode		*inode;

	if (!S_ISDIR(VFS_I(ip)->i_mode))
		return ERR_PTR(-ENOTDIR);

	if (handle->ha_fid.fid_len != xfs_filehandle_fid_len())
		return ERR_PTR(-EINVAL);

	inode = xfs_nfs_get_inode(mp->m_super, handle->ha_fid.fid_ino,
			handle->ha_fid.fid_gen);
	if (IS_ERR(inode))
		return ERR_CAST(inode);

	return XFS_I(inode);
}

/*
 * Convert userspace handle data into a dentry.
 */
struct dentry *
xfs_handle_to_dentry(
	struct file		*parfilp,
	void __user		*uhandle,
	u32			hlen)
{
	xfs_handle_t		handle;

	if (hlen != sizeof(xfs_handle_t))
		return ERR_PTR(-EINVAL);
	if (copy_from_user(&handle, uhandle, hlen))
		return ERR_PTR(-EFAULT);

	return xfs_khandle_to_dentry(parfilp, &handle);
}

STATIC struct dentry *
xfs_handlereq_to_dentry(
	struct file		*parfilp,
	xfs_fsop_handlereq_t	*hreq)
{
	return xfs_handle_to_dentry(parfilp, hreq->ihandle, hreq->ihandlen);
}

int
xfs_open_by_handle(
	struct file		*parfilp,
	xfs_fsop_handlereq_t	*hreq)
{
	const struct cred	*cred = current_cred();
	int			error;
	int			fd;
	int			permflag;
	struct file		*filp;
	struct inode		*inode;
	struct dentry		*dentry;
	fmode_t			fmode;
	struct path		path;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	dentry = xfs_handlereq_to_dentry(parfilp, hreq);
	if (IS_ERR(dentry))
		return PTR_ERR(dentry);
	inode = d_inode(dentry);

	/* Restrict xfs_open_by_handle to directories & regular files. */
	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
		error = -EPERM;
		goto out_dput;
	}

#if BITS_PER_LONG != 32
	hreq->oflags |= O_LARGEFILE;
#endif

	permflag = hreq->oflags;
	fmode = OPEN_FMODE(permflag);
	if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
	    (fmode & FMODE_WRITE) && IS_APPEND(inode)) {
		error = -EPERM;
		goto out_dput;
	}

	if ((fmode & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
		error = -EPERM;
		goto out_dput;
	}

	/* Can't write directories. */
	if (S_ISDIR(inode->i_mode) && (fmode & FMODE_WRITE)) {
		error = -EISDIR;
		goto out_dput;
	}

	fd = get_unused_fd_flags(0);
	if (fd < 0) {
		error = fd;
		goto out_dput;
	}

	path.mnt = parfilp->f_path.mnt;
	path.dentry = dentry;
	filp = dentry_open(&path, hreq->oflags, cred);
	dput(dentry);
	if (IS_ERR(filp)) {
		put_unused_fd(fd);
		return PTR_ERR(filp);
	}

	if (S_ISREG(inode->i_mode)) {
		filp->f_flags |= O_NOATIME;
		filp->f_mode |= FMODE_NOCMTIME;
	}

	fd_install(fd, filp);
	return fd;

 out_dput:
	dput(dentry);
	return error;
}

int
xfs_readlink_by_handle(
	struct file		*parfilp,
	xfs_fsop_handlereq_t	*hreq)
{
	struct dentry		*dentry;
	__u32			olen;
	int			error;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	dentry = xfs_handlereq_to_dentry(parfilp, hreq);
	if (IS_ERR(dentry))
		return PTR_ERR(dentry);

	/* Restrict this handle operation to symlinks only. */
	if (!d_is_symlink(dentry)) {
		error = -EINVAL;
		goto out_dput;
	}

	if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) {
		error = -EFAULT;
		goto out_dput;
	}

	error = vfs_readlink(dentry, hreq->ohandle, olen);

 out_dput:
	dput(dentry);
	return error;
}

/*
 * Format an attribute and copy it out to the user's buffer.
 * Take care to check values and protect against them changing later,
 * we may be reading them directly out of a user buffer.
 */
static void
xfs_ioc_attr_put_listent(
	struct xfs_attr_list_context *context,
	int			flags,
	unsigned char		*name,
	int			namelen,
	void			*value,
	int			valuelen)
{
	struct xfs_attrlist	*alist = context->buffer;
	struct xfs_attrlist_ent	*aep;
	int			arraytop;

	ASSERT(!context->seen_enough);
	ASSERT(context->count >= 0);
	ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
	ASSERT(context->firstu >= sizeof(*alist));
	ASSERT(context->firstu <= context->bufsize);

	/*
	 * Only list entries in the right namespace.
	 */
	if (context->attr_filter != (flags & XFS_ATTR_NSP_ONDISK_MASK))
		return;

	arraytop = sizeof(*alist) +
			context->count * sizeof(alist->al_offset[0]);

	/* decrement by the actual bytes used by the attr */
	context->firstu -= round_up(offsetof(struct xfs_attrlist_ent, a_name) +
			namelen + 1, sizeof(uint32_t));
	if (context->firstu < arraytop) {
		trace_xfs_attr_list_full(context);
		alist->al_more = 1;
		context->seen_enough = 1;
		return;
	}

	aep = context->buffer + context->firstu;
	aep->a_valuelen = valuelen;
	memcpy(aep->a_name, name, namelen);
	aep->a_name[namelen] = 0;
	alist->al_offset[context->count++] = context->firstu;
	alist->al_count = context->count;
	trace_xfs_attr_list_add(context);
}

static unsigned int
xfs_attr_filter(
	u32			ioc_flags)
{
	if (ioc_flags & XFS_IOC_ATTR_ROOT)
		return XFS_ATTR_ROOT;
	if (ioc_flags & XFS_IOC_ATTR_SECURE)
		return XFS_ATTR_SECURE;
	return 0;
}

static inline enum xfs_attr_update
xfs_xattr_flags(
	u32			ioc_flags,
	void			*value)
{
	if (!value)
		return XFS_ATTRUPDATE_REMOVE;
	if (ioc_flags & XFS_IOC_ATTR_CREATE)
		return XFS_ATTRUPDATE_CREATE;
	if (ioc_flags & XFS_IOC_ATTR_REPLACE)
		return XFS_ATTRUPDATE_REPLACE;
	return XFS_ATTRUPDATE_UPSERT;
}

int
xfs_ioc_attr_list(
	struct xfs_inode		*dp,
	void __user			*ubuf,
	size_t				bufsize,
	int				flags,
	struct xfs_attrlist_cursor __user *ucursor)
{
	struct xfs_attr_list_context	context = { };
	struct xfs_attrlist		*alist;
	void				*buffer;
	int				error;

	if (bufsize < sizeof(struct xfs_attrlist) ||
	    bufsize > XFS_XATTR_LIST_MAX)
		return -EINVAL;

	/*
	 * Reject flags, only allow namespaces.
	 */
	if (flags & ~(XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
		return -EINVAL;
	if (flags == (XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
		return -EINVAL;

	/*
	 * Validate the cursor.
	 */
	if (copy_from_user(&context.cursor, ucursor, sizeof(context.cursor)))
		return -EFAULT;
	if (context.cursor.pad1 || context.cursor.pad2)
		return -EINVAL;
	if (!context.cursor.initted &&
	    (context.cursor.hashval || context.cursor.blkno ||
	     context.cursor.offset))
		return -EINVAL;

	buffer = kvzalloc(bufsize, GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;

	/*
	 * Initialize the output buffer.
	 */
	context.dp = dp;
	context.resynch = 1;
	context.attr_filter = xfs_attr_filter(flags);
	context.buffer = buffer;
	context.bufsize = round_down(bufsize, sizeof(uint32_t));
	context.firstu = context.bufsize;
	context.put_listent = xfs_ioc_attr_put_listent;

	alist = context.buffer;
	alist->al_count = 0;
	alist->al_more = 0;
	alist->al_offset[0] = context.bufsize;

	error = xfs_attr_list(&context);
	if (error)
		goto out_free;

	if (copy_to_user(ubuf, buffer, bufsize) ||
	    copy_to_user(ucursor, &context.cursor, sizeof(context.cursor)))
		error = -EFAULT;
out_free:
	kvfree(buffer);
	return error;
}

int
xfs_attrlist_by_handle(
	struct file		*parfilp,
	struct xfs_fsop_attrlist_handlereq __user *p)
{
	struct xfs_fsop_attrlist_handlereq al_hreq;
	struct dentry		*dentry;
	int			error = -ENOMEM;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;
	if (copy_from_user(&al_hreq, p, sizeof(al_hreq)))
		return -EFAULT;

	dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
	if (IS_ERR(dentry))
		return PTR_ERR(dentry);

	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), al_hreq.buffer,
				  al_hreq.buflen, al_hreq.flags, &p->pos);
	dput(dentry);
	return error;
}

static int
xfs_attrmulti_attr_get(
	struct inode		*inode,
	unsigned char		*name,
	unsigned char		__user *ubuf,
	uint32_t		*len,
	uint32_t		flags)
{
	struct xfs_da_args	args = {
		.dp		= XFS_I(inode),
		.attr_filter	= xfs_attr_filter(flags),
		.name		= name,
		.namelen	= strlen(name),
		.valuelen	= *len,
	};
	int			error;

	if (*len > XFS_XATTR_SIZE_MAX)
		return -EINVAL;

	error = xfs_attr_get(&args);
	if (error)
		goto out_kfree;

	*len = args.valuelen;
	if (copy_to_user(ubuf, args.value, args.valuelen))
		error = -EFAULT;

out_kfree:
	kvfree(args.value);
	return error;
}

static int
xfs_attrmulti_attr_set(
	struct inode		*inode,
	unsigned char		*name,
	const unsigned char	__user *ubuf,
	uint32_t		len,
	uint32_t		flags)
{
	struct xfs_da_args	args = {
		.dp		= XFS_I(inode),
		.attr_filter	= xfs_attr_filter(flags),
		.name		= name,
		.namelen	= strlen(name),
	};
	int			error;

	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
		return -EPERM;

	if (ubuf) {
		if (len > XFS_XATTR_SIZE_MAX)
			return -EINVAL;
		args.value = memdup_user(ubuf, len);
		if (IS_ERR(args.value))
			return PTR_ERR(args.value);
		args.valuelen = len;
	}

	error = xfs_attr_change(&args, xfs_xattr_flags(flags, args.value));
	if (!error && (flags & XFS_IOC_ATTR_ROOT))
		xfs_forget_acl(inode, name);
	kfree(args.value);
	return error;
}

int
xfs_ioc_attrmulti_one(
	struct file		*parfilp,
	struct inode		*inode,
	uint32_t		opcode,
	void __user		*uname,
	void __user		*value,
	uint32_t		*len,
	uint32_t		flags)
{
	unsigned char		*name;
	int			error;

	if ((flags & XFS_IOC_ATTR_ROOT) && (flags & XFS_IOC_ATTR_SECURE))
		return -EINVAL;

	name = strndup_user(uname, MAXNAMELEN);
	if (IS_ERR(name))
		return PTR_ERR(name);

	switch (opcode) {
	case ATTR_OP_GET:
		error = xfs_attrmulti_attr_get(inode, name, value, len, flags);
		break;
	case ATTR_OP_REMOVE:
		value = NULL;
		*len = 0;
		fallthrough;
	case ATTR_OP_SET:
		error = mnt_want_write_file(parfilp);
		if (error)
			break;
		error = xfs_attrmulti_attr_set(inode, name, value, *len, flags);
		mnt_drop_write_file(parfilp);
		break;
	default:
		error = -EINVAL;
		break;
	}

	kfree(name);
	return error;
}

int
xfs_attrmulti_by_handle(
	struct file		*parfilp,
	void			__user *arg)
{
	int			error;
	xfs_attr_multiop_t	*ops;
	xfs_fsop_attrmulti_handlereq_t am_hreq;
	struct dentry		*dentry;
	unsigned int		i, size;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;
	if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t)))
		return -EFAULT;

	/* overflow check */
	if (am_hreq.opcount >= INT_MAX / sizeof(xfs_attr_multiop_t))
		return -E2BIG;

	dentry = xfs_handlereq_to_dentry(parfilp, &am_hreq.hreq);
	if (IS_ERR(dentry))
		return PTR_ERR(dentry);

	error = -E2BIG;
	size = am_hreq.opcount * sizeof(xfs_attr_multiop_t);
	if (!size || size > 16 * PAGE_SIZE)
		goto out_dput;

	ops = memdup_user(am_hreq.ops, size);
	if (IS_ERR(ops)) {
		error = PTR_ERR(ops);
		goto out_dput;
	}

	error = 0;
	for (i = 0; i < am_hreq.opcount; i++) {
		ops[i].am_error = xfs_ioc_attrmulti_one(parfilp,
				d_inode(dentry), ops[i].am_opcode,
				ops[i].am_attrname, ops[i].am_attrvalue,
				&ops[i].am_length, ops[i].am_flags);
	}

	if (copy_to_user(am_hreq.ops, ops, size))
		error = -EFAULT;

	kfree(ops);
 out_dput:
	dput(dentry);
	return error;
}

struct xfs_getparents_ctx {
	struct xfs_attr_list_context	context;
	struct xfs_getparents_by_handle	gph;

	/* File to target */
	struct xfs_inode		*ip;

	/* Internal buffer where we format records */
	void				*krecords;

	/* Last record filled out */
	struct xfs_getparents_rec	*lastrec;

	unsigned int			count;
};

static inline unsigned int
xfs_getparents_rec_sizeof(
	unsigned int		namelen)
{
	return round_up(sizeof(struct xfs_getparents_rec) + namelen + 1,
			sizeof(uint64_t));
}

static void
xfs_getparents_put_listent(
	struct xfs_attr_list_context	*context,
	int				flags,
	unsigned char			*name,
	int				namelen,
	void				*value,
	int				valuelen)
{
	struct xfs_getparents_ctx	*gpx =
		container_of(context, struct xfs_getparents_ctx, context);
	struct xfs_inode		*ip = context->dp;
	struct xfs_mount		*mp = ip->i_mount;
	struct xfs_getparents		*gp = &gpx->gph.gph_request;
	struct xfs_getparents_rec	*gpr = gpx->krecords + context->firstu;
	unsigned short			reclen =
		xfs_getparents_rec_sizeof(namelen);
	xfs_ino_t			ino;
	uint32_t			gen;
	int				error;

	if (!(flags & XFS_ATTR_PARENT))
		return;

	error = xfs_parent_from_attr(mp, flags, name, namelen, value, valuelen,
			&ino, &gen);
	if (error) {
		xfs_inode_mark_sick(ip, XFS_SICK_INO_PARENT);
		context->seen_enough = -EFSCORRUPTED;
		return;
	}

	/*
	 * We found a parent pointer, but we've filled up the buffer.  Signal
	 * to the caller that we did /not/ reach the end of the parent pointer
	 * recordset.
	 */
	if (context->firstu > context->bufsize - reclen) {
		context->seen_enough = 1;
		return;
	}

	/* Format the parent pointer directly into the caller buffer. */
	gpr->gpr_reclen = reclen;
	xfs_filehandle_init(mp, ino, gen, &gpr->gpr_parent);
	memcpy(gpr->gpr_name, name, namelen);
	gpr->gpr_name[namelen] = 0;

	trace_xfs_getparents_put_listent(ip, gp, context, gpr);

	context->firstu += reclen;
	gpx->count++;
	gpx->lastrec = gpr;
}

/* Expand the last record to fill the rest of the caller's buffer. */
static inline void
xfs_getparents_expand_lastrec(
	struct xfs_getparents_ctx	*gpx)
{
	struct xfs_getparents		*gp = &gpx->gph.gph_request;
	struct xfs_getparents_rec	*gpr = gpx->lastrec;

	if (!gpx->lastrec)
		gpr = gpx->krecords;

	gpr->gpr_reclen = gp->gp_bufsize - ((void *)gpr - gpx->krecords);

	trace_xfs_getparents_expand_lastrec(gpx->ip, gp, &gpx->context, gpr);
}

/* Retrieve the parent pointers for a given inode. */
STATIC int
xfs_getparents(
	struct xfs_getparents_ctx	*gpx)
{
	struct xfs_getparents		*gp = &gpx->gph.gph_request;
	struct xfs_inode		*ip = gpx->ip;
	struct xfs_mount		*mp = ip->i_mount;
	size_t				bufsize;
	int				error;

	/* Check size of buffer requested by user */
	if (gp->gp_bufsize > XFS_XATTR_LIST_MAX)
		return -ENOMEM;
	if (gp->gp_bufsize < xfs_getparents_rec_sizeof(1))
		return -EINVAL;

	if (gp->gp_iflags & ~XFS_GETPARENTS_IFLAGS_ALL)
		return -EINVAL;
	if (gp->gp_reserved)
		return -EINVAL;

	bufsize = round_down(gp->gp_bufsize, sizeof(uint64_t));
	gpx->krecords = kvzalloc(bufsize, GFP_KERNEL);
	if (!gpx->krecords) {
		bufsize = min(bufsize, PAGE_SIZE);
		gpx->krecords = kvzalloc(bufsize, GFP_KERNEL);
		if (!gpx->krecords)
			return -ENOMEM;
	}

	gpx->context.dp = ip;
	gpx->context.resynch = 1;
	gpx->context.put_listent = xfs_getparents_put_listent;
	gpx->context.bufsize = bufsize;
	/* firstu is used to track the bytes filled in the buffer */
	gpx->context.firstu = 0;

	/* Copy the cursor provided by caller */
	memcpy(&gpx->context.cursor, &gp->gp_cursor,
			sizeof(struct xfs_attrlist_cursor));
	gpx->count = 0;
	gp->gp_oflags = 0;

	trace_xfs_getparents_begin(ip, gp, &gpx->context.cursor);

	error = xfs_attr_list(&gpx->context);
	if (error)
		goto out_free_buf;
	if (gpx->context.seen_enough < 0) {
		error = gpx->context.seen_enough;
		goto out_free_buf;
	}
	xfs_getparents_expand_lastrec(gpx);

	/* Update the caller with the current cursor position */
	memcpy(&gp->gp_cursor, &gpx->context.cursor,
			sizeof(struct xfs_attrlist_cursor));

	/* Is this the root directory? */
	if (ip->i_ino == mp->m_sb.sb_rootino)
		gp->gp_oflags |= XFS_GETPARENTS_OFLAG_ROOT;

	if (gpx->context.seen_enough == 0) {
		/*
		 * If we did not run out of buffer space, then we reached the
		 * end of the pptr recordset, so set the DONE flag.
		 */
		gp->gp_oflags |= XFS_GETPARENTS_OFLAG_DONE;
	} else if (gpx->count == 0) {
		/*
		 * If we ran out of buffer space before copying any parent
		 * pointers at all, the caller's buffer was too short.  Tell
		 * userspace that, erm, the message is too long.
		 */
		error = -EMSGSIZE;
		goto out_free_buf;
	}

	trace_xfs_getparents_end(ip, gp, &gpx->context.cursor);

	ASSERT(gpx->context.firstu <= gpx->gph.gph_request.gp_bufsize);

	/* Copy the records to userspace. */
	if (copy_to_user(u64_to_user_ptr(gpx->gph.gph_request.gp_buffer),
				gpx->krecords, gpx->context.firstu))
		error = -EFAULT;

out_free_buf:
	kvfree(gpx->krecords);
	gpx->krecords = NULL;
	return error;
}

/* Retrieve the parents of this file and pass them back to userspace. */
int
xfs_ioc_getparents(
	struct file			*file,
	struct xfs_getparents __user	*ureq)
{
	struct xfs_getparents_ctx	gpx = {
		.ip			= XFS_I(file_inode(file)),
	};
	struct xfs_getparents		*kreq = &gpx.gph.gph_request;
	struct xfs_mount		*mp = gpx.ip->i_mount;
	int				error;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;
	if (!xfs_has_parent(mp))
		return -EOPNOTSUPP;
	if (copy_from_user(kreq, ureq, sizeof(*kreq)))
		return -EFAULT;

	error = xfs_getparents(&gpx);
	if (error)
		return error;

	if (copy_to_user(ureq, kreq, sizeof(*kreq)))
		return -EFAULT;

	return 0;
}

/* Retrieve the parents of this file handle and pass them back to userspace. */
int
xfs_ioc_getparents_by_handle(
	struct file			*file,
	struct xfs_getparents_by_handle __user	*ureq)
{
	struct xfs_getparents_ctx	gpx = { };
	struct xfs_inode		*ip = XFS_I(file_inode(file));
	struct xfs_mount		*mp = ip->i_mount;
	struct xfs_getparents_by_handle	*kreq = &gpx.gph;
	struct xfs_handle		*handle = &kreq->gph_handle;
	int				error;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;
	if (!xfs_has_parent(mp))
		return -EOPNOTSUPP;
	if (copy_from_user(kreq, ureq, sizeof(*kreq)))
		return -EFAULT;

	/*
	 * We don't use exportfs_decode_fh because it does too much work here.
	 * If the handle refers to a directory, the exportfs code will walk
	 * upwards through the directory tree to connect the dentries to the
	 * root directory dentry.  For GETPARENTS we don't care about that
	 * because we're not actually going to open a file descriptor; we only
	 * want to open an inode and read its parent pointers.
	 *
	 * Note that xfs_scrub uses GETPARENTS to log that it will try to fix a
	 * corrupted file's metadata.  For this usecase we would really rather
	 * userspace single-step the path reconstruction to avoid loops or
	 * other strange things if the directory tree is corrupt.
	 */
	gpx.ip = xfs_khandle_to_inode(file, handle);
	if (IS_ERR(gpx.ip))
		return PTR_ERR(gpx.ip);

	error = xfs_getparents(&gpx);
	if (error)
		goto out_rele;

	if (copy_to_user(ureq, kreq, sizeof(*kreq)))
		error = -EFAULT;

out_rele:
	xfs_irele(gpx.ip);
	return error;
}
