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