PageRenderTime 310ms CodeModel.GetById 214ms app.highlight 82ms RepoModel.GetById 2ms app.codeStats 1ms

/fs/xfs/xfs_ioctl.c

https://bitbucket.org/emiliolopez/linux
C | 2072 lines | 1536 code | 331 blank | 205 comment | 325 complexity | e3ec6b856ff6481a71b25ec6ea099c28 MD5 | raw file
   1/*
   2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
   3 * All Rights Reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it would be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program; if not, write the Free Software Foundation,
  16 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  17 */
  18#include "xfs.h"
  19#include "xfs_fs.h"
  20#include "xfs_shared.h"
  21#include "xfs_format.h"
  22#include "xfs_log_format.h"
  23#include "xfs_trans_resv.h"
  24#include "xfs_mount.h"
  25#include "xfs_inode.h"
  26#include "xfs_ioctl.h"
  27#include "xfs_alloc.h"
  28#include "xfs_rtalloc.h"
  29#include "xfs_itable.h"
  30#include "xfs_error.h"
  31#include "xfs_attr.h"
  32#include "xfs_bmap.h"
  33#include "xfs_bmap_util.h"
  34#include "xfs_fsops.h"
  35#include "xfs_discard.h"
  36#include "xfs_quota.h"
  37#include "xfs_export.h"
  38#include "xfs_trace.h"
  39#include "xfs_icache.h"
  40#include "xfs_symlink.h"
  41#include "xfs_trans.h"
  42#include "xfs_pnfs.h"
  43#include "xfs_acl.h"
  44#include "xfs_btree.h"
  45#include <linux/fsmap.h>
  46#include "xfs_fsmap.h"
  47
  48#include <linux/capability.h>
  49#include <linux/cred.h>
  50#include <linux/dcache.h>
  51#include <linux/mount.h>
  52#include <linux/namei.h>
  53#include <linux/pagemap.h>
  54#include <linux/slab.h>
  55#include <linux/exportfs.h>
  56
  57/*
  58 * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to
  59 * a file or fs handle.
  60 *
  61 * XFS_IOC_PATH_TO_FSHANDLE
  62 *    returns fs handle for a mount point or path within that mount point
  63 * XFS_IOC_FD_TO_HANDLE
  64 *    returns full handle for a FD opened in user space
  65 * XFS_IOC_PATH_TO_HANDLE
  66 *    returns full handle for a path
  67 */
  68int
  69xfs_find_handle(
  70	unsigned int		cmd,
  71	xfs_fsop_handlereq_t	*hreq)
  72{
  73	int			hsize;
  74	xfs_handle_t		handle;
  75	struct inode		*inode;
  76	struct fd		f = {NULL};
  77	struct path		path;
  78	int			error;
  79	struct xfs_inode	*ip;
  80
  81	if (cmd == XFS_IOC_FD_TO_HANDLE) {
  82		f = fdget(hreq->fd);
  83		if (!f.file)
  84			return -EBADF;
  85		inode = file_inode(f.file);
  86	} else {
  87		error = user_lpath((const char __user *)hreq->path, &path);
  88		if (error)
  89			return error;
  90		inode = d_inode(path.dentry);
  91	}
  92	ip = XFS_I(inode);
  93
  94	/*
  95	 * We can only generate handles for inodes residing on a XFS filesystem,
  96	 * and only for regular files, directories or symbolic links.
  97	 */
  98	error = -EINVAL;
  99	if (inode->i_sb->s_magic != XFS_SB_MAGIC)
 100		goto out_put;
 101
 102	error = -EBADF;
 103	if (!S_ISREG(inode->i_mode) &&
 104	    !S_ISDIR(inode->i_mode) &&
 105	    !S_ISLNK(inode->i_mode))
 106		goto out_put;
 107
 108
 109	memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
 110
 111	if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
 112		/*
 113		 * This handle only contains an fsid, zero the rest.
 114		 */
 115		memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
 116		hsize = sizeof(xfs_fsid_t);
 117	} else {
 118		handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
 119					sizeof(handle.ha_fid.fid_len);
 120		handle.ha_fid.fid_pad = 0;
 121		handle.ha_fid.fid_gen = inode->i_generation;
 122		handle.ha_fid.fid_ino = ip->i_ino;
 123		hsize = sizeof(xfs_handle_t);
 124	}
 125
 126	error = -EFAULT;
 127	if (copy_to_user(hreq->ohandle, &handle, hsize) ||
 128	    copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
 129		goto out_put;
 130
 131	error = 0;
 132
 133 out_put:
 134	if (cmd == XFS_IOC_FD_TO_HANDLE)
 135		fdput(f);
 136	else
 137		path_put(&path);
 138	return error;
 139}
 140
 141/*
 142 * No need to do permission checks on the various pathname components
 143 * as the handle operations are privileged.
 144 */
 145STATIC int
 146xfs_handle_acceptable(
 147	void			*context,
 148	struct dentry		*dentry)
 149{
 150	return 1;
 151}
 152
 153/*
 154 * Convert userspace handle data into a dentry.
 155 */
 156struct dentry *
 157xfs_handle_to_dentry(
 158	struct file		*parfilp,
 159	void __user		*uhandle,
 160	u32			hlen)
 161{
 162	xfs_handle_t		handle;
 163	struct xfs_fid64	fid;
 164
 165	/*
 166	 * Only allow handle opens under a directory.
 167	 */
 168	if (!S_ISDIR(file_inode(parfilp)->i_mode))
 169		return ERR_PTR(-ENOTDIR);
 170
 171	if (hlen != sizeof(xfs_handle_t))
 172		return ERR_PTR(-EINVAL);
 173	if (copy_from_user(&handle, uhandle, hlen))
 174		return ERR_PTR(-EFAULT);
 175	if (handle.ha_fid.fid_len !=
 176	    sizeof(handle.ha_fid) - sizeof(handle.ha_fid.fid_len))
 177		return ERR_PTR(-EINVAL);
 178
 179	memset(&fid, 0, sizeof(struct fid));
 180	fid.ino = handle.ha_fid.fid_ino;
 181	fid.gen = handle.ha_fid.fid_gen;
 182
 183	return exportfs_decode_fh(parfilp->f_path.mnt, (struct fid *)&fid, 3,
 184			FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG,
 185			xfs_handle_acceptable, NULL);
 186}
 187
 188STATIC struct dentry *
 189xfs_handlereq_to_dentry(
 190	struct file		*parfilp,
 191	xfs_fsop_handlereq_t	*hreq)
 192{
 193	return xfs_handle_to_dentry(parfilp, hreq->ihandle, hreq->ihandlen);
 194}
 195
 196int
 197xfs_open_by_handle(
 198	struct file		*parfilp,
 199	xfs_fsop_handlereq_t	*hreq)
 200{
 201	const struct cred	*cred = current_cred();
 202	int			error;
 203	int			fd;
 204	int			permflag;
 205	struct file		*filp;
 206	struct inode		*inode;
 207	struct dentry		*dentry;
 208	fmode_t			fmode;
 209	struct path		path;
 210
 211	if (!capable(CAP_SYS_ADMIN))
 212		return -EPERM;
 213
 214	dentry = xfs_handlereq_to_dentry(parfilp, hreq);
 215	if (IS_ERR(dentry))
 216		return PTR_ERR(dentry);
 217	inode = d_inode(dentry);
 218
 219	/* Restrict xfs_open_by_handle to directories & regular files. */
 220	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
 221		error = -EPERM;
 222		goto out_dput;
 223	}
 224
 225#if BITS_PER_LONG != 32
 226	hreq->oflags |= O_LARGEFILE;
 227#endif
 228
 229	permflag = hreq->oflags;
 230	fmode = OPEN_FMODE(permflag);
 231	if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
 232	    (fmode & FMODE_WRITE) && IS_APPEND(inode)) {
 233		error = -EPERM;
 234		goto out_dput;
 235	}
 236
 237	if ((fmode & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
 238		error = -EPERM;
 239		goto out_dput;
 240	}
 241
 242	/* Can't write directories. */
 243	if (S_ISDIR(inode->i_mode) && (fmode & FMODE_WRITE)) {
 244		error = -EISDIR;
 245		goto out_dput;
 246	}
 247
 248	fd = get_unused_fd_flags(0);
 249	if (fd < 0) {
 250		error = fd;
 251		goto out_dput;
 252	}
 253
 254	path.mnt = parfilp->f_path.mnt;
 255	path.dentry = dentry;
 256	filp = dentry_open(&path, hreq->oflags, cred);
 257	dput(dentry);
 258	if (IS_ERR(filp)) {
 259		put_unused_fd(fd);
 260		return PTR_ERR(filp);
 261	}
 262
 263	if (S_ISREG(inode->i_mode)) {
 264		filp->f_flags |= O_NOATIME;
 265		filp->f_mode |= FMODE_NOCMTIME;
 266	}
 267
 268	fd_install(fd, filp);
 269	return fd;
 270
 271 out_dput:
 272	dput(dentry);
 273	return error;
 274}
 275
 276int
 277xfs_readlink_by_handle(
 278	struct file		*parfilp,
 279	xfs_fsop_handlereq_t	*hreq)
 280{
 281	struct dentry		*dentry;
 282	__u32			olen;
 283	int			error;
 284
 285	if (!capable(CAP_SYS_ADMIN))
 286		return -EPERM;
 287
 288	dentry = xfs_handlereq_to_dentry(parfilp, hreq);
 289	if (IS_ERR(dentry))
 290		return PTR_ERR(dentry);
 291
 292	/* Restrict this handle operation to symlinks only. */
 293	if (!d_is_symlink(dentry)) {
 294		error = -EINVAL;
 295		goto out_dput;
 296	}
 297
 298	if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) {
 299		error = -EFAULT;
 300		goto out_dput;
 301	}
 302
 303	error = vfs_readlink(dentry, hreq->ohandle, olen);
 304
 305 out_dput:
 306	dput(dentry);
 307	return error;
 308}
 309
 310int
 311xfs_set_dmattrs(
 312	xfs_inode_t     *ip,
 313	u_int		evmask,
 314	u_int16_t	state)
 315{
 316	xfs_mount_t	*mp = ip->i_mount;
 317	xfs_trans_t	*tp;
 318	int		error;
 319
 320	if (!capable(CAP_SYS_ADMIN))
 321		return -EPERM;
 322
 323	if (XFS_FORCED_SHUTDOWN(mp))
 324		return -EIO;
 325
 326	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
 327	if (error)
 328		return error;
 329
 330	xfs_ilock(ip, XFS_ILOCK_EXCL);
 331	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
 332
 333	ip->i_d.di_dmevmask = evmask;
 334	ip->i_d.di_dmstate  = state;
 335
 336	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 337	error = xfs_trans_commit(tp);
 338
 339	return error;
 340}
 341
 342STATIC int
 343xfs_fssetdm_by_handle(
 344	struct file		*parfilp,
 345	void			__user *arg)
 346{
 347	int			error;
 348	struct fsdmidata	fsd;
 349	xfs_fsop_setdm_handlereq_t dmhreq;
 350	struct dentry		*dentry;
 351
 352	if (!capable(CAP_MKNOD))
 353		return -EPERM;
 354	if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t)))
 355		return -EFAULT;
 356
 357	error = mnt_want_write_file(parfilp);
 358	if (error)
 359		return error;
 360
 361	dentry = xfs_handlereq_to_dentry(parfilp, &dmhreq.hreq);
 362	if (IS_ERR(dentry)) {
 363		mnt_drop_write_file(parfilp);
 364		return PTR_ERR(dentry);
 365	}
 366
 367	if (IS_IMMUTABLE(d_inode(dentry)) || IS_APPEND(d_inode(dentry))) {
 368		error = -EPERM;
 369		goto out;
 370	}
 371
 372	if (copy_from_user(&fsd, dmhreq.data, sizeof(fsd))) {
 373		error = -EFAULT;
 374		goto out;
 375	}
 376
 377	error = xfs_set_dmattrs(XFS_I(d_inode(dentry)), fsd.fsd_dmevmask,
 378				 fsd.fsd_dmstate);
 379
 380 out:
 381	mnt_drop_write_file(parfilp);
 382	dput(dentry);
 383	return error;
 384}
 385
 386STATIC int
 387xfs_attrlist_by_handle(
 388	struct file		*parfilp,
 389	void			__user *arg)
 390{
 391	int			error = -ENOMEM;
 392	attrlist_cursor_kern_t	*cursor;
 393	struct xfs_fsop_attrlist_handlereq __user	*p = arg;
 394	xfs_fsop_attrlist_handlereq_t al_hreq;
 395	struct dentry		*dentry;
 396	char			*kbuf;
 397
 398	if (!capable(CAP_SYS_ADMIN))
 399		return -EPERM;
 400	if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
 401		return -EFAULT;
 402	if (al_hreq.buflen < sizeof(struct attrlist) ||
 403	    al_hreq.buflen > XFS_XATTR_LIST_MAX)
 404		return -EINVAL;
 405
 406	/*
 407	 * Reject flags, only allow namespaces.
 408	 */
 409	if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE))
 410		return -EINVAL;
 411
 412	dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
 413	if (IS_ERR(dentry))
 414		return PTR_ERR(dentry);
 415
 416	kbuf = kmem_zalloc_large(al_hreq.buflen, KM_SLEEP);
 417	if (!kbuf)
 418		goto out_dput;
 419
 420	cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
 421	error = xfs_attr_list(XFS_I(d_inode(dentry)), kbuf, al_hreq.buflen,
 422					al_hreq.flags, cursor);
 423	if (error)
 424		goto out_kfree;
 425
 426	if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t))) {
 427		error = -EFAULT;
 428		goto out_kfree;
 429	}
 430
 431	if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen))
 432		error = -EFAULT;
 433
 434out_kfree:
 435	kmem_free(kbuf);
 436out_dput:
 437	dput(dentry);
 438	return error;
 439}
 440
 441int
 442xfs_attrmulti_attr_get(
 443	struct inode		*inode,
 444	unsigned char		*name,
 445	unsigned char		__user *ubuf,
 446	uint32_t		*len,
 447	uint32_t		flags)
 448{
 449	unsigned char		*kbuf;
 450	int			error = -EFAULT;
 451
 452	if (*len > XFS_XATTR_SIZE_MAX)
 453		return -EINVAL;
 454	kbuf = kmem_zalloc_large(*len, KM_SLEEP);
 455	if (!kbuf)
 456		return -ENOMEM;
 457
 458	error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags);
 459	if (error)
 460		goto out_kfree;
 461
 462	if (copy_to_user(ubuf, kbuf, *len))
 463		error = -EFAULT;
 464
 465out_kfree:
 466	kmem_free(kbuf);
 467	return error;
 468}
 469
 470int
 471xfs_attrmulti_attr_set(
 472	struct inode		*inode,
 473	unsigned char		*name,
 474	const unsigned char	__user *ubuf,
 475	uint32_t		len,
 476	uint32_t		flags)
 477{
 478	unsigned char		*kbuf;
 479	int			error;
 480
 481	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 482		return -EPERM;
 483	if (len > XFS_XATTR_SIZE_MAX)
 484		return -EINVAL;
 485
 486	kbuf = memdup_user(ubuf, len);
 487	if (IS_ERR(kbuf))
 488		return PTR_ERR(kbuf);
 489
 490	error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags);
 491	if (!error)
 492		xfs_forget_acl(inode, name, flags);
 493	kfree(kbuf);
 494	return error;
 495}
 496
 497int
 498xfs_attrmulti_attr_remove(
 499	struct inode		*inode,
 500	unsigned char		*name,
 501	uint32_t		flags)
 502{
 503	int			error;
 504
 505	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 506		return -EPERM;
 507	error = xfs_attr_remove(XFS_I(inode), name, flags);
 508	if (!error)
 509		xfs_forget_acl(inode, name, flags);
 510	return error;
 511}
 512
 513STATIC int
 514xfs_attrmulti_by_handle(
 515	struct file		*parfilp,
 516	void			__user *arg)
 517{
 518	int			error;
 519	xfs_attr_multiop_t	*ops;
 520	xfs_fsop_attrmulti_handlereq_t am_hreq;
 521	struct dentry		*dentry;
 522	unsigned int		i, size;
 523	unsigned char		*attr_name;
 524
 525	if (!capable(CAP_SYS_ADMIN))
 526		return -EPERM;
 527	if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t)))
 528		return -EFAULT;
 529
 530	/* overflow check */
 531	if (am_hreq.opcount >= INT_MAX / sizeof(xfs_attr_multiop_t))
 532		return -E2BIG;
 533
 534	dentry = xfs_handlereq_to_dentry(parfilp, &am_hreq.hreq);
 535	if (IS_ERR(dentry))
 536		return PTR_ERR(dentry);
 537
 538	error = -E2BIG;
 539	size = am_hreq.opcount * sizeof(xfs_attr_multiop_t);
 540	if (!size || size > 16 * PAGE_SIZE)
 541		goto out_dput;
 542
 543	ops = memdup_user(am_hreq.ops, size);
 544	if (IS_ERR(ops)) {
 545		error = PTR_ERR(ops);
 546		goto out_dput;
 547	}
 548
 549	error = -ENOMEM;
 550	attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL);
 551	if (!attr_name)
 552		goto out_kfree_ops;
 553
 554	error = 0;
 555	for (i = 0; i < am_hreq.opcount; i++) {
 556		ops[i].am_error = strncpy_from_user((char *)attr_name,
 557				ops[i].am_attrname, MAXNAMELEN);
 558		if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN)
 559			error = -ERANGE;
 560		if (ops[i].am_error < 0)
 561			break;
 562
 563		switch (ops[i].am_opcode) {
 564		case ATTR_OP_GET:
 565			ops[i].am_error = xfs_attrmulti_attr_get(
 566					d_inode(dentry), attr_name,
 567					ops[i].am_attrvalue, &ops[i].am_length,
 568					ops[i].am_flags);
 569			break;
 570		case ATTR_OP_SET:
 571			ops[i].am_error = mnt_want_write_file(parfilp);
 572			if (ops[i].am_error)
 573				break;
 574			ops[i].am_error = xfs_attrmulti_attr_set(
 575					d_inode(dentry), attr_name,
 576					ops[i].am_attrvalue, ops[i].am_length,
 577					ops[i].am_flags);
 578			mnt_drop_write_file(parfilp);
 579			break;
 580		case ATTR_OP_REMOVE:
 581			ops[i].am_error = mnt_want_write_file(parfilp);
 582			if (ops[i].am_error)
 583				break;
 584			ops[i].am_error = xfs_attrmulti_attr_remove(
 585					d_inode(dentry), attr_name,
 586					ops[i].am_flags);
 587			mnt_drop_write_file(parfilp);
 588			break;
 589		default:
 590			ops[i].am_error = -EINVAL;
 591		}
 592	}
 593
 594	if (copy_to_user(am_hreq.ops, ops, size))
 595		error = -EFAULT;
 596
 597	kfree(attr_name);
 598 out_kfree_ops:
 599	kfree(ops);
 600 out_dput:
 601	dput(dentry);
 602	return error;
 603}
 604
 605int
 606xfs_ioc_space(
 607	struct file		*filp,
 608	unsigned int		cmd,
 609	xfs_flock64_t		*bf)
 610{
 611	struct inode		*inode = file_inode(filp);
 612	struct xfs_inode	*ip = XFS_I(inode);
 613	struct iattr		iattr;
 614	enum xfs_prealloc_flags	flags = 0;
 615	uint			iolock = XFS_IOLOCK_EXCL;
 616	int			error;
 617
 618	/*
 619	 * Only allow the sys admin to reserve space unless
 620	 * unwritten extents are enabled.
 621	 */
 622	if (!xfs_sb_version_hasextflgbit(&ip->i_mount->m_sb) &&
 623	    !capable(CAP_SYS_ADMIN))
 624		return -EPERM;
 625
 626	if (inode->i_flags & (S_IMMUTABLE|S_APPEND))
 627		return -EPERM;
 628
 629	if (!(filp->f_mode & FMODE_WRITE))
 630		return -EBADF;
 631
 632	if (!S_ISREG(inode->i_mode))
 633		return -EINVAL;
 634
 635	if (filp->f_flags & O_DSYNC)
 636		flags |= XFS_PREALLOC_SYNC;
 637	if (filp->f_mode & FMODE_NOCMTIME)
 638		flags |= XFS_PREALLOC_INVISIBLE;
 639
 640	error = mnt_want_write_file(filp);
 641	if (error)
 642		return error;
 643
 644	xfs_ilock(ip, iolock);
 645	error = xfs_break_layouts(inode, &iolock);
 646	if (error)
 647		goto out_unlock;
 648
 649	xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
 650	iolock |= XFS_MMAPLOCK_EXCL;
 651
 652	switch (bf->l_whence) {
 653	case 0: /*SEEK_SET*/
 654		break;
 655	case 1: /*SEEK_CUR*/
 656		bf->l_start += filp->f_pos;
 657		break;
 658	case 2: /*SEEK_END*/
 659		bf->l_start += XFS_ISIZE(ip);
 660		break;
 661	default:
 662		error = -EINVAL;
 663		goto out_unlock;
 664	}
 665
 666	/*
 667	 * length of <= 0 for resv/unresv/zero is invalid.  length for
 668	 * alloc/free is ignored completely and we have no idea what userspace
 669	 * might have set it to, so set it to zero to allow range
 670	 * checks to pass.
 671	 */
 672	switch (cmd) {
 673	case XFS_IOC_ZERO_RANGE:
 674	case XFS_IOC_RESVSP:
 675	case XFS_IOC_RESVSP64:
 676	case XFS_IOC_UNRESVSP:
 677	case XFS_IOC_UNRESVSP64:
 678		if (bf->l_len <= 0) {
 679			error = -EINVAL;
 680			goto out_unlock;
 681		}
 682		break;
 683	default:
 684		bf->l_len = 0;
 685		break;
 686	}
 687
 688	if (bf->l_start < 0 ||
 689	    bf->l_start > inode->i_sb->s_maxbytes ||
 690	    bf->l_start + bf->l_len < 0 ||
 691	    bf->l_start + bf->l_len >= inode->i_sb->s_maxbytes) {
 692		error = -EINVAL;
 693		goto out_unlock;
 694	}
 695
 696	switch (cmd) {
 697	case XFS_IOC_ZERO_RANGE:
 698		flags |= XFS_PREALLOC_SET;
 699		error = xfs_zero_file_space(ip, bf->l_start, bf->l_len);
 700		break;
 701	case XFS_IOC_RESVSP:
 702	case XFS_IOC_RESVSP64:
 703		flags |= XFS_PREALLOC_SET;
 704		error = xfs_alloc_file_space(ip, bf->l_start, bf->l_len,
 705						XFS_BMAPI_PREALLOC);
 706		break;
 707	case XFS_IOC_UNRESVSP:
 708	case XFS_IOC_UNRESVSP64:
 709		error = xfs_free_file_space(ip, bf->l_start, bf->l_len);
 710		break;
 711	case XFS_IOC_ALLOCSP:
 712	case XFS_IOC_ALLOCSP64:
 713	case XFS_IOC_FREESP:
 714	case XFS_IOC_FREESP64:
 715		flags |= XFS_PREALLOC_CLEAR;
 716		if (bf->l_start > XFS_ISIZE(ip)) {
 717			error = xfs_alloc_file_space(ip, XFS_ISIZE(ip),
 718					bf->l_start - XFS_ISIZE(ip), 0);
 719			if (error)
 720				goto out_unlock;
 721		}
 722
 723		iattr.ia_valid = ATTR_SIZE;
 724		iattr.ia_size = bf->l_start;
 725
 726		error = xfs_vn_setattr_size(file_dentry(filp), &iattr);
 727		break;
 728	default:
 729		ASSERT(0);
 730		error = -EINVAL;
 731	}
 732
 733	if (error)
 734		goto out_unlock;
 735
 736	error = xfs_update_prealloc_flags(ip, flags);
 737
 738out_unlock:
 739	xfs_iunlock(ip, iolock);
 740	mnt_drop_write_file(filp);
 741	return error;
 742}
 743
 744STATIC int
 745xfs_ioc_bulkstat(
 746	xfs_mount_t		*mp,
 747	unsigned int		cmd,
 748	void			__user *arg)
 749{
 750	xfs_fsop_bulkreq_t	bulkreq;
 751	int			count;	/* # of records returned */
 752	xfs_ino_t		inlast;	/* last inode number */
 753	int			done;
 754	int			error;
 755
 756	/* done = 1 if there are more stats to get and if bulkstat */
 757	/* should be called again (unused here, but used in dmapi) */
 758
 759	if (!capable(CAP_SYS_ADMIN))
 760		return -EPERM;
 761
 762	if (XFS_FORCED_SHUTDOWN(mp))
 763		return -EIO;
 764
 765	if (copy_from_user(&bulkreq, arg, sizeof(xfs_fsop_bulkreq_t)))
 766		return -EFAULT;
 767
 768	if (copy_from_user(&inlast, bulkreq.lastip, sizeof(__s64)))
 769		return -EFAULT;
 770
 771	if ((count = bulkreq.icount) <= 0)
 772		return -EINVAL;
 773
 774	if (bulkreq.ubuffer == NULL)
 775		return -EINVAL;
 776
 777	if (cmd == XFS_IOC_FSINUMBERS)
 778		error = xfs_inumbers(mp, &inlast, &count,
 779					bulkreq.ubuffer, xfs_inumbers_fmt);
 780	else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE)
 781		error = xfs_bulkstat_one(mp, inlast, bulkreq.ubuffer,
 782					sizeof(xfs_bstat_t), NULL, &done);
 783	else	/* XFS_IOC_FSBULKSTAT */
 784		error = xfs_bulkstat(mp, &inlast, &count, xfs_bulkstat_one,
 785				     sizeof(xfs_bstat_t), bulkreq.ubuffer,
 786				     &done);
 787
 788	if (error)
 789		return error;
 790
 791	if (bulkreq.ocount != NULL) {
 792		if (copy_to_user(bulkreq.lastip, &inlast,
 793						sizeof(xfs_ino_t)))
 794			return -EFAULT;
 795
 796		if (copy_to_user(bulkreq.ocount, &count, sizeof(count)))
 797			return -EFAULT;
 798	}
 799
 800	return 0;
 801}
 802
 803STATIC int
 804xfs_ioc_fsgeometry_v1(
 805	xfs_mount_t		*mp,
 806	void			__user *arg)
 807{
 808	xfs_fsop_geom_t         fsgeo;
 809	int			error;
 810
 811	error = xfs_fs_geometry(mp, &fsgeo, 3);
 812	if (error)
 813		return error;
 814
 815	/*
 816	 * Caller should have passed an argument of type
 817	 * xfs_fsop_geom_v1_t.  This is a proper subset of the
 818	 * xfs_fsop_geom_t that xfs_fs_geometry() fills in.
 819	 */
 820	if (copy_to_user(arg, &fsgeo, sizeof(xfs_fsop_geom_v1_t)))
 821		return -EFAULT;
 822	return 0;
 823}
 824
 825STATIC int
 826xfs_ioc_fsgeometry(
 827	xfs_mount_t		*mp,
 828	void			__user *arg)
 829{
 830	xfs_fsop_geom_t		fsgeo;
 831	int			error;
 832
 833	error = xfs_fs_geometry(mp, &fsgeo, 4);
 834	if (error)
 835		return error;
 836
 837	if (copy_to_user(arg, &fsgeo, sizeof(fsgeo)))
 838		return -EFAULT;
 839	return 0;
 840}
 841
 842/*
 843 * Linux extended inode flags interface.
 844 */
 845
 846STATIC unsigned int
 847xfs_merge_ioc_xflags(
 848	unsigned int	flags,
 849	unsigned int	start)
 850{
 851	unsigned int	xflags = start;
 852
 853	if (flags & FS_IMMUTABLE_FL)
 854		xflags |= FS_XFLAG_IMMUTABLE;
 855	else
 856		xflags &= ~FS_XFLAG_IMMUTABLE;
 857	if (flags & FS_APPEND_FL)
 858		xflags |= FS_XFLAG_APPEND;
 859	else
 860		xflags &= ~FS_XFLAG_APPEND;
 861	if (flags & FS_SYNC_FL)
 862		xflags |= FS_XFLAG_SYNC;
 863	else
 864		xflags &= ~FS_XFLAG_SYNC;
 865	if (flags & FS_NOATIME_FL)
 866		xflags |= FS_XFLAG_NOATIME;
 867	else
 868		xflags &= ~FS_XFLAG_NOATIME;
 869	if (flags & FS_NODUMP_FL)
 870		xflags |= FS_XFLAG_NODUMP;
 871	else
 872		xflags &= ~FS_XFLAG_NODUMP;
 873
 874	return xflags;
 875}
 876
 877STATIC unsigned int
 878xfs_di2lxflags(
 879	uint16_t	di_flags)
 880{
 881	unsigned int	flags = 0;
 882
 883	if (di_flags & XFS_DIFLAG_IMMUTABLE)
 884		flags |= FS_IMMUTABLE_FL;
 885	if (di_flags & XFS_DIFLAG_APPEND)
 886		flags |= FS_APPEND_FL;
 887	if (di_flags & XFS_DIFLAG_SYNC)
 888		flags |= FS_SYNC_FL;
 889	if (di_flags & XFS_DIFLAG_NOATIME)
 890		flags |= FS_NOATIME_FL;
 891	if (di_flags & XFS_DIFLAG_NODUMP)
 892		flags |= FS_NODUMP_FL;
 893	return flags;
 894}
 895
 896STATIC int
 897xfs_ioc_fsgetxattr(
 898	xfs_inode_t		*ip,
 899	int			attr,
 900	void			__user *arg)
 901{
 902	struct fsxattr		fa;
 903
 904	memset(&fa, 0, sizeof(struct fsxattr));
 905
 906	xfs_ilock(ip, XFS_ILOCK_SHARED);
 907	fa.fsx_xflags = xfs_ip2xflags(ip);
 908	fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog;
 909	fa.fsx_cowextsize = ip->i_d.di_cowextsize <<
 910			ip->i_mount->m_sb.sb_blocklog;
 911	fa.fsx_projid = xfs_get_projid(ip);
 912
 913	if (attr) {
 914		if (ip->i_afp) {
 915			if (ip->i_afp->if_flags & XFS_IFEXTENTS)
 916				fa.fsx_nextents = xfs_iext_count(ip->i_afp);
 917			else
 918				fa.fsx_nextents = ip->i_d.di_anextents;
 919		} else
 920			fa.fsx_nextents = 0;
 921	} else {
 922		if (ip->i_df.if_flags & XFS_IFEXTENTS)
 923			fa.fsx_nextents = xfs_iext_count(&ip->i_df);
 924		else
 925			fa.fsx_nextents = ip->i_d.di_nextents;
 926	}
 927	xfs_iunlock(ip, XFS_ILOCK_SHARED);
 928
 929	if (copy_to_user(arg, &fa, sizeof(fa)))
 930		return -EFAULT;
 931	return 0;
 932}
 933
 934STATIC void
 935xfs_set_diflags(
 936	struct xfs_inode	*ip,
 937	unsigned int		xflags)
 938{
 939	unsigned int		di_flags;
 940	uint64_t		di_flags2;
 941
 942	/* can't set PREALLOC this way, just preserve it */
 943	di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
 944	if (xflags & FS_XFLAG_IMMUTABLE)
 945		di_flags |= XFS_DIFLAG_IMMUTABLE;
 946	if (xflags & FS_XFLAG_APPEND)
 947		di_flags |= XFS_DIFLAG_APPEND;
 948	if (xflags & FS_XFLAG_SYNC)
 949		di_flags |= XFS_DIFLAG_SYNC;
 950	if (xflags & FS_XFLAG_NOATIME)
 951		di_flags |= XFS_DIFLAG_NOATIME;
 952	if (xflags & FS_XFLAG_NODUMP)
 953		di_flags |= XFS_DIFLAG_NODUMP;
 954	if (xflags & FS_XFLAG_NODEFRAG)
 955		di_flags |= XFS_DIFLAG_NODEFRAG;
 956	if (xflags & FS_XFLAG_FILESTREAM)
 957		di_flags |= XFS_DIFLAG_FILESTREAM;
 958	if (S_ISDIR(VFS_I(ip)->i_mode)) {
 959		if (xflags & FS_XFLAG_RTINHERIT)
 960			di_flags |= XFS_DIFLAG_RTINHERIT;
 961		if (xflags & FS_XFLAG_NOSYMLINKS)
 962			di_flags |= XFS_DIFLAG_NOSYMLINKS;
 963		if (xflags & FS_XFLAG_EXTSZINHERIT)
 964			di_flags |= XFS_DIFLAG_EXTSZINHERIT;
 965		if (xflags & FS_XFLAG_PROJINHERIT)
 966			di_flags |= XFS_DIFLAG_PROJINHERIT;
 967	} else if (S_ISREG(VFS_I(ip)->i_mode)) {
 968		if (xflags & FS_XFLAG_REALTIME)
 969			di_flags |= XFS_DIFLAG_REALTIME;
 970		if (xflags & FS_XFLAG_EXTSIZE)
 971			di_flags |= XFS_DIFLAG_EXTSIZE;
 972	}
 973	ip->i_d.di_flags = di_flags;
 974
 975	/* diflags2 only valid for v3 inodes. */
 976	if (ip->i_d.di_version < 3)
 977		return;
 978
 979	di_flags2 = (ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK);
 980	if (xflags & FS_XFLAG_DAX)
 981		di_flags2 |= XFS_DIFLAG2_DAX;
 982	if (xflags & FS_XFLAG_COWEXTSIZE)
 983		di_flags2 |= XFS_DIFLAG2_COWEXTSIZE;
 984
 985	ip->i_d.di_flags2 = di_flags2;
 986}
 987
 988STATIC void
 989xfs_diflags_to_linux(
 990	struct xfs_inode	*ip)
 991{
 992	struct inode		*inode = VFS_I(ip);
 993	unsigned int		xflags = xfs_ip2xflags(ip);
 994
 995	if (xflags & FS_XFLAG_IMMUTABLE)
 996		inode->i_flags |= S_IMMUTABLE;
 997	else
 998		inode->i_flags &= ~S_IMMUTABLE;
 999	if (xflags & FS_XFLAG_APPEND)
1000		inode->i_flags |= S_APPEND;
1001	else
1002		inode->i_flags &= ~S_APPEND;
1003	if (xflags & FS_XFLAG_SYNC)
1004		inode->i_flags |= S_SYNC;
1005	else
1006		inode->i_flags &= ~S_SYNC;
1007	if (xflags & FS_XFLAG_NOATIME)
1008		inode->i_flags |= S_NOATIME;
1009	else
1010		inode->i_flags &= ~S_NOATIME;
1011	if (xflags & FS_XFLAG_DAX)
1012		inode->i_flags |= S_DAX;
1013	else
1014		inode->i_flags &= ~S_DAX;
1015
1016}
1017
1018static int
1019xfs_ioctl_setattr_xflags(
1020	struct xfs_trans	*tp,
1021	struct xfs_inode	*ip,
1022	struct fsxattr		*fa)
1023{
1024	struct xfs_mount	*mp = ip->i_mount;
1025
1026	/* Can't change realtime flag if any extents are allocated. */
1027	if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
1028	    XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & FS_XFLAG_REALTIME))
1029		return -EINVAL;
1030
1031	/* If realtime flag is set then must have realtime device */
1032	if (fa->fsx_xflags & FS_XFLAG_REALTIME) {
1033		if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||
1034		    (ip->i_d.di_extsize % mp->m_sb.sb_rextsize))
1035			return -EINVAL;
1036	}
1037
1038	/* Clear reflink if we are actually able to set the rt flag. */
1039	if ((fa->fsx_xflags & FS_XFLAG_REALTIME) && xfs_is_reflink_inode(ip))
1040		ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
1041
1042	/* Don't allow us to set DAX mode for a reflinked file for now. */
1043	if ((fa->fsx_xflags & FS_XFLAG_DAX) && xfs_is_reflink_inode(ip))
1044		return -EINVAL;
1045
1046	/*
1047	 * Can't modify an immutable/append-only file unless
1048	 * we have appropriate permission.
1049	 */
1050	if (((ip->i_d.di_flags & (XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND)) ||
1051	     (fa->fsx_xflags & (FS_XFLAG_IMMUTABLE | FS_XFLAG_APPEND))) &&
1052	    !capable(CAP_LINUX_IMMUTABLE))
1053		return -EPERM;
1054
1055	xfs_set_diflags(ip, fa->fsx_xflags);
1056	xfs_diflags_to_linux(ip);
1057	xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
1058	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1059	XFS_STATS_INC(mp, xs_ig_attrchg);
1060	return 0;
1061}
1062
1063/*
1064 * If we are changing DAX flags, we have to ensure the file is clean and any
1065 * cached objects in the address space are invalidated and removed. This
1066 * requires us to lock out other IO and page faults similar to a truncate
1067 * operation. The locks need to be held until the transaction has been committed
1068 * so that the cache invalidation is atomic with respect to the DAX flag
1069 * manipulation.
1070 */
1071static int
1072xfs_ioctl_setattr_dax_invalidate(
1073	struct xfs_inode	*ip,
1074	struct fsxattr		*fa,
1075	int			*join_flags)
1076{
1077	struct inode		*inode = VFS_I(ip);
1078	int			error;
1079
1080	*join_flags = 0;
1081
1082	/*
1083	 * It is only valid to set the DAX flag on regular files and
1084	 * directories on filesystems where the block size is equal to the page
1085	 * size. On directories it serves as an inherit hint.
1086	 */
1087	if (fa->fsx_xflags & FS_XFLAG_DAX) {
1088		if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
1089			return -EINVAL;
1090		if (ip->i_mount->m_sb.sb_blocksize != PAGE_SIZE)
1091			return -EINVAL;
1092	}
1093
1094	/* If the DAX state is not changing, we have nothing to do here. */
1095	if ((fa->fsx_xflags & FS_XFLAG_DAX) && IS_DAX(inode))
1096		return 0;
1097	if (!(fa->fsx_xflags & FS_XFLAG_DAX) && !IS_DAX(inode))
1098		return 0;
1099
1100	/* lock, flush and invalidate mapping in preparation for flag change */
1101	xfs_ilock(ip, XFS_MMAPLOCK_EXCL | XFS_IOLOCK_EXCL);
1102	error = filemap_write_and_wait(inode->i_mapping);
1103	if (error)
1104		goto out_unlock;
1105	error = invalidate_inode_pages2(inode->i_mapping);
1106	if (error)
1107		goto out_unlock;
1108
1109	*join_flags = XFS_MMAPLOCK_EXCL | XFS_IOLOCK_EXCL;
1110	return 0;
1111
1112out_unlock:
1113	xfs_iunlock(ip, XFS_MMAPLOCK_EXCL | XFS_IOLOCK_EXCL);
1114	return error;
1115
1116}
1117
1118/*
1119 * Set up the transaction structure for the setattr operation, checking that we
1120 * have permission to do so. On success, return a clean transaction and the
1121 * inode locked exclusively ready for further operation specific checks. On
1122 * failure, return an error without modifying or locking the inode.
1123 *
1124 * The inode might already be IO locked on call. If this is the case, it is
1125 * indicated in @join_flags and we take full responsibility for ensuring they
1126 * are unlocked from now on. Hence if we have an error here, we still have to
1127 * unlock them. Otherwise, once they are joined to the transaction, they will
1128 * be unlocked on commit/cancel.
1129 */
1130static struct xfs_trans *
1131xfs_ioctl_setattr_get_trans(
1132	struct xfs_inode	*ip,
1133	int			join_flags)
1134{
1135	struct xfs_mount	*mp = ip->i_mount;
1136	struct xfs_trans	*tp;
1137	int			error = -EROFS;
1138
1139	if (mp->m_flags & XFS_MOUNT_RDONLY)
1140		goto out_unlock;
1141	error = -EIO;
1142	if (XFS_FORCED_SHUTDOWN(mp))
1143		goto out_unlock;
1144
1145	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
1146	if (error)
1147		return ERR_PTR(error);
1148
1149	xfs_ilock(ip, XFS_ILOCK_EXCL);
1150	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | join_flags);
1151	join_flags = 0;
1152
1153	/*
1154	 * CAP_FOWNER overrides the following restrictions:
1155	 *
1156	 * The user ID of the calling process must be equal to the file owner
1157	 * ID, except in cases where the CAP_FSETID capability is applicable.
1158	 */
1159	if (!inode_owner_or_capable(VFS_I(ip))) {
1160		error = -EPERM;
1161		goto out_cancel;
1162	}
1163
1164	if (mp->m_flags & XFS_MOUNT_WSYNC)
1165		xfs_trans_set_sync(tp);
1166
1167	return tp;
1168
1169out_cancel:
1170	xfs_trans_cancel(tp);
1171out_unlock:
1172	if (join_flags)
1173		xfs_iunlock(ip, join_flags);
1174	return ERR_PTR(error);
1175}
1176
1177/*
1178 * extent size hint validation is somewhat cumbersome. Rules are:
1179 *
1180 * 1. extent size hint is only valid for directories and regular files
1181 * 2. FS_XFLAG_EXTSIZE is only valid for regular files
1182 * 3. FS_XFLAG_EXTSZINHERIT is only valid for directories.
1183 * 4. can only be changed on regular files if no extents are allocated
1184 * 5. can be changed on directories at any time
1185 * 6. extsize hint of 0 turns off hints, clears inode flags.
1186 * 7. Extent size must be a multiple of the appropriate block size.
1187 * 8. for non-realtime files, the extent size hint must be limited
1188 *    to half the AG size to avoid alignment extending the extent beyond the
1189 *    limits of the AG.
1190 */
1191static int
1192xfs_ioctl_setattr_check_extsize(
1193	struct xfs_inode	*ip,
1194	struct fsxattr		*fa)
1195{
1196	struct xfs_mount	*mp = ip->i_mount;
1197
1198	if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(VFS_I(ip)->i_mode))
1199		return -EINVAL;
1200
1201	if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) &&
1202	    !S_ISDIR(VFS_I(ip)->i_mode))
1203		return -EINVAL;
1204
1205	if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_d.di_nextents &&
1206	    ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize))
1207		return -EINVAL;
1208
1209	if (fa->fsx_extsize != 0) {
1210		xfs_extlen_t    size;
1211		xfs_fsblock_t   extsize_fsb;
1212
1213		extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize);
1214		if (extsize_fsb > MAXEXTLEN)
1215			return -EINVAL;
1216
1217		if (XFS_IS_REALTIME_INODE(ip) ||
1218		    (fa->fsx_xflags & FS_XFLAG_REALTIME)) {
1219			size = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog;
1220		} else {
1221			size = mp->m_sb.sb_blocksize;
1222			if (extsize_fsb > mp->m_sb.sb_agblocks / 2)
1223				return -EINVAL;
1224		}
1225
1226		if (fa->fsx_extsize % size)
1227			return -EINVAL;
1228	} else
1229		fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT);
1230
1231	return 0;
1232}
1233
1234/*
1235 * CoW extent size hint validation rules are:
1236 *
1237 * 1. CoW extent size hint can only be set if reflink is enabled on the fs.
1238 *    The inode does not have to have any shared blocks, but it must be a v3.
1239 * 2. FS_XFLAG_COWEXTSIZE is only valid for directories and regular files;
1240 *    for a directory, the hint is propagated to new files.
1241 * 3. Can be changed on files & directories at any time.
1242 * 4. CoW extsize hint of 0 turns off hints, clears inode flags.
1243 * 5. Extent size must be a multiple of the appropriate block size.
1244 * 6. The extent size hint must be limited to half the AG size to avoid
1245 *    alignment extending the extent beyond the limits of the AG.
1246 */
1247static int
1248xfs_ioctl_setattr_check_cowextsize(
1249	struct xfs_inode	*ip,
1250	struct fsxattr		*fa)
1251{
1252	struct xfs_mount	*mp = ip->i_mount;
1253
1254	if (!(fa->fsx_xflags & FS_XFLAG_COWEXTSIZE))
1255		return 0;
1256
1257	if (!xfs_sb_version_hasreflink(&ip->i_mount->m_sb) ||
1258	    ip->i_d.di_version != 3)
1259		return -EINVAL;
1260
1261	if (!S_ISREG(VFS_I(ip)->i_mode) && !S_ISDIR(VFS_I(ip)->i_mode))
1262		return -EINVAL;
1263
1264	if (fa->fsx_cowextsize != 0) {
1265		xfs_extlen_t    size;
1266		xfs_fsblock_t   cowextsize_fsb;
1267
1268		cowextsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_cowextsize);
1269		if (cowextsize_fsb > MAXEXTLEN)
1270			return -EINVAL;
1271
1272		size = mp->m_sb.sb_blocksize;
1273		if (cowextsize_fsb > mp->m_sb.sb_agblocks / 2)
1274			return -EINVAL;
1275
1276		if (fa->fsx_cowextsize % size)
1277			return -EINVAL;
1278	} else
1279		fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE;
1280
1281	return 0;
1282}
1283
1284static int
1285xfs_ioctl_setattr_check_projid(
1286	struct xfs_inode	*ip,
1287	struct fsxattr		*fa)
1288{
1289	/* Disallow 32bit project ids if projid32bit feature is not enabled. */
1290	if (fa->fsx_projid > (uint16_t)-1 &&
1291	    !xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb))
1292		return -EINVAL;
1293
1294	/*
1295	 * Project Quota ID state is only allowed to change from within the init
1296	 * namespace. Enforce that restriction only if we are trying to change
1297	 * the quota ID state. Everything else is allowed in user namespaces.
1298	 */
1299	if (current_user_ns() == &init_user_ns)
1300		return 0;
1301
1302	if (xfs_get_projid(ip) != fa->fsx_projid)
1303		return -EINVAL;
1304	if ((fa->fsx_xflags & FS_XFLAG_PROJINHERIT) !=
1305	    (ip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT))
1306		return -EINVAL;
1307
1308	return 0;
1309}
1310
1311STATIC int
1312xfs_ioctl_setattr(
1313	xfs_inode_t		*ip,
1314	struct fsxattr		*fa)
1315{
1316	struct xfs_mount	*mp = ip->i_mount;
1317	struct xfs_trans	*tp;
1318	struct xfs_dquot	*udqp = NULL;
1319	struct xfs_dquot	*pdqp = NULL;
1320	struct xfs_dquot	*olddquot = NULL;
1321	int			code;
1322	int			join_flags = 0;
1323
1324	trace_xfs_ioctl_setattr(ip);
1325
1326	code = xfs_ioctl_setattr_check_projid(ip, fa);
1327	if (code)
1328		return code;
1329
1330	/*
1331	 * If disk quotas is on, we make sure that the dquots do exist on disk,
1332	 * before we start any other transactions. Trying to do this later
1333	 * is messy. We don't care to take a readlock to look at the ids
1334	 * in inode here, because we can't hold it across the trans_reserve.
1335	 * If the IDs do change before we take the ilock, we're covered
1336	 * because the i_*dquot fields will get updated anyway.
1337	 */
1338	if (XFS_IS_QUOTA_ON(mp)) {
1339		code = xfs_qm_vop_dqalloc(ip, ip->i_d.di_uid,
1340					 ip->i_d.di_gid, fa->fsx_projid,
1341					 XFS_QMOPT_PQUOTA, &udqp, NULL, &pdqp);
1342		if (code)
1343			return code;
1344	}
1345
1346	/*
1347	 * Changing DAX config may require inode locking for mapping
1348	 * invalidation. These need to be held all the way to transaction commit
1349	 * or cancel time, so need to be passed through to
1350	 * xfs_ioctl_setattr_get_trans() so it can apply them to the join call
1351	 * appropriately.
1352	 */
1353	code = xfs_ioctl_setattr_dax_invalidate(ip, fa, &join_flags);
1354	if (code)
1355		goto error_free_dquots;
1356
1357	tp = xfs_ioctl_setattr_get_trans(ip, join_flags);
1358	if (IS_ERR(tp)) {
1359		code = PTR_ERR(tp);
1360		goto error_free_dquots;
1361	}
1362
1363
1364	if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp) &&
1365	    xfs_get_projid(ip) != fa->fsx_projid) {
1366		code = xfs_qm_vop_chown_reserve(tp, ip, udqp, NULL, pdqp,
1367				capable(CAP_FOWNER) ?  XFS_QMOPT_FORCE_RES : 0);
1368		if (code)	/* out of quota */
1369			goto error_trans_cancel;
1370	}
1371
1372	code = xfs_ioctl_setattr_check_extsize(ip, fa);
1373	if (code)
1374		goto error_trans_cancel;
1375
1376	code = xfs_ioctl_setattr_check_cowextsize(ip, fa);
1377	if (code)
1378		goto error_trans_cancel;
1379
1380	code = xfs_ioctl_setattr_xflags(tp, ip, fa);
1381	if (code)
1382		goto error_trans_cancel;
1383
1384	/*
1385	 * Change file ownership.  Must be the owner or privileged.  CAP_FSETID
1386	 * overrides the following restrictions:
1387	 *
1388	 * The set-user-ID and set-group-ID bits of a file will be cleared upon
1389	 * successful return from chown()
1390	 */
1391
1392	if ((VFS_I(ip)->i_mode & (S_ISUID|S_ISGID)) &&
1393	    !capable_wrt_inode_uidgid(VFS_I(ip), CAP_FSETID))
1394		VFS_I(ip)->i_mode &= ~(S_ISUID|S_ISGID);
1395
1396	/* Change the ownerships and register project quota modifications */
1397	if (xfs_get_projid(ip) != fa->fsx_projid) {
1398		if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
1399			olddquot = xfs_qm_vop_chown(tp, ip,
1400						&ip->i_pdquot, pdqp);
1401		}
1402		ASSERT(ip->i_d.di_version > 1);
1403		xfs_set_projid(ip, fa->fsx_projid);
1404	}
1405
1406	/*
1407	 * Only set the extent size hint if we've already determined that the
1408	 * extent size hint should be set on the inode. If no extent size flags
1409	 * are set on the inode then unconditionally clear the extent size hint.
1410	 */
1411	if (ip->i_d.di_flags & (XFS_DIFLAG_EXTSIZE | XFS_DIFLAG_EXTSZINHERIT))
1412		ip->i_d.di_extsize = fa->fsx_extsize >> mp->m_sb.sb_blocklog;
1413	else
1414		ip->i_d.di_extsize = 0;
1415	if (ip->i_d.di_version == 3 &&
1416	    (ip->i_d.di_flags2 & XFS_DIFLAG2_COWEXTSIZE))
1417		ip->i_d.di_cowextsize = fa->fsx_cowextsize >>
1418				mp->m_sb.sb_blocklog;
1419	else
1420		ip->i_d.di_cowextsize = 0;
1421
1422	code = xfs_trans_commit(tp);
1423
1424	/*
1425	 * Release any dquot(s) the inode had kept before chown.
1426	 */
1427	xfs_qm_dqrele(olddquot);
1428	xfs_qm_dqrele(udqp);
1429	xfs_qm_dqrele(pdqp);
1430
1431	return code;
1432
1433error_trans_cancel:
1434	xfs_trans_cancel(tp);
1435error_free_dquots:
1436	xfs_qm_dqrele(udqp);
1437	xfs_qm_dqrele(pdqp);
1438	return code;
1439}
1440
1441STATIC int
1442xfs_ioc_fssetxattr(
1443	xfs_inode_t		*ip,
1444	struct file		*filp,
1445	void			__user *arg)
1446{
1447	struct fsxattr		fa;
1448	int error;
1449
1450	if (copy_from_user(&fa, arg, sizeof(fa)))
1451		return -EFAULT;
1452
1453	error = mnt_want_write_file(filp);
1454	if (error)
1455		return error;
1456	error = xfs_ioctl_setattr(ip, &fa);
1457	mnt_drop_write_file(filp);
1458	return error;
1459}
1460
1461STATIC int
1462xfs_ioc_getxflags(
1463	xfs_inode_t		*ip,
1464	void			__user *arg)
1465{
1466	unsigned int		flags;
1467
1468	flags = xfs_di2lxflags(ip->i_d.di_flags);
1469	if (copy_to_user(arg, &flags, sizeof(flags)))
1470		return -EFAULT;
1471	return 0;
1472}
1473
1474STATIC int
1475xfs_ioc_setxflags(
1476	struct xfs_inode	*ip,
1477	struct file		*filp,
1478	void			__user *arg)
1479{
1480	struct xfs_trans	*tp;
1481	struct fsxattr		fa;
1482	unsigned int		flags;
1483	int			join_flags = 0;
1484	int			error;
1485
1486	if (copy_from_user(&flags, arg, sizeof(flags)))
1487		return -EFAULT;
1488
1489	if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \
1490		      FS_NOATIME_FL | FS_NODUMP_FL | \
1491		      FS_SYNC_FL))
1492		return -EOPNOTSUPP;
1493
1494	fa.fsx_xflags = xfs_merge_ioc_xflags(flags, xfs_ip2xflags(ip));
1495
1496	error = mnt_want_write_file(filp);
1497	if (error)
1498		return error;
1499
1500	/*
1501	 * Changing DAX config may require inode locking for mapping
1502	 * invalidation. These need to be held all the way to transaction commit
1503	 * or cancel time, so need to be passed through to
1504	 * xfs_ioctl_setattr_get_trans() so it can apply them to the join call
1505	 * appropriately.
1506	 */
1507	error = xfs_ioctl_setattr_dax_invalidate(ip, &fa, &join_flags);
1508	if (error)
1509		goto out_drop_write;
1510
1511	tp = xfs_ioctl_setattr_get_trans(ip, join_flags);
1512	if (IS_ERR(tp)) {
1513		error = PTR_ERR(tp);
1514		goto out_drop_write;
1515	}
1516
1517	error = xfs_ioctl_setattr_xflags(tp, ip, &fa);
1518	if (error) {
1519		xfs_trans_cancel(tp);
1520		goto out_drop_write;
1521	}
1522
1523	error = xfs_trans_commit(tp);
1524out_drop_write:
1525	mnt_drop_write_file(filp);
1526	return error;
1527}
1528
1529STATIC int
1530xfs_getbmap_format(void **ap, struct getbmapx *bmv)
1531{
1532	struct getbmap __user	*base = (struct getbmap __user *)*ap;
1533
1534	/* copy only getbmap portion (not getbmapx) */
1535	if (copy_to_user(base, bmv, sizeof(struct getbmap)))
1536		return -EFAULT;
1537
1538	*ap += sizeof(struct getbmap);
1539	return 0;
1540}
1541
1542STATIC int
1543xfs_ioc_getbmap(
1544	struct file		*file,
1545	unsigned int		cmd,
1546	void			__user *arg)
1547{
1548	struct getbmapx		bmx = { 0 };
1549	int			error;
1550
1551	/* struct getbmap is a strict subset of struct getbmapx. */
1552	if (copy_from_user(&bmx, arg, offsetof(struct getbmapx, bmv_iflags)))
1553		return -EFAULT;
1554
1555	if (bmx.bmv_count < 2)
1556		return -EINVAL;
1557
1558	bmx.bmv_iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0);
1559	if (file->f_mode & FMODE_NOCMTIME)
1560		bmx.bmv_iflags |= BMV_IF_NO_DMAPI_READ;
1561
1562	error = xfs_getbmap(XFS_I(file_inode(file)), &bmx, xfs_getbmap_format,
1563			    (__force struct getbmap *)arg+1);
1564	if (error)
1565		return error;
1566
1567	/* copy back header - only size of getbmap */
1568	if (copy_to_user(arg, &bmx, sizeof(struct getbmap)))
1569		return -EFAULT;
1570	return 0;
1571}
1572
1573STATIC int
1574xfs_getbmapx_format(void **ap, struct getbmapx *bmv)
1575{
1576	struct getbmapx __user	*base = (struct getbmapx __user *)*ap;
1577
1578	if (copy_to_user(base, bmv, sizeof(struct getbmapx)))
1579		return -EFAULT;
1580
1581	*ap += sizeof(struct getbmapx);
1582	return 0;
1583}
1584
1585STATIC int
1586xfs_ioc_getbmapx(
1587	struct xfs_inode	*ip,
1588	void			__user *arg)
1589{
1590	struct getbmapx		bmx;
1591	int			error;
1592
1593	if (copy_from_user(&bmx, arg, sizeof(bmx)))
1594		return -EFAULT;
1595
1596	if (bmx.bmv_count < 2)
1597		return -EINVAL;
1598
1599	if (bmx.bmv_iflags & (~BMV_IF_VALID))
1600		return -EINVAL;
1601
1602	error = xfs_getbmap(ip, &bmx, xfs_getbmapx_format,
1603			    (__force struct getbmapx *)arg+1);
1604	if (error)
1605		return error;
1606
1607	/* copy back header */
1608	if (copy_to_user(arg, &bmx, sizeof(struct getbmapx)))
1609		return -EFAULT;
1610
1611	return 0;
1612}
1613
1614struct getfsmap_info {
1615	struct xfs_mount	*mp;
1616	struct fsmap_head __user *data;
1617	unsigned int		idx;
1618	__u32			last_flags;
1619};
1620
1621STATIC int
1622xfs_getfsmap_format(struct xfs_fsmap *xfm, void *priv)
1623{
1624	struct getfsmap_info	*info = priv;
1625	struct fsmap		fm;
1626
1627	trace_xfs_getfsmap_mapping(info->mp, xfm);
1628
1629	info->last_flags = xfm->fmr_flags;
1630	xfs_fsmap_from_internal(&fm, xfm);
1631	if (copy_to_user(&info->data->fmh_recs[info->idx++], &fm,
1632			sizeof(struct fsmap)))
1633		return -EFAULT;
1634
1635	return 0;
1636}
1637
1638STATIC int
1639xfs_ioc_getfsmap(
1640	struct xfs_inode	*ip,
1641	struct fsmap_head	__user *arg)
1642{
1643	struct getfsmap_info	info = { NULL };
1644	struct xfs_fsmap_head	xhead = {0};
1645	struct fsmap_head	head;
1646	bool			aborted = false;
1647	int			error;
1648
1649	if (copy_from_user(&head, arg, sizeof(struct fsmap_head)))
1650		return -EFAULT;
1651	if (memchr_inv(head.fmh_reserved, 0, sizeof(head.fmh_reserved)) ||
1652	    memchr_inv(head.fmh_keys[0].fmr_reserved, 0,
1653		       sizeof(head.fmh_keys[0].fmr_reserved)) ||
1654	    memchr_inv(head.fmh_keys[1].fmr_reserved, 0,
1655		       sizeof(head.fmh_keys[1].fmr_reserved)))
1656		return -EINVAL;
1657
1658	xhead.fmh_iflags = head.fmh_iflags;
1659	xhead.fmh_count = head.fmh_count;
1660	xfs_fsmap_to_internal(&xhead.fmh_keys[0], &head.fmh_keys[0]);
1661	xfs_fsmap_to_internal(&xhead.fmh_keys[1], &head.fmh_keys[1]);
1662
1663	trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]);
1664	trace_xfs_getfsmap_high_key(ip->i_mount, &xhead.fmh_keys[1]);
1665
1666	info.mp = ip->i_mount;
1667	info.data = arg;
1668	error = xfs_getfsmap(ip->i_mount, &xhead, xfs_getfsmap_format, &info);
1669	if (error == XFS_BTREE_QUERY_RANGE_ABORT) {
1670		error = 0;
1671		aborted = true;
1672	} else if (error)
1673		return error;
1674
1675	/* If we didn't abort, set the "last" flag in the last fmx */
1676	if (!aborted && info.idx) {
1677		info.last_flags |= FMR_OF_LAST;
1678		if (copy_to_user(&info.data->fmh_recs[info.idx - 1].fmr_flags,
1679				&info.last_flags, sizeof(info.last_flags)))
1680			return -EFAULT;
1681	}
1682
1683	/* copy back header */
1684	head.fmh_entries = xhead.fmh_entries;
1685	head.fmh_oflags = xhead.fmh_oflags;
1686	if (copy_to_user(arg, &head, sizeof(struct fsmap_head)))
1687		return -EFAULT;
1688
1689	return 0;
1690}
1691
1692int
1693xfs_ioc_swapext(
1694	xfs_swapext_t	*sxp)
1695{
1696	xfs_inode_t     *ip, *tip;
1697	struct fd	f, tmp;
1698	int		error = 0;
1699
1700	/* Pull information for the target fd */
1701	f = fdget((int)sxp->sx_fdtarget);
1702	if (!f.file) {
1703		error = -EINVAL;
1704		goto out;
1705	}
1706
1707	if (!(f.file->f_mode & FMODE_WRITE) ||
1708	    !(f.file->f_mode & FMODE_READ) ||
1709	    (f.file->f_flags & O_APPEND)) {
1710		error = -EBADF;
1711		goto out_put_file;
1712	}
1713
1714	tmp = fdget((int)sxp->sx_fdtmp);
1715	if (!tmp.file) {
1716		error = -EINVAL;
1717		goto out_put_file;
1718	}
1719
1720	if (!(tmp.file->f_mode & FMODE_WRITE) ||
1721	    !(tmp.file->f_mode & FMODE_READ) ||
1722	    (tmp.file->f_flags & O_APPEND)) {
1723		error = -EBADF;
1724		goto out_put_tmp_file;
1725	}
1726
1727	if (IS_SWAPFILE(file_inode(f.file)) ||
1728	    IS_SWAPFILE(file_inode(tmp.file))) {
1729		error = -EINVAL;
1730		goto out_put_tmp_file;
1731	}
1732
1733	/*
1734	 * We need to ensure that the fds passed in point to XFS inodes
1735	 * before we cast and access them as XFS structures as we have no
1736	 * control over what the user passes us here.
1737	 */
1738	if (f.file->f_op != &xfs_file_operations ||
1739	    tmp.file->f_op != &xfs_file_operations) {
1740		error = -EINVAL;
1741		goto out_put_tmp_file;
1742	}
1743
1744	ip = XFS_I(file_inode(f.file));
1745	tip = XFS_I(file_inode(tmp.file));
1746
1747	if (ip->i_mount != tip->i_mount) {
1748		error = -EINVAL;
1749		goto out_put_tmp_file;
1750	}
1751
1752	if (ip->i_ino == tip->i_ino) {
1753		error = -EINVAL;
1754		goto out_put_tmp_file;
1755	}
1756
1757	if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
1758		error = -EIO;
1759		goto out_put_tmp_file;
1760	}
1761
1762	error = xfs_swap_extents(ip, tip, sxp);
1763
1764 out_put_tmp_file:
1765	fdput(tmp);
1766 out_put_file:
1767	fdput(f);
1768 out:
1769	return error;
1770}
1771
1772/*
1773 * Note: some of the ioctl's return positive numbers as a
1774 * byte count indicating success, such as readlink_by_handle.
1775 * So we don't "sign flip" like most other routines.  This means
1776 * true errors need to be returned as a negative value.
1777 */
1778long
1779xfs_file_ioctl(
1780	struct file		*filp,
1781	unsigned int		cmd,
1782	unsigned long		p)
1783{
1784	struct inode		*inode = file_inode(filp);
1785	struct xfs_inode	*ip = XFS_I(inode);
1786	struct xfs_mount	*mp = ip->i_mount;
1787	void			__user *arg = (void __user *)p;
1788	int			error;
1789
1790	trace_xfs_file_ioctl(ip);
1791
1792	switch (cmd) {
1793	case FITRIM:
1794		return xfs_ioc_trim(mp, arg);
1795	case XFS_IOC_ALLOCSP:
1796	case XFS_IOC_FREESP:
1797	case XFS_IOC_RESVSP:
1798	case XFS_IOC_UNRESVSP:
1799	case XFS_IOC_ALLOCSP64:
1800	case XFS_IOC_FREESP64:
1801	case XFS_IOC_RESVSP64:
1802	case XFS_IOC_UNRESVSP64:
1803	case XFS_IOC_ZERO_RANGE: {
1804		xfs_flock64_t		bf;
1805
1806		if (copy_from_user(&bf, arg, sizeof(bf)))
1807			return -EFAULT;
1808		return xfs_ioc_space(filp, cmd, &bf);
1809	}
1810	case XFS_IOC_DIOINFO: {
1811		struct dioattr	da;
1812		xfs_buftarg_t	*target =
1813			XFS_IS_REALTIME_INODE(ip) ?
1814			mp->m_rtdev_targp : mp->m_ddev_targp;
1815
1816		da.d_mem =  da.d_miniosz = target->bt_logical_sectorsize;
1817		da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
1818
1819		if (copy_to_user(arg, &da, sizeof(da)))
1820			return -EFAULT;
1821		return 0;
1822	}
1823
1824	case XFS_IOC_FSBULKSTAT_SINGLE:
1825	case XFS_IOC_FSBULKSTAT:
1826	case XFS_IOC_FSINUMBERS:
1827		return xfs_ioc_bulkstat(mp, cmd, arg);
1828
1829	case XFS_IOC_FSGEOMETRY_V1:
1830		return xfs_ioc_fsgeometry_v1(mp, arg);
1831
1832	case XFS_IOC_FSGEOMETRY:
1833		return xfs_ioc_fsgeometry(mp, arg);
1834
1835	case XFS_IOC_GETVERSION:
1836		return put_user(inode->i_generation, (int __user *)arg);
1837
1838	case XFS_IOC_FSGETXATTR:
1839		return xfs_ioc_fsgetxattr(ip, 0, arg);
1840	case XFS_IOC_FSGETXATTRA:
1841		return xfs_ioc_fsgetxattr(ip, 1, arg);
1842	case XFS_IOC_FSSETXATTR:
1843		return xfs_ioc_fssetxattr(ip, filp, arg);
1844	case XFS_IOC_GETXFLAGS:
1845		return xfs_ioc_getxflags(ip, arg);
1846	case XFS_IOC_SETXFLAGS:
1847		return xfs_ioc_setxflags(ip, filp, arg);
1848
1849	case XFS_IOC_FSSETDM: {
1850		struct fsdmidata	dmi;
1851
1852		if (copy_from_user(&dmi, arg, sizeof(dmi)))
1853			return -EFAULT;
1854
1855		error = mnt_want_write_file(filp);
1856		if (error)
1857			return error;
1858
1859		error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask,
1860				dmi.fsd_dmstate);
1861		mnt_drop_write_file(filp);
1862		return error;
1863	}
1864
1865	case XFS_IOC_GETBMAP:
1866	case XFS_IOC_GETBMAPA:
1867		return xfs_ioc_getbmap(filp, cmd, arg);
1868
1869	case XFS_IOC_GETBMAPX:
1870		return xfs_ioc_getbmapx(ip, arg);
1871
1872	case FS_IOC_GETFSMAP:
1873		return xfs_ioc_getfsmap(ip, arg);
1874
1875	case XFS_IOC_FD_TO_HANDLE:
1876	case XFS_IOC_PATH_TO_HANDLE:
1877	case XFS_IOC_PATH_TO_FSHANDLE: {
1878		xfs_fsop_handlereq_t	hreq;
1879
1880		if (copy_from_user(&hreq, arg, sizeof(hreq)))
1881			return -EFAULT;
1882		return xfs_find_handle(cmd, &hreq);
1883	}
1884	case XFS_IOC_OPEN_BY_HANDLE: {
1885		xfs_fsop_handlereq_t	hreq;
1886
1887		if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
1888			return -EFAULT;
1889		return xfs_open_by_handle(filp, &hreq);
1890	}
1891	case XFS_IOC_FSSETDM_BY_HANDLE:
1892		return xfs_fssetdm_by_handle(filp, arg);
1893
1894	case XFS_IOC_READLINK_BY_HANDLE: {
1895		xfs_fsop_handlereq_t	hreq;
1896
1897		if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
1898			return -EFAULT;
1899		return xfs_readlink_by_handle(filp, &hreq);
1900	}
1901	case XFS_IOC_ATTRLIST_BY_HANDLE:
1902		return xfs_attrlist_by_handle(filp, arg);
1903
1904	case XFS_IOC_ATTRMULTI_BY_HANDLE:
1905		return xfs_attrmulti_by_handle(filp, arg);
1906
1907	case XFS_IOC_SWAPEXT: {
1908		struct xfs_swapext	sxp;
1909
1910		if (copy_from_user(&sxp, arg, sizeof(xfs_swapext_t)))
1911			return -EFAULT;
1912		error = mnt_want_write_file(filp);
1913		if (error)
1914			return error;
1915		error = xfs_ioc_swapext(&sxp);
1916		mnt_drop_write_file(filp);
1917		return error;
1918	}
1919
1920	case XFS_IOC_FSCOUNTS: {
1921		xfs_fsop_counts_t out;
1922
1923		error = xfs_fs_counts(mp, &out);
1924		if (error)
1925			return error;
1926
1927		if (copy_to_user(arg, &out, sizeof(out)))
1928			return -EFAULT;
1929		return 0;
1930	}
1931
1932	case XFS_IOC_SET_RESBLKS: {
1933		xfs_fsop_resblks_t inout;
1934		uint64_t	   in;
1935
1936		if (!capable(CAP_SYS_ADMIN))
1937			return -EPERM;
1938
1939		if (mp->m_flags & XFS_MOUNT_RDONLY)
1940			return -EROFS;
1941
1942		if (copy_from_user(&inout, arg, sizeof(inout)))
1943			return -EFAULT;
1944
1945		error = mnt_want_write_file(filp);
1946		if (error)
1947			return error;
1948
1949		/* input parameter is passed in resblks field of structure */
1950		in = inout.resblks;
1951		error = xfs_reserve_blocks(mp, &in, &inout);
1952		mnt_drop_write_file(filp);
1953		if (error)
1954			return error;
1955
1956		if (copy_to_user(arg, &inout, sizeof(inout)))
1957			return -EFAULT;
1958		return 0;
1959	}
1960
1961	case XFS_IOC_GET_RESBLKS: {
1962		xfs_fsop_resblks_t out;
1963
1964		if (!capable(CAP_SYS_ADMIN))
1965			return -EPERM;
1966
1967		error = xfs_reserve_blocks(mp, NULL, &out);
1968		if (error)
1969			return error;
1970
1971		if (copy_to_user(arg, &out, sizeof(out)))
1972			return -EFAULT;
1973
1974		return 0;
1975	}
1976
1977	case XFS_IOC_FSGROWFSDATA: {
1978		xfs_growfs_data_t in;
1979
1980		if (copy_from_user(&in, arg, sizeof(in)))
1981			return -EFAULT;
1982
1983		error = mnt_want_write_file(filp);
1984		if (error)
1985			return error;
1986		error = xfs_growfs_data(mp, &in);
1987		mnt_drop_write_file(filp);
1988		return error;
1989	}
1990
1991	case XFS_IOC_FSGROWFSLOG: {
1992		xfs_growfs_log_t in;
1993
1994		if (copy_from_user(&in, arg, sizeof(in)))
1995			return -EFAULT;
1996
1997		error = mnt_want_write_file(filp);
1998		if (error)
1999			return error;
2000		error = xfs_growfs_log(mp, &in);
2001		mnt_drop_write_file(filp);
2002		return error;
2003	}
2004
2005	case XFS_IOC_FSGROWFSRT: {
2006		xfs_growfs_rt_t in;
2007
2008		if (copy_from_user(&in, arg, sizeof(in)))
2009			return -EFAULT;
2010
2011		error = mnt_want_write_file(filp);
2012		if (error)
2013			return error;
2014		error = xfs_growfs_rt(mp, &in);
2015		mnt_drop_write_file(filp);
2016		return error;
2017	}
2018
2019	case XFS_IOC_GOINGDOWN: {
2020		uint32_t in;
2021
2022		if (!capable(CAP_SYS_ADMIN))
2023			return -EPERM;
2024
2025		if (get_user(in, (uint32_t __user *)arg))
2026			return -EFAULT;
2027
2028		return xfs_fs_goingdown(mp, in);
2029	}
2030
2031	case XFS_IOC_ERROR_INJECTION: {
2032		xfs_error_injection_t in;
2033
2034		if (!capable(CAP_SYS_ADMIN))
2035			return -EPERM;
2036
2037		if (copy_from_user(&in, arg, sizeof(in)))
2038			return -EFAULT;
2039
2040		return xfs_errortag_add(mp, in.errtag);
2041	}
2042
2043	case XFS_IOC_ERROR_CLEARALL:
2044		if (!capable(CAP_SYS_ADMIN))
2045			return -EPERM;
2046
2047		return xfs_errortag_clearall(mp);
2048
2049	case XFS_IOC_FREE_EOFBLOCKS: {
2050		struct xfs_fs_eofblocks eofb;
2051		struct xfs_eofblocks keofb;
2052
2053		if (!capable(CAP_SYS_ADMIN))
2054			return -EPERM;
2055
2056		if (mp->m_flags & XFS_MOUNT_RDONLY)
2057			return -EROFS;
2058
2059		if (copy_from_user(&eofb, arg, sizeof(eofb)))
2060			return -EFAULT;
2061
2062		error = xfs_fs_eofblocks_from_user(&eofb, &keofb);
2063		if (error)
2064			return error;
2065
2066		return xfs_icache_free_eofblocks(mp, &keofb);
2067	}
2068
2069	default:
2070		return -ENOTTY;
2071	}
2072}