PageRenderTime 107ms CodeModel.GetById 3ms app.highlight 94ms RepoModel.GetById 1ms app.codeStats 0ms

/fs/xfs/xfs_ioctl.c

https://bitbucket.org/digetx/picasso-kernel
C | 1636 lines | 1220 code | 257 blank | 159 comment | 259 complexity | d2f89192bff8afdbec0470009de71767 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_log.h"
  21#include "xfs_trans.h"
  22#include "xfs_sb.h"
  23#include "xfs_ag.h"
  24#include "xfs_alloc.h"
  25#include "xfs_mount.h"
  26#include "xfs_bmap_btree.h"
  27#include "xfs_dinode.h"
  28#include "xfs_inode.h"
  29#include "xfs_ioctl.h"
  30#include "xfs_rtalloc.h"
  31#include "xfs_itable.h"
  32#include "xfs_error.h"
  33#include "xfs_attr.h"
  34#include "xfs_bmap.h"
  35#include "xfs_buf_item.h"
  36#include "xfs_utils.h"
  37#include "xfs_dfrag.h"
  38#include "xfs_fsops.h"
  39#include "xfs_vnodeops.h"
  40#include "xfs_discard.h"
  41#include "xfs_quota.h"
  42#include "xfs_inode_item.h"
  43#include "xfs_export.h"
  44#include "xfs_trace.h"
  45#include "xfs_icache.h"
  46
  47#include <linux/capability.h>
  48#include <linux/dcache.h>
  49#include <linux/mount.h>
  50#include <linux/namei.h>
  51#include <linux/pagemap.h>
  52#include <linux/slab.h>
  53#include <linux/exportfs.h>
  54
  55/*
  56 * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to
  57 * a file or fs handle.
  58 *
  59 * XFS_IOC_PATH_TO_FSHANDLE
  60 *    returns fs handle for a mount point or path within that mount point
  61 * XFS_IOC_FD_TO_HANDLE
  62 *    returns full handle for a FD opened in user space
  63 * XFS_IOC_PATH_TO_HANDLE
  64 *    returns full handle for a path
  65 */
  66int
  67xfs_find_handle(
  68	unsigned int		cmd,
  69	xfs_fsop_handlereq_t	*hreq)
  70{
  71	int			hsize;
  72	xfs_handle_t		handle;
  73	struct inode		*inode;
  74	struct fd		f = {0};
  75	struct path		path;
  76	int			error;
  77	struct xfs_inode	*ip;
  78
  79	if (cmd == XFS_IOC_FD_TO_HANDLE) {
  80		f = fdget(hreq->fd);
  81		if (!f.file)
  82			return -EBADF;
  83		inode = f.file->f_path.dentry->d_inode;
  84	} else {
  85		error = user_lpath((const char __user *)hreq->path, &path);
  86		if (error)
  87			return error;
  88		inode = path.dentry->d_inode;
  89	}
  90	ip = XFS_I(inode);
  91
  92	/*
  93	 * We can only generate handles for inodes residing on a XFS filesystem,
  94	 * and only for regular files, directories or symbolic links.
  95	 */
  96	error = -EINVAL;
  97	if (inode->i_sb->s_magic != XFS_SB_MAGIC)
  98		goto out_put;
  99
 100	error = -EBADF;
 101	if (!S_ISREG(inode->i_mode) &&
 102	    !S_ISDIR(inode->i_mode) &&
 103	    !S_ISLNK(inode->i_mode))
 104		goto out_put;
 105
 106
 107	memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
 108
 109	if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
 110		/*
 111		 * This handle only contains an fsid, zero the rest.
 112		 */
 113		memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
 114		hsize = sizeof(xfs_fsid_t);
 115	} else {
 116		int		lock_mode;
 117
 118		lock_mode = xfs_ilock_map_shared(ip);
 119		handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
 120					sizeof(handle.ha_fid.fid_len);
 121		handle.ha_fid.fid_pad = 0;
 122		handle.ha_fid.fid_gen = ip->i_d.di_gen;
 123		handle.ha_fid.fid_ino = ip->i_ino;
 124		xfs_iunlock_map_shared(ip, lock_mode);
 125
 126		hsize = XFS_HSIZE(handle);
 127	}
 128
 129	error = -EFAULT;
 130	if (copy_to_user(hreq->ohandle, &handle, hsize) ||
 131	    copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
 132		goto out_put;
 133
 134	error = 0;
 135
 136 out_put:
 137	if (cmd == XFS_IOC_FD_TO_HANDLE)
 138		fdput(f);
 139	else
 140		path_put(&path);
 141	return error;
 142}
 143
 144/*
 145 * No need to do permission checks on the various pathname components
 146 * as the handle operations are privileged.
 147 */
 148STATIC int
 149xfs_handle_acceptable(
 150	void			*context,
 151	struct dentry		*dentry)
 152{
 153	return 1;
 154}
 155
 156/*
 157 * Convert userspace handle data into a dentry.
 158 */
 159struct dentry *
 160xfs_handle_to_dentry(
 161	struct file		*parfilp,
 162	void __user		*uhandle,
 163	u32			hlen)
 164{
 165	xfs_handle_t		handle;
 166	struct xfs_fid64	fid;
 167
 168	/*
 169	 * Only allow handle opens under a directory.
 170	 */
 171	if (!S_ISDIR(parfilp->f_path.dentry->d_inode->i_mode))
 172		return ERR_PTR(-ENOTDIR);
 173
 174	if (hlen != sizeof(xfs_handle_t))
 175		return ERR_PTR(-EINVAL);
 176	if (copy_from_user(&handle, uhandle, hlen))
 177		return ERR_PTR(-EFAULT);
 178	if (handle.ha_fid.fid_len !=
 179	    sizeof(handle.ha_fid) - sizeof(handle.ha_fid.fid_len))
 180		return ERR_PTR(-EINVAL);
 181
 182	memset(&fid, 0, sizeof(struct fid));
 183	fid.ino = handle.ha_fid.fid_ino;
 184	fid.gen = handle.ha_fid.fid_gen;
 185
 186	return exportfs_decode_fh(parfilp->f_path.mnt, (struct fid *)&fid, 3,
 187			FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG,
 188			xfs_handle_acceptable, NULL);
 189}
 190
 191STATIC struct dentry *
 192xfs_handlereq_to_dentry(
 193	struct file		*parfilp,
 194	xfs_fsop_handlereq_t	*hreq)
 195{
 196	return xfs_handle_to_dentry(parfilp, hreq->ihandle, hreq->ihandlen);
 197}
 198
 199int
 200xfs_open_by_handle(
 201	struct file		*parfilp,
 202	xfs_fsop_handlereq_t	*hreq)
 203{
 204	const struct cred	*cred = current_cred();
 205	int			error;
 206	int			fd;
 207	int			permflag;
 208	struct file		*filp;
 209	struct inode		*inode;
 210	struct dentry		*dentry;
 211	fmode_t			fmode;
 212	struct path		path;
 213
 214	if (!capable(CAP_SYS_ADMIN))
 215		return -XFS_ERROR(EPERM);
 216
 217	dentry = xfs_handlereq_to_dentry(parfilp, hreq);
 218	if (IS_ERR(dentry))
 219		return PTR_ERR(dentry);
 220	inode = dentry->d_inode;
 221
 222	/* Restrict xfs_open_by_handle to directories & regular files. */
 223	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
 224		error = -XFS_ERROR(EPERM);
 225		goto out_dput;
 226	}
 227
 228#if BITS_PER_LONG != 32
 229	hreq->oflags |= O_LARGEFILE;
 230#endif
 231
 232	permflag = hreq->oflags;
 233	fmode = OPEN_FMODE(permflag);
 234	if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
 235	    (fmode & FMODE_WRITE) && IS_APPEND(inode)) {
 236		error = -XFS_ERROR(EPERM);
 237		goto out_dput;
 238	}
 239
 240	if ((fmode & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
 241		error = -XFS_ERROR(EACCES);
 242		goto out_dput;
 243	}
 244
 245	/* Can't write directories. */
 246	if (S_ISDIR(inode->i_mode) && (fmode & FMODE_WRITE)) {
 247		error = -XFS_ERROR(EISDIR);
 248		goto out_dput;
 249	}
 250
 251	fd = get_unused_fd();
 252	if (fd < 0) {
 253		error = fd;
 254		goto out_dput;
 255	}
 256
 257	path.mnt = parfilp->f_path.mnt;
 258	path.dentry = dentry;
 259	filp = dentry_open(&path, hreq->oflags, cred);
 260	dput(dentry);
 261	if (IS_ERR(filp)) {
 262		put_unused_fd(fd);
 263		return PTR_ERR(filp);
 264	}
 265
 266	if (S_ISREG(inode->i_mode)) {
 267		filp->f_flags |= O_NOATIME;
 268		filp->f_mode |= FMODE_NOCMTIME;
 269	}
 270
 271	fd_install(fd, filp);
 272	return fd;
 273
 274 out_dput:
 275	dput(dentry);
 276	return error;
 277}
 278
 279/*
 280 * This is a copy from fs/namei.c:vfs_readlink(), except for removing it's
 281 * unused first argument.
 282 */
 283STATIC int
 284do_readlink(
 285	char __user		*buffer,
 286	int			buflen,
 287	const char		*link)
 288{
 289        int len;
 290
 291	len = PTR_ERR(link);
 292	if (IS_ERR(link))
 293		goto out;
 294
 295	len = strlen(link);
 296	if (len > (unsigned) buflen)
 297		len = buflen;
 298	if (copy_to_user(buffer, link, len))
 299		len = -EFAULT;
 300 out:
 301	return len;
 302}
 303
 304
 305int
 306xfs_readlink_by_handle(
 307	struct file		*parfilp,
 308	xfs_fsop_handlereq_t	*hreq)
 309{
 310	struct dentry		*dentry;
 311	__u32			olen;
 312	void			*link;
 313	int			error;
 314
 315	if (!capable(CAP_SYS_ADMIN))
 316		return -XFS_ERROR(EPERM);
 317
 318	dentry = xfs_handlereq_to_dentry(parfilp, hreq);
 319	if (IS_ERR(dentry))
 320		return PTR_ERR(dentry);
 321
 322	/* Restrict this handle operation to symlinks only. */
 323	if (!S_ISLNK(dentry->d_inode->i_mode)) {
 324		error = -XFS_ERROR(EINVAL);
 325		goto out_dput;
 326	}
 327
 328	if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) {
 329		error = -XFS_ERROR(EFAULT);
 330		goto out_dput;
 331	}
 332
 333	link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
 334	if (!link) {
 335		error = -XFS_ERROR(ENOMEM);
 336		goto out_dput;
 337	}
 338
 339	error = -xfs_readlink(XFS_I(dentry->d_inode), link);
 340	if (error)
 341		goto out_kfree;
 342	error = do_readlink(hreq->ohandle, olen, link);
 343	if (error)
 344		goto out_kfree;
 345
 346 out_kfree:
 347	kfree(link);
 348 out_dput:
 349	dput(dentry);
 350	return error;
 351}
 352
 353STATIC int
 354xfs_fssetdm_by_handle(
 355	struct file		*parfilp,
 356	void			__user *arg)
 357{
 358	int			error;
 359	struct fsdmidata	fsd;
 360	xfs_fsop_setdm_handlereq_t dmhreq;
 361	struct dentry		*dentry;
 362
 363	if (!capable(CAP_MKNOD))
 364		return -XFS_ERROR(EPERM);
 365	if (copy_from_user(&dmhreq, arg, sizeof(xfs_fsop_setdm_handlereq_t)))
 366		return -XFS_ERROR(EFAULT);
 367
 368	error = mnt_want_write_file(parfilp);
 369	if (error)
 370		return error;
 371
 372	dentry = xfs_handlereq_to_dentry(parfilp, &dmhreq.hreq);
 373	if (IS_ERR(dentry)) {
 374		mnt_drop_write_file(parfilp);
 375		return PTR_ERR(dentry);
 376	}
 377
 378	if (IS_IMMUTABLE(dentry->d_inode) || IS_APPEND(dentry->d_inode)) {
 379		error = -XFS_ERROR(EPERM);
 380		goto out;
 381	}
 382
 383	if (copy_from_user(&fsd, dmhreq.data, sizeof(fsd))) {
 384		error = -XFS_ERROR(EFAULT);
 385		goto out;
 386	}
 387
 388	error = -xfs_set_dmattrs(XFS_I(dentry->d_inode), fsd.fsd_dmevmask,
 389				 fsd.fsd_dmstate);
 390
 391 out:
 392	mnt_drop_write_file(parfilp);
 393	dput(dentry);
 394	return error;
 395}
 396
 397STATIC int
 398xfs_attrlist_by_handle(
 399	struct file		*parfilp,
 400	void			__user *arg)
 401{
 402	int			error = -ENOMEM;
 403	attrlist_cursor_kern_t	*cursor;
 404	xfs_fsop_attrlist_handlereq_t al_hreq;
 405	struct dentry		*dentry;
 406	char			*kbuf;
 407
 408	if (!capable(CAP_SYS_ADMIN))
 409		return -XFS_ERROR(EPERM);
 410	if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
 411		return -XFS_ERROR(EFAULT);
 412	if (al_hreq.buflen < sizeof(struct attrlist) ||
 413	    al_hreq.buflen > XATTR_LIST_MAX)
 414		return -XFS_ERROR(EINVAL);
 415
 416	/*
 417	 * Reject flags, only allow namespaces.
 418	 */
 419	if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE))
 420		return -XFS_ERROR(EINVAL);
 421
 422	dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
 423	if (IS_ERR(dentry))
 424		return PTR_ERR(dentry);
 425
 426	kbuf = kzalloc(al_hreq.buflen, GFP_KERNEL);
 427	if (!kbuf)
 428		goto out_dput;
 429
 430	cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
 431	error = -xfs_attr_list(XFS_I(dentry->d_inode), kbuf, al_hreq.buflen,
 432					al_hreq.flags, cursor);
 433	if (error)
 434		goto out_kfree;
 435
 436	if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen))
 437		error = -EFAULT;
 438
 439 out_kfree:
 440	kfree(kbuf);
 441 out_dput:
 442	dput(dentry);
 443	return error;
 444}
 445
 446int
 447xfs_attrmulti_attr_get(
 448	struct inode		*inode,
 449	unsigned char		*name,
 450	unsigned char		__user *ubuf,
 451	__uint32_t		*len,
 452	__uint32_t		flags)
 453{
 454	unsigned char		*kbuf;
 455	int			error = EFAULT;
 456
 457	if (*len > XATTR_SIZE_MAX)
 458		return EINVAL;
 459	kbuf = kmem_zalloc(*len, KM_SLEEP | KM_MAYFAIL);
 460	if (!kbuf) {
 461		kbuf = kmem_zalloc_large(*len);
 462		if (!kbuf)
 463			return ENOMEM;
 464	}
 465
 466	error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags);
 467	if (error)
 468		goto out_kfree;
 469
 470	if (copy_to_user(ubuf, kbuf, *len))
 471		error = EFAULT;
 472
 473 out_kfree:
 474	if (is_vmalloc_addr(kbuf))
 475		kmem_free_large(kbuf);
 476	else
 477		kmem_free(kbuf);
 478	return error;
 479}
 480
 481int
 482xfs_attrmulti_attr_set(
 483	struct inode		*inode,
 484	unsigned char		*name,
 485	const unsigned char	__user *ubuf,
 486	__uint32_t		len,
 487	__uint32_t		flags)
 488{
 489	unsigned char		*kbuf;
 490	int			error = EFAULT;
 491
 492	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 493		return EPERM;
 494	if (len > XATTR_SIZE_MAX)
 495		return EINVAL;
 496
 497	kbuf = memdup_user(ubuf, len);
 498	if (IS_ERR(kbuf))
 499		return PTR_ERR(kbuf);
 500
 501	error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags);
 502
 503	return error;
 504}
 505
 506int
 507xfs_attrmulti_attr_remove(
 508	struct inode		*inode,
 509	unsigned char		*name,
 510	__uint32_t		flags)
 511{
 512	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 513		return EPERM;
 514	return xfs_attr_remove(XFS_I(inode), name, flags);
 515}
 516
 517STATIC int
 518xfs_attrmulti_by_handle(
 519	struct file		*parfilp,
 520	void			__user *arg)
 521{
 522	int			error;
 523	xfs_attr_multiop_t	*ops;
 524	xfs_fsop_attrmulti_handlereq_t am_hreq;
 525	struct dentry		*dentry;
 526	unsigned int		i, size;
 527	unsigned char		*attr_name;
 528
 529	if (!capable(CAP_SYS_ADMIN))
 530		return -XFS_ERROR(EPERM);
 531	if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t)))
 532		return -XFS_ERROR(EFAULT);
 533
 534	/* overflow check */
 535	if (am_hreq.opcount >= INT_MAX / sizeof(xfs_attr_multiop_t))
 536		return -E2BIG;
 537
 538	dentry = xfs_handlereq_to_dentry(parfilp, &am_hreq.hreq);
 539	if (IS_ERR(dentry))
 540		return PTR_ERR(dentry);
 541
 542	error = E2BIG;
 543	size = am_hreq.opcount * sizeof(xfs_attr_multiop_t);
 544	if (!size || size > 16 * PAGE_SIZE)
 545		goto out_dput;
 546
 547	ops = memdup_user(am_hreq.ops, size);
 548	if (IS_ERR(ops)) {
 549		error = PTR_ERR(ops);
 550		goto out_dput;
 551	}
 552
 553	attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL);
 554	if (!attr_name)
 555		goto out_kfree_ops;
 556
 557	error = 0;
 558	for (i = 0; i < am_hreq.opcount; i++) {
 559		ops[i].am_error = strncpy_from_user((char *)attr_name,
 560				ops[i].am_attrname, MAXNAMELEN);
 561		if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN)
 562			error = -ERANGE;
 563		if (ops[i].am_error < 0)
 564			break;
 565
 566		switch (ops[i].am_opcode) {
 567		case ATTR_OP_GET:
 568			ops[i].am_error = xfs_attrmulti_attr_get(
 569					dentry->d_inode, attr_name,
 570					ops[i].am_attrvalue, &ops[i].am_length,
 571					ops[i].am_flags);
 572			break;
 573		case ATTR_OP_SET:
 574			ops[i].am_error = mnt_want_write_file(parfilp);
 575			if (ops[i].am_error)
 576				break;
 577			ops[i].am_error = xfs_attrmulti_attr_set(
 578					dentry->d_inode, attr_name,
 579					ops[i].am_attrvalue, ops[i].am_length,
 580					ops[i].am_flags);
 581			mnt_drop_write_file(parfilp);
 582			break;
 583		case ATTR_OP_REMOVE:
 584			ops[i].am_error = mnt_want_write_file(parfilp);
 585			if (ops[i].am_error)
 586				break;
 587			ops[i].am_error = xfs_attrmulti_attr_remove(
 588					dentry->d_inode, attr_name,
 589					ops[i].am_flags);
 590			mnt_drop_write_file(parfilp);
 591			break;
 592		default:
 593			ops[i].am_error = EINVAL;
 594		}
 595	}
 596
 597	if (copy_to_user(am_hreq.ops, ops, size))
 598		error = XFS_ERROR(EFAULT);
 599
 600	kfree(attr_name);
 601 out_kfree_ops:
 602	kfree(ops);
 603 out_dput:
 604	dput(dentry);
 605	return -error;
 606}
 607
 608int
 609xfs_ioc_space(
 610	struct xfs_inode	*ip,
 611	struct inode		*inode,
 612	struct file		*filp,
 613	int			ioflags,
 614	unsigned int		cmd,
 615	xfs_flock64_t		*bf)
 616{
 617	int			attr_flags = 0;
 618	int			error;
 619
 620	/*
 621	 * Only allow the sys admin to reserve space unless
 622	 * unwritten extents are enabled.
 623	 */
 624	if (!xfs_sb_version_hasextflgbit(&ip->i_mount->m_sb) &&
 625	    !capable(CAP_SYS_ADMIN))
 626		return -XFS_ERROR(EPERM);
 627
 628	if (inode->i_flags & (S_IMMUTABLE|S_APPEND))
 629		return -XFS_ERROR(EPERM);
 630
 631	if (!(filp->f_mode & FMODE_WRITE))
 632		return -XFS_ERROR(EBADF);
 633
 634	if (!S_ISREG(inode->i_mode))
 635		return -XFS_ERROR(EINVAL);
 636
 637	if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
 638		attr_flags |= XFS_ATTR_NONBLOCK;
 639
 640	if (filp->f_flags & O_DSYNC)
 641		attr_flags |= XFS_ATTR_SYNC;
 642
 643	if (ioflags & IO_INVIS)
 644		attr_flags |= XFS_ATTR_DMI;
 645
 646	error = mnt_want_write_file(filp);
 647	if (error)
 648		return error;
 649	error = xfs_change_file_space(ip, cmd, bf, filp->f_pos, attr_flags);
 650	mnt_drop_write_file(filp);
 651	return -error;
 652}
 653
 654STATIC int
 655xfs_ioc_bulkstat(
 656	xfs_mount_t		*mp,
 657	unsigned int		cmd,
 658	void			__user *arg)
 659{
 660	xfs_fsop_bulkreq_t	bulkreq;
 661	int			count;	/* # of records returned */
 662	xfs_ino_t		inlast;	/* last inode number */
 663	int			done;
 664	int			error;
 665
 666	/* done = 1 if there are more stats to get and if bulkstat */
 667	/* should be called again (unused here, but used in dmapi) */
 668
 669	if (!capable(CAP_SYS_ADMIN))
 670		return -EPERM;
 671
 672	if (XFS_FORCED_SHUTDOWN(mp))
 673		return -XFS_ERROR(EIO);
 674
 675	if (copy_from_user(&bulkreq, arg, sizeof(xfs_fsop_bulkreq_t)))
 676		return -XFS_ERROR(EFAULT);
 677
 678	if (copy_from_user(&inlast, bulkreq.lastip, sizeof(__s64)))
 679		return -XFS_ERROR(EFAULT);
 680
 681	if ((count = bulkreq.icount) <= 0)
 682		return -XFS_ERROR(EINVAL);
 683
 684	if (bulkreq.ubuffer == NULL)
 685		return -XFS_ERROR(EINVAL);
 686
 687	if (cmd == XFS_IOC_FSINUMBERS)
 688		error = xfs_inumbers(mp, &inlast, &count,
 689					bulkreq.ubuffer, xfs_inumbers_fmt);
 690	else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE)
 691		error = xfs_bulkstat_single(mp, &inlast,
 692						bulkreq.ubuffer, &done);
 693	else	/* XFS_IOC_FSBULKSTAT */
 694		error = xfs_bulkstat(mp, &inlast, &count, xfs_bulkstat_one,
 695				     sizeof(xfs_bstat_t), bulkreq.ubuffer,
 696				     &done);
 697
 698	if (error)
 699		return -error;
 700
 701	if (bulkreq.ocount != NULL) {
 702		if (copy_to_user(bulkreq.lastip, &inlast,
 703						sizeof(xfs_ino_t)))
 704			return -XFS_ERROR(EFAULT);
 705
 706		if (copy_to_user(bulkreq.ocount, &count, sizeof(count)))
 707			return -XFS_ERROR(EFAULT);
 708	}
 709
 710	return 0;
 711}
 712
 713STATIC int
 714xfs_ioc_fsgeometry_v1(
 715	xfs_mount_t		*mp,
 716	void			__user *arg)
 717{
 718	xfs_fsop_geom_t         fsgeo;
 719	int			error;
 720
 721	error = xfs_fs_geometry(mp, &fsgeo, 3);
 722	if (error)
 723		return -error;
 724
 725	/*
 726	 * Caller should have passed an argument of type
 727	 * xfs_fsop_geom_v1_t.  This is a proper subset of the
 728	 * xfs_fsop_geom_t that xfs_fs_geometry() fills in.
 729	 */
 730	if (copy_to_user(arg, &fsgeo, sizeof(xfs_fsop_geom_v1_t)))
 731		return -XFS_ERROR(EFAULT);
 732	return 0;
 733}
 734
 735STATIC int
 736xfs_ioc_fsgeometry(
 737	xfs_mount_t		*mp,
 738	void			__user *arg)
 739{
 740	xfs_fsop_geom_t		fsgeo;
 741	int			error;
 742
 743	error = xfs_fs_geometry(mp, &fsgeo, 4);
 744	if (error)
 745		return -error;
 746
 747	if (copy_to_user(arg, &fsgeo, sizeof(fsgeo)))
 748		return -XFS_ERROR(EFAULT);
 749	return 0;
 750}
 751
 752/*
 753 * Linux extended inode flags interface.
 754 */
 755
 756STATIC unsigned int
 757xfs_merge_ioc_xflags(
 758	unsigned int	flags,
 759	unsigned int	start)
 760{
 761	unsigned int	xflags = start;
 762
 763	if (flags & FS_IMMUTABLE_FL)
 764		xflags |= XFS_XFLAG_IMMUTABLE;
 765	else
 766		xflags &= ~XFS_XFLAG_IMMUTABLE;
 767	if (flags & FS_APPEND_FL)
 768		xflags |= XFS_XFLAG_APPEND;
 769	else
 770		xflags &= ~XFS_XFLAG_APPEND;
 771	if (flags & FS_SYNC_FL)
 772		xflags |= XFS_XFLAG_SYNC;
 773	else
 774		xflags &= ~XFS_XFLAG_SYNC;
 775	if (flags & FS_NOATIME_FL)
 776		xflags |= XFS_XFLAG_NOATIME;
 777	else
 778		xflags &= ~XFS_XFLAG_NOATIME;
 779	if (flags & FS_NODUMP_FL)
 780		xflags |= XFS_XFLAG_NODUMP;
 781	else
 782		xflags &= ~XFS_XFLAG_NODUMP;
 783
 784	return xflags;
 785}
 786
 787STATIC unsigned int
 788xfs_di2lxflags(
 789	__uint16_t	di_flags)
 790{
 791	unsigned int	flags = 0;
 792
 793	if (di_flags & XFS_DIFLAG_IMMUTABLE)
 794		flags |= FS_IMMUTABLE_FL;
 795	if (di_flags & XFS_DIFLAG_APPEND)
 796		flags |= FS_APPEND_FL;
 797	if (di_flags & XFS_DIFLAG_SYNC)
 798		flags |= FS_SYNC_FL;
 799	if (di_flags & XFS_DIFLAG_NOATIME)
 800		flags |= FS_NOATIME_FL;
 801	if (di_flags & XFS_DIFLAG_NODUMP)
 802		flags |= FS_NODUMP_FL;
 803	return flags;
 804}
 805
 806STATIC int
 807xfs_ioc_fsgetxattr(
 808	xfs_inode_t		*ip,
 809	int			attr,
 810	void			__user *arg)
 811{
 812	struct fsxattr		fa;
 813
 814	memset(&fa, 0, sizeof(struct fsxattr));
 815
 816	xfs_ilock(ip, XFS_ILOCK_SHARED);
 817	fa.fsx_xflags = xfs_ip2xflags(ip);
 818	fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog;
 819	fa.fsx_projid = xfs_get_projid(ip);
 820
 821	if (attr) {
 822		if (ip->i_afp) {
 823			if (ip->i_afp->if_flags & XFS_IFEXTENTS)
 824				fa.fsx_nextents = ip->i_afp->if_bytes /
 825							sizeof(xfs_bmbt_rec_t);
 826			else
 827				fa.fsx_nextents = ip->i_d.di_anextents;
 828		} else
 829			fa.fsx_nextents = 0;
 830	} else {
 831		if (ip->i_df.if_flags & XFS_IFEXTENTS)
 832			fa.fsx_nextents = ip->i_df.if_bytes /
 833						sizeof(xfs_bmbt_rec_t);
 834		else
 835			fa.fsx_nextents = ip->i_d.di_nextents;
 836	}
 837	xfs_iunlock(ip, XFS_ILOCK_SHARED);
 838
 839	if (copy_to_user(arg, &fa, sizeof(fa)))
 840		return -EFAULT;
 841	return 0;
 842}
 843
 844STATIC void
 845xfs_set_diflags(
 846	struct xfs_inode	*ip,
 847	unsigned int		xflags)
 848{
 849	unsigned int		di_flags;
 850
 851	/* can't set PREALLOC this way, just preserve it */
 852	di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
 853	if (xflags & XFS_XFLAG_IMMUTABLE)
 854		di_flags |= XFS_DIFLAG_IMMUTABLE;
 855	if (xflags & XFS_XFLAG_APPEND)
 856		di_flags |= XFS_DIFLAG_APPEND;
 857	if (xflags & XFS_XFLAG_SYNC)
 858		di_flags |= XFS_DIFLAG_SYNC;
 859	if (xflags & XFS_XFLAG_NOATIME)
 860		di_flags |= XFS_DIFLAG_NOATIME;
 861	if (xflags & XFS_XFLAG_NODUMP)
 862		di_flags |= XFS_DIFLAG_NODUMP;
 863	if (xflags & XFS_XFLAG_PROJINHERIT)
 864		di_flags |= XFS_DIFLAG_PROJINHERIT;
 865	if (xflags & XFS_XFLAG_NODEFRAG)
 866		di_flags |= XFS_DIFLAG_NODEFRAG;
 867	if (xflags & XFS_XFLAG_FILESTREAM)
 868		di_flags |= XFS_DIFLAG_FILESTREAM;
 869	if (S_ISDIR(ip->i_d.di_mode)) {
 870		if (xflags & XFS_XFLAG_RTINHERIT)
 871			di_flags |= XFS_DIFLAG_RTINHERIT;
 872		if (xflags & XFS_XFLAG_NOSYMLINKS)
 873			di_flags |= XFS_DIFLAG_NOSYMLINKS;
 874		if (xflags & XFS_XFLAG_EXTSZINHERIT)
 875			di_flags |= XFS_DIFLAG_EXTSZINHERIT;
 876	} else if (S_ISREG(ip->i_d.di_mode)) {
 877		if (xflags & XFS_XFLAG_REALTIME)
 878			di_flags |= XFS_DIFLAG_REALTIME;
 879		if (xflags & XFS_XFLAG_EXTSIZE)
 880			di_flags |= XFS_DIFLAG_EXTSIZE;
 881	}
 882
 883	ip->i_d.di_flags = di_flags;
 884}
 885
 886STATIC void
 887xfs_diflags_to_linux(
 888	struct xfs_inode	*ip)
 889{
 890	struct inode		*inode = VFS_I(ip);
 891	unsigned int		xflags = xfs_ip2xflags(ip);
 892
 893	if (xflags & XFS_XFLAG_IMMUTABLE)
 894		inode->i_flags |= S_IMMUTABLE;
 895	else
 896		inode->i_flags &= ~S_IMMUTABLE;
 897	if (xflags & XFS_XFLAG_APPEND)
 898		inode->i_flags |= S_APPEND;
 899	else
 900		inode->i_flags &= ~S_APPEND;
 901	if (xflags & XFS_XFLAG_SYNC)
 902		inode->i_flags |= S_SYNC;
 903	else
 904		inode->i_flags &= ~S_SYNC;
 905	if (xflags & XFS_XFLAG_NOATIME)
 906		inode->i_flags |= S_NOATIME;
 907	else
 908		inode->i_flags &= ~S_NOATIME;
 909}
 910
 911#define FSX_PROJID	1
 912#define FSX_EXTSIZE	2
 913#define FSX_XFLAGS	4
 914#define FSX_NONBLOCK	8
 915
 916STATIC int
 917xfs_ioctl_setattr(
 918	xfs_inode_t		*ip,
 919	struct fsxattr		*fa,
 920	int			mask)
 921{
 922	struct xfs_mount	*mp = ip->i_mount;
 923	struct xfs_trans	*tp;
 924	unsigned int		lock_flags = 0;
 925	struct xfs_dquot	*udqp = NULL;
 926	struct xfs_dquot	*gdqp = NULL;
 927	struct xfs_dquot	*olddquot = NULL;
 928	int			code;
 929
 930	trace_xfs_ioctl_setattr(ip);
 931
 932	if (mp->m_flags & XFS_MOUNT_RDONLY)
 933		return XFS_ERROR(EROFS);
 934	if (XFS_FORCED_SHUTDOWN(mp))
 935		return XFS_ERROR(EIO);
 936
 937	/*
 938	 * Disallow 32bit project ids when projid32bit feature is not enabled.
 939	 */
 940	if ((mask & FSX_PROJID) && (fa->fsx_projid > (__uint16_t)-1) &&
 941			!xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb))
 942		return XFS_ERROR(EINVAL);
 943
 944	/*
 945	 * If disk quotas is on, we make sure that the dquots do exist on disk,
 946	 * before we start any other transactions. Trying to do this later
 947	 * is messy. We don't care to take a readlock to look at the ids
 948	 * in inode here, because we can't hold it across the trans_reserve.
 949	 * If the IDs do change before we take the ilock, we're covered
 950	 * because the i_*dquot fields will get updated anyway.
 951	 */
 952	if (XFS_IS_QUOTA_ON(mp) && (mask & FSX_PROJID)) {
 953		code = xfs_qm_vop_dqalloc(ip, ip->i_d.di_uid,
 954					 ip->i_d.di_gid, fa->fsx_projid,
 955					 XFS_QMOPT_PQUOTA, &udqp, &gdqp);
 956		if (code)
 957			return code;
 958	}
 959
 960	/*
 961	 * For the other attributes, we acquire the inode lock and
 962	 * first do an error checking pass.
 963	 */
 964	tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
 965	code = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0);
 966	if (code)
 967		goto error_return;
 968
 969	lock_flags = XFS_ILOCK_EXCL;
 970	xfs_ilock(ip, lock_flags);
 971
 972	/*
 973	 * CAP_FOWNER overrides the following restrictions:
 974	 *
 975	 * The user ID of the calling process must be equal
 976	 * to the file owner ID, except in cases where the
 977	 * CAP_FSETID capability is applicable.
 978	 */
 979	if (current_fsuid() != ip->i_d.di_uid && !capable(CAP_FOWNER)) {
 980		code = XFS_ERROR(EPERM);
 981		goto error_return;
 982	}
 983
 984	/*
 985	 * Do a quota reservation only if projid is actually going to change.
 986	 */
 987	if (mask & FSX_PROJID) {
 988		if (XFS_IS_QUOTA_RUNNING(mp) &&
 989		    XFS_IS_PQUOTA_ON(mp) &&
 990		    xfs_get_projid(ip) != fa->fsx_projid) {
 991			ASSERT(tp);
 992			code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
 993						capable(CAP_FOWNER) ?
 994						XFS_QMOPT_FORCE_RES : 0);
 995			if (code)	/* out of quota */
 996				goto error_return;
 997		}
 998	}
 999
1000	if (mask & FSX_EXTSIZE) {
1001		/*
1002		 * Can't change extent size if any extents are allocated.
1003		 */
1004		if (ip->i_d.di_nextents &&
1005		    ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) !=
1006		     fa->fsx_extsize)) {
1007			code = XFS_ERROR(EINVAL);	/* EFBIG? */
1008			goto error_return;
1009		}
1010
1011		/*
1012		 * Extent size must be a multiple of the appropriate block
1013		 * size, if set at all. It must also be smaller than the
1014		 * maximum extent size supported by the filesystem.
1015		 *
1016		 * Also, for non-realtime files, limit the extent size hint to
1017		 * half the size of the AGs in the filesystem so alignment
1018		 * doesn't result in extents larger than an AG.
1019		 */
1020		if (fa->fsx_extsize != 0) {
1021			xfs_extlen_t    size;
1022			xfs_fsblock_t   extsize_fsb;
1023
1024			extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize);
1025			if (extsize_fsb > MAXEXTLEN) {
1026				code = XFS_ERROR(EINVAL);
1027				goto error_return;
1028			}
1029
1030			if (XFS_IS_REALTIME_INODE(ip) ||
1031			    ((mask & FSX_XFLAGS) &&
1032			    (fa->fsx_xflags & XFS_XFLAG_REALTIME))) {
1033				size = mp->m_sb.sb_rextsize <<
1034				       mp->m_sb.sb_blocklog;
1035			} else {
1036				size = mp->m_sb.sb_blocksize;
1037				if (extsize_fsb > mp->m_sb.sb_agblocks / 2) {
1038					code = XFS_ERROR(EINVAL);
1039					goto error_return;
1040				}
1041			}
1042
1043			if (fa->fsx_extsize % size) {
1044				code = XFS_ERROR(EINVAL);
1045				goto error_return;
1046			}
1047		}
1048	}
1049
1050
1051	if (mask & FSX_XFLAGS) {
1052		/*
1053		 * Can't change realtime flag if any extents are allocated.
1054		 */
1055		if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
1056		    (XFS_IS_REALTIME_INODE(ip)) !=
1057		    (fa->fsx_xflags & XFS_XFLAG_REALTIME)) {
1058			code = XFS_ERROR(EINVAL);	/* EFBIG? */
1059			goto error_return;
1060		}
1061
1062		/*
1063		 * If realtime flag is set then must have realtime data.
1064		 */
1065		if ((fa->fsx_xflags & XFS_XFLAG_REALTIME)) {
1066			if ((mp->m_sb.sb_rblocks == 0) ||
1067			    (mp->m_sb.sb_rextsize == 0) ||
1068			    (ip->i_d.di_extsize % mp->m_sb.sb_rextsize)) {
1069				code = XFS_ERROR(EINVAL);
1070				goto error_return;
1071			}
1072		}
1073
1074		/*
1075		 * Can't modify an immutable/append-only file unless
1076		 * we have appropriate permission.
1077		 */
1078		if ((ip->i_d.di_flags &
1079				(XFS_DIFLAG_IMMUTABLE|XFS_DIFLAG_APPEND) ||
1080		     (fa->fsx_xflags &
1081				(XFS_XFLAG_IMMUTABLE | XFS_XFLAG_APPEND))) &&
1082		    !capable(CAP_LINUX_IMMUTABLE)) {
1083			code = XFS_ERROR(EPERM);
1084			goto error_return;
1085		}
1086	}
1087
1088	xfs_trans_ijoin(tp, ip, 0);
1089
1090	/*
1091	 * Change file ownership.  Must be the owner or privileged.
1092	 */
1093	if (mask & FSX_PROJID) {
1094		/*
1095		 * CAP_FSETID overrides the following restrictions:
1096		 *
1097		 * The set-user-ID and set-group-ID bits of a file will be
1098		 * cleared upon successful return from chown()
1099		 */
1100		if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) &&
1101		    !capable(CAP_FSETID))
1102			ip->i_d.di_mode &= ~(S_ISUID|S_ISGID);
1103
1104		/*
1105		 * Change the ownerships and register quota modifications
1106		 * in the transaction.
1107		 */
1108		if (xfs_get_projid(ip) != fa->fsx_projid) {
1109			if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
1110				olddquot = xfs_qm_vop_chown(tp, ip,
1111							&ip->i_gdquot, gdqp);
1112			}
1113			xfs_set_projid(ip, fa->fsx_projid);
1114
1115			/*
1116			 * We may have to rev the inode as well as
1117			 * the superblock version number since projids didn't
1118			 * exist before DINODE_VERSION_2 and SB_VERSION_NLINK.
1119			 */
1120			if (ip->i_d.di_version == 1)
1121				xfs_bump_ino_vers2(tp, ip);
1122		}
1123
1124	}
1125
1126	if (mask & FSX_EXTSIZE)
1127		ip->i_d.di_extsize = fa->fsx_extsize >> mp->m_sb.sb_blocklog;
1128	if (mask & FSX_XFLAGS) {
1129		xfs_set_diflags(ip, fa->fsx_xflags);
1130		xfs_diflags_to_linux(ip);
1131	}
1132
1133	xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
1134	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1135
1136	XFS_STATS_INC(xs_ig_attrchg);
1137
1138	/*
1139	 * If this is a synchronous mount, make sure that the
1140	 * transaction goes to disk before returning to the user.
1141	 * This is slightly sub-optimal in that truncates require
1142	 * two sync transactions instead of one for wsync filesystems.
1143	 * One for the truncate and one for the timestamps since we
1144	 * don't want to change the timestamps unless we're sure the
1145	 * truncate worked.  Truncates are less than 1% of the laddis
1146	 * mix so this probably isn't worth the trouble to optimize.
1147	 */
1148	if (mp->m_flags & XFS_MOUNT_WSYNC)
1149		xfs_trans_set_sync(tp);
1150	code = xfs_trans_commit(tp, 0);
1151	xfs_iunlock(ip, lock_flags);
1152
1153	/*
1154	 * Release any dquot(s) the inode had kept before chown.
1155	 */
1156	xfs_qm_dqrele(olddquot);
1157	xfs_qm_dqrele(udqp);
1158	xfs_qm_dqrele(gdqp);
1159
1160	return code;
1161
1162 error_return:
1163	xfs_qm_dqrele(udqp);
1164	xfs_qm_dqrele(gdqp);
1165	xfs_trans_cancel(tp, 0);
1166	if (lock_flags)
1167		xfs_iunlock(ip, lock_flags);
1168	return code;
1169}
1170
1171STATIC int
1172xfs_ioc_fssetxattr(
1173	xfs_inode_t		*ip,
1174	struct file		*filp,
1175	void			__user *arg)
1176{
1177	struct fsxattr		fa;
1178	unsigned int		mask;
1179	int error;
1180
1181	if (copy_from_user(&fa, arg, sizeof(fa)))
1182		return -EFAULT;
1183
1184	mask = FSX_XFLAGS | FSX_EXTSIZE | FSX_PROJID;
1185	if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
1186		mask |= FSX_NONBLOCK;
1187
1188	error = mnt_want_write_file(filp);
1189	if (error)
1190		return error;
1191	error = xfs_ioctl_setattr(ip, &fa, mask);
1192	mnt_drop_write_file(filp);
1193	return -error;
1194}
1195
1196STATIC int
1197xfs_ioc_getxflags(
1198	xfs_inode_t		*ip,
1199	void			__user *arg)
1200{
1201	unsigned int		flags;
1202
1203	flags = xfs_di2lxflags(ip->i_d.di_flags);
1204	if (copy_to_user(arg, &flags, sizeof(flags)))
1205		return -EFAULT;
1206	return 0;
1207}
1208
1209STATIC int
1210xfs_ioc_setxflags(
1211	xfs_inode_t		*ip,
1212	struct file		*filp,
1213	void			__user *arg)
1214{
1215	struct fsxattr		fa;
1216	unsigned int		flags;
1217	unsigned int		mask;
1218	int error;
1219
1220	if (copy_from_user(&flags, arg, sizeof(flags)))
1221		return -EFAULT;
1222
1223	if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \
1224		      FS_NOATIME_FL | FS_NODUMP_FL | \
1225		      FS_SYNC_FL))
1226		return -EOPNOTSUPP;
1227
1228	mask = FSX_XFLAGS;
1229	if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
1230		mask |= FSX_NONBLOCK;
1231	fa.fsx_xflags = xfs_merge_ioc_xflags(flags, xfs_ip2xflags(ip));
1232
1233	error = mnt_want_write_file(filp);
1234	if (error)
1235		return error;
1236	error = xfs_ioctl_setattr(ip, &fa, mask);
1237	mnt_drop_write_file(filp);
1238	return -error;
1239}
1240
1241STATIC int
1242xfs_getbmap_format(void **ap, struct getbmapx *bmv, int *full)
1243{
1244	struct getbmap __user	*base = *ap;
1245
1246	/* copy only getbmap portion (not getbmapx) */
1247	if (copy_to_user(base, bmv, sizeof(struct getbmap)))
1248		return XFS_ERROR(EFAULT);
1249
1250	*ap += sizeof(struct getbmap);
1251	return 0;
1252}
1253
1254STATIC int
1255xfs_ioc_getbmap(
1256	struct xfs_inode	*ip,
1257	int			ioflags,
1258	unsigned int		cmd,
1259	void			__user *arg)
1260{
1261	struct getbmapx		bmx;
1262	int			error;
1263
1264	if (copy_from_user(&bmx, arg, sizeof(struct getbmapx)))
1265		return -XFS_ERROR(EFAULT);
1266
1267	if (bmx.bmv_count < 2)
1268		return -XFS_ERROR(EINVAL);
1269
1270	bmx.bmv_iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0);
1271	if (ioflags & IO_INVIS)
1272		bmx.bmv_iflags |= BMV_IF_NO_DMAPI_READ;
1273
1274	error = xfs_getbmap(ip, &bmx, xfs_getbmap_format,
1275			    (struct getbmap *)arg+1);
1276	if (error)
1277		return -error;
1278
1279	/* copy back header - only size of getbmap */
1280	if (copy_to_user(arg, &bmx, sizeof(struct getbmap)))
1281		return -XFS_ERROR(EFAULT);
1282	return 0;
1283}
1284
1285STATIC int
1286xfs_getbmapx_format(void **ap, struct getbmapx *bmv, int *full)
1287{
1288	struct getbmapx __user	*base = *ap;
1289
1290	if (copy_to_user(base, bmv, sizeof(struct getbmapx)))
1291		return XFS_ERROR(EFAULT);
1292
1293	*ap += sizeof(struct getbmapx);
1294	return 0;
1295}
1296
1297STATIC int
1298xfs_ioc_getbmapx(
1299	struct xfs_inode	*ip,
1300	void			__user *arg)
1301{
1302	struct getbmapx		bmx;
1303	int			error;
1304
1305	if (copy_from_user(&bmx, arg, sizeof(bmx)))
1306		return -XFS_ERROR(EFAULT);
1307
1308	if (bmx.bmv_count < 2)
1309		return -XFS_ERROR(EINVAL);
1310
1311	if (bmx.bmv_iflags & (~BMV_IF_VALID))
1312		return -XFS_ERROR(EINVAL);
1313
1314	error = xfs_getbmap(ip, &bmx, xfs_getbmapx_format,
1315			    (struct getbmapx *)arg+1);
1316	if (error)
1317		return -error;
1318
1319	/* copy back header */
1320	if (copy_to_user(arg, &bmx, sizeof(struct getbmapx)))
1321		return -XFS_ERROR(EFAULT);
1322
1323	return 0;
1324}
1325
1326/*
1327 * Note: some of the ioctl's return positive numbers as a
1328 * byte count indicating success, such as readlink_by_handle.
1329 * So we don't "sign flip" like most other routines.  This means
1330 * true errors need to be returned as a negative value.
1331 */
1332long
1333xfs_file_ioctl(
1334	struct file		*filp,
1335	unsigned int		cmd,
1336	unsigned long		p)
1337{
1338	struct inode		*inode = filp->f_path.dentry->d_inode;
1339	struct xfs_inode	*ip = XFS_I(inode);
1340	struct xfs_mount	*mp = ip->i_mount;
1341	void			__user *arg = (void __user *)p;
1342	int			ioflags = 0;
1343	int			error;
1344
1345	if (filp->f_mode & FMODE_NOCMTIME)
1346		ioflags |= IO_INVIS;
1347
1348	trace_xfs_file_ioctl(ip);
1349
1350	switch (cmd) {
1351	case FITRIM:
1352		return xfs_ioc_trim(mp, arg);
1353	case XFS_IOC_ALLOCSP:
1354	case XFS_IOC_FREESP:
1355	case XFS_IOC_RESVSP:
1356	case XFS_IOC_UNRESVSP:
1357	case XFS_IOC_ALLOCSP64:
1358	case XFS_IOC_FREESP64:
1359	case XFS_IOC_RESVSP64:
1360	case XFS_IOC_UNRESVSP64:
1361	case XFS_IOC_ZERO_RANGE: {
1362		xfs_flock64_t		bf;
1363
1364		if (copy_from_user(&bf, arg, sizeof(bf)))
1365			return -XFS_ERROR(EFAULT);
1366		return xfs_ioc_space(ip, inode, filp, ioflags, cmd, &bf);
1367	}
1368	case XFS_IOC_DIOINFO: {
1369		struct dioattr	da;
1370		xfs_buftarg_t	*target =
1371			XFS_IS_REALTIME_INODE(ip) ?
1372			mp->m_rtdev_targp : mp->m_ddev_targp;
1373
1374		da.d_mem = da.d_miniosz = 1 << target->bt_sshift;
1375		da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
1376
1377		if (copy_to_user(arg, &da, sizeof(da)))
1378			return -XFS_ERROR(EFAULT);
1379		return 0;
1380	}
1381
1382	case XFS_IOC_FSBULKSTAT_SINGLE:
1383	case XFS_IOC_FSBULKSTAT:
1384	case XFS_IOC_FSINUMBERS:
1385		return xfs_ioc_bulkstat(mp, cmd, arg);
1386
1387	case XFS_IOC_FSGEOMETRY_V1:
1388		return xfs_ioc_fsgeometry_v1(mp, arg);
1389
1390	case XFS_IOC_FSGEOMETRY:
1391		return xfs_ioc_fsgeometry(mp, arg);
1392
1393	case XFS_IOC_GETVERSION:
1394		return put_user(inode->i_generation, (int __user *)arg);
1395
1396	case XFS_IOC_FSGETXATTR:
1397		return xfs_ioc_fsgetxattr(ip, 0, arg);
1398	case XFS_IOC_FSGETXATTRA:
1399		return xfs_ioc_fsgetxattr(ip, 1, arg);
1400	case XFS_IOC_FSSETXATTR:
1401		return xfs_ioc_fssetxattr(ip, filp, arg);
1402	case XFS_IOC_GETXFLAGS:
1403		return xfs_ioc_getxflags(ip, arg);
1404	case XFS_IOC_SETXFLAGS:
1405		return xfs_ioc_setxflags(ip, filp, arg);
1406
1407	case XFS_IOC_FSSETDM: {
1408		struct fsdmidata	dmi;
1409
1410		if (copy_from_user(&dmi, arg, sizeof(dmi)))
1411			return -XFS_ERROR(EFAULT);
1412
1413		error = mnt_want_write_file(filp);
1414		if (error)
1415			return error;
1416
1417		error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask,
1418				dmi.fsd_dmstate);
1419		mnt_drop_write_file(filp);
1420		return -error;
1421	}
1422
1423	case XFS_IOC_GETBMAP:
1424	case XFS_IOC_GETBMAPA:
1425		return xfs_ioc_getbmap(ip, ioflags, cmd, arg);
1426
1427	case XFS_IOC_GETBMAPX:
1428		return xfs_ioc_getbmapx(ip, arg);
1429
1430	case XFS_IOC_FD_TO_HANDLE:
1431	case XFS_IOC_PATH_TO_HANDLE:
1432	case XFS_IOC_PATH_TO_FSHANDLE: {
1433		xfs_fsop_handlereq_t	hreq;
1434
1435		if (copy_from_user(&hreq, arg, sizeof(hreq)))
1436			return -XFS_ERROR(EFAULT);
1437		return xfs_find_handle(cmd, &hreq);
1438	}
1439	case XFS_IOC_OPEN_BY_HANDLE: {
1440		xfs_fsop_handlereq_t	hreq;
1441
1442		if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
1443			return -XFS_ERROR(EFAULT);
1444		return xfs_open_by_handle(filp, &hreq);
1445	}
1446	case XFS_IOC_FSSETDM_BY_HANDLE:
1447		return xfs_fssetdm_by_handle(filp, arg);
1448
1449	case XFS_IOC_READLINK_BY_HANDLE: {
1450		xfs_fsop_handlereq_t	hreq;
1451
1452		if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
1453			return -XFS_ERROR(EFAULT);
1454		return xfs_readlink_by_handle(filp, &hreq);
1455	}
1456	case XFS_IOC_ATTRLIST_BY_HANDLE:
1457		return xfs_attrlist_by_handle(filp, arg);
1458
1459	case XFS_IOC_ATTRMULTI_BY_HANDLE:
1460		return xfs_attrmulti_by_handle(filp, arg);
1461
1462	case XFS_IOC_SWAPEXT: {
1463		struct xfs_swapext	sxp;
1464
1465		if (copy_from_user(&sxp, arg, sizeof(xfs_swapext_t)))
1466			return -XFS_ERROR(EFAULT);
1467		error = mnt_want_write_file(filp);
1468		if (error)
1469			return error;
1470		error = xfs_swapext(&sxp);
1471		mnt_drop_write_file(filp);
1472		return -error;
1473	}
1474
1475	case XFS_IOC_FSCOUNTS: {
1476		xfs_fsop_counts_t out;
1477
1478		error = xfs_fs_counts(mp, &out);
1479		if (error)
1480			return -error;
1481
1482		if (copy_to_user(arg, &out, sizeof(out)))
1483			return -XFS_ERROR(EFAULT);
1484		return 0;
1485	}
1486
1487	case XFS_IOC_SET_RESBLKS: {
1488		xfs_fsop_resblks_t inout;
1489		__uint64_t	   in;
1490
1491		if (!capable(CAP_SYS_ADMIN))
1492			return -EPERM;
1493
1494		if (mp->m_flags & XFS_MOUNT_RDONLY)
1495			return -XFS_ERROR(EROFS);
1496
1497		if (copy_from_user(&inout, arg, sizeof(inout)))
1498			return -XFS_ERROR(EFAULT);
1499
1500		error = mnt_want_write_file(filp);
1501		if (error)
1502			return error;
1503
1504		/* input parameter is passed in resblks field of structure */
1505		in = inout.resblks;
1506		error = xfs_reserve_blocks(mp, &in, &inout);
1507		mnt_drop_write_file(filp);
1508		if (error)
1509			return -error;
1510
1511		if (copy_to_user(arg, &inout, sizeof(inout)))
1512			return -XFS_ERROR(EFAULT);
1513		return 0;
1514	}
1515
1516	case XFS_IOC_GET_RESBLKS: {
1517		xfs_fsop_resblks_t out;
1518
1519		if (!capable(CAP_SYS_ADMIN))
1520			return -EPERM;
1521
1522		error = xfs_reserve_blocks(mp, NULL, &out);
1523		if (error)
1524			return -error;
1525
1526		if (copy_to_user(arg, &out, sizeof(out)))
1527			return -XFS_ERROR(EFAULT);
1528
1529		return 0;
1530	}
1531
1532	case XFS_IOC_FSGROWFSDATA: {
1533		xfs_growfs_data_t in;
1534
1535		if (copy_from_user(&in, arg, sizeof(in)))
1536			return -XFS_ERROR(EFAULT);
1537
1538		error = mnt_want_write_file(filp);
1539		if (error)
1540			return error;
1541		error = xfs_growfs_data(mp, &in);
1542		mnt_drop_write_file(filp);
1543		return -error;
1544	}
1545
1546	case XFS_IOC_FSGROWFSLOG: {
1547		xfs_growfs_log_t in;
1548
1549		if (copy_from_user(&in, arg, sizeof(in)))
1550			return -XFS_ERROR(EFAULT);
1551
1552		error = mnt_want_write_file(filp);
1553		if (error)
1554			return error;
1555		error = xfs_growfs_log(mp, &in);
1556		mnt_drop_write_file(filp);
1557		return -error;
1558	}
1559
1560	case XFS_IOC_FSGROWFSRT: {
1561		xfs_growfs_rt_t in;
1562
1563		if (copy_from_user(&in, arg, sizeof(in)))
1564			return -XFS_ERROR(EFAULT);
1565
1566		error = mnt_want_write_file(filp);
1567		if (error)
1568			return error;
1569		error = xfs_growfs_rt(mp, &in);
1570		mnt_drop_write_file(filp);
1571		return -error;
1572	}
1573
1574	case XFS_IOC_GOINGDOWN: {
1575		__uint32_t in;
1576
1577		if (!capable(CAP_SYS_ADMIN))
1578			return -EPERM;
1579
1580		if (get_user(in, (__uint32_t __user *)arg))
1581			return -XFS_ERROR(EFAULT);
1582
1583		error = xfs_fs_goingdown(mp, in);
1584		return -error;
1585	}
1586
1587	case XFS_IOC_ERROR_INJECTION: {
1588		xfs_error_injection_t in;
1589
1590		if (!capable(CAP_SYS_ADMIN))
1591			return -EPERM;
1592
1593		if (copy_from_user(&in, arg, sizeof(in)))
1594			return -XFS_ERROR(EFAULT);
1595
1596		error = xfs_errortag_add(in.errtag, mp);
1597		return -error;
1598	}
1599
1600	case XFS_IOC_ERROR_CLEARALL:
1601		if (!capable(CAP_SYS_ADMIN))
1602			return -EPERM;
1603
1604		error = xfs_errortag_clearall(mp, 1);
1605		return -error;
1606
1607	case XFS_IOC_FREE_EOFBLOCKS: {
1608		struct xfs_eofblocks eofb;
1609
1610		if (!capable(CAP_SYS_ADMIN))
1611			return -EPERM;
1612
1613		if (mp->m_flags & XFS_MOUNT_RDONLY)
1614			return -XFS_ERROR(EROFS);
1615
1616		if (copy_from_user(&eofb, arg, sizeof(eofb)))
1617			return -XFS_ERROR(EFAULT);
1618
1619		if (eofb.eof_version != XFS_EOFBLOCKS_VERSION)
1620			return -XFS_ERROR(EINVAL);
1621
1622		if (eofb.eof_flags & ~XFS_EOF_FLAGS_VALID)
1623			return -XFS_ERROR(EINVAL);
1624
1625		if (memchr_inv(&eofb.pad32, 0, sizeof(eofb.pad32)) ||
1626		    memchr_inv(eofb.pad64, 0, sizeof(eofb.pad64)))
1627			return -XFS_ERROR(EINVAL);
1628
1629		error = xfs_icache_free_eofblocks(mp, &eofb);
1630		return -error;
1631	}
1632
1633	default:
1634		return -ENOTTY;
1635	}
1636}