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