brintos

brintos / linux-shallow public Read only

0
0
Text · 32.9 KiB · 2567fd2 Raw
1400 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.4 * All Rights Reserved.5 */6#include "xfs.h"7#include "xfs_fs.h"8#include "xfs_shared.h"9#include "xfs_format.h"10#include "xfs_log_format.h"11#include "xfs_trans_resv.h"12#include "xfs_mount.h"13#include "xfs_inode.h"14#include "xfs_rtalloc.h"15#include "xfs_iwalk.h"16#include "xfs_itable.h"17#include "xfs_error.h"18#include "xfs_da_format.h"19#include "xfs_da_btree.h"20#include "xfs_attr.h"21#include "xfs_bmap.h"22#include "xfs_bmap_util.h"23#include "xfs_fsops.h"24#include "xfs_discard.h"25#include "xfs_quota.h"26#include "xfs_trace.h"27#include "xfs_icache.h"28#include "xfs_trans.h"29#include "xfs_btree.h"30#include <linux/fsmap.h>31#include "xfs_fsmap.h"32#include "scrub/xfs_scrub.h"33#include "xfs_sb.h"34#include "xfs_ag.h"35#include "xfs_health.h"36#include "xfs_reflink.h"37#include "xfs_ioctl.h"38#include "xfs_xattr.h"39#include "xfs_rtbitmap.h"40#include "xfs_file.h"41#include "xfs_exchrange.h"42#include "xfs_handle.h"43 44#include <linux/mount.h>45#include <linux/fileattr.h>46 47/* Return 0 on success or positive error */48int49xfs_fsbulkstat_one_fmt(50	struct xfs_ibulk		*breq,51	const struct xfs_bulkstat	*bstat)52{53	struct xfs_bstat		bs1;54 55	xfs_bulkstat_to_bstat(breq->mp, &bs1, bstat);56	if (copy_to_user(breq->ubuffer, &bs1, sizeof(bs1)))57		return -EFAULT;58	return xfs_ibulk_advance(breq, sizeof(struct xfs_bstat));59}60 61int62xfs_fsinumbers_fmt(63	struct xfs_ibulk		*breq,64	const struct xfs_inumbers	*igrp)65{66	struct xfs_inogrp		ig1;67 68	xfs_inumbers_to_inogrp(&ig1, igrp);69	if (copy_to_user(breq->ubuffer, &ig1, sizeof(struct xfs_inogrp)))70		return -EFAULT;71	return xfs_ibulk_advance(breq, sizeof(struct xfs_inogrp));72}73 74STATIC int75xfs_ioc_fsbulkstat(76	struct file		*file,77	unsigned int		cmd,78	void			__user *arg)79{80	struct xfs_mount	*mp = XFS_I(file_inode(file))->i_mount;81	struct xfs_fsop_bulkreq	bulkreq;82	struct xfs_ibulk	breq = {83		.mp		= mp,84		.idmap		= file_mnt_idmap(file),85		.ocount		= 0,86	};87	xfs_ino_t		lastino;88	int			error;89 90	/* done = 1 if there are more stats to get and if bulkstat */91	/* should be called again (unused here, but used in dmapi) */92 93	if (!capable(CAP_SYS_ADMIN))94		return -EPERM;95 96	if (xfs_is_shutdown(mp))97		return -EIO;98 99	if (copy_from_user(&bulkreq, arg, sizeof(struct xfs_fsop_bulkreq)))100		return -EFAULT;101 102	if (copy_from_user(&lastino, bulkreq.lastip, sizeof(__s64)))103		return -EFAULT;104 105	if (bulkreq.icount <= 0)106		return -EINVAL;107 108	if (bulkreq.ubuffer == NULL)109		return -EINVAL;110 111	breq.ubuffer = bulkreq.ubuffer;112	breq.icount = bulkreq.icount;113 114	/*115	 * FSBULKSTAT_SINGLE expects that *lastip contains the inode number116	 * that we want to stat.  However, FSINUMBERS and FSBULKSTAT expect117	 * that *lastip contains either zero or the number of the last inode to118	 * be examined by the previous call and return results starting with119	 * the next inode after that.  The new bulk request back end functions120	 * take the inode to start with, so we have to compute the startino121	 * parameter from lastino to maintain correct function.  lastino == 0122	 * is a special case because it has traditionally meant "first inode123	 * in filesystem".124	 */125	if (cmd == XFS_IOC_FSINUMBERS) {126		breq.startino = lastino ? lastino + 1 : 0;127		error = xfs_inumbers(&breq, xfs_fsinumbers_fmt);128		lastino = breq.startino - 1;129	} else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE) {130		breq.startino = lastino;131		breq.icount = 1;132		error = xfs_bulkstat_one(&breq, xfs_fsbulkstat_one_fmt);133	} else {	/* XFS_IOC_FSBULKSTAT */134		breq.startino = lastino ? lastino + 1 : 0;135		error = xfs_bulkstat(&breq, xfs_fsbulkstat_one_fmt);136		lastino = breq.startino - 1;137	}138 139	if (error)140		return error;141 142	if (bulkreq.lastip != NULL &&143	    copy_to_user(bulkreq.lastip, &lastino, sizeof(xfs_ino_t)))144		return -EFAULT;145 146	if (bulkreq.ocount != NULL &&147	    copy_to_user(bulkreq.ocount, &breq.ocount, sizeof(__s32)))148		return -EFAULT;149 150	return 0;151}152 153/* Return 0 on success or positive error */154static int155xfs_bulkstat_fmt(156	struct xfs_ibulk		*breq,157	const struct xfs_bulkstat	*bstat)158{159	if (copy_to_user(breq->ubuffer, bstat, sizeof(struct xfs_bulkstat)))160		return -EFAULT;161	return xfs_ibulk_advance(breq, sizeof(struct xfs_bulkstat));162}163 164/*165 * Check the incoming bulk request @hdr from userspace and initialize the166 * internal @breq bulk request appropriately.  Returns 0 if the bulk request167 * should proceed; -ECANCELED if there's nothing to do; or the usual168 * negative error code.169 */170static int171xfs_bulk_ireq_setup(172	struct xfs_mount	*mp,173	const struct xfs_bulk_ireq *hdr,174	struct xfs_ibulk	*breq,175	void __user		*ubuffer)176{177	if (hdr->icount == 0 ||178	    (hdr->flags & ~XFS_BULK_IREQ_FLAGS_ALL) ||179	    memchr_inv(hdr->reserved, 0, sizeof(hdr->reserved)))180		return -EINVAL;181 182	breq->startino = hdr->ino;183	breq->ubuffer = ubuffer;184	breq->icount = hdr->icount;185	breq->ocount = 0;186	breq->flags = 0;187 188	/*189	 * The @ino parameter is a special value, so we must look it up here.190	 * We're not allowed to have IREQ_AGNO, and we only return one inode191	 * worth of data.192	 */193	if (hdr->flags & XFS_BULK_IREQ_SPECIAL) {194		if (hdr->flags & XFS_BULK_IREQ_AGNO)195			return -EINVAL;196 197		switch (hdr->ino) {198		case XFS_BULK_IREQ_SPECIAL_ROOT:199			breq->startino = mp->m_sb.sb_rootino;200			break;201		default:202			return -EINVAL;203		}204		breq->icount = 1;205	}206 207	/*208	 * The IREQ_AGNO flag means that we only want results from a given AG.209	 * If @hdr->ino is zero, we start iterating in that AG.  If @hdr->ino is210	 * beyond the specified AG then we return no results.211	 */212	if (hdr->flags & XFS_BULK_IREQ_AGNO) {213		if (hdr->agno >= mp->m_sb.sb_agcount)214			return -EINVAL;215 216		if (breq->startino == 0)217			breq->startino = XFS_AGINO_TO_INO(mp, hdr->agno, 0);218		else if (XFS_INO_TO_AGNO(mp, breq->startino) < hdr->agno)219			return -EINVAL;220 221		breq->flags |= XFS_IBULK_SAME_AG;222 223		/* Asking for an inode past the end of the AG?  We're done! */224		if (XFS_INO_TO_AGNO(mp, breq->startino) > hdr->agno)225			return -ECANCELED;226	} else if (hdr->agno)227		return -EINVAL;228 229	/* Asking for an inode past the end of the FS?  We're done! */230	if (XFS_INO_TO_AGNO(mp, breq->startino) >= mp->m_sb.sb_agcount)231		return -ECANCELED;232 233	if (hdr->flags & XFS_BULK_IREQ_NREXT64)234		breq->flags |= XFS_IBULK_NREXT64;235 236	return 0;237}238 239/*240 * Update the userspace bulk request @hdr to reflect the end state of the241 * internal bulk request @breq.242 */243static void244xfs_bulk_ireq_teardown(245	struct xfs_bulk_ireq	*hdr,246	struct xfs_ibulk	*breq)247{248	hdr->ino = breq->startino;249	hdr->ocount = breq->ocount;250}251 252/* Handle the v5 bulkstat ioctl. */253STATIC int254xfs_ioc_bulkstat(255	struct file			*file,256	unsigned int			cmd,257	struct xfs_bulkstat_req __user	*arg)258{259	struct xfs_mount		*mp = XFS_I(file_inode(file))->i_mount;260	struct xfs_bulk_ireq		hdr;261	struct xfs_ibulk		breq = {262		.mp			= mp,263		.idmap			= file_mnt_idmap(file),264	};265	int				error;266 267	if (!capable(CAP_SYS_ADMIN))268		return -EPERM;269 270	if (xfs_is_shutdown(mp))271		return -EIO;272 273	if (copy_from_user(&hdr, &arg->hdr, sizeof(hdr)))274		return -EFAULT;275 276	error = xfs_bulk_ireq_setup(mp, &hdr, &breq, arg->bulkstat);277	if (error == -ECANCELED)278		goto out_teardown;279	if (error < 0)280		return error;281 282	error = xfs_bulkstat(&breq, xfs_bulkstat_fmt);283	if (error)284		return error;285 286out_teardown:287	xfs_bulk_ireq_teardown(&hdr, &breq);288	if (copy_to_user(&arg->hdr, &hdr, sizeof(hdr)))289		return -EFAULT;290 291	return 0;292}293 294STATIC int295xfs_inumbers_fmt(296	struct xfs_ibulk		*breq,297	const struct xfs_inumbers	*igrp)298{299	if (copy_to_user(breq->ubuffer, igrp, sizeof(struct xfs_inumbers)))300		return -EFAULT;301	return xfs_ibulk_advance(breq, sizeof(struct xfs_inumbers));302}303 304/* Handle the v5 inumbers ioctl. */305STATIC int306xfs_ioc_inumbers(307	struct xfs_mount		*mp,308	unsigned int			cmd,309	struct xfs_inumbers_req __user	*arg)310{311	struct xfs_bulk_ireq		hdr;312	struct xfs_ibulk		breq = {313		.mp			= mp,314	};315	int				error;316 317	if (!capable(CAP_SYS_ADMIN))318		return -EPERM;319 320	if (xfs_is_shutdown(mp))321		return -EIO;322 323	if (copy_from_user(&hdr, &arg->hdr, sizeof(hdr)))324		return -EFAULT;325 326	error = xfs_bulk_ireq_setup(mp, &hdr, &breq, arg->inumbers);327	if (error == -ECANCELED)328		goto out_teardown;329	if (error < 0)330		return error;331 332	error = xfs_inumbers(&breq, xfs_inumbers_fmt);333	if (error)334		return error;335 336out_teardown:337	xfs_bulk_ireq_teardown(&hdr, &breq);338	if (copy_to_user(&arg->hdr, &hdr, sizeof(hdr)))339		return -EFAULT;340 341	return 0;342}343 344STATIC int345xfs_ioc_fsgeometry(346	struct xfs_mount	*mp,347	void			__user *arg,348	int			struct_version)349{350	struct xfs_fsop_geom	fsgeo;351	size_t			len;352 353	xfs_fs_geometry(mp, &fsgeo, struct_version);354 355	if (struct_version <= 3)356		len = sizeof(struct xfs_fsop_geom_v1);357	else if (struct_version == 4)358		len = sizeof(struct xfs_fsop_geom_v4);359	else {360		xfs_fsop_geom_health(mp, &fsgeo);361		len = sizeof(fsgeo);362	}363 364	if (copy_to_user(arg, &fsgeo, len))365		return -EFAULT;366	return 0;367}368 369STATIC int370xfs_ioc_ag_geometry(371	struct xfs_mount	*mp,372	void			__user *arg)373{374	struct xfs_perag	*pag;375	struct xfs_ag_geometry	ageo;376	int			error;377 378	if (copy_from_user(&ageo, arg, sizeof(ageo)))379		return -EFAULT;380	if (ageo.ag_flags)381		return -EINVAL;382	if (memchr_inv(&ageo.ag_reserved, 0, sizeof(ageo.ag_reserved)))383		return -EINVAL;384 385	pag = xfs_perag_get(mp, ageo.ag_number);386	if (!pag)387		return -EINVAL;388 389	error = xfs_ag_get_geometry(pag, &ageo);390	xfs_perag_put(pag);391	if (error)392		return error;393 394	if (copy_to_user(arg, &ageo, sizeof(ageo)))395		return -EFAULT;396	return 0;397}398 399/*400 * Linux extended inode flags interface.401 */402 403static void404xfs_fill_fsxattr(405	struct xfs_inode	*ip,406	int			whichfork,407	struct fileattr		*fa)408{409	struct xfs_mount	*mp = ip->i_mount;410	struct xfs_ifork	*ifp = xfs_ifork_ptr(ip, whichfork);411 412	fileattr_fill_xflags(fa, xfs_ip2xflags(ip));413 414	if (ip->i_diflags & XFS_DIFLAG_EXTSIZE) {415		fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);416	} else if (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) {417		/*418		 * Don't let a misaligned extent size hint on a directory419		 * escape to userspace if it won't pass the setattr checks420		 * later.421		 */422		if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&423		    xfs_extlen_to_rtxmod(mp, ip->i_extsize) > 0) {424			fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE |425					    FS_XFLAG_EXTSZINHERIT);426			fa->fsx_extsize = 0;427		} else {428			fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);429		}430	}431 432	if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)433		fa->fsx_cowextsize = XFS_FSB_TO_B(mp, ip->i_cowextsize);434	fa->fsx_projid = ip->i_projid;435	if (ifp && !xfs_need_iread_extents(ifp))436		fa->fsx_nextents = xfs_iext_count(ifp);437	else438		fa->fsx_nextents = xfs_ifork_nextents(ifp);439}440 441STATIC int442xfs_ioc_fsgetxattra(443	xfs_inode_t		*ip,444	void			__user *arg)445{446	struct fileattr		fa;447 448	xfs_ilock(ip, XFS_ILOCK_SHARED);449	xfs_fill_fsxattr(ip, XFS_ATTR_FORK, &fa);450	xfs_iunlock(ip, XFS_ILOCK_SHARED);451 452	return copy_fsxattr_to_user(&fa, arg);453}454 455int456xfs_fileattr_get(457	struct dentry		*dentry,458	struct fileattr		*fa)459{460	struct xfs_inode	*ip = XFS_I(d_inode(dentry));461 462	if (d_is_special(dentry))463		return -ENOTTY;464 465	xfs_ilock(ip, XFS_ILOCK_SHARED);466	xfs_fill_fsxattr(ip, XFS_DATA_FORK, fa);467	xfs_iunlock(ip, XFS_ILOCK_SHARED);468 469	return 0;470}471 472static int473xfs_ioctl_setattr_xflags(474	struct xfs_trans	*tp,475	struct xfs_inode	*ip,476	struct fileattr		*fa)477{478	struct xfs_mount	*mp = ip->i_mount;479	bool			rtflag = (fa->fsx_xflags & FS_XFLAG_REALTIME);480	uint64_t		i_flags2;481 482	if (rtflag != XFS_IS_REALTIME_INODE(ip)) {483		/* Can't change realtime flag if any extents are allocated. */484		if (xfs_inode_has_filedata(ip))485			return -EINVAL;486 487		/*488		 * If S_DAX is enabled on this file, we can only switch the489		 * device if both support fsdax.  We can't update S_DAX because490		 * there might be other threads walking down the access paths.491		 */492		if (IS_DAX(VFS_I(ip)) &&493		    (mp->m_ddev_targp->bt_daxdev == NULL ||494		     (mp->m_rtdev_targp &&495		      mp->m_rtdev_targp->bt_daxdev == NULL)))496			return -EINVAL;497	}498 499	if (rtflag) {500		/* If realtime flag is set then must have realtime device */501		if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||502		    xfs_extlen_to_rtxmod(mp, ip->i_extsize))503			return -EINVAL;504 505		/* Clear reflink if we are actually able to set the rt flag. */506		if (xfs_is_reflink_inode(ip))507			ip->i_diflags2 &= ~XFS_DIFLAG2_REFLINK;508	}509 510	/* diflags2 only valid for v3 inodes. */511	i_flags2 = xfs_flags2diflags2(ip, fa->fsx_xflags);512	if (i_flags2 && !xfs_has_v3inodes(mp))513		return -EINVAL;514 515	ip->i_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);516	ip->i_diflags2 = i_flags2;517 518	xfs_diflags_to_iflags(ip, false);519 520	/*521	 * Make the stable writes flag match that of the device the inode522	 * resides on when flipping the RT flag.523	 */524	if (rtflag != XFS_IS_REALTIME_INODE(ip) && S_ISREG(VFS_I(ip)->i_mode))525		xfs_update_stable_writes(ip);526 527	xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);528	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);529	XFS_STATS_INC(mp, xs_ig_attrchg);530	return 0;531}532 533static void534xfs_ioctl_setattr_prepare_dax(535	struct xfs_inode	*ip,536	struct fileattr		*fa)537{538	struct xfs_mount	*mp = ip->i_mount;539	struct inode            *inode = VFS_I(ip);540 541	if (S_ISDIR(inode->i_mode))542		return;543 544	if (xfs_has_dax_always(mp) || xfs_has_dax_never(mp))545		return;546 547	if (((fa->fsx_xflags & FS_XFLAG_DAX) &&548	    !(ip->i_diflags2 & XFS_DIFLAG2_DAX)) ||549	    (!(fa->fsx_xflags & FS_XFLAG_DAX) &&550	     (ip->i_diflags2 & XFS_DIFLAG2_DAX)))551		d_mark_dontcache(inode);552}553 554/*555 * Set up the transaction structure for the setattr operation, checking that we556 * have permission to do so. On success, return a clean transaction and the557 * inode locked exclusively ready for further operation specific checks. On558 * failure, return an error without modifying or locking the inode.559 */560static struct xfs_trans *561xfs_ioctl_setattr_get_trans(562	struct xfs_inode	*ip,563	struct xfs_dquot	*pdqp)564{565	struct xfs_mount	*mp = ip->i_mount;566	struct xfs_trans	*tp;567	int			error = -EROFS;568 569	if (xfs_is_readonly(mp))570		goto out_error;571	error = -EIO;572	if (xfs_is_shutdown(mp))573		goto out_error;574 575	error = xfs_trans_alloc_ichange(ip, NULL, NULL, pdqp,576			has_capability_noaudit(current, CAP_FOWNER), &tp);577	if (error)578		goto out_error;579 580	if (xfs_has_wsync(mp))581		xfs_trans_set_sync(tp);582 583	return tp;584 585out_error:586	return ERR_PTR(error);587}588 589/*590 * Validate a proposed extent size hint.  For regular files, the hint can only591 * be changed if no extents are allocated.592 */593static int594xfs_ioctl_setattr_check_extsize(595	struct xfs_inode	*ip,596	struct fileattr		*fa)597{598	struct xfs_mount	*mp = ip->i_mount;599	xfs_failaddr_t		failaddr;600	uint16_t		new_diflags;601 602	if (!fa->fsx_valid)603		return 0;604 605	if (S_ISREG(VFS_I(ip)->i_mode) && xfs_inode_has_filedata(ip) &&606	    XFS_FSB_TO_B(mp, ip->i_extsize) != fa->fsx_extsize)607		return -EINVAL;608 609	if (fa->fsx_extsize & mp->m_blockmask)610		return -EINVAL;611 612	new_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);613 614	/*615	 * Inode verifiers do not check that the extent size hint is an integer616	 * multiple of the rt extent size on a directory with both rtinherit617	 * and extszinherit flags set.  Don't let sysadmins misconfigure618	 * directories.619	 */620	if ((new_diflags & XFS_DIFLAG_RTINHERIT) &&621	    (new_diflags & XFS_DIFLAG_EXTSZINHERIT)) {622		unsigned int	rtextsize_bytes;623 624		rtextsize_bytes = XFS_FSB_TO_B(mp, mp->m_sb.sb_rextsize);625		if (fa->fsx_extsize % rtextsize_bytes)626			return -EINVAL;627	}628 629	failaddr = xfs_inode_validate_extsize(ip->i_mount,630			XFS_B_TO_FSB(mp, fa->fsx_extsize),631			VFS_I(ip)->i_mode, new_diflags);632	return failaddr != NULL ? -EINVAL : 0;633}634 635static int636xfs_ioctl_setattr_check_cowextsize(637	struct xfs_inode	*ip,638	struct fileattr		*fa)639{640	struct xfs_mount	*mp = ip->i_mount;641	xfs_failaddr_t		failaddr;642	uint64_t		new_diflags2;643	uint16_t		new_diflags;644 645	if (!fa->fsx_valid)646		return 0;647 648	if (fa->fsx_cowextsize & mp->m_blockmask)649		return -EINVAL;650 651	new_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);652	new_diflags2 = xfs_flags2diflags2(ip, fa->fsx_xflags);653 654	failaddr = xfs_inode_validate_cowextsize(ip->i_mount,655			XFS_B_TO_FSB(mp, fa->fsx_cowextsize),656			VFS_I(ip)->i_mode, new_diflags, new_diflags2);657	return failaddr != NULL ? -EINVAL : 0;658}659 660static int661xfs_ioctl_setattr_check_projid(662	struct xfs_inode	*ip,663	struct fileattr		*fa)664{665	if (!fa->fsx_valid)666		return 0;667 668	/* Disallow 32bit project ids if 32bit IDs are not enabled. */669	if (fa->fsx_projid > (uint16_t)-1 &&670	    !xfs_has_projid32(ip->i_mount))671		return -EINVAL;672	return 0;673}674 675int676xfs_fileattr_set(677	struct mnt_idmap	*idmap,678	struct dentry		*dentry,679	struct fileattr		*fa)680{681	struct xfs_inode	*ip = XFS_I(d_inode(dentry));682	struct xfs_mount	*mp = ip->i_mount;683	struct xfs_trans	*tp;684	struct xfs_dquot	*pdqp = NULL;685	struct xfs_dquot	*olddquot = NULL;686	int			error;687 688	trace_xfs_ioctl_setattr(ip);689 690	if (d_is_special(dentry))691		return -ENOTTY;692 693	if (!fa->fsx_valid) {694		if (fa->flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL |695				  FS_NOATIME_FL | FS_NODUMP_FL |696				  FS_SYNC_FL | FS_DAX_FL | FS_PROJINHERIT_FL))697			return -EOPNOTSUPP;698	}699 700	error = xfs_ioctl_setattr_check_projid(ip, fa);701	if (error)702		return error;703 704	/*705	 * If disk quotas is on, we make sure that the dquots do exist on disk,706	 * before we start any other transactions. Trying to do this later707	 * is messy. We don't care to take a readlock to look at the ids708	 * in inode here, because we can't hold it across the trans_reserve.709	 * If the IDs do change before we take the ilock, we're covered710	 * because the i_*dquot fields will get updated anyway.711	 */712	if (fa->fsx_valid && XFS_IS_QUOTA_ON(mp)) {713		error = xfs_qm_vop_dqalloc(ip, VFS_I(ip)->i_uid,714				VFS_I(ip)->i_gid, fa->fsx_projid,715				XFS_QMOPT_PQUOTA, NULL, NULL, &pdqp);716		if (error)717			return error;718	}719 720	xfs_ioctl_setattr_prepare_dax(ip, fa);721 722	tp = xfs_ioctl_setattr_get_trans(ip, pdqp);723	if (IS_ERR(tp)) {724		error = PTR_ERR(tp);725		goto error_free_dquots;726	}727 728	error = xfs_ioctl_setattr_check_extsize(ip, fa);729	if (error)730		goto error_trans_cancel;731 732	error = xfs_ioctl_setattr_check_cowextsize(ip, fa);733	if (error)734		goto error_trans_cancel;735 736	error = xfs_ioctl_setattr_xflags(tp, ip, fa);737	if (error)738		goto error_trans_cancel;739 740	if (!fa->fsx_valid)741		goto skip_xattr;742	/*743	 * Change file ownership.  Must be the owner or privileged.  CAP_FSETID744	 * overrides the following restrictions:745	 *746	 * The set-user-ID and set-group-ID bits of a file will be cleared upon747	 * successful return from chown()748	 */749 750	if ((VFS_I(ip)->i_mode & (S_ISUID|S_ISGID)) &&751	    !capable_wrt_inode_uidgid(idmap, VFS_I(ip), CAP_FSETID))752		VFS_I(ip)->i_mode &= ~(S_ISUID|S_ISGID);753 754	/* Change the ownerships and register project quota modifications */755	if (ip->i_projid != fa->fsx_projid) {756		if (XFS_IS_PQUOTA_ON(mp)) {757			olddquot = xfs_qm_vop_chown(tp, ip,758						&ip->i_pdquot, pdqp);759		}760		ip->i_projid = fa->fsx_projid;761	}762 763	/*764	 * Only set the extent size hint if we've already determined that the765	 * extent size hint should be set on the inode. If no extent size flags766	 * are set on the inode then unconditionally clear the extent size hint.767	 */768	if (ip->i_diflags & (XFS_DIFLAG_EXTSIZE | XFS_DIFLAG_EXTSZINHERIT))769		ip->i_extsize = XFS_B_TO_FSB(mp, fa->fsx_extsize);770	else771		ip->i_extsize = 0;772 773	if (xfs_has_v3inodes(mp)) {774		if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)775			ip->i_cowextsize = XFS_B_TO_FSB(mp, fa->fsx_cowextsize);776		else777			ip->i_cowextsize = 0;778	}779 780skip_xattr:781	error = xfs_trans_commit(tp);782 783	/*784	 * Release any dquot(s) the inode had kept before chown.785	 */786	xfs_qm_dqrele(olddquot);787	xfs_qm_dqrele(pdqp);788 789	return error;790 791error_trans_cancel:792	xfs_trans_cancel(tp);793error_free_dquots:794	xfs_qm_dqrele(pdqp);795	return error;796}797 798static bool799xfs_getbmap_format(800	struct kgetbmap		*p,801	struct getbmapx __user	*u,802	size_t			recsize)803{804	if (put_user(p->bmv_offset, &u->bmv_offset) ||805	    put_user(p->bmv_block, &u->bmv_block) ||806	    put_user(p->bmv_length, &u->bmv_length) ||807	    put_user(0, &u->bmv_count) ||808	    put_user(0, &u->bmv_entries))809		return false;810	if (recsize < sizeof(struct getbmapx))811		return true;812	if (put_user(0, &u->bmv_iflags) ||813	    put_user(p->bmv_oflags, &u->bmv_oflags) ||814	    put_user(0, &u->bmv_unused1) ||815	    put_user(0, &u->bmv_unused2))816		return false;817	return true;818}819 820STATIC int821xfs_ioc_getbmap(822	struct file		*file,823	unsigned int		cmd,824	void			__user *arg)825{826	struct getbmapx		bmx = { 0 };827	struct kgetbmap		*buf;828	size_t			recsize;829	int			error, i;830 831	switch (cmd) {832	case XFS_IOC_GETBMAPA:833		bmx.bmv_iflags = BMV_IF_ATTRFORK;834		fallthrough;835	case XFS_IOC_GETBMAP:836		/* struct getbmap is a strict subset of struct getbmapx. */837		recsize = sizeof(struct getbmap);838		break;839	case XFS_IOC_GETBMAPX:840		recsize = sizeof(struct getbmapx);841		break;842	default:843		return -EINVAL;844	}845 846	if (copy_from_user(&bmx, arg, recsize))847		return -EFAULT;848 849	if (bmx.bmv_count < 2)850		return -EINVAL;851	if (bmx.bmv_count >= INT_MAX / recsize)852		return -ENOMEM;853 854	buf = kvcalloc(bmx.bmv_count, sizeof(*buf), GFP_KERNEL);855	if (!buf)856		return -ENOMEM;857 858	error = xfs_getbmap(XFS_I(file_inode(file)), &bmx, buf);859	if (error)860		goto out_free_buf;861 862	error = -EFAULT;863	if (copy_to_user(arg, &bmx, recsize))864		goto out_free_buf;865	arg += recsize;866 867	for (i = 0; i < bmx.bmv_entries; i++) {868		if (!xfs_getbmap_format(buf + i, arg, recsize))869			goto out_free_buf;870		arg += recsize;871	}872 873	error = 0;874out_free_buf:875	kvfree(buf);876	return error;877}878 879int880xfs_ioc_swapext(881	xfs_swapext_t	*sxp)882{883	xfs_inode_t     *ip, *tip;884	struct fd	f, tmp;885	int		error = 0;886 887	/* Pull information for the target fd */888	f = fdget((int)sxp->sx_fdtarget);889	if (!fd_file(f)) {890		error = -EINVAL;891		goto out;892	}893 894	if (!(fd_file(f)->f_mode & FMODE_WRITE) ||895	    !(fd_file(f)->f_mode & FMODE_READ) ||896	    (fd_file(f)->f_flags & O_APPEND)) {897		error = -EBADF;898		goto out_put_file;899	}900 901	tmp = fdget((int)sxp->sx_fdtmp);902	if (!fd_file(tmp)) {903		error = -EINVAL;904		goto out_put_file;905	}906 907	if (!(fd_file(tmp)->f_mode & FMODE_WRITE) ||908	    !(fd_file(tmp)->f_mode & FMODE_READ) ||909	    (fd_file(tmp)->f_flags & O_APPEND)) {910		error = -EBADF;911		goto out_put_tmp_file;912	}913 914	if (IS_SWAPFILE(file_inode(fd_file(f))) ||915	    IS_SWAPFILE(file_inode(fd_file(tmp)))) {916		error = -EINVAL;917		goto out_put_tmp_file;918	}919 920	/*921	 * We need to ensure that the fds passed in point to XFS inodes922	 * before we cast and access them as XFS structures as we have no923	 * control over what the user passes us here.924	 */925	if (fd_file(f)->f_op != &xfs_file_operations ||926	    fd_file(tmp)->f_op != &xfs_file_operations) {927		error = -EINVAL;928		goto out_put_tmp_file;929	}930 931	ip = XFS_I(file_inode(fd_file(f)));932	tip = XFS_I(file_inode(fd_file(tmp)));933 934	if (ip->i_mount != tip->i_mount) {935		error = -EINVAL;936		goto out_put_tmp_file;937	}938 939	if (ip->i_ino == tip->i_ino) {940		error = -EINVAL;941		goto out_put_tmp_file;942	}943 944	if (xfs_is_shutdown(ip->i_mount)) {945		error = -EIO;946		goto out_put_tmp_file;947	}948 949	error = xfs_swap_extents(ip, tip, sxp);950 951 out_put_tmp_file:952	fdput(tmp);953 out_put_file:954	fdput(f);955 out:956	return error;957}958 959static int960xfs_ioc_getlabel(961	struct xfs_mount	*mp,962	char			__user *user_label)963{964	struct xfs_sb		*sbp = &mp->m_sb;965	char			label[XFSLABEL_MAX + 1];966 967	/* Paranoia */968	BUILD_BUG_ON(sizeof(sbp->sb_fname) > FSLABEL_MAX);969 970	/* 1 larger than sb_fname, so this ensures a trailing NUL char */971	memset(label, 0, sizeof(label));972	spin_lock(&mp->m_sb_lock);973	strncpy(label, sbp->sb_fname, XFSLABEL_MAX);974	spin_unlock(&mp->m_sb_lock);975 976	if (copy_to_user(user_label, label, sizeof(label)))977		return -EFAULT;978	return 0;979}980 981static int982xfs_ioc_setlabel(983	struct file		*filp,984	struct xfs_mount	*mp,985	char			__user *newlabel)986{987	struct xfs_sb		*sbp = &mp->m_sb;988	char			label[XFSLABEL_MAX + 1];989	size_t			len;990	int			error;991 992	if (!capable(CAP_SYS_ADMIN))993		return -EPERM;994	/*995	 * The generic ioctl allows up to FSLABEL_MAX chars, but XFS is much996	 * smaller, at 12 bytes.  We copy one more to be sure we find the997	 * (required) NULL character to test the incoming label length.998	 * NB: The on disk label doesn't need to be null terminated.999	 */1000	if (copy_from_user(label, newlabel, XFSLABEL_MAX + 1))1001		return -EFAULT;1002	len = strnlen(label, XFSLABEL_MAX + 1);1003	if (len > sizeof(sbp->sb_fname))1004		return -EINVAL;1005 1006	error = mnt_want_write_file(filp);1007	if (error)1008		return error;1009 1010	spin_lock(&mp->m_sb_lock);1011	memset(sbp->sb_fname, 0, sizeof(sbp->sb_fname));1012	memcpy(sbp->sb_fname, label, len);1013	spin_unlock(&mp->m_sb_lock);1014 1015	/*1016	 * Now we do several things to satisfy userspace.1017	 * In addition to normal logging of the primary superblock, we also1018	 * immediately write these changes to sector zero for the primary, then1019	 * update all backup supers (as xfs_db does for a label change), then1020	 * invalidate the block device page cache.  This is so that any prior1021	 * buffered reads from userspace (i.e. from blkid) are invalidated,1022	 * and userspace will see the newly-written label.1023	 */1024	error = xfs_sync_sb_buf(mp);1025	if (error)1026		goto out;1027	/*1028	 * growfs also updates backup supers so lock against that.1029	 */1030	mutex_lock(&mp->m_growlock);1031	error = xfs_update_secondary_sbs(mp);1032	mutex_unlock(&mp->m_growlock);1033 1034	invalidate_bdev(mp->m_ddev_targp->bt_bdev);1035 1036out:1037	mnt_drop_write_file(filp);1038	return error;1039}1040 1041static inline int1042xfs_fs_eofblocks_from_user(1043	struct xfs_fs_eofblocks		*src,1044	struct xfs_icwalk		*dst)1045{1046	if (src->eof_version != XFS_EOFBLOCKS_VERSION)1047		return -EINVAL;1048 1049	if (src->eof_flags & ~XFS_EOF_FLAGS_VALID)1050		return -EINVAL;1051 1052	if (memchr_inv(&src->pad32, 0, sizeof(src->pad32)) ||1053	    memchr_inv(src->pad64, 0, sizeof(src->pad64)))1054		return -EINVAL;1055 1056	dst->icw_flags = 0;1057	if (src->eof_flags & XFS_EOF_FLAGS_SYNC)1058		dst->icw_flags |= XFS_ICWALK_FLAG_SYNC;1059	if (src->eof_flags & XFS_EOF_FLAGS_UID)1060		dst->icw_flags |= XFS_ICWALK_FLAG_UID;1061	if (src->eof_flags & XFS_EOF_FLAGS_GID)1062		dst->icw_flags |= XFS_ICWALK_FLAG_GID;1063	if (src->eof_flags & XFS_EOF_FLAGS_PRID)1064		dst->icw_flags |= XFS_ICWALK_FLAG_PRID;1065	if (src->eof_flags & XFS_EOF_FLAGS_MINFILESIZE)1066		dst->icw_flags |= XFS_ICWALK_FLAG_MINFILESIZE;1067 1068	dst->icw_prid = src->eof_prid;1069	dst->icw_min_file_size = src->eof_min_file_size;1070 1071	dst->icw_uid = INVALID_UID;1072	if (src->eof_flags & XFS_EOF_FLAGS_UID) {1073		dst->icw_uid = make_kuid(current_user_ns(), src->eof_uid);1074		if (!uid_valid(dst->icw_uid))1075			return -EINVAL;1076	}1077 1078	dst->icw_gid = INVALID_GID;1079	if (src->eof_flags & XFS_EOF_FLAGS_GID) {1080		dst->icw_gid = make_kgid(current_user_ns(), src->eof_gid);1081		if (!gid_valid(dst->icw_gid))1082			return -EINVAL;1083	}1084	return 0;1085}1086 1087static int1088xfs_ioctl_getset_resblocks(1089	struct file		*filp,1090	unsigned int		cmd,1091	void __user		*arg)1092{1093	struct xfs_mount	*mp = XFS_I(file_inode(filp))->i_mount;1094	struct xfs_fsop_resblks	fsop = { };1095	int			error;1096 1097	if (!capable(CAP_SYS_ADMIN))1098		return -EPERM;1099 1100	if (cmd == XFS_IOC_SET_RESBLKS) {1101		if (xfs_is_readonly(mp))1102			return -EROFS;1103 1104		if (copy_from_user(&fsop, arg, sizeof(fsop)))1105			return -EFAULT;1106 1107		error = mnt_want_write_file(filp);1108		if (error)1109			return error;1110		error = xfs_reserve_blocks(mp, fsop.resblks);1111		mnt_drop_write_file(filp);1112		if (error)1113			return error;1114	}1115 1116	spin_lock(&mp->m_sb_lock);1117	fsop.resblks = mp->m_resblks;1118	fsop.resblks_avail = mp->m_resblks_avail;1119	spin_unlock(&mp->m_sb_lock);1120 1121	if (copy_to_user(arg, &fsop, sizeof(fsop)))1122		return -EFAULT;1123	return 0;1124}1125 1126static int1127xfs_ioctl_fs_counts(1128	struct xfs_mount	*mp,1129	struct xfs_fsop_counts __user	*uarg)1130{1131	struct xfs_fsop_counts	out = {1132		.allocino = percpu_counter_read_positive(&mp->m_icount),1133		.freeino  = percpu_counter_read_positive(&mp->m_ifree),1134		.freedata = percpu_counter_read_positive(&mp->m_fdblocks) -1135				xfs_fdblocks_unavailable(mp),1136		.freertx  = percpu_counter_read_positive(&mp->m_frextents),1137	};1138 1139	if (copy_to_user(uarg, &out, sizeof(out)))1140		return -EFAULT;1141	return 0;1142}1143 1144/*1145 * These long-unused ioctls were removed from the official ioctl API in 5.17,1146 * but retain these definitions so that we can log warnings about them.1147 */1148#define XFS_IOC_ALLOCSP		_IOW ('X', 10, struct xfs_flock64)1149#define XFS_IOC_FREESP		_IOW ('X', 11, struct xfs_flock64)1150#define XFS_IOC_ALLOCSP64	_IOW ('X', 36, struct xfs_flock64)1151#define XFS_IOC_FREESP64	_IOW ('X', 37, struct xfs_flock64)1152 1153/*1154 * Note: some of the ioctl's return positive numbers as a1155 * byte count indicating success, such as readlink_by_handle.1156 * So we don't "sign flip" like most other routines.  This means1157 * true errors need to be returned as a negative value.1158 */1159long1160xfs_file_ioctl(1161	struct file		*filp,1162	unsigned int		cmd,1163	unsigned long		p)1164{1165	struct inode		*inode = file_inode(filp);1166	struct xfs_inode	*ip = XFS_I(inode);1167	struct xfs_mount	*mp = ip->i_mount;1168	void			__user *arg = (void __user *)p;1169	int			error;1170 1171	trace_xfs_file_ioctl(ip);1172 1173	switch (cmd) {1174	case FITRIM:1175		return xfs_ioc_trim(mp, arg);1176	case FS_IOC_GETFSLABEL:1177		return xfs_ioc_getlabel(mp, arg);1178	case FS_IOC_SETFSLABEL:1179		return xfs_ioc_setlabel(filp, mp, arg);1180	case XFS_IOC_ALLOCSP:1181	case XFS_IOC_FREESP:1182	case XFS_IOC_ALLOCSP64:1183	case XFS_IOC_FREESP64:1184		xfs_warn_once(mp,1185	"%s should use fallocate; XFS_IOC_{ALLOC,FREE}SP ioctl unsupported",1186				current->comm);1187		return -ENOTTY;1188	case XFS_IOC_DIOINFO: {1189		struct xfs_buftarg	*target = xfs_inode_buftarg(ip);1190		struct dioattr		da;1191 1192		da.d_mem =  da.d_miniosz = target->bt_logical_sectorsize;1193		da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);1194 1195		if (copy_to_user(arg, &da, sizeof(da)))1196			return -EFAULT;1197		return 0;1198	}1199 1200	case XFS_IOC_FSBULKSTAT_SINGLE:1201	case XFS_IOC_FSBULKSTAT:1202	case XFS_IOC_FSINUMBERS:1203		return xfs_ioc_fsbulkstat(filp, cmd, arg);1204 1205	case XFS_IOC_BULKSTAT:1206		return xfs_ioc_bulkstat(filp, cmd, arg);1207	case XFS_IOC_INUMBERS:1208		return xfs_ioc_inumbers(mp, cmd, arg);1209 1210	case XFS_IOC_FSGEOMETRY_V1:1211		return xfs_ioc_fsgeometry(mp, arg, 3);1212	case XFS_IOC_FSGEOMETRY_V4:1213		return xfs_ioc_fsgeometry(mp, arg, 4);1214	case XFS_IOC_FSGEOMETRY:1215		return xfs_ioc_fsgeometry(mp, arg, 5);1216 1217	case XFS_IOC_AG_GEOMETRY:1218		return xfs_ioc_ag_geometry(mp, arg);1219 1220	case XFS_IOC_GETVERSION:1221		return put_user(inode->i_generation, (int __user *)arg);1222 1223	case XFS_IOC_FSGETXATTRA:1224		return xfs_ioc_fsgetxattra(ip, arg);1225	case XFS_IOC_GETPARENTS:1226		return xfs_ioc_getparents(filp, arg);1227	case XFS_IOC_GETPARENTS_BY_HANDLE:1228		return xfs_ioc_getparents_by_handle(filp, arg);1229	case XFS_IOC_GETBMAP:1230	case XFS_IOC_GETBMAPA:1231	case XFS_IOC_GETBMAPX:1232		return xfs_ioc_getbmap(filp, cmd, arg);1233 1234	case FS_IOC_GETFSMAP:1235		return xfs_ioc_getfsmap(ip, arg);1236 1237	case XFS_IOC_SCRUBV_METADATA:1238		return xfs_ioc_scrubv_metadata(filp, arg);1239	case XFS_IOC_SCRUB_METADATA:1240		return xfs_ioc_scrub_metadata(filp, arg);1241 1242	case XFS_IOC_FD_TO_HANDLE:1243	case XFS_IOC_PATH_TO_HANDLE:1244	case XFS_IOC_PATH_TO_FSHANDLE: {1245		xfs_fsop_handlereq_t	hreq;1246 1247		if (copy_from_user(&hreq, arg, sizeof(hreq)))1248			return -EFAULT;1249		return xfs_find_handle(cmd, &hreq);1250	}1251	case XFS_IOC_OPEN_BY_HANDLE: {1252		xfs_fsop_handlereq_t	hreq;1253 1254		if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))1255			return -EFAULT;1256		return xfs_open_by_handle(filp, &hreq);1257	}1258 1259	case XFS_IOC_READLINK_BY_HANDLE: {1260		xfs_fsop_handlereq_t	hreq;1261 1262		if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))1263			return -EFAULT;1264		return xfs_readlink_by_handle(filp, &hreq);1265	}1266	case XFS_IOC_ATTRLIST_BY_HANDLE:1267		return xfs_attrlist_by_handle(filp, arg);1268 1269	case XFS_IOC_ATTRMULTI_BY_HANDLE:1270		return xfs_attrmulti_by_handle(filp, arg);1271 1272	case XFS_IOC_SWAPEXT: {1273		struct xfs_swapext	sxp;1274 1275		if (copy_from_user(&sxp, arg, sizeof(xfs_swapext_t)))1276			return -EFAULT;1277		error = mnt_want_write_file(filp);1278		if (error)1279			return error;1280		error = xfs_ioc_swapext(&sxp);1281		mnt_drop_write_file(filp);1282		return error;1283	}1284 1285	case XFS_IOC_FSCOUNTS:1286		return xfs_ioctl_fs_counts(mp, arg);1287 1288	case XFS_IOC_SET_RESBLKS:1289	case XFS_IOC_GET_RESBLKS:1290		return xfs_ioctl_getset_resblocks(filp, cmd, arg);1291 1292	case XFS_IOC_FSGROWFSDATA: {1293		struct xfs_growfs_data in;1294 1295		if (copy_from_user(&in, arg, sizeof(in)))1296			return -EFAULT;1297 1298		error = mnt_want_write_file(filp);1299		if (error)1300			return error;1301		error = xfs_growfs_data(mp, &in);1302		mnt_drop_write_file(filp);1303		return error;1304	}1305 1306	case XFS_IOC_FSGROWFSLOG: {1307		struct xfs_growfs_log in;1308 1309		if (copy_from_user(&in, arg, sizeof(in)))1310			return -EFAULT;1311 1312		error = mnt_want_write_file(filp);1313		if (error)1314			return error;1315		error = xfs_growfs_log(mp, &in);1316		mnt_drop_write_file(filp);1317		return error;1318	}1319 1320	case XFS_IOC_FSGROWFSRT: {1321		xfs_growfs_rt_t in;1322 1323		if (copy_from_user(&in, arg, sizeof(in)))1324			return -EFAULT;1325 1326		error = mnt_want_write_file(filp);1327		if (error)1328			return error;1329		error = xfs_growfs_rt(mp, &in);1330		mnt_drop_write_file(filp);1331		return error;1332	}1333 1334	case XFS_IOC_GOINGDOWN: {1335		uint32_t in;1336 1337		if (!capable(CAP_SYS_ADMIN))1338			return -EPERM;1339 1340		if (get_user(in, (uint32_t __user *)arg))1341			return -EFAULT;1342 1343		return xfs_fs_goingdown(mp, in);1344	}1345 1346	case XFS_IOC_ERROR_INJECTION: {1347		xfs_error_injection_t in;1348 1349		if (!capable(CAP_SYS_ADMIN))1350			return -EPERM;1351 1352		if (copy_from_user(&in, arg, sizeof(in)))1353			return -EFAULT;1354 1355		return xfs_errortag_add(mp, in.errtag);1356	}1357 1358	case XFS_IOC_ERROR_CLEARALL:1359		if (!capable(CAP_SYS_ADMIN))1360			return -EPERM;1361 1362		return xfs_errortag_clearall(mp);1363 1364	case XFS_IOC_FREE_EOFBLOCKS: {1365		struct xfs_fs_eofblocks	eofb;1366		struct xfs_icwalk	icw;1367 1368		if (!capable(CAP_SYS_ADMIN))1369			return -EPERM;1370 1371		if (xfs_is_readonly(mp))1372			return -EROFS;1373 1374		if (copy_from_user(&eofb, arg, sizeof(eofb)))1375			return -EFAULT;1376 1377		error = xfs_fs_eofblocks_from_user(&eofb, &icw);1378		if (error)1379			return error;1380 1381		trace_xfs_ioc_free_eofblocks(mp, &icw, _RET_IP_);1382 1383		sb_start_write(mp->m_super);1384		error = xfs_blockgc_free_space(mp, &icw);1385		sb_end_write(mp->m_super);1386		return error;1387	}1388 1389	case XFS_IOC_EXCHANGE_RANGE:1390		return xfs_ioc_exchange_range(filp, arg);1391	case XFS_IOC_START_COMMIT:1392		return xfs_ioc_start_commit(filp, arg);1393	case XFS_IOC_COMMIT_RANGE:1394		return xfs_ioc_commit_range(filp, arg);1395 1396	default:1397		return -ENOTTY;1398	}1399}1400