LCOV - code coverage report
Current view: top level - fs/xfs - xfs_ioctl.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsa @ Mon Jul 31 20:08:27 PDT 2023 Lines: 897 1167 76.9 %
Date: 2023-07-31 20:08:27 Functions: 43 47 91.5 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
       4             :  * All Rights Reserved.
       5             :  */
       6             : #include "xfs.h"
       7             : #include "xfs_fs.h"
       8             : #include "xfs_shared.h"
       9             : #include "xfs_format.h"
      10             : #include "xfs_log_format.h"
      11             : #include "xfs_trans_resv.h"
      12             : #include "xfs_mount.h"
      13             : #include "xfs_inode.h"
      14             : #include "xfs_rtalloc.h"
      15             : #include "xfs_iwalk.h"
      16             : #include "xfs_itable.h"
      17             : #include "xfs_error.h"
      18             : #include "xfs_da_format.h"
      19             : #include "xfs_da_btree.h"
      20             : #include "xfs_attr.h"
      21             : #include "xfs_bmap.h"
      22             : #include "xfs_bmap_util.h"
      23             : #include "xfs_fsops.h"
      24             : #include "xfs_discard.h"
      25             : #include "xfs_quota.h"
      26             : #include "xfs_export.h"
      27             : #include "xfs_trace.h"
      28             : #include "xfs_icache.h"
      29             : #include "xfs_trans.h"
      30             : #include "xfs_acl.h"
      31             : #include "xfs_btree.h"
      32             : #include <linux/fsmap.h>
      33             : #include "xfs_fsmap.h"
      34             : #include "xfs_fsrefs.h"
      35             : #include "scrub/xfs_scrub.h"
      36             : #include "xfs_sb.h"
      37             : #include "xfs_ag.h"
      38             : #include "xfs_health.h"
      39             : #include "xfs_reflink.h"
      40             : #include "xfs_ioctl.h"
      41             : #include "xfs_parent_utils.h"
      42             : #include "xfs_xattr.h"
      43             : #include "xfs_xchgrange.h"
      44             : #include "xfs_file.h"
      45             : #include "xfs_rtbitmap.h"
      46             : #include "xfs_rtgroup.h"
      47             : 
      48             : #include <linux/mount.h>
      49             : #include <linux/namei.h>
      50             : #include <linux/fileattr.h>
      51             : 
      52             : /*
      53             :  * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to
      54             :  * a file or fs handle.
      55             :  *
      56             :  * XFS_IOC_PATH_TO_FSHANDLE
      57             :  *    returns fs handle for a mount point or path within that mount point
      58             :  * XFS_IOC_FD_TO_HANDLE
      59             :  *    returns full handle for a FD opened in user space
      60             :  * XFS_IOC_PATH_TO_HANDLE
      61             :  *    returns full handle for a path
      62             :  */
      63             : int
      64       26244 : xfs_find_handle(
      65             :         unsigned int            cmd,
      66             :         xfs_fsop_handlereq_t    *hreq)
      67             : {
      68       26244 :         int                     hsize;
      69       26244 :         xfs_handle_t            handle;
      70       26244 :         struct inode            *inode;
      71       26244 :         struct fd               f = {NULL};
      72       26244 :         struct path             path;
      73       26244 :         int                     error;
      74       26244 :         struct xfs_inode        *ip;
      75             : 
      76       26244 :         if (cmd == XFS_IOC_FD_TO_HANDLE) {
      77         436 :                 f = fdget(hreq->fd);
      78         436 :                 if (!f.file)
      79             :                         return -EBADF;
      80         436 :                 inode = file_inode(f.file);
      81             :         } else {
      82       25808 :                 error = user_path_at(AT_FDCWD, hreq->path, 0, &path);
      83       25808 :                 if (error)
      84             :                         return error;
      85       25808 :                 inode = d_inode(path.dentry);
      86             :         }
      87       26244 :         ip = XFS_I(inode);
      88             : 
      89             :         /*
      90             :          * We can only generate handles for inodes residing on a XFS filesystem,
      91             :          * and only for regular files, directories or symbolic links.
      92             :          */
      93       26244 :         error = -EINVAL;
      94       26244 :         if (inode->i_sb->s_magic != XFS_SB_MAGIC)
      95           0 :                 goto out_put;
      96             : 
      97       26244 :         error = -EBADF;
      98       26244 :         if (!S_ISREG(inode->i_mode) &&
      99           0 :             !S_ISDIR(inode->i_mode) &&
     100             :             !S_ISLNK(inode->i_mode))
     101           0 :                 goto out_put;
     102             : 
     103             : 
     104       26244 :         memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
     105             : 
     106       26244 :         if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
     107             :                 /*
     108             :                  * This handle only contains an fsid, zero the rest.
     109             :                  */
     110       22772 :                 memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
     111       22772 :                 hsize = sizeof(xfs_fsid_t);
     112             :         } else {
     113        3472 :                 handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
     114             :                                         sizeof(handle.ha_fid.fid_len);
     115        3472 :                 handle.ha_fid.fid_pad = 0;
     116        3472 :                 handle.ha_fid.fid_gen = inode->i_generation;
     117        3472 :                 handle.ha_fid.fid_ino = ip->i_ino;
     118        3472 :                 hsize = sizeof(xfs_handle_t);
     119             :         }
     120             : 
     121       26244 :         error = -EFAULT;
     122       78732 :         if (copy_to_user(hreq->ohandle, &handle, hsize) ||
     123       26244 :             copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
     124           0 :                 goto out_put;
     125             : 
     126             :         error = 0;
     127             : 
     128       26244 :  out_put:
     129       26244 :         if (cmd == XFS_IOC_FD_TO_HANDLE)
     130         436 :                 fdput(f);
     131             :         else
     132       25808 :                 path_put(&path);
     133             :         return error;
     134             : }
     135             : 
     136             : /*
     137             :  * No need to do permission checks on the various pathname components
     138             :  * as the handle operations are privileged.
     139             :  */
     140             : STATIC int
     141   168187985 : xfs_handle_acceptable(
     142             :         void                    *context,
     143             :         struct dentry           *dentry)
     144             : {
     145   168187985 :         return 1;
     146             : }
     147             : 
     148             : /*
     149             :  * Convert userspace handle data into a dentry.
     150             :  */
     151             : struct dentry *
     152   168214772 : xfs_handle_to_dentry(
     153             :         struct file             *parfilp,
     154             :         void __user             *uhandle,
     155             :         u32                     hlen)
     156             : {
     157   168214772 :         xfs_handle_t            handle;
     158   168214772 :         struct xfs_fid64        fid;
     159             : 
     160             :         /*
     161             :          * Only allow handle opens under a directory.
     162             :          */
     163   168214772 :         if (!S_ISDIR(file_inode(parfilp)->i_mode))
     164             :                 return ERR_PTR(-ENOTDIR);
     165             : 
     166   168215934 :         if (hlen != sizeof(xfs_handle_t))
     167             :                 return ERR_PTR(-EINVAL);
     168   168215428 :         if (copy_from_user(&handle, uhandle, hlen))
     169             :                 return ERR_PTR(-EFAULT);
     170   168219409 :         if (handle.ha_fid.fid_len !=
     171             :             sizeof(handle.ha_fid) - sizeof(handle.ha_fid.fid_len))
     172             :                 return ERR_PTR(-EINVAL);
     173             : 
     174   168217701 :         memset(&fid, 0, sizeof(struct fid));
     175   168217701 :         fid.ino = handle.ha_fid.fid_ino;
     176   168217701 :         fid.gen = handle.ha_fid.fid_gen;
     177             : 
     178   168217701 :         return exportfs_decode_fh(parfilp->f_path.mnt, (struct fid *)&fid, 3,
     179             :                         FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG,
     180             :                         xfs_handle_acceptable, NULL);
     181             : }
     182             : 
     183             : STATIC struct dentry *
     184   168210384 : xfs_handlereq_to_dentry(
     185             :         struct file             *parfilp,
     186             :         xfs_fsop_handlereq_t    *hreq)
     187             : {
     188   168210384 :         return xfs_handle_to_dentry(parfilp, hreq->ihandle, hreq->ihandlen);
     189             : }
     190             : 
     191             : int
     192    33293157 : xfs_open_by_handle(
     193             :         struct file             *parfilp,
     194             :         xfs_fsop_handlereq_t    *hreq)
     195             : {
     196    33293157 :         const struct cred       *cred = current_cred();
     197    33293157 :         int                     error;
     198    33293157 :         int                     fd;
     199    33293157 :         int                     permflag;
     200    33293157 :         struct file             *filp;
     201    33293157 :         struct inode            *inode;
     202    33293157 :         struct dentry           *dentry;
     203    33293157 :         fmode_t                 fmode;
     204    33293157 :         struct path             path;
     205             : 
     206    33293157 :         if (!capable(CAP_SYS_ADMIN))
     207             :                 return -EPERM;
     208             : 
     209    33293120 :         dentry = xfs_handlereq_to_dentry(parfilp, hreq);
     210    33292939 :         if (IS_ERR(dentry))
     211        2084 :                 return PTR_ERR(dentry);
     212    33290855 :         inode = d_inode(dentry);
     213             : 
     214             :         /* Restrict xfs_open_by_handle to directories & regular files. */
     215    33290855 :         if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
     216           0 :                 error = -EPERM;
     217           0 :                 goto out_dput;
     218             :         }
     219             : 
     220             : #if BITS_PER_LONG != 32
     221    33290855 :         hreq->oflags |= O_LARGEFILE;
     222             : #endif
     223             : 
     224    33290855 :         permflag = hreq->oflags;
     225    33290855 :         fmode = OPEN_FMODE(permflag);
     226    33290855 :         if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
     227    33290846 :             (fmode & FMODE_WRITE) && IS_APPEND(inode)) {
     228          12 :                 error = -EPERM;
     229          12 :                 goto out_dput;
     230             :         }
     231             : 
     232    33290843 :         if ((fmode & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
     233          16 :                 error = -EPERM;
     234          16 :                 goto out_dput;
     235             :         }
     236             : 
     237             :         /* Can't write directories. */
     238    33290827 :         if (S_ISDIR(inode->i_mode) && (fmode & FMODE_WRITE)) {
     239           0 :                 error = -EISDIR;
     240           0 :                 goto out_dput;
     241             :         }
     242             : 
     243    33290827 :         fd = get_unused_fd_flags(0);
     244    33291450 :         if (fd < 0) {
     245           0 :                 error = fd;
     246           0 :                 goto out_dput;
     247             :         }
     248             : 
     249    33291450 :         path.mnt = parfilp->f_path.mnt;
     250    33291450 :         path.dentry = dentry;
     251    33291450 :         filp = dentry_open(&path, hreq->oflags, cred);
     252    33290930 :         dput(dentry);
     253    33290988 :         if (IS_ERR(filp)) {
     254           0 :                 put_unused_fd(fd);
     255           0 :                 return PTR_ERR(filp);
     256             :         }
     257             : 
     258    33290988 :         if (S_ISREG(inode->i_mode)) {
     259    22147193 :                 filp->f_flags |= O_NOATIME;
     260    22147193 :                 filp->f_mode |= FMODE_NOCMTIME;
     261             :         }
     262             : 
     263    33290988 :         fd_install(fd, filp);
     264    33290988 :         return fd;
     265             : 
     266          28 :  out_dput:
     267          28 :         dput(dentry);
     268          28 :         return error;
     269             : }
     270             : 
     271             : int
     272         184 : xfs_readlink_by_handle(
     273             :         struct file             *parfilp,
     274             :         xfs_fsop_handlereq_t    *hreq)
     275             : {
     276         184 :         struct dentry           *dentry;
     277         184 :         __u32                   olen;
     278         184 :         int                     error;
     279             : 
     280         184 :         if (!capable(CAP_SYS_ADMIN))
     281             :                 return -EPERM;
     282             : 
     283         184 :         dentry = xfs_handlereq_to_dentry(parfilp, hreq);
     284         184 :         if (IS_ERR(dentry))
     285           0 :                 return PTR_ERR(dentry);
     286             : 
     287             :         /* Restrict this handle operation to symlinks only. */
     288         184 :         if (!d_is_symlink(dentry)) {
     289           2 :                 error = -EINVAL;
     290           2 :                 goto out_dput;
     291             :         }
     292             : 
     293         182 :         if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) {
     294           0 :                 error = -EFAULT;
     295           0 :                 goto out_dput;
     296             :         }
     297             : 
     298         182 :         error = vfs_readlink(dentry, hreq->ohandle, olen);
     299             : 
     300         184 :  out_dput:
     301         184 :         dput(dentry);
     302         184 :         return error;
     303             : }
     304             : 
     305             : /*
     306             :  * Format an attribute and copy it out to the user's buffer.
     307             :  * Take care to check values and protect against them changing later,
     308             :  * we may be reading them directly out of a user buffer.
     309             :  */
     310             : static void
     311   271239910 : xfs_ioc_attr_put_listent(
     312             :         struct xfs_attr_list_context *context,
     313             :         int                     flags,
     314             :         unsigned char           *name,
     315             :         int                     namelen,
     316             :         void                    *value,
     317             :         int                     valuelen)
     318             : {
     319   271239910 :         struct xfs_attrlist     *alist = context->buffer;
     320   271239910 :         struct xfs_attrlist_ent *aep;
     321   271239910 :         int                     arraytop;
     322             : 
     323   271239910 :         ASSERT(!context->seen_enough);
     324   271239910 :         ASSERT(context->count >= 0);
     325   271239910 :         ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
     326   271239910 :         ASSERT(context->firstu >= sizeof(*alist));
     327   271239910 :         ASSERT(context->firstu <= context->bufsize);
     328             : 
     329             :         /*
     330             :          * Only list entries in the right namespace.
     331             :          */
     332   271239910 :         if (context->attr_filter != (flags & XFS_ATTR_NSP_ONDISK_MASK))
     333             :                 return;
     334             : 
     335    39378140 :         arraytop = sizeof(*alist) +
     336    39378140 :                         context->count * sizeof(alist->al_offset[0]);
     337             : 
     338             :         /* decrement by the actual bytes used by the attr */
     339    39378140 :         context->firstu -= round_up(offsetof(struct xfs_attrlist_ent, a_name) +
     340             :                         namelen + 1, sizeof(uint32_t));
     341    39378140 :         if (context->firstu < arraytop) {
     342         365 :                 trace_xfs_attr_list_full(context);
     343         365 :                 alist->al_more = 1;
     344         365 :                 context->seen_enough = 1;
     345         365 :                 return;
     346             :         }
     347             : 
     348    39377775 :         aep = context->buffer + context->firstu;
     349    39377775 :         aep->a_valuelen = valuelen;
     350    78755550 :         memcpy(aep->a_name, name, namelen);
     351    39377775 :         aep->a_name[namelen] = 0;
     352    39377775 :         alist->al_offset[context->count++] = context->firstu;
     353    39377775 :         alist->al_count = context->count;
     354    39377775 :         trace_xfs_attr_list_add(context);
     355             : }
     356             : 
     357             : static unsigned int
     358             : xfs_attr_filter(
     359             :         u32                     ioc_flags)
     360             : {
     361   134917980 :         if (ioc_flags & XFS_IOC_ATTR_ROOT)
     362             :                 return XFS_ATTR_ROOT;
     363    89942830 :         if (ioc_flags & XFS_IOC_ATTR_SECURE)
     364    44975407 :                 return XFS_ATTR_SECURE;
     365             :         return 0;
     366             : }
     367             : 
     368             : static unsigned int
     369             : xfs_attr_flags(
     370             :         u32                     ioc_flags)
     371             : {
     372         140 :         if (ioc_flags & XFS_IOC_ATTR_CREATE)
     373             :                 return XATTR_CREATE;
     374         140 :         if (ioc_flags & XFS_IOC_ATTR_REPLACE)
     375           0 :                 return XATTR_REPLACE;
     376             :         return 0;
     377             : }
     378             : 
     379             : int
     380   134912245 : xfs_ioc_attr_list(
     381             :         struct xfs_inode                *dp,
     382             :         void __user                     *ubuf,
     383             :         size_t                          bufsize,
     384             :         int                             flags,
     385             :         struct xfs_attrlist_cursor __user *ucursor)
     386             : {
     387   134912245 :         struct xfs_attr_list_context    context = { };
     388   134912245 :         struct xfs_attrlist             *alist;
     389   134912245 :         void                            *buffer;
     390   134912245 :         int                             error;
     391             : 
     392   134912245 :         if (bufsize < sizeof(struct xfs_attrlist) ||
     393             :             bufsize > XFS_XATTR_LIST_MAX)
     394             :                 return -EINVAL;
     395             : 
     396             :         /*
     397             :          * Reject flags, only allow namespaces.
     398             :          */
     399   134912245 :         if (flags & ~(XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
     400             :                 return -EINVAL;
     401   134912245 :         if (flags == (XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
     402             :                 return -EINVAL;
     403             : 
     404             :         /*
     405             :          * Validate the cursor.
     406             :          */
     407   134912245 :         if (copy_from_user(&context.cursor, ucursor, sizeof(context.cursor)))
     408             :                 return -EFAULT;
     409   134916694 :         if (context.cursor.pad1 || context.cursor.pad2)
     410             :                 return -EINVAL;
     411   134916694 :         if (!context.cursor.initted &&
     412   134916329 :             (context.cursor.hashval || context.cursor.blkno ||
     413   134916329 :              context.cursor.offset))
     414             :                 return -EINVAL;
     415             : 
     416   134916694 :         buffer = kvzalloc(bufsize, GFP_KERNEL);
     417   134917840 :         if (!buffer)
     418             :                 return -ENOMEM;
     419             : 
     420             :         /*
     421             :          * Initialize the output buffer.
     422             :          */
     423   134917840 :         context.dp = dp;
     424   134917840 :         context.resynch = 1;
     425   134917840 :         context.attr_filter = xfs_attr_filter(flags);
     426   134917840 :         context.buffer = buffer;
     427   134917840 :         context.bufsize = round_down(bufsize, sizeof(uint32_t));
     428   134917840 :         context.firstu = context.bufsize;
     429   134917840 :         context.put_listent = xfs_ioc_attr_put_listent;
     430             : 
     431   134917840 :         alist = context.buffer;
     432   134917840 :         alist->al_count = 0;
     433   134917840 :         alist->al_more = 0;
     434   134917840 :         alist->al_offset[0] = context.bufsize;
     435             : 
     436   134917840 :         error = xfs_attr_list(&context);
     437   134904492 :         if (error)
     438           0 :                 goto out_free;
     439             : 
     440   404714082 :         if (copy_to_user(ubuf, buffer, bufsize) ||
     441             :             copy_to_user(ucursor, &context.cursor, sizeof(context.cursor)))
     442             :                 error = -EFAULT;
     443   134910033 : out_free:
     444   134910033 :         kmem_free(buffer);
     445   134910033 :         return error;
     446             : }
     447             : 
     448             : STATIC int
     449   134913826 : xfs_attrlist_by_handle(
     450             :         struct file             *parfilp,
     451             :         struct xfs_fsop_attrlist_handlereq __user *p)
     452             : {
     453   134913826 :         struct xfs_fsop_attrlist_handlereq al_hreq;
     454   134913826 :         struct dentry           *dentry;
     455   134913826 :         int                     error = -ENOMEM;
     456             : 
     457   134913826 :         if (!capable(CAP_SYS_ADMIN))
     458             :                 return -EPERM;
     459   134915993 :         if (copy_from_user(&al_hreq, p, sizeof(al_hreq)))
     460             :                 return -EFAULT;
     461             : 
     462   134917181 :         dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
     463   134905769 :         if (IS_ERR(dentry))
     464         167 :                 return PTR_ERR(dentry);
     465             : 
     466   134905602 :         error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), al_hreq.buffer,
     467   134905602 :                                   al_hreq.buflen, al_hreq.flags, &p->pos);
     468   134909726 :         dput(dentry);
     469   134909726 :         return error;
     470             : }
     471             : 
     472             : static int
     473         140 : xfs_attrmulti_attr_get(
     474             :         struct inode            *inode,
     475             :         unsigned char           *name,
     476             :         unsigned char           __user *ubuf,
     477             :         uint32_t                *len,
     478             :         uint32_t                flags)
     479             : {
     480         420 :         struct xfs_da_args      args = {
     481             :                 .dp             = XFS_I(inode),
     482             :                 .attr_filter    = xfs_attr_filter(flags),
     483             :                 .attr_flags     = xfs_attr_flags(flags),
     484             :                 .name           = name,
     485             :                 .namelen        = strlen(name),
     486         140 :                 .valuelen       = *len,
     487         140 :                 .owner          = XFS_I(inode)->i_ino,
     488             :         };
     489         140 :         int                     error;
     490             : 
     491         140 :         if (*len > XFS_XATTR_SIZE_MAX)
     492             :                 return -EINVAL;
     493             : 
     494         140 :         error = xfs_attr_get(&args);
     495         140 :         if (error)
     496           0 :                 goto out_kfree;
     497             : 
     498         140 :         *len = args.valuelen;
     499         280 :         if (copy_to_user(ubuf, args.value, args.valuelen))
     500           0 :                 error = -EFAULT;
     501             : 
     502         140 : out_kfree:
     503         140 :         kmem_free(args.value);
     504         140 :         return error;
     505             : }
     506             : 
     507             : static int
     508           0 : xfs_attrmulti_attr_set(
     509             :         struct inode            *inode,
     510             :         unsigned char           *name,
     511             :         const unsigned char     __user *ubuf,
     512             :         uint32_t                len,
     513             :         uint32_t                flags)
     514             : {
     515           0 :         struct xfs_da_args      args = {
     516             :                 .dp             = XFS_I(inode),
     517             :                 .attr_filter    = xfs_attr_filter(flags),
     518             :                 .attr_flags     = xfs_attr_flags(flags),
     519             :                 .name           = name,
     520             :                 .namelen        = strlen(name),
     521           0 :                 .owner          = XFS_I(inode)->i_ino,
     522             :         };
     523           0 :         int                     error;
     524             : 
     525           0 :         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
     526             :                 return -EPERM;
     527             : 
     528           0 :         if (ubuf) {
     529           0 :                 if (len > XFS_XATTR_SIZE_MAX)
     530             :                         return -EINVAL;
     531           0 :                 args.value = memdup_user(ubuf, len);
     532           0 :                 if (IS_ERR(args.value))
     533           0 :                         return PTR_ERR(args.value);
     534           0 :                 args.valuelen = len;
     535             :         }
     536             : 
     537           0 :         error = xfs_attr_change(&args);
     538           0 :         if (!error && (flags & XFS_IOC_ATTR_ROOT))
     539           0 :                 xfs_forget_acl(inode, name);
     540           0 :         kfree(args.value);
     541           0 :         return error;
     542             : }
     543             : 
     544             : int
     545         140 : xfs_ioc_attrmulti_one(
     546             :         struct file             *parfilp,
     547             :         struct inode            *inode,
     548             :         uint32_t                opcode,
     549             :         void __user             *uname,
     550             :         void __user             *value,
     551             :         uint32_t                *len,
     552             :         uint32_t                flags)
     553             : {
     554         140 :         unsigned char           *name;
     555         140 :         int                     error;
     556             : 
     557         140 :         if ((flags & XFS_IOC_ATTR_ROOT) && (flags & XFS_IOC_ATTR_SECURE))
     558             :                 return -EINVAL;
     559             : 
     560         140 :         name = strndup_user(uname, MAXNAMELEN);
     561         140 :         if (IS_ERR(name))
     562           0 :                 return PTR_ERR(name);
     563             : 
     564         140 :         switch (opcode) {
     565         140 :         case ATTR_OP_GET:
     566         140 :                 error = xfs_attrmulti_attr_get(inode, name, value, len, flags);
     567         140 :                 break;
     568           0 :         case ATTR_OP_REMOVE:
     569           0 :                 value = NULL;
     570           0 :                 *len = 0;
     571           0 :                 fallthrough;
     572           0 :         case ATTR_OP_SET:
     573           0 :                 error = mnt_want_write_file(parfilp);
     574           0 :                 if (error)
     575             :                         break;
     576           0 :                 error = xfs_attrmulti_attr_set(inode, name, value, *len, flags);
     577           0 :                 mnt_drop_write_file(parfilp);
     578           0 :                 break;
     579             :         default:
     580             :                 error = -EINVAL;
     581             :                 break;
     582             :         }
     583             : 
     584         140 :         kfree(name);
     585         140 :         return error;
     586             : }
     587             : 
     588             : STATIC int
     589         132 : xfs_attrmulti_by_handle(
     590             :         struct file             *parfilp,
     591             :         void                    __user *arg)
     592             : {
     593         132 :         int                     error;
     594         132 :         xfs_attr_multiop_t      *ops;
     595         132 :         xfs_fsop_attrmulti_handlereq_t am_hreq;
     596         132 :         struct dentry           *dentry;
     597         132 :         unsigned int            i, size;
     598             : 
     599         132 :         if (!capable(CAP_SYS_ADMIN))
     600             :                 return -EPERM;
     601         132 :         if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t)))
     602             :                 return -EFAULT;
     603             : 
     604             :         /* overflow check */
     605         132 :         if (am_hreq.opcount >= INT_MAX / sizeof(xfs_attr_multiop_t))
     606             :                 return -E2BIG;
     607             : 
     608         132 :         dentry = xfs_handlereq_to_dentry(parfilp, &am_hreq.hreq);
     609         132 :         if (IS_ERR(dentry))
     610           0 :                 return PTR_ERR(dentry);
     611             : 
     612         132 :         error = -E2BIG;
     613         132 :         size = am_hreq.opcount * sizeof(xfs_attr_multiop_t);
     614         132 :         if (!size || size > 16 * PAGE_SIZE)
     615           0 :                 goto out_dput;
     616             : 
     617         132 :         ops = memdup_user(am_hreq.ops, size);
     618         132 :         if (IS_ERR(ops)) {
     619           0 :                 error = PTR_ERR(ops);
     620           0 :                 goto out_dput;
     621             :         }
     622             : 
     623             :         error = 0;
     624         272 :         for (i = 0; i < am_hreq.opcount; i++) {
     625         140 :                 ops[i].am_error = xfs_ioc_attrmulti_one(parfilp,
     626         140 :                                 d_inode(dentry), ops[i].am_opcode,
     627             :                                 ops[i].am_attrname, ops[i].am_attrvalue,
     628         140 :                                 &ops[i].am_length, ops[i].am_flags);
     629             :         }
     630             : 
     631         264 :         if (copy_to_user(am_hreq.ops, ops, size))
     632           0 :                 error = -EFAULT;
     633             : 
     634         132 :         kfree(ops);
     635         132 :  out_dput:
     636         132 :         dput(dentry);
     637         132 :         return error;
     638             : }
     639             : 
     640             : /* Return 0 on success or positive error */
     641             : int
     642 68814237307 : xfs_fsbulkstat_one_fmt(
     643             :         struct xfs_ibulk                *breq,
     644             :         const struct xfs_bulkstat       *bstat)
     645             : {
     646 68814237307 :         struct xfs_bstat                bs1;
     647             : 
     648 68814237307 :         xfs_bulkstat_to_bstat(breq->mp, &bs1, bstat);
     649 68841402096 :         if (copy_to_user(breq->ubuffer, &bs1, sizeof(bs1)))
     650             :                 return -EFAULT;
     651 68760304474 :         return xfs_ibulk_advance(breq, sizeof(struct xfs_bstat));
     652             : }
     653             : 
     654             : int
     655       11596 : xfs_fsinumbers_fmt(
     656             :         struct xfs_ibulk                *breq,
     657             :         const struct xfs_inumbers       *igrp)
     658             : {
     659       11596 :         struct xfs_inogrp               ig1;
     660             : 
     661       11596 :         xfs_inumbers_to_inogrp(&ig1, igrp);
     662       11596 :         if (copy_to_user(breq->ubuffer, &ig1, sizeof(struct xfs_inogrp)))
     663             :                 return -EFAULT;
     664       11596 :         return xfs_ibulk_advance(breq, sizeof(struct xfs_inogrp));
     665             : }
     666             : 
     667             : STATIC int
     668   450691340 : xfs_ioc_fsbulkstat(
     669             :         struct file             *file,
     670             :         unsigned int            cmd,
     671             :         void                    __user *arg)
     672             : {
     673   450691340 :         struct xfs_mount        *mp = XFS_I(file_inode(file))->i_mount;
     674   450691340 :         struct xfs_fsop_bulkreq bulkreq;
     675   450691340 :         struct xfs_ibulk        breq = {
     676             :                 .mp             = mp,
     677             :                 .idmap          = file_mnt_idmap(file),
     678             :                 .ocount         = 0,
     679             :         };
     680   450706070 :         xfs_ino_t               lastino;
     681   450706070 :         int                     error;
     682             : 
     683             :         /* done = 1 if there are more stats to get and if bulkstat */
     684             :         /* should be called again (unused here, but used in dmapi) */
     685             : 
     686   450706070 :         if (!capable(CAP_SYS_ADMIN))
     687             :                 return -EPERM;
     688             : 
     689   901361602 :         if (xfs_is_shutdown(mp))
     690             :                 return -EIO;
     691             : 
     692   450667333 :         if (copy_from_user(&bulkreq, arg, sizeof(struct xfs_fsop_bulkreq)))
     693             :                 return -EFAULT;
     694             : 
     695   450676729 :         if (copy_from_user(&lastino, bulkreq.lastip, sizeof(__s64)))
     696             :                 return -EFAULT;
     697             : 
     698   450681444 :         if (bulkreq.icount <= 0)
     699             :                 return -EINVAL;
     700             : 
     701   450681444 :         if (bulkreq.ubuffer == NULL)
     702             :                 return -EINVAL;
     703             : 
     704   450681444 :         breq.ubuffer = bulkreq.ubuffer;
     705   450681444 :         breq.icount = bulkreq.icount;
     706             : 
     707             :         /*
     708             :          * FSBULKSTAT_SINGLE expects that *lastip contains the inode number
     709             :          * that we want to stat.  However, FSINUMBERS and FSBULKSTAT expect
     710             :          * that *lastip contains either zero or the number of the last inode to
     711             :          * be examined by the previous call and return results starting with
     712             :          * the next inode after that.  The new bulk request back end functions
     713             :          * take the inode to start with, so we have to compute the startino
     714             :          * parameter from lastino to maintain correct function.  lastino == 0
     715             :          * is a special case because it has traditionally meant "first inode
     716             :          * in filesystem".
     717             :          */
     718   450681444 :         if (cmd == XFS_IOC_FSINUMBERS) {
     719        3074 :                 breq.startino = lastino ? lastino + 1 : 0;
     720        3074 :                 error = xfs_inumbers(&breq, xfs_fsinumbers_fmt);
     721        3074 :                 lastino = breq.startino - 1;
     722   450678370 :         } else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE) {
     723     1402961 :                 breq.startino = lastino;
     724     1402961 :                 breq.icount = 1;
     725     1402961 :                 error = xfs_bulkstat_one(&breq, xfs_fsbulkstat_one_fmt);
     726             :         } else {        /* XFS_IOC_FSBULKSTAT */
     727   449275409 :                 breq.startino = lastino ? lastino + 1 : 0;
     728   449275409 :                 error = xfs_bulkstat(&breq, xfs_fsbulkstat_one_fmt);
     729   449247851 :                 lastino = breq.startino - 1;
     730             :         }
     731             : 
     732   450653887 :         if (error)
     733             :                 return error;
     734             : 
     735   899891022 :         if (bulkreq.lastip != NULL &&
     736             :             copy_to_user(bulkreq.lastip, &lastino, sizeof(xfs_ino_t)))
     737             :                 return -EFAULT;
     738             : 
     739   899222101 :         if (bulkreq.ocount != NULL &&
     740             :             copy_to_user(bulkreq.ocount, &breq.ocount, sizeof(__s32)))
     741           0 :                 return -EFAULT;
     742             : 
     743             :         return 0;
     744             : }
     745             : 
     746             : /* Return 0 on success or positive error */
     747             : static int
     748   157272966 : xfs_bulkstat_fmt(
     749             :         struct xfs_ibulk                *breq,
     750             :         const struct xfs_bulkstat       *bstat)
     751             : {
     752   314542691 :         if (copy_to_user(breq->ubuffer, bstat, sizeof(struct xfs_bulkstat)))
     753           0 :                 return -EFAULT;
     754   157269725 :         return xfs_ibulk_advance(breq, sizeof(struct xfs_bulkstat));
     755             : }
     756             : 
     757             : /*
     758             :  * Check the incoming bulk request @hdr from userspace and initialize the
     759             :  * internal @breq bulk request appropriately.  Returns 0 if the bulk request
     760             :  * should proceed; -ECANCELED if there's nothing to do; or the usual
     761             :  * negative error code.
     762             :  */
     763             : static int
     764     8270311 : xfs_bulk_ireq_setup(
     765             :         struct xfs_mount        *mp,
     766             :         const struct xfs_bulk_ireq *hdr,
     767             :         struct xfs_ibulk        *breq,
     768             :         void __user             *ubuffer)
     769             : {
     770     8270311 :         if (hdr->icount == 0 ||
     771    16541730 :             (hdr->flags & ~XFS_BULK_IREQ_FLAGS_ALL) ||
     772     8270311 :             memchr_inv(hdr->reserved, 0, sizeof(hdr->reserved)))
     773           0 :                 return -EINVAL;
     774             : 
     775     8271419 :         breq->startino = hdr->ino;
     776     8271419 :         breq->ubuffer = ubuffer;
     777     8271419 :         breq->icount = hdr->icount;
     778     8271419 :         breq->ocount = 0;
     779     8271419 :         breq->flags = 0;
     780             : 
     781             :         /*
     782             :          * The @ino parameter is a special value, so we must look it up here.
     783             :          * We're not allowed to have IREQ_AGNO, and we only return one inode
     784             :          * worth of data.
     785             :          */
     786     8271419 :         if (hdr->flags & XFS_BULK_IREQ_SPECIAL) {
     787           4 :                 if (hdr->flags & XFS_BULK_IREQ_AGNO)
     788             :                         return -EINVAL;
     789             : 
     790           4 :                 switch (hdr->ino) {
     791           4 :                 case XFS_BULK_IREQ_SPECIAL_ROOT:
     792           4 :                         breq->startino = mp->m_sb.sb_rootino;
     793           4 :                         break;
     794             :                 default:
     795             :                         return -EINVAL;
     796             :                 }
     797           4 :                 breq->icount = 1;
     798             :         }
     799             : 
     800             :         /*
     801             :          * The IREQ_AGNO flag means that we only want results from a given AG.
     802             :          * If @hdr->ino is zero, we start iterating in that AG.  If @hdr->ino is
     803             :          * beyond the specified AG then we return no results.
     804             :          */
     805     8271419 :         if (hdr->flags & XFS_BULK_IREQ_AGNO) {
     806     2627314 :                 if (hdr->agno >= mp->m_sb.sb_agcount)
     807             :                         return -EINVAL;
     808             : 
     809     2627314 :                 if (breq->startino == 0)
     810      135242 :                         breq->startino = XFS_AGINO_TO_INO(mp, hdr->agno, 0);
     811     2492072 :                 else if (XFS_INO_TO_AGNO(mp, breq->startino) < hdr->agno)
     812             :                         return -EINVAL;
     813             : 
     814     2627314 :                 breq->flags |= XFS_IBULK_SAME_AG;
     815             : 
     816             :                 /* Asking for an inode past the end of the AG?  We're done! */
     817     2627314 :                 if (XFS_INO_TO_AGNO(mp, breq->startino) > hdr->agno)
     818             :                         return -ECANCELED;
     819     5644105 :         } else if (hdr->agno)
     820             :                 return -EINVAL;
     821             : 
     822             :         /* Asking for an inode past the end of the FS?  We're done! */
     823     8271419 :         if (XFS_INO_TO_AGNO(mp, breq->startino) >= mp->m_sb.sb_agcount)
     824             :                 return -ECANCELED;
     825             : 
     826     8271409 :         if (hdr->flags & XFS_BULK_IREQ_NREXT64)
     827     5659979 :                 breq->flags |= XFS_IBULK_NREXT64;
     828             : 
     829             :         /* Caller wants to see metadata directories in bulkstat output. */
     830     8271409 :         if (hdr->flags & XFS_BULK_IREQ_METADIR)
     831     1774187 :                 breq->flags |= XFS_IBULK_METADIR;
     832             : 
     833             :         return 0;
     834             : }
     835             : 
     836             : /*
     837             :  * Update the userspace bulk request @hdr to reflect the end state of the
     838             :  * internal bulk request @breq.
     839             :  */
     840             : static void
     841             : xfs_bulk_ireq_teardown(
     842             :         struct xfs_bulk_ireq    *hdr,
     843             :         struct xfs_ibulk        *breq)
     844             : {
     845     8271578 :         hdr->ino = breq->startino;
     846     8271578 :         hdr->ocount = breq->ocount;
     847             : }
     848             : 
     849             : /* Handle the v5 bulkstat ioctl. */
     850             : STATIC int
     851     5659927 : xfs_ioc_bulkstat(
     852             :         struct file                     *file,
     853             :         unsigned int                    cmd,
     854             :         struct xfs_bulkstat_req __user  *arg)
     855             : {
     856     5659927 :         struct xfs_mount                *mp = XFS_I(file_inode(file))->i_mount;
     857     5659927 :         struct xfs_bulk_ireq            hdr;
     858     5659927 :         struct xfs_ibulk                breq = {
     859             :                 .mp                     = mp,
     860             :                 .idmap                  = file_mnt_idmap(file),
     861             :         };
     862     5660064 :         int                             error;
     863             : 
     864     5660064 :         if (!capable(CAP_SYS_ADMIN))
     865             :                 return -EPERM;
     866             : 
     867    11320056 :         if (xfs_is_shutdown(mp))
     868             :                 return -EIO;
     869             : 
     870     5660028 :         if (copy_from_user(&hdr, &arg->hdr, sizeof(hdr)))
     871             :                 return -EFAULT;
     872             : 
     873     5660030 :         error = xfs_bulk_ireq_setup(mp, &hdr, &breq, arg->bulkstat);
     874     5660034 :         if (error == -ECANCELED)
     875          10 :                 goto out_teardown;
     876     5660024 :         if (error < 0)
     877             :                 return error;
     878             : 
     879     5660024 :         error = xfs_bulkstat(&breq, xfs_bulkstat_fmt);
     880     5660036 :         if (error)
     881             :                 return error;
     882             : 
     883     5660034 : out_teardown:
     884     5660044 :         xfs_bulk_ireq_teardown(&hdr, &breq);
     885     5660044 :         if (copy_to_user(&arg->hdr, &hdr, sizeof(hdr)))
     886           0 :                 return -EFAULT;
     887             : 
     888             :         return 0;
     889             : }
     890             : 
     891             : STATIC int
     892     3941807 : xfs_inumbers_fmt(
     893             :         struct xfs_ibulk                *breq,
     894             :         const struct xfs_inumbers       *igrp)
     895             : {
     896     7884680 :         if (copy_to_user(breq->ubuffer, igrp, sizeof(struct xfs_inumbers)))
     897           0 :                 return -EFAULT;
     898     3942873 :         return xfs_ibulk_advance(breq, sizeof(struct xfs_inumbers));
     899             : }
     900             : 
     901             : /* Handle the v5 inumbers ioctl. */
     902             : STATIC int
     903     2611652 : xfs_ioc_inumbers(
     904             :         struct xfs_mount                *mp,
     905             :         unsigned int                    cmd,
     906             :         struct xfs_inumbers_req __user  *arg)
     907             : {
     908     2611652 :         struct xfs_bulk_ireq            hdr;
     909     2611652 :         struct xfs_ibulk                breq = {
     910             :                 .mp                     = mp,
     911             :         };
     912     2611652 :         int                             error;
     913             : 
     914     2611652 :         if (!capable(CAP_SYS_ADMIN))
     915             :                 return -EPERM;
     916             : 
     917     5222026 :         if (xfs_is_shutdown(mp))
     918             :                 return -EIO;
     919             : 
     920     2611013 :         if (copy_from_user(&hdr, &arg->hdr, sizeof(hdr)))
     921             :                 return -EFAULT;
     922             : 
     923     2611544 :         if (hdr.flags & XFS_BULK_IREQ_METADIR)
     924             :                 return -EINVAL;
     925             : 
     926     2611544 :         error = xfs_bulk_ireq_setup(mp, &hdr, &breq, arg->inumbers);
     927     2611537 :         if (error == -ECANCELED)
     928           0 :                 goto out_teardown;
     929     2611537 :         if (error < 0)
     930             :                 return error;
     931             : 
     932     2611537 :         error = xfs_inumbers(&breq, xfs_inumbers_fmt);
     933     2611534 :         if (error)
     934             :                 return error;
     935             : 
     936     2611534 : out_teardown:
     937     2611534 :         xfs_bulk_ireq_teardown(&hdr, &breq);
     938     2611534 :         if (copy_to_user(&arg->hdr, &hdr, sizeof(hdr)))
     939           0 :                 return -EFAULT;
     940             : 
     941             :         return 0;
     942             : }
     943             : 
     944             : STATIC int
     945     2049051 : xfs_ioc_fsgeometry(
     946             :         struct xfs_mount        *mp,
     947             :         void                    __user *arg,
     948             :         int                     struct_version)
     949             : {
     950     2049051 :         struct xfs_fsop_geom    fsgeo;
     951     2049051 :         size_t                  len;
     952             : 
     953     2049051 :         xfs_fs_geometry(mp, &fsgeo, struct_version);
     954             : 
     955     2048953 :         if (struct_version <= 3)
     956             :                 len = sizeof(struct xfs_fsop_geom_v1);
     957     2048821 :         else if (struct_version == 4)
     958             :                 len = sizeof(struct xfs_fsop_geom_v4);
     959             :         else {
     960     2048784 :                 xfs_fsop_geom_health(mp, &fsgeo);
     961     2048784 :                 len = sizeof(fsgeo);
     962             :         }
     963             : 
     964     4118060 :         if (copy_to_user(arg, &fsgeo, len))
     965           0 :                 return -EFAULT;
     966             :         return 0;
     967             : }
     968             : 
     969             : STATIC int
     970       15595 : xfs_ioc_ag_geometry(
     971             :         struct xfs_mount        *mp,
     972             :         void                    __user *arg)
     973             : {
     974       15595 :         struct xfs_perag        *pag;
     975       15595 :         struct xfs_ag_geometry  ageo;
     976       15595 :         int                     error;
     977             : 
     978       15595 :         if (copy_from_user(&ageo, arg, sizeof(ageo)))
     979             :                 return -EFAULT;
     980       15595 :         if (ageo.ag_flags & ~XFS_AG_FLAG_ALL)
     981             :                 return -EINVAL;
     982       15595 :         if (memchr_inv(&ageo.ag_reserved, 0, sizeof(ageo.ag_reserved)))
     983             :                 return -EINVAL;
     984       15595 :         if ((ageo.ag_flags & XFS_AG_FLAG_UPDATE) && !capable(CAP_SYS_ADMIN))
     985             :                 return -EPERM;
     986             : 
     987       15595 :         pag = xfs_perag_get(mp, ageo.ag_number);
     988       15595 :         if (!pag)
     989             :                 return -EINVAL;
     990             : 
     991       15595 :         error = xfs_ag_get_geometry(pag, &ageo);
     992       15595 :         xfs_perag_put(pag);
     993       15595 :         if (error)
     994             :                 return error;
     995             : 
     996       15595 :         if (copy_to_user(arg, &ageo, sizeof(ageo)))
     997           0 :                 return -EFAULT;
     998             :         return 0;
     999             : }
    1000             : 
    1001             : STATIC int
    1002         396 : xfs_ioc_rtgroup_geometry(
    1003             :         struct xfs_mount        *mp,
    1004             :         void                    __user *arg)
    1005             : {
    1006         396 :         struct xfs_rtgroup      *rtg;
    1007         396 :         struct xfs_rtgroup_geometry rgeo;
    1008         396 :         int                     error;
    1009             : 
    1010         396 :         if (copy_from_user(&rgeo, arg, sizeof(rgeo)))
    1011             :                 return -EFAULT;
    1012         396 :         if (rgeo.rg_flags || rgeo.rg_pad)
    1013             :                 return -EINVAL;
    1014         396 :         if (memchr_inv(&rgeo.rg_reserved, 0, sizeof(rgeo.rg_reserved)))
    1015             :                 return -EINVAL;
    1016             : 
    1017         396 :         rtg = xfs_rtgroup_get(mp, rgeo.rg_number);
    1018         396 :         if (!rtg)
    1019             :                 return -EINVAL;
    1020             : 
    1021         396 :         error = xfs_rtgroup_get_geometry(rtg, &rgeo);
    1022         396 :         xfs_rtgroup_put(rtg);
    1023         396 :         if (error)
    1024             :                 return error;
    1025             : 
    1026         396 :         if (copy_to_user(arg, &rgeo, sizeof(rgeo)))
    1027           0 :                 return -EFAULT;
    1028             :         return 0;
    1029             : }
    1030             : 
    1031             : /*
    1032             :  * Linux extended inode flags interface.
    1033             :  */
    1034             : 
    1035             : static void
    1036     3246839 : xfs_fill_fsxattr(
    1037             :         struct xfs_inode        *ip,
    1038             :         int                     whichfork,
    1039             :         struct fileattr         *fa)
    1040             : {
    1041     3246839 :         struct xfs_mount        *mp = ip->i_mount;
    1042     3246839 :         struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
    1043             : 
    1044     3246827 :         fileattr_fill_xflags(fa, xfs_ip2xflags(ip));
    1045             : 
    1046     3246824 :         if (ip->i_diflags & XFS_DIFLAG_EXTSIZE) {
    1047          35 :                 fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);
    1048     3246789 :         } else if (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) {
    1049             :                 /*
    1050             :                  * Don't let a misaligned extent size hint on a directory
    1051             :                  * escape to userspace if it won't pass the setattr checks
    1052             :                  * later.
    1053             :                  */
    1054           8 :                 if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
    1055           0 :                     xfs_extlen_to_rtxmod(mp, ip->i_extsize) > 0) {
    1056           0 :                         fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE |
    1057             :                                             FS_XFLAG_EXTSZINHERIT);
    1058           0 :                         fa->fsx_extsize = 0;
    1059             :                 } else {
    1060           8 :                         fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);
    1061             :                 }
    1062             :         }
    1063             : 
    1064     3246824 :         if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE) {
    1065             :                 /*
    1066             :                  * Don't let a misaligned CoW extent size hint on a directory
    1067             :                  * escape to userspace if it won't pass the setattr checks
    1068             :                  * later.
    1069             :                  */
    1070         255 :                 if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
    1071           0 :                     ip->i_cowextsize % mp->m_sb.sb_rextsize > 0) {
    1072           0 :                         fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE;
    1073           0 :                         fa->fsx_cowextsize = 0;
    1074             :                 } else {
    1075         255 :                         fa->fsx_cowextsize = XFS_FSB_TO_B(mp, ip->i_cowextsize);
    1076             :                 }
    1077             :         }
    1078             : 
    1079     3246824 :         fa->fsx_projid = ip->i_projid;
    1080     6490080 :         if (ifp && !xfs_need_iread_extents(ifp))
    1081     3231773 :                 fa->fsx_nextents = xfs_iext_count(ifp);
    1082             :         else
    1083       26571 :                 fa->fsx_nextents = xfs_ifork_nextents(ifp);
    1084     3246808 : }
    1085             : 
    1086             : STATIC int
    1087        5216 : xfs_ioc_fsgetxattra(
    1088             :         xfs_inode_t             *ip,
    1089             :         void                    __user *arg)
    1090             : {
    1091        5216 :         struct fileattr         fa;
    1092             : 
    1093        5216 :         xfs_ilock(ip, XFS_ILOCK_SHARED);
    1094        5216 :         xfs_fill_fsxattr(ip, XFS_ATTR_FORK, &fa);
    1095        5216 :         xfs_iunlock(ip, XFS_ILOCK_SHARED);
    1096             : 
    1097        5216 :         return copy_fsxattr_to_user(&fa, arg);
    1098             : }
    1099             : 
    1100             : int
    1101     3241639 : xfs_fileattr_get(
    1102             :         struct dentry           *dentry,
    1103             :         struct fileattr         *fa)
    1104             : {
    1105     3241639 :         struct xfs_inode        *ip = XFS_I(d_inode(dentry));
    1106             : 
    1107     3241639 :         if (d_is_special(dentry))
    1108             :                 return -ENOTTY;
    1109             : 
    1110     3241639 :         xfs_ilock(ip, XFS_ILOCK_SHARED);
    1111     3241620 :         xfs_fill_fsxattr(ip, XFS_DATA_FORK, fa);
    1112     3241594 :         xfs_iunlock(ip, XFS_ILOCK_SHARED);
    1113             : 
    1114     3241594 :         return 0;
    1115             : }
    1116             : 
    1117             : static int
    1118      671461 : xfs_ioctl_setattr_xflags(
    1119             :         struct xfs_trans        *tp,
    1120             :         struct xfs_inode        *ip,
    1121             :         struct fileattr         *fa)
    1122             : {
    1123      671461 :         struct xfs_mount        *mp = ip->i_mount;
    1124      671461 :         uint64_t                i_flags2;
    1125             : 
    1126             :         /* Can't change realtime flag if any extents are allocated. */
    1127      671461 :         if ((ip->i_df.if_nextents || ip->i_delayed_blks) &&
    1128      814086 :             XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & FS_XFLAG_REALTIME))
    1129             :                 return -EINVAL;
    1130             : 
    1131             :         /* If realtime flag is set then must have realtime device */
    1132      671461 :         if (fa->fsx_xflags & FS_XFLAG_REALTIME) {
    1133      376536 :                 if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||
    1134      188268 :                     xfs_extlen_to_rtxmod(mp, ip->i_extsize))
    1135             :                         return -EINVAL;
    1136             :         }
    1137             : 
    1138             :         /* diflags2 only valid for v3 inodes. */
    1139      671461 :         i_flags2 = xfs_flags2diflags2(ip, fa->fsx_xflags);
    1140      671460 :         if (i_flags2 && !xfs_has_v3inodes(mp))
    1141             :                 return -EINVAL;
    1142             : 
    1143      671460 :         ip->i_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);
    1144      671460 :         ip->i_diflags2 = i_flags2;
    1145             : 
    1146      671460 :         xfs_diflags_to_iflags(ip, false);
    1147      671461 :         xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
    1148      671460 :         xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
    1149      671461 :         XFS_STATS_INC(mp, xs_ig_attrchg);
    1150      671461 :         return 0;
    1151             : }
    1152             : 
    1153             : static void
    1154      671466 : xfs_ioctl_setattr_prepare_dax(
    1155             :         struct xfs_inode        *ip,
    1156             :         struct fileattr         *fa)
    1157             : {
    1158      671466 :         struct xfs_mount        *mp = ip->i_mount;
    1159      671466 :         struct inode            *inode = VFS_I(ip);
    1160             : 
    1161      671466 :         if (S_ISDIR(inode->i_mode))
    1162             :                 return;
    1163             : 
    1164      663716 :         if (xfs_has_dax_always(mp) || xfs_has_dax_never(mp))
    1165             :                 return;
    1166             : 
    1167      663716 :         if (((fa->fsx_xflags & FS_XFLAG_DAX) &&
    1168      663716 :             !(ip->i_diflags2 & XFS_DIFLAG2_DAX)) ||
    1169      663714 :             (!(fa->fsx_xflags & FS_XFLAG_DAX) &&
    1170      663714 :              (ip->i_diflags2 & XFS_DIFLAG2_DAX)))
    1171           4 :                 d_mark_dontcache(inode);
    1172             : }
    1173             : 
    1174             : /*
    1175             :  * Set up the transaction structure for the setattr operation, checking that we
    1176             :  * have permission to do so. On success, return a clean transaction and the
    1177             :  * inode locked exclusively ready for further operation specific checks. On
    1178             :  * failure, return an error without modifying or locking the inode.
    1179             :  */
    1180             : static struct xfs_trans *
    1181      671466 : xfs_ioctl_setattr_get_trans(
    1182             :         struct xfs_inode        *ip,
    1183             :         struct xfs_dquot        *pdqp)
    1184             : {
    1185      671466 :         struct xfs_mount        *mp = ip->i_mount;
    1186      671466 :         struct xfs_trans        *tp;
    1187      671466 :         int                     error = -EROFS;
    1188             : 
    1189     1342932 :         if (xfs_is_readonly(mp))
    1190           0 :                 goto out_error;
    1191      671466 :         error = -EIO;
    1192     1342932 :         if (xfs_is_shutdown(mp))
    1193           0 :                 goto out_error;
    1194             : 
    1195      671466 :         error = xfs_trans_alloc_ichange(ip, NULL, NULL, pdqp,
    1196             :                         has_capability_noaudit(current, CAP_FOWNER), &tp);
    1197      671464 :         if (error)
    1198           0 :                 goto out_error;
    1199             : 
    1200      671464 :         if (xfs_has_wsync(mp))
    1201         152 :                 xfs_trans_set_sync(tp);
    1202             : 
    1203      671464 :         return tp;
    1204             : 
    1205           0 : out_error:
    1206           0 :         return ERR_PTR(error);
    1207             : }
    1208             : 
    1209             : /*
    1210             :  * Validate a proposed extent size hint.  For regular files, the hint can only
    1211             :  * be changed if no extents are allocated.
    1212             :  */
    1213             : static int
    1214      671465 : xfs_ioctl_setattr_check_extsize(
    1215             :         struct xfs_inode        *ip,
    1216             :         struct fileattr         *fa)
    1217             : {
    1218      671465 :         struct xfs_mount        *mp = ip->i_mount;
    1219      671465 :         xfs_failaddr_t          failaddr;
    1220      671465 :         uint16_t                new_diflags;
    1221             : 
    1222      671465 :         if (!fa->fsx_valid)
    1223             :                 return 0;
    1224             : 
    1225      601727 :         if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_df.if_nextents &&
    1226      471202 :             XFS_FSB_TO_B(mp, ip->i_extsize) != fa->fsx_extsize)
    1227             :                 return -EINVAL;
    1228             : 
    1229      601725 :         if (fa->fsx_extsize & mp->m_blockmask)
    1230             :                 return -EINVAL;
    1231             : 
    1232      601723 :         new_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);
    1233             : 
    1234             :         /*
    1235             :          * Inode verifiers do not check that the extent size hint is an integer
    1236             :          * multiple of the rt extent size on a directory with both rtinherit
    1237             :          * and extszinherit flags set.  Don't let sysadmins misconfigure
    1238             :          * directories.
    1239             :          */
    1240      601722 :         if ((new_diflags & XFS_DIFLAG_RTINHERIT) &&
    1241             :             (new_diflags & XFS_DIFLAG_EXTSZINHERIT)) {
    1242           0 :                 unsigned int    rtextsize_bytes;
    1243             : 
    1244           0 :                 rtextsize_bytes = XFS_FSB_TO_B(mp, mp->m_sb.sb_rextsize);
    1245           0 :                 if (fa->fsx_extsize % rtextsize_bytes)
    1246             :                         return -EINVAL;
    1247             :         }
    1248             : 
    1249      601722 :         failaddr = xfs_inode_validate_extsize(ip->i_mount,
    1250      601722 :                         XFS_B_TO_FSB(mp, fa->fsx_extsize),
    1251             :                         VFS_I(ip)->i_mode, new_diflags);
    1252      601722 :         return failaddr != NULL ? -EINVAL : 0;
    1253             : }
    1254             : 
    1255             : static int
    1256      671461 : xfs_ioctl_setattr_check_cowextsize(
    1257             :         struct xfs_inode        *ip,
    1258             :         struct fileattr         *fa)
    1259             : {
    1260      671461 :         struct xfs_mount        *mp = ip->i_mount;
    1261      671461 :         xfs_failaddr_t          failaddr;
    1262      671461 :         uint64_t                new_diflags2;
    1263      671461 :         uint16_t                new_diflags;
    1264             : 
    1265      671461 :         if (!fa->fsx_valid)
    1266             :                 return 0;
    1267             : 
    1268      601723 :         if (fa->fsx_cowextsize & mp->m_blockmask)
    1269             :                 return -EINVAL;
    1270             : 
    1271      601723 :         new_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);
    1272      601723 :         new_diflags2 = xfs_flags2diflags2(ip, fa->fsx_xflags);
    1273             : 
    1274      601724 :         failaddr = xfs_inode_validate_cowextsize(ip->i_mount,
    1275      601724 :                         XFS_B_TO_FSB(mp, fa->fsx_cowextsize),
    1276             :                         VFS_I(ip)->i_mode, new_diflags, new_diflags2);
    1277      601723 :         return failaddr != NULL ? -EINVAL : 0;
    1278             : }
    1279             : 
    1280             : static int
    1281             : xfs_ioctl_setattr_check_projid(
    1282             :         struct xfs_inode        *ip,
    1283             :         struct fileattr         *fa)
    1284             : {
    1285      672542 :         if (!fa->fsx_valid)
    1286             :                 return 0;
    1287             : 
    1288             :         /* Disallow 32bit project ids if 32bit IDs are not enabled. */
    1289      602805 :         if (fa->fsx_projid > (uint16_t)-1 &&
    1290           0 :             !xfs_has_projid32(ip->i_mount))
    1291             :                 return -EINVAL;
    1292             :         return 0;
    1293             : }
    1294             : 
    1295             : int
    1296      687104 : xfs_fileattr_set(
    1297             :         struct mnt_idmap        *idmap,
    1298             :         struct dentry           *dentry,
    1299             :         struct fileattr         *fa)
    1300             : {
    1301      687104 :         struct xfs_inode        *ip = XFS_I(d_inode(dentry));
    1302      687104 :         struct xfs_mount        *mp = ip->i_mount;
    1303      687104 :         struct xfs_trans        *tp;
    1304      687104 :         struct xfs_dquot        *pdqp = NULL;
    1305      687104 :         struct xfs_dquot        *olddquot = NULL;
    1306      687104 :         int                     error;
    1307             : 
    1308      687104 :         trace_xfs_ioctl_setattr(ip);
    1309             : 
    1310      687103 :         if (d_is_special(dentry))
    1311             :                 return -ENOTTY;
    1312             : 
    1313      687103 :         if (!fa->fsx_valid) {
    1314       84299 :                 if (fa->flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL |
    1315             :                                   FS_NOATIME_FL | FS_NODUMP_FL |
    1316             :                                   FS_SYNC_FL | FS_DAX_FL | FS_PROJINHERIT_FL))
    1317             :                         return -EOPNOTSUPP;
    1318             :         }
    1319             : 
    1320      672542 :         error = xfs_ioctl_setattr_check_projid(ip, fa);
    1321             :         if (error)
    1322             :                 return error;
    1323             : 
    1324             :         /*
    1325             :          * If disk quotas is on, we make sure that the dquots do exist on disk,
    1326             :          * before we start any other transactions. Trying to do this later
    1327             :          * is messy. We don't care to take a readlock to look at the ids
    1328             :          * in inode here, because we can't hold it across the trans_reserve.
    1329             :          * If the IDs do change before we take the ilock, we're covered
    1330             :          * because the i_*dquot fields will get updated anyway.
    1331             :          */
    1332      672542 :         if (fa->fsx_valid && XFS_IS_QUOTA_ON(mp)) {
    1333      591910 :                 error = xfs_qm_vop_dqalloc(ip, VFS_I(ip)->i_uid,
    1334             :                                 VFS_I(ip)->i_gid, fa->fsx_projid,
    1335             :                                 XFS_QMOPT_PQUOTA, NULL, NULL, &pdqp);
    1336      591911 :                 if (error)
    1337             :                         return error;
    1338             :         }
    1339             : 
    1340      671466 :         xfs_ioctl_setattr_prepare_dax(ip, fa);
    1341             : 
    1342      671466 :         tp = xfs_ioctl_setattr_get_trans(ip, pdqp);
    1343      671464 :         if (IS_ERR(tp)) {
    1344           0 :                 error = PTR_ERR(tp);
    1345           0 :                 goto error_free_dquots;
    1346             :         }
    1347             : 
    1348      671464 :         error = xfs_ioctl_setattr_check_extsize(ip, fa);
    1349      671464 :         if (error)
    1350           4 :                 goto error_trans_cancel;
    1351             : 
    1352      671460 :         error = xfs_ioctl_setattr_check_cowextsize(ip, fa);
    1353      671461 :         if (error)
    1354           0 :                 goto error_trans_cancel;
    1355             : 
    1356      671461 :         error = xfs_ioctl_setattr_xflags(tp, ip, fa);
    1357      671462 :         if (error)
    1358           0 :                 goto error_trans_cancel;
    1359             : 
    1360      671462 :         if (!fa->fsx_valid)
    1361       69738 :                 goto skip_xattr;
    1362             :         /*
    1363             :          * Change file ownership.  Must be the owner or privileged.  CAP_FSETID
    1364             :          * overrides the following restrictions:
    1365             :          *
    1366             :          * The set-user-ID and set-group-ID bits of a file will be cleared upon
    1367             :          * successful return from chown()
    1368             :          */
    1369             : 
    1370      601732 :         if ((VFS_I(ip)->i_mode & (S_ISUID|S_ISGID)) &&
    1371           8 :             !capable_wrt_inode_uidgid(idmap, VFS_I(ip), CAP_FSETID))
    1372           0 :                 VFS_I(ip)->i_mode &= ~(S_ISUID|S_ISGID);
    1373             : 
    1374             :         /* Change the ownerships and register project quota modifications */
    1375      601724 :         if (ip->i_projid != fa->fsx_projid) {
    1376      526746 :                 if (XFS_IS_PQUOTA_ON(mp)) {
    1377      516987 :                         olddquot = xfs_qm_vop_chown(tp, ip,
    1378             :                                                 &ip->i_pdquot, pdqp);
    1379             :                 }
    1380      526746 :                 ip->i_projid = fa->fsx_projid;
    1381             :         }
    1382             : 
    1383             :         /*
    1384             :          * Only set the extent size hint if we've already determined that the
    1385             :          * extent size hint should be set on the inode. If no extent size flags
    1386             :          * are set on the inode then unconditionally clear the extent size hint.
    1387             :          */
    1388      601724 :         if (ip->i_diflags & (XFS_DIFLAG_EXTSIZE | XFS_DIFLAG_EXTSZINHERIT))
    1389          33 :                 ip->i_extsize = XFS_B_TO_FSB(mp, fa->fsx_extsize);
    1390             :         else
    1391      601691 :                 ip->i_extsize = 0;
    1392             : 
    1393      601724 :         if (xfs_has_v3inodes(mp)) {
    1394      601724 :                 if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)
    1395         137 :                         ip->i_cowextsize = XFS_B_TO_FSB(mp, fa->fsx_cowextsize);
    1396             :                 else
    1397      601587 :                         ip->i_cowextsize = 0;
    1398             :         }
    1399             : 
    1400           0 : skip_xattr:
    1401      671462 :         error = xfs_trans_commit(tp);
    1402             : 
    1403             :         /*
    1404             :          * Release any dquot(s) the inode had kept before chown.
    1405             :          */
    1406      671461 :         xfs_qm_dqrele(olddquot);
    1407      671461 :         xfs_qm_dqrele(pdqp);
    1408             : 
    1409      671461 :         return error;
    1410             : 
    1411           4 : error_trans_cancel:
    1412           4 :         xfs_trans_cancel(tp);
    1413           4 : error_free_dquots:
    1414           4 :         xfs_qm_dqrele(pdqp);
    1415           4 :         return error;
    1416             : }
    1417             : 
    1418             : static bool
    1419     5416358 : xfs_getbmap_format(
    1420             :         struct kgetbmap         *p,
    1421             :         struct getbmapx __user  *u,
    1422             :         size_t                  recsize)
    1423             : {
    1424     5416358 :         if (put_user(p->bmv_offset, &u->bmv_offset) ||
    1425     5416353 :             put_user(p->bmv_block, &u->bmv_block) ||
    1426     5416405 :             put_user(p->bmv_length, &u->bmv_length) ||
    1427     5416380 :             put_user(0, &u->bmv_count) ||
    1428     5416351 :             put_user(0, &u->bmv_entries))
    1429           5 :                 return false;
    1430     5416354 :         if (recsize < sizeof(struct getbmapx))
    1431             :                 return true;
    1432     5279092 :         if (put_user(0, &u->bmv_iflags) ||
    1433     5279100 :             put_user(p->bmv_oflags, &u->bmv_oflags) ||
    1434     5279067 :             put_user(0, &u->bmv_unused1) ||
    1435     5279086 :             put_user(0, &u->bmv_unused2))
    1436          24 :                 return false;
    1437             :         return true;
    1438             : }
    1439             : 
    1440             : STATIC int
    1441     1196120 : xfs_ioc_getbmap(
    1442             :         struct file             *file,
    1443             :         unsigned int            cmd,
    1444             :         void                    __user *arg)
    1445             : {
    1446     1196120 :         struct getbmapx         bmx = { 0 };
    1447     1196120 :         struct kgetbmap         *buf;
    1448     1196120 :         size_t                  recsize;
    1449     1196120 :         int                     error, i;
    1450             : 
    1451     1196120 :         switch (cmd) {
    1452           0 :         case XFS_IOC_GETBMAPA:
    1453           0 :                 bmx.bmv_iflags = BMV_IF_ATTRFORK;
    1454             :                 fallthrough;
    1455             :         case XFS_IOC_GETBMAP:
    1456             :                 /* struct getbmap is a strict subset of struct getbmapx. */
    1457             :                 recsize = sizeof(struct getbmap);
    1458             :                 break;
    1459             :         case XFS_IOC_GETBMAPX:
    1460             :                 recsize = sizeof(struct getbmapx);
    1461             :                 break;
    1462             :         default:
    1463             :                 return -EINVAL;
    1464             :         }
    1465             : 
    1466     2392171 :         if (copy_from_user(&bmx, arg, recsize))
    1467             :                 return -EFAULT;
    1468             : 
    1469     1196051 :         if (bmx.bmv_count < 2)
    1470             :                 return -EINVAL;
    1471     1196051 :         if (bmx.bmv_count >= INT_MAX / recsize)
    1472             :                 return -ENOMEM;
    1473             : 
    1474     1196051 :         buf = kvcalloc(bmx.bmv_count, sizeof(*buf), GFP_KERNEL);
    1475     1196050 :         if (!buf)
    1476             :                 return -ENOMEM;
    1477             : 
    1478     1196050 :         error = xfs_getbmap(XFS_I(file_inode(file)), &bmx, buf);
    1479     1196077 :         if (error)
    1480           0 :                 goto out_free_buf;
    1481             : 
    1482     1196077 :         error = -EFAULT;
    1483     2392162 :         if (copy_to_user(arg, &bmx, recsize))
    1484           0 :                 goto out_free_buf;
    1485     1196085 :         arg += recsize;
    1486             : 
    1487     6612425 :         for (i = 0; i < bmx.bmv_entries; i++) {
    1488     5416370 :                 if (!xfs_getbmap_format(buf + i, arg, recsize))
    1489           0 :                         goto out_free_buf;
    1490     5416340 :                 arg += recsize;
    1491             :         }
    1492             : 
    1493             :         error = 0;
    1494     1196055 : out_free_buf:
    1495     1196055 :         kmem_free(buf);
    1496     1196055 :         return error;
    1497             : }
    1498             : 
    1499             : STATIC int
    1500       95045 : xfs_ioc_getfsmap(
    1501             :         struct xfs_inode        *ip,
    1502             :         struct fsmap_head       __user *arg)
    1503             : {
    1504       95045 :         struct xfs_fsmap_head   xhead = {0};
    1505       95045 :         struct fsmap_head       head;
    1506       95045 :         struct fsmap            *recs;
    1507       95045 :         unsigned int            count;
    1508       95045 :         __u32                   last_flags = 0;
    1509       95045 :         bool                    done = false;
    1510       95045 :         int                     error;
    1511             : 
    1512       95045 :         if (copy_from_user(&head, arg, sizeof(struct fsmap_head)))
    1513             :                 return -EFAULT;
    1514      189488 :         if (memchr_inv(head.fmh_reserved, 0, sizeof(head.fmh_reserved)) ||
    1515             :             memchr_inv(head.fmh_keys[0].fmr_reserved, 0,
    1516       94682 :                        sizeof(head.fmh_keys[0].fmr_reserved)) ||
    1517             :             memchr_inv(head.fmh_keys[1].fmr_reserved, 0,
    1518             :                        sizeof(head.fmh_keys[1].fmr_reserved)))
    1519           0 :                 return -EINVAL;
    1520             : 
    1521             :         /*
    1522             :          * Use an internal memory buffer so that we don't have to copy fsmap
    1523             :          * data to userspace while holding locks.  Start by trying to allocate
    1524             :          * up to 128k for the buffer, but fall back to a single page if needed.
    1525             :          */
    1526       94682 :         count = min_t(unsigned int, head.fmh_count,
    1527             :                         131072 / sizeof(struct fsmap));
    1528       94682 :         recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL);
    1529       94778 :         if (!recs) {
    1530           0 :                 count = min_t(unsigned int, head.fmh_count,
    1531             :                                 PAGE_SIZE / sizeof(struct fsmap));
    1532           0 :                 recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL);
    1533           0 :                 if (!recs)
    1534             :                         return -ENOMEM;
    1535             :         }
    1536             : 
    1537       94778 :         xhead.fmh_iflags = head.fmh_iflags;
    1538       94778 :         xfs_fsmap_to_internal(&xhead.fmh_keys[0], &head.fmh_keys[0]);
    1539       94586 :         xfs_fsmap_to_internal(&xhead.fmh_keys[1], &head.fmh_keys[1]);
    1540             : 
    1541       94598 :         trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]);
    1542       94587 :         trace_xfs_getfsmap_high_key(ip->i_mount, &xhead.fmh_keys[1]);
    1543             : 
    1544       94792 :         head.fmh_entries = 0;
    1545      135939 :         do {
    1546      135939 :                 struct fsmap __user     *user_recs;
    1547      135939 :                 struct fsmap            *last_rec;
    1548             : 
    1549      135939 :                 user_recs = &arg->fmh_recs[head.fmh_entries];
    1550      135939 :                 xhead.fmh_entries = 0;
    1551      135939 :                 xhead.fmh_count = min_t(unsigned int, count,
    1552             :                                         head.fmh_count - head.fmh_entries);
    1553             : 
    1554             :                 /* Run query, record how many entries we got. */
    1555      135939 :                 error = xfs_getfsmap(ip->i_mount, &xhead, recs);
    1556      136196 :                 switch (error) {
    1557             :                 case 0:
    1558             :                         /*
    1559             :                          * There are no more records in the result set.  Copy
    1560             :                          * whatever we got to userspace and break out.
    1561             :                          */
    1562             :                         done = true;
    1563             :                         break;
    1564       59366 :                 case -ECANCELED:
    1565             :                         /*
    1566             :                          * The internal memory buffer is full.  Copy whatever
    1567             :                          * records we got to userspace and go again if we have
    1568             :                          * not yet filled the userspace buffer.
    1569             :                          */
    1570       59366 :                         error = 0;
    1571       59366 :                         break;
    1572           0 :                 default:
    1573           0 :                         goto out_free;
    1574             :                 }
    1575      136196 :                 head.fmh_entries += xhead.fmh_entries;
    1576      136196 :                 head.fmh_oflags = xhead.fmh_oflags;
    1577             : 
    1578             :                 /*
    1579             :                  * If the caller wanted a record count or there aren't any
    1580             :                  * new records to return, we're done.
    1581             :                  */
    1582      136196 :                 if (head.fmh_count == 0 || xhead.fmh_entries == 0)
    1583             :                         break;
    1584             : 
    1585             :                 /* Copy all the records we got out to userspace. */
    1586      136199 :                 if (copy_to_user(user_recs, recs,
    1587      136196 :                                  xhead.fmh_entries * sizeof(struct fsmap))) {
    1588           0 :                         error = -EFAULT;
    1589           0 :                         goto out_free;
    1590             :                 }
    1591             : 
    1592             :                 /* Remember the last record flags we copied to userspace. */
    1593      136199 :                 last_rec = &recs[xhead.fmh_entries - 1];
    1594      136199 :                 last_flags = last_rec->fmr_flags;
    1595             : 
    1596             :                 /* Set up the low key for the next iteration. */
    1597      136199 :                 xfs_fsmap_to_internal(&xhead.fmh_keys[0], last_rec);
    1598      136204 :                 trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]);
    1599      136199 :         } while (!done && head.fmh_entries < head.fmh_count);
    1600             : 
    1601             :         /*
    1602             :          * If there are no more records in the query result set and we're not
    1603             :          * in counting mode, mark the last record returned with the LAST flag.
    1604             :          */
    1605       95052 :         if (done && head.fmh_count > 0 && head.fmh_entries > 0) {
    1606       76830 :                 struct fsmap __user     *user_rec;
    1607             : 
    1608       76830 :                 last_flags |= FMR_OF_LAST;
    1609       76830 :                 user_rec = &arg->fmh_recs[head.fmh_entries - 1];
    1610             : 
    1611       76830 :                 if (copy_to_user(&user_rec->fmr_flags, &last_flags,
    1612             :                                         sizeof(last_flags))) {
    1613           0 :                         error = -EFAULT;
    1614           0 :                         goto out_free;
    1615             :                 }
    1616             :         }
    1617             : 
    1618             :         /* copy back header */
    1619       95049 :         if (copy_to_user(arg, &head, sizeof(struct fsmap_head))) {
    1620           0 :                 error = -EFAULT;
    1621           0 :                 goto out_free;
    1622             :         }
    1623             : 
    1624       95043 : out_free:
    1625       95043 :         kmem_free(recs);
    1626       95043 :         return error;
    1627             : }
    1628             : 
    1629             : STATIC int
    1630        1011 : xfs_ioc_getfsrefcounts(
    1631             :         struct xfs_inode                *ip,
    1632             :         struct xfs_getfsrefs_head       __user *arg)
    1633             : {
    1634        1011 :         struct xfs_fsrefs_head          xhead = {0};
    1635        1011 :         struct xfs_getfsrefs_head       head;
    1636        1011 :         struct xfs_getfsrefs            *recs;
    1637        1011 :         unsigned int                    count;
    1638        1011 :         __u32                           last_flags = 0;
    1639        1011 :         bool                            done = false;
    1640        1011 :         int                             error;
    1641             : 
    1642        1011 :         if (copy_from_user(&head, arg, sizeof(struct xfs_getfsrefs_head)))
    1643             :                 return -EFAULT;
    1644        2022 :         if (memchr_inv(head.fch_reserved, 0, sizeof(head.fch_reserved)) ||
    1645             :             memchr_inv(head.fch_keys[0].fcr_reserved, 0,
    1646        1011 :                        sizeof(head.fch_keys[0].fcr_reserved)) ||
    1647             :             memchr_inv(head.fch_keys[1].fcr_reserved, 0,
    1648             :                        sizeof(head.fch_keys[1].fcr_reserved)))
    1649           0 :                 return -EINVAL;
    1650             : 
    1651             :         /*
    1652             :          * Use an internal memory buffer so that we don't have to copy fsrefs
    1653             :          * data to userspace while holding locks.  Start by trying to allocate
    1654             :          * up to 128k for the buffer, but fall back to a single page if needed.
    1655             :          */
    1656        1011 :         count = min_t(unsigned int, head.fch_count,
    1657             :                         131072 / sizeof(struct xfs_getfsrefs));
    1658        1011 :         recs = kvzalloc(count * sizeof(struct xfs_getfsrefs), GFP_KERNEL);
    1659        1011 :         if (!recs) {
    1660           0 :                 count = min_t(unsigned int, head.fch_count,
    1661             :                                 PAGE_SIZE / sizeof(struct xfs_getfsrefs));
    1662           0 :                 recs = kvzalloc(count * sizeof(struct xfs_getfsrefs),
    1663             :                                 GFP_KERNEL);
    1664           0 :                 if (!recs)
    1665             :                         return -ENOMEM;
    1666             :         }
    1667             : 
    1668        1011 :         xhead.fch_iflags = head.fch_iflags;
    1669        1011 :         xfs_fsrefs_to_internal(&xhead.fch_keys[0], &head.fch_keys[0]);
    1670        1011 :         xfs_fsrefs_to_internal(&xhead.fch_keys[1], &head.fch_keys[1]);
    1671             : 
    1672        1011 :         trace_xfs_getfsrefs_low_key(ip->i_mount, &xhead.fch_keys[0]);
    1673        1011 :         trace_xfs_getfsrefs_high_key(ip->i_mount, &xhead.fch_keys[1]);
    1674             : 
    1675        1011 :         head.fch_entries = 0;
    1676        1011 :         do {
    1677        1011 :                 struct xfs_getfsrefs __user     *user_recs;
    1678        1011 :                 struct xfs_getfsrefs            *last_rec;
    1679             : 
    1680        1011 :                 user_recs = &arg->fch_recs[head.fch_entries];
    1681        1011 :                 xhead.fch_entries = 0;
    1682        1011 :                 xhead.fch_count = min_t(unsigned int, count,
    1683             :                                         head.fch_count - head.fch_entries);
    1684             : 
    1685             :                 /* Run query, record how many entries we got. */
    1686        1011 :                 error = xfs_getfsrefs(ip->i_mount, &xhead, recs);
    1687        1011 :                 switch (error) {
    1688             :                 case 0:
    1689             :                         /*
    1690             :                          * There are no more records in the result set.  Copy
    1691             :                          * whatever we got to userspace and break out.
    1692             :                          */
    1693             :                         done = true;
    1694             :                         break;
    1695        1005 :                 case -ECANCELED:
    1696             :                         /*
    1697             :                          * The internal memory buffer is full.  Copy whatever
    1698             :                          * records we got to userspace and go again if we have
    1699             :                          * not yet filled the userspace buffer.
    1700             :                          */
    1701        1005 :                         error = 0;
    1702        1005 :                         break;
    1703           0 :                 default:
    1704           0 :                         goto out_free;
    1705             :                 }
    1706        1011 :                 head.fch_entries += xhead.fch_entries;
    1707        1011 :                 head.fch_oflags = xhead.fch_oflags;
    1708             : 
    1709             :                 /*
    1710             :                  * If the caller wanted a record count or there aren't any
    1711             :                  * new records to return, we're done.
    1712             :                  */
    1713        1011 :                 if (head.fch_count == 0 || xhead.fch_entries == 0)
    1714             :                         break;
    1715             : 
    1716             :                 /* Copy all the records we got out to userspace. */
    1717        1011 :                 if (copy_to_user(user_recs, recs,
    1718        1011 :                                  xhead.fch_entries * sizeof(struct xfs_getfsrefs))) {
    1719           0 :                         error = -EFAULT;
    1720           0 :                         goto out_free;
    1721             :                 }
    1722             : 
    1723             :                 /* Remember the last record flags we copied to userspace. */
    1724        1011 :                 last_rec = &recs[xhead.fch_entries - 1];
    1725        1011 :                 last_flags = last_rec->fcr_flags;
    1726             : 
    1727             :                 /* Set up the low key for the next iteration. */
    1728        1011 :                 xfs_fsrefs_to_internal(&xhead.fch_keys[0], last_rec);
    1729        1011 :                 trace_xfs_getfsrefs_low_key(ip->i_mount, &xhead.fch_keys[0]);
    1730        1011 :         } while (!done && head.fch_entries < head.fch_count);
    1731             : 
    1732             :         /*
    1733             :          * If there are no more records in the query result set and we're not
    1734             :          * in counting mode, mark the last record returned with the LAST flag.
    1735             :          */
    1736        1011 :         if (done && head.fch_count > 0 && head.fch_entries > 0) {
    1737           6 :                 struct xfs_getfsrefs __user     *user_rec;
    1738             : 
    1739           6 :                 last_flags |= FCR_OF_LAST;
    1740           6 :                 user_rec = &arg->fch_recs[head.fch_entries - 1];
    1741             : 
    1742           6 :                 if (copy_to_user(&user_rec->fcr_flags, &last_flags,
    1743             :                                         sizeof(last_flags))) {
    1744           0 :                         error = -EFAULT;
    1745           0 :                         goto out_free;
    1746             :                 }
    1747             :         }
    1748             : 
    1749             :         /* copy back header */
    1750        1011 :         if (copy_to_user(arg, &head, sizeof(struct xfs_getfsrefs_head))) {
    1751           0 :                 error = -EFAULT;
    1752           0 :                 goto out_free;
    1753             :         }
    1754             : 
    1755        1011 : out_free:
    1756        1011 :         kmem_free(recs);
    1757        1011 :         return error;
    1758             : }
    1759             : 
    1760             : STATIC int
    1761     2689436 : xfs_ioc_scrub_metadata(
    1762             :         struct file                     *file,
    1763             :         void                            __user *arg)
    1764             : {
    1765     2689436 :         struct xfs_scrub_metadata       scrub;
    1766     2689436 :         int                             error;
    1767             : 
    1768     2689436 :         if (!capable(CAP_SYS_ADMIN))
    1769             :                 return -EPERM;
    1770             : 
    1771     2689436 :         if (copy_from_user(&scrub, arg, sizeof(scrub)))
    1772             :                 return -EFAULT;
    1773             : 
    1774     2689436 :         error = xfs_scrub_metadata(file, &scrub);
    1775     2689436 :         if (error)
    1776             :                 return error;
    1777             : 
    1778     2664380 :         if (copy_to_user(arg, &scrub, sizeof(scrub)))
    1779           0 :                 return -EFAULT;
    1780             : 
    1781             :         return 0;
    1782             : }
    1783             : 
    1784             : /*
    1785             :  * IOCTL routine to get the parent pointers of an inode and return it to user
    1786             :  * space.  Caller must pass a buffer space containing a struct xfs_getparents,
    1787             :  * followed by a region large enough to contain an array of struct
    1788             :  * xfs_getparents_rec of a size specified in gp_bufsize.  If the inode contains
    1789             :  * more parent pointers than can fit in the buffer space, caller may re-call
    1790             :  * the function using the returned gp_cursor to resume iteration.  The
    1791             :  * number of xfs_getparents_rec returned will be stored in gp_count.
    1792             :  *
    1793             :  * Returns 0 on success or non-zero on failure
    1794             :  */
    1795             : STATIC int
    1796    36289764 : xfs_ioc_get_parent_pointer(
    1797             :         struct file                     *filp,
    1798             :         void                            __user *arg)
    1799             : {
    1800    36289764 :         struct xfs_getparents           *ppi = NULL;
    1801    36289764 :         int                             error = 0;
    1802    36289764 :         struct xfs_inode                *file_ip = XFS_I(file_inode(filp));
    1803    36289764 :         struct xfs_inode                *call_ip = file_ip;
    1804    36289764 :         struct xfs_mount                *mp = file_ip->i_mount;
    1805    36289764 :         void                            __user *o_pptr;
    1806    36289764 :         struct xfs_getparents_rec       *i_pptr;
    1807    36289764 :         unsigned int                    bytes;
    1808             : 
    1809    36289764 :         if (!capable(CAP_SYS_ADMIN))
    1810             :                 return -EPERM;
    1811             : 
    1812             :         /* Allocate an xfs_getparents to put the user data */
    1813    36290483 :         ppi = kvmalloc(sizeof(struct xfs_getparents), GFP_KERNEL);
    1814    36290659 :         if (!ppi)
    1815             :                 return -ENOMEM;
    1816             : 
    1817             :         /* Copy the data from the user */
    1818    36290659 :         error = copy_from_user(ppi, arg, sizeof(struct xfs_getparents));
    1819    36290621 :         if (error) {
    1820           0 :                 error = -EFAULT;
    1821           0 :                 goto out;
    1822             :         }
    1823             : 
    1824             :         /* Check size of buffer requested by user */
    1825    36290621 :         if (ppi->gp_bufsize > XFS_XATTR_LIST_MAX) {
    1826           0 :                 error = -ENOMEM;
    1827           0 :                 goto out;
    1828             :         }
    1829    36290621 :         if (ppi->gp_bufsize < sizeof(struct xfs_getparents)) {
    1830           0 :                 error = -EINVAL;
    1831           0 :                 goto out;
    1832             :         }
    1833             : 
    1834    36290621 :         if (ppi->gp_flags & ~XFS_GETPARENTS_FLAG_ALL) {
    1835           0 :                 error = -EINVAL;
    1836           0 :                 goto out;
    1837             :         }
    1838    36290621 :         ppi->gp_flags &= ~(XFS_GETPARENTS_OFLAG_ROOT | XFS_GETPARENTS_OFLAG_DONE);
    1839             : 
    1840             :         /*
    1841             :          * Now that we know how big the trailing buffer is, expand
    1842             :          * our kernel xfs_getparents to be the same size
    1843             :          */
    1844    36290621 :         ppi = kvrealloc(ppi, sizeof(struct xfs_getparents), ppi->gp_bufsize,
    1845             :                         GFP_KERNEL | __GFP_ZERO);
    1846    36284726 :         if (!ppi)
    1847             :                 return -ENOMEM;
    1848             : 
    1849    36284726 :         if (ppi->gp_flags & XFS_GETPARENTS_IFLAG_HANDLE) {
    1850    36284292 :                 struct xfs_handle       *hanp = &ppi->gp_handle;
    1851             : 
    1852    72568584 :                 if (memcmp(&hanp->ha_fsid, mp->m_fixedfsid,
    1853             :                                                         sizeof(xfs_fsid_t))) {
    1854           0 :                         error = -EINVAL;
    1855           0 :                         goto out;
    1856             :                 }
    1857             : 
    1858    36284292 :                 if (hanp->ha_fid.fid_ino != file_ip->i_ino) {
    1859    34230758 :                         error = xfs_iget(mp, NULL, hanp->ha_fid.fid_ino,
    1860             :                                         XFS_IGET_UNTRUSTED, 0, &call_ip);
    1861    34234688 :                         if (error)
    1862         175 :                                 goto out;
    1863             :                 }
    1864             : 
    1865    36288047 :                 if (VFS_I(call_ip)->i_generation != hanp->ha_fid.fid_gen) {
    1866       19927 :                         error = -EINVAL;
    1867       19927 :                         goto out;
    1868             :                 }
    1869             :         }
    1870             : 
    1871             :         /* Get the parent pointers */
    1872    36268554 :         error = xfs_getparent_pointers(call_ip, ppi);
    1873    36270374 :         if (error)
    1874           0 :                 goto out;
    1875             : 
    1876             :         /*
    1877             :          * If we ran out of buffer space before copying any parent pointers at
    1878             :          * all, the caller's buffer was too short.  Tell userspace that, erm,
    1879             :          * the message is too long.
    1880             :          */
    1881    36270374 :         if (ppi->gp_count == 0 && !(ppi->gp_flags & XFS_GETPARENTS_OFLAG_DONE)) {
    1882           0 :                 error = -EMSGSIZE;
    1883           0 :                 goto out;
    1884             :         }
    1885             : 
    1886             :         /* Copy the parent pointer head back to the user */
    1887    36270374 :         bytes = xfs_getparents_arraytop(ppi, ppi->gp_count);
    1888    36270374 :         error = copy_to_user(arg, ppi, bytes);
    1889    36269756 :         if (error) {
    1890           0 :                 error = -EFAULT;
    1891           0 :                 goto out;
    1892             :         }
    1893             : 
    1894    36269756 :         if (ppi->gp_count == 0)
    1895     2091478 :                 goto out;
    1896             : 
    1897             :         /* Copy the parent pointer records back to the user. */
    1898    34178278 :         o_pptr = (__user char*)arg + ppi->gp_offsets[ppi->gp_count - 1];
    1899    34178278 :         i_pptr = xfs_getparents_rec(ppi, ppi->gp_count - 1);
    1900    34178278 :         bytes = ((char *)ppi + ppi->gp_bufsize) - (char *)i_pptr;
    1901    34178278 :         error = copy_to_user(o_pptr, i_pptr, bytes);
    1902    34177745 :         if (error) {
    1903           0 :                 error = -EFAULT;
    1904           0 :                 goto out;
    1905             :         }
    1906             : 
    1907    34177745 : out:
    1908    36289325 :         if (call_ip != file_ip)
    1909    34235689 :                 xfs_irele(call_ip);
    1910    36289414 :         kvfree(ppi);
    1911    36289414 :         return error;
    1912             : }
    1913             : 
    1914             : int
    1915           0 : xfs_ioc_swapext(
    1916             :         struct xfs_swapext      *sxp)
    1917             : {
    1918           0 :         struct xfs_exch_range   fxr = { 0 };
    1919           0 :         struct fd               fd2, fd1;
    1920           0 :         int                     error = 0;
    1921             : 
    1922           0 :         fd2 = fdget((int)sxp->sx_fdtarget);
    1923           0 :         if (!fd2.file)
    1924             :                 return -EINVAL;
    1925             : 
    1926           0 :         fd1 = fdget((int)sxp->sx_fdtmp);
    1927           0 :         if (!fd1.file) {
    1928           0 :                 error = -EINVAL;
    1929           0 :                 goto dest_fdput;
    1930             :         }
    1931             : 
    1932           0 :         fxr.file1_fd = sxp->sx_fdtmp;
    1933           0 :         fxr.length = sxp->sx_length;
    1934           0 :         fxr.flags = XFS_EXCH_RANGE_NONATOMIC | XFS_EXCH_RANGE_FILE2_FRESH |
    1935             :                     XFS_EXCH_RANGE_FULL_FILES;
    1936           0 :         fxr.file2_ino = sxp->sx_stat.bs_ino;
    1937           0 :         fxr.file2_mtime = sxp->sx_stat.bs_mtime.tv_sec;
    1938           0 :         fxr.file2_ctime = sxp->sx_stat.bs_ctime.tv_sec;
    1939           0 :         fxr.file2_mtime_nsec = sxp->sx_stat.bs_mtime.tv_nsec;
    1940           0 :         fxr.file2_ctime_nsec = sxp->sx_stat.bs_ctime.tv_nsec;
    1941             : 
    1942           0 :         error = xfs_exch_range(fd1.file, fd2.file, &fxr);
    1943             : 
    1944             :         /*
    1945             :          * The old implementation returned EFAULT if the swap range was not
    1946             :          * the entirety of both files.
    1947             :          */
    1948           0 :         if (error == -EDOM)
    1949           0 :                 error = -EFAULT;
    1950           0 :         fdput(fd1);
    1951           0 : dest_fdput:
    1952           0 :         fdput(fd2);
    1953           0 :         return error;
    1954             : }
    1955             : 
    1956             : static int
    1957        7058 : xfs_ioc_getlabel(
    1958             :         struct xfs_mount        *mp,
    1959             :         char                    __user *user_label)
    1960             : {
    1961        7058 :         struct xfs_sb           *sbp = &mp->m_sb;
    1962        7058 :         char                    label[XFSLABEL_MAX + 1];
    1963             : 
    1964             :         /* Paranoia */
    1965        7058 :         BUILD_BUG_ON(sizeof(sbp->sb_fname) > FSLABEL_MAX);
    1966             : 
    1967             :         /* 1 larger than sb_fname, so this ensures a trailing NUL char */
    1968        7058 :         memset(label, 0, sizeof(label));
    1969        7058 :         spin_lock(&mp->m_sb_lock);
    1970        7058 :         strncpy(label, sbp->sb_fname, XFSLABEL_MAX);
    1971        7058 :         spin_unlock(&mp->m_sb_lock);
    1972             : 
    1973        7058 :         if (copy_to_user(user_label, label, sizeof(label)))
    1974           0 :                 return -EFAULT;
    1975             :         return 0;
    1976             : }
    1977             : 
    1978             : static int
    1979          54 : xfs_ioc_setlabel(
    1980             :         struct file             *filp,
    1981             :         struct xfs_mount        *mp,
    1982             :         char                    __user *newlabel)
    1983             : {
    1984          54 :         struct xfs_sb           *sbp = &mp->m_sb;
    1985          54 :         struct block_device     *bdev = xfs_buftarg_bdev(mp->m_ddev_targp);
    1986          54 :         char                    label[XFSLABEL_MAX + 1];
    1987          54 :         size_t                  len;
    1988          54 :         int                     error;
    1989             : 
    1990          54 :         if (!capable(CAP_SYS_ADMIN))
    1991             :                 return -EPERM;
    1992             :         /*
    1993             :          * The generic ioctl allows up to FSLABEL_MAX chars, but XFS is much
    1994             :          * smaller, at 12 bytes.  We copy one more to be sure we find the
    1995             :          * (required) NULL character to test the incoming label length.
    1996             :          * NB: The on disk label doesn't need to be null terminated.
    1997             :          */
    1998          54 :         if (copy_from_user(label, newlabel, XFSLABEL_MAX + 1))
    1999             :                 return -EFAULT;
    2000          54 :         len = strnlen(label, XFSLABEL_MAX + 1);
    2001          54 :         if (len > sizeof(sbp->sb_fname))
    2002             :                 return -EINVAL;
    2003             : 
    2004          52 :         error = mnt_want_write_file(filp);
    2005          52 :         if (error)
    2006             :                 return error;
    2007             : 
    2008          52 :         spin_lock(&mp->m_sb_lock);
    2009          52 :         memset(sbp->sb_fname, 0, sizeof(sbp->sb_fname));
    2010         104 :         memcpy(sbp->sb_fname, label, len);
    2011          52 :         spin_unlock(&mp->m_sb_lock);
    2012             : 
    2013             :         /*
    2014             :          * Now we do several things to satisfy userspace.
    2015             :          * In addition to normal logging of the primary superblock, we also
    2016             :          * immediately write these changes to sector zero for the primary, then
    2017             :          * update all backup supers (as xfs_db does for a label change), then
    2018             :          * invalidate the block device page cache.  This is so that any prior
    2019             :          * buffered reads from userspace (i.e. from blkid) are invalidated,
    2020             :          * and userspace will see the newly-written label.
    2021             :          */
    2022          52 :         error = xfs_sync_sb_buf(mp);
    2023          52 :         if (error)
    2024           0 :                 goto out;
    2025             :         /*
    2026             :          * growfs also updates backup supers so lock against that.
    2027             :          */
    2028          52 :         mutex_lock(&mp->m_growlock);
    2029          52 :         error = xfs_update_secondary_sbs(mp);
    2030          52 :         if (!error)
    2031          52 :                 error = xfs_rtgroup_update_secondary_sbs(mp);
    2032          52 :         mutex_unlock(&mp->m_growlock);
    2033             : 
    2034          52 :         invalidate_bdev(bdev);
    2035             : 
    2036          52 : out:
    2037          52 :         mnt_drop_write_file(filp);
    2038          52 :         return error;
    2039             : }
    2040             : 
    2041             : STATIC int
    2042    89747449 : xfs_ioc_scrubv_metadata(
    2043             :         struct file                     *filp,
    2044             :         void                            __user *arg)
    2045             : {
    2046    89747449 :         struct xfs_scrub_vec_head       __user *uhead = arg;
    2047    89747449 :         struct xfs_scrub_vec_head       head;
    2048    89747449 :         struct xfs_scrub_vec_head       *vhead;
    2049    89747449 :         size_t                          bytes;
    2050    89747449 :         int                             error;
    2051             : 
    2052    89747449 :         if (!capable(CAP_SYS_ADMIN))
    2053             :                 return -EPERM;
    2054             : 
    2055    89747867 :         if (copy_from_user(&head, uhead, sizeof(head)))
    2056             :                 return -EFAULT;
    2057             : 
    2058    89748724 :         bytes = sizeof_xfs_scrub_vec(head.svh_nr);
    2059    89748724 :         if (bytes > PAGE_SIZE)
    2060             :                 return -ENOMEM;
    2061    89748724 :         vhead = kvmalloc(bytes, GFP_KERNEL | __GFP_RETRY_MAYFAIL);
    2062    89748945 :         if (!vhead)
    2063             :                 return -ENOMEM;
    2064   179497890 :         memcpy(vhead, &head, sizeof(struct xfs_scrub_vec_head));
    2065             : 
    2066    89748498 :         if (copy_from_user(&vhead->svh_vecs, &uhead->svh_vecs,
    2067    89748945 :                                 head.svh_nr * sizeof(struct xfs_scrub_vec))) {
    2068           0 :                 error = -EFAULT;
    2069           0 :                 goto err_free;
    2070             :         }
    2071             : 
    2072    89748498 :         error = xfs_scrubv_metadata(filp, vhead);
    2073    89749620 :         if (error)
    2074          79 :                 goto err_free;
    2075             : 
    2076   179499682 :         if (copy_to_user(uhead, vhead, bytes)) {
    2077           0 :                 error = -EFAULT;
    2078           0 :                 goto err_free;
    2079             :         }
    2080             : 
    2081    89750141 : err_free:
    2082    89750220 :         kvfree(vhead);
    2083    89750220 :         return error;
    2084             : }
    2085             : 
    2086             : #define XFS_ADDFEATURE_SUPPORTED        (XFS_FSOP_GEOM_FLAGS_INOBTCNT | \
    2087             :                                          XFS_FSOP_GEOM_FLAGS_BIGTIME | \
    2088             :                                          XFS_FSOP_GEOM_FLAGS_NREXT64)
    2089             : static int
    2090           0 : xfs_ioc_addfeature(
    2091             :         struct file             *filp,
    2092             :         struct xfs_mount        *mp,
    2093             :         __u64                   __user *uflags)
    2094             : {
    2095           0 :         struct xfs_sb           *sbp = &mp->m_sb;
    2096           0 :         struct block_device     *bdev = xfs_buftarg_bdev(mp->m_ddev_targp);
    2097           0 :         __u64                   flags;
    2098           0 :         bool                    dirty = false;
    2099           0 :         int                     error = 0;
    2100             : 
    2101           0 :         if (!capable(CAP_SYS_ADMIN))
    2102             :                 return -EPERM;
    2103             : 
    2104           0 :         if (copy_from_user(&flags, uflags, sizeof(__u64)))
    2105             :                 return -EFAULT;
    2106             : 
    2107           0 :         if (flags & ~XFS_ADDFEATURE_SUPPORTED)
    2108             :                 return -EINVAL;
    2109             : 
    2110           0 :         error = mnt_want_write_file(filp);
    2111           0 :         if (error)
    2112             :                 return error;
    2113             : 
    2114           0 :         spin_lock(&mp->m_sb_lock);
    2115           0 :         if ((flags & XFS_FSOP_GEOM_FLAGS_BIGTIME) && !xfs_has_bigtime(mp)) {
    2116           0 :                 xfs_info(mp, "Adding bigtime feature.");
    2117           0 :                 sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_BIGTIME;
    2118           0 :                 mp->m_features |= XFS_FEAT_BIGTIME;
    2119           0 :                 dirty = true;
    2120             :         }
    2121           0 :         if ((flags & XFS_FSOP_GEOM_FLAGS_INOBTCNT) &&
    2122             :             !xfs_has_inobtcounts(mp)) {
    2123           0 :                 xfs_info(mp, "Adding inobtcount feature.");
    2124           0 :                 sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_INOBTCNT;
    2125           0 :                 mp->m_features |= XFS_FEAT_INOBTCNT;
    2126           0 :                 dirty = true;
    2127             :         }
    2128           0 :         if ((flags & XFS_FSOP_GEOM_FLAGS_NREXT64) &&
    2129             :             !xfs_has_large_extent_counts(mp)) {
    2130           0 :                 xfs_info(mp, "Adding nrext64 feature.");
    2131           0 :                 sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_NREXT64;
    2132           0 :                 mp->m_features |= XFS_FEAT_NREXT64;
    2133           0 :                 dirty = true;
    2134             :         }
    2135           0 :         spin_unlock(&mp->m_sb_lock);
    2136             : 
    2137           0 :         if (!dirty)
    2138           0 :                 goto out;
    2139             : 
    2140             :         /*
    2141             :          * Now we do several things to satisfy userspace.
    2142             :          * In addition to normal logging of the primary superblock, we also
    2143             :          * immediately write these changes to sector zero for the primary, then
    2144             :          * update all backup supers (as xfs_db does for a label change), then
    2145             :          * invalidate the block device page cache.  This is so that any prior
    2146             :          * buffered reads from userspace (i.e. from blkid) are invalidated,
    2147             :          * and userspace will see the newly-written label.
    2148             :          */
    2149           0 :         error = xfs_sync_sb_buf(mp);
    2150           0 :         if (error)
    2151           0 :                 goto out;
    2152             :         /*
    2153             :          * growfs also updates backup supers so lock against that.
    2154             :          */
    2155           0 :         mutex_lock(&mp->m_growlock);
    2156           0 :         error = xfs_update_secondary_sbs(mp);
    2157           0 :         mutex_unlock(&mp->m_growlock);
    2158             : 
    2159           0 :         invalidate_bdev(bdev);
    2160             : 
    2161           0 : out:
    2162           0 :         mnt_drop_write_file(filp);
    2163           0 :         return error;
    2164             : }
    2165             : 
    2166             : static inline int
    2167           0 : xfs_fs_eofblocks_from_user(
    2168             :         struct xfs_fs_eofblocks         *src,
    2169             :         struct xfs_icwalk               *dst)
    2170             : {
    2171           0 :         if (src->eof_version != XFS_EOFBLOCKS_VERSION)
    2172             :                 return -EINVAL;
    2173             : 
    2174           0 :         if (src->eof_flags & ~XFS_EOF_FLAGS_VALID)
    2175             :                 return -EINVAL;
    2176             : 
    2177           0 :         if (memchr_inv(&src->pad32, 0, sizeof(src->pad32)) ||
    2178           0 :             memchr_inv(src->pad64, 0, sizeof(src->pad64)))
    2179           0 :                 return -EINVAL;
    2180             : 
    2181           0 :         dst->icw_flags = 0;
    2182           0 :         if (src->eof_flags & XFS_EOF_FLAGS_SYNC)
    2183           0 :                 dst->icw_flags |= XFS_ICWALK_FLAG_SYNC;
    2184           0 :         if (src->eof_flags & XFS_EOF_FLAGS_UID)
    2185           0 :                 dst->icw_flags |= XFS_ICWALK_FLAG_UID;
    2186           0 :         if (src->eof_flags & XFS_EOF_FLAGS_GID)
    2187           0 :                 dst->icw_flags |= XFS_ICWALK_FLAG_GID;
    2188           0 :         if (src->eof_flags & XFS_EOF_FLAGS_PRID)
    2189           0 :                 dst->icw_flags |= XFS_ICWALK_FLAG_PRID;
    2190           0 :         if (src->eof_flags & XFS_EOF_FLAGS_MINFILESIZE)
    2191           0 :                 dst->icw_flags |= XFS_ICWALK_FLAG_MINFILESIZE;
    2192             : 
    2193           0 :         dst->icw_prid = src->eof_prid;
    2194           0 :         dst->icw_min_file_size = src->eof_min_file_size;
    2195             : 
    2196           0 :         dst->icw_uid = INVALID_UID;
    2197           0 :         if (src->eof_flags & XFS_EOF_FLAGS_UID) {
    2198           0 :                 dst->icw_uid = make_kuid(current_user_ns(), src->eof_uid);
    2199           0 :                 if (!uid_valid(dst->icw_uid))
    2200             :                         return -EINVAL;
    2201             :         }
    2202             : 
    2203           0 :         dst->icw_gid = INVALID_GID;
    2204           0 :         if (src->eof_flags & XFS_EOF_FLAGS_GID) {
    2205           0 :                 dst->icw_gid = make_kgid(current_user_ns(), src->eof_gid);
    2206           0 :                 if (!gid_valid(dst->icw_gid))
    2207           0 :                         return -EINVAL;
    2208             :         }
    2209             :         return 0;
    2210             : }
    2211             : 
    2212             : static long
    2213     2313621 : xfs_ioc_exchange_range(
    2214             :         struct file                     *file2,
    2215             :         struct xfs_exch_range __user    *argp)
    2216             : {
    2217     2313621 :         struct xfs_exch_range           args;
    2218     2313621 :         struct fd                       file1;
    2219     2313621 :         int                             error;
    2220             : 
    2221     2313621 :         if (copy_from_user(&args, argp, sizeof(args)))
    2222             :                 return -EFAULT;
    2223             : 
    2224     2313618 :         file1 = fdget(args.file1_fd);
    2225     2313619 :         if (!file1.file)
    2226             :                 return -EBADF;
    2227             : 
    2228     2313619 :         error = -EXDEV;
    2229     2313619 :         if (file1.file->f_path.mnt != file2->f_path.mnt)
    2230           4 :                 goto fdput;
    2231             : 
    2232     2313615 :         error = xfs_exch_range(file1.file, file2, &args);
    2233     2313615 : fdput:
    2234     2313615 :         fdput(file1);
    2235     2313615 :         return error;
    2236             : }
    2237             : 
    2238             : /*
    2239             :  * These long-unused ioctls were removed from the official ioctl API in 5.17,
    2240             :  * but retain these definitions so that we can log warnings about them.
    2241             :  */
    2242             : #define XFS_IOC_ALLOCSP         _IOW ('X', 10, struct xfs_flock64)
    2243             : #define XFS_IOC_FREESP          _IOW ('X', 11, struct xfs_flock64)
    2244             : #define XFS_IOC_ALLOCSP64       _IOW ('X', 36, struct xfs_flock64)
    2245             : #define XFS_IOC_FREESP64        _IOW ('X', 37, struct xfs_flock64)
    2246             : 
    2247             : /*
    2248             :  * Note: some of the ioctl's return positive numbers as a
    2249             :  * byte count indicating success, such as readlink_by_handle.
    2250             :  * So we don't "sign flip" like most other routines.  This means
    2251             :  * true errors need to be returned as a negative value.
    2252             :  */
    2253             : long
    2254   773823385 : xfs_file_ioctl(
    2255             :         struct file             *filp,
    2256             :         unsigned int            cmd,
    2257             :         unsigned long           p)
    2258             : {
    2259   773823385 :         struct inode            *inode = file_inode(filp);
    2260   773823385 :         struct xfs_inode        *ip = XFS_I(inode);
    2261   773823385 :         struct xfs_mount        *mp = ip->i_mount;
    2262   773823385 :         void                    __user *arg = (void __user *)p;
    2263   773823385 :         int                     error;
    2264             : 
    2265   773823385 :         trace_xfs_file_ioctl(ip);
    2266             : 
    2267   773865391 :         switch (cmd) {
    2268       39469 :         case FITRIM:
    2269       39469 :                 return xfs_ioc_trim(mp, arg);
    2270        7058 :         case FS_IOC_GETFSLABEL:
    2271        7058 :                 return xfs_ioc_getlabel(mp, arg);
    2272          54 :         case FS_IOC_SETFSLABEL:
    2273          54 :                 return xfs_ioc_setlabel(filp, mp, arg);
    2274           0 :         case XFS_IOC_ADDFEATURE:
    2275           0 :                 return xfs_ioc_addfeature(filp, mp, arg);
    2276             :         case XFS_IOC_ALLOCSP:
    2277             :         case XFS_IOC_FREESP:
    2278             :         case XFS_IOC_ALLOCSP64:
    2279             :         case XFS_IOC_FREESP64:
    2280           2 :                 xfs_warn_once(mp,
    2281             :         "%s should use fallocate; XFS_IOC_{ALLOC,FREE}SP ioctl unsupported",
    2282             :                                 current->comm);
    2283             :                 return -ENOTTY;
    2284    12131443 :         case XFS_IOC_DIOINFO: {
    2285    12131443 :                 struct xfs_buftarg      *target = xfs_inode_buftarg(ip);
    2286    12131443 :                 struct dioattr          da;
    2287             : 
    2288    12131443 :                 da.d_mem =  da.d_miniosz = target->bt_logical_sectorsize;
    2289    12131443 :                 da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
    2290             : 
    2291    12131443 :                 if (copy_to_user(arg, &da, sizeof(da)))
    2292           0 :                         return -EFAULT;
    2293             :                 return 0;
    2294             :         }
    2295             : 
    2296   450696976 :         case XFS_IOC_FSBULKSTAT_SINGLE:
    2297             :         case XFS_IOC_FSBULKSTAT:
    2298             :         case XFS_IOC_FSINUMBERS:
    2299   450696976 :                 return xfs_ioc_fsbulkstat(filp, cmd, arg);
    2300             : 
    2301     5660035 :         case XFS_IOC_BULKSTAT:
    2302     5660035 :                 return xfs_ioc_bulkstat(filp, cmd, arg);
    2303     2611631 :         case XFS_IOC_INUMBERS:
    2304     2611631 :                 return xfs_ioc_inumbers(mp, cmd, arg);
    2305             : 
    2306         144 :         case XFS_IOC_FSGEOMETRY_V1:
    2307         144 :                 return xfs_ioc_fsgeometry(mp, arg, 3);
    2308           0 :         case XFS_IOC_FSGEOMETRY_V4:
    2309           0 :                 return xfs_ioc_fsgeometry(mp, arg, 4);
    2310     2051862 :         case XFS_IOC_FSGEOMETRY:
    2311     2051862 :                 return xfs_ioc_fsgeometry(mp, arg, 5);
    2312             : 
    2313       15595 :         case XFS_IOC_AG_GEOMETRY:
    2314       15595 :                 return xfs_ioc_ag_geometry(mp, arg);
    2315         396 :         case XFS_IOC_RTGROUP_GEOMETRY:
    2316         396 :                 return xfs_ioc_rtgroup_geometry(mp, arg);
    2317             : 
    2318           0 :         case XFS_IOC_GETVERSION:
    2319           0 :                 return put_user(inode->i_generation, (int __user *)arg);
    2320             : 
    2321        5216 :         case XFS_IOC_FSGETXATTRA:
    2322        5216 :                 return xfs_ioc_fsgetxattra(ip, arg);
    2323    36290603 :         case XFS_IOC_GETPARENTS:
    2324    36290603 :                 return xfs_ioc_get_parent_pointer(filp, arg);
    2325     1196056 :         case XFS_IOC_GETBMAP:
    2326             :         case XFS_IOC_GETBMAPA:
    2327             :         case XFS_IOC_GETBMAPX:
    2328     1196056 :                 return xfs_ioc_getbmap(filp, cmd, arg);
    2329             : 
    2330       94829 :         case FS_IOC_GETFSMAP:
    2331       94829 :                 return xfs_ioc_getfsmap(ip, arg);
    2332             : 
    2333        1011 :         case XFS_IOC_GETFSREFCOUNTS:
    2334        1011 :                 return xfs_ioc_getfsrefcounts(ip, arg);
    2335             : 
    2336    89747893 :         case XFS_IOC_SCRUBV_METADATA:
    2337    89747893 :                 return xfs_ioc_scrubv_metadata(filp, arg);
    2338     2689436 :         case XFS_IOC_SCRUB_METADATA:
    2339     2689436 :                 return xfs_ioc_scrub_metadata(filp, arg);
    2340             : 
    2341             :         case XFS_IOC_FD_TO_HANDLE:
    2342             :         case XFS_IOC_PATH_TO_HANDLE:
    2343             :         case XFS_IOC_PATH_TO_FSHANDLE: {
    2344       26244 :                 xfs_fsop_handlereq_t    hreq;
    2345             : 
    2346       26244 :                 if (copy_from_user(&hreq, arg, sizeof(hreq)))
    2347             :                         return -EFAULT;
    2348       26244 :                 return xfs_find_handle(cmd, &hreq);
    2349             :         }
    2350             :         case XFS_IOC_OPEN_BY_HANDLE: {
    2351    33293251 :                 xfs_fsop_handlereq_t    hreq;
    2352             : 
    2353    33293251 :                 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
    2354             :                         return -EFAULT;
    2355    33293263 :                 return xfs_open_by_handle(filp, &hreq);
    2356             :         }
    2357             : 
    2358             :         case XFS_IOC_READLINK_BY_HANDLE: {
    2359         184 :                 xfs_fsop_handlereq_t    hreq;
    2360             : 
    2361         184 :                 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
    2362             :                         return -EFAULT;
    2363         184 :                 return xfs_readlink_by_handle(filp, &hreq);
    2364             :         }
    2365   134918157 :         case XFS_IOC_ATTRLIST_BY_HANDLE:
    2366   134918157 :                 return xfs_attrlist_by_handle(filp, arg);
    2367             : 
    2368         132 :         case XFS_IOC_ATTRMULTI_BY_HANDLE:
    2369         132 :                 return xfs_attrmulti_by_handle(filp, arg);
    2370             : 
    2371             :         case XFS_IOC_SWAPEXT: {
    2372           0 :                 struct xfs_swapext      sxp;
    2373             : 
    2374           0 :                 if (copy_from_user(&sxp, arg, sizeof(struct xfs_swapext)))
    2375             :                         return -EFAULT;
    2376             : 
    2377           0 :                 return xfs_ioc_swapext(&sxp);
    2378             :         }
    2379             : 
    2380       11318 :         case XFS_IOC_FSCOUNTS: {
    2381       11318 :                 xfs_fsop_counts_t out;
    2382             : 
    2383       11318 :                 xfs_fs_counts(mp, &out);
    2384             : 
    2385       11318 :                 if (copy_to_user(arg, &out, sizeof(out)))
    2386           2 :                         return -EFAULT;
    2387             :                 return 0;
    2388             :         }
    2389             : 
    2390          20 :         case XFS_IOC_SET_RESBLKS: {
    2391          20 :                 xfs_fsop_resblks_t inout;
    2392          20 :                 uint64_t           in;
    2393             : 
    2394          20 :                 if (!capable(CAP_SYS_ADMIN))
    2395             :                         return -EPERM;
    2396             : 
    2397          40 :                 if (xfs_is_readonly(mp))
    2398             :                         return -EROFS;
    2399             : 
    2400          20 :                 if (copy_from_user(&inout, arg, sizeof(inout)))
    2401             :                         return -EFAULT;
    2402             : 
    2403          18 :                 error = mnt_want_write_file(filp);
    2404          18 :                 if (error)
    2405           0 :                         return error;
    2406             : 
    2407             :                 /* input parameter is passed in resblks field of structure */
    2408          18 :                 in = inout.resblks;
    2409          18 :                 error = xfs_reserve_blocks(mp, &in, &inout);
    2410          18 :                 mnt_drop_write_file(filp);
    2411          18 :                 if (error)
    2412           0 :                         return error;
    2413             : 
    2414          18 :                 if (copy_to_user(arg, &inout, sizeof(inout)))
    2415           0 :                         return -EFAULT;
    2416             :                 return 0;
    2417             :         }
    2418             : 
    2419           6 :         case XFS_IOC_GET_RESBLKS: {
    2420           6 :                 xfs_fsop_resblks_t out;
    2421             : 
    2422           6 :                 if (!capable(CAP_SYS_ADMIN))
    2423             :                         return -EPERM;
    2424             : 
    2425           6 :                 error = xfs_reserve_blocks(mp, NULL, &out);
    2426           6 :                 if (error)
    2427           0 :                         return error;
    2428             : 
    2429           6 :                 if (copy_to_user(arg, &out, sizeof(out)))
    2430           0 :                         return -EFAULT;
    2431             : 
    2432             :                 return 0;
    2433             :         }
    2434             : 
    2435             :         case XFS_IOC_FSGROWFSDATA: {
    2436         336 :                 struct xfs_growfs_data in;
    2437             : 
    2438         336 :                 if (copy_from_user(&in, arg, sizeof(in)))
    2439             :                         return -EFAULT;
    2440             : 
    2441         336 :                 error = mnt_want_write_file(filp);
    2442         336 :                 if (error)
    2443           0 :                         return error;
    2444         336 :                 error = xfs_growfs_data(mp, &in);
    2445         336 :                 mnt_drop_write_file(filp);
    2446         336 :                 return error;
    2447             :         }
    2448             : 
    2449             :         case XFS_IOC_FSGROWFSLOG: {
    2450           0 :                 struct xfs_growfs_log in;
    2451             : 
    2452           0 :                 if (copy_from_user(&in, arg, sizeof(in)))
    2453             :                         return -EFAULT;
    2454             : 
    2455           0 :                 error = mnt_want_write_file(filp);
    2456           0 :                 if (error)
    2457           0 :                         return error;
    2458           0 :                 error = xfs_growfs_log(mp, &in);
    2459           0 :                 mnt_drop_write_file(filp);
    2460           0 :                 return error;
    2461             :         }
    2462             : 
    2463             :         case XFS_IOC_FSGROWFSRT: {
    2464           3 :                 xfs_growfs_rt_t in;
    2465             : 
    2466           3 :                 if (copy_from_user(&in, arg, sizeof(in)))
    2467             :                         return -EFAULT;
    2468             : 
    2469           3 :                 error = mnt_want_write_file(filp);
    2470           3 :                 if (error)
    2471           0 :                         return error;
    2472           3 :                 error = xfs_growfs_rt(mp, &in);
    2473           3 :                 mnt_drop_write_file(filp);
    2474           3 :                 return error;
    2475             :         }
    2476             : 
    2477        4816 :         case XFS_IOC_GOINGDOWN: {
    2478        4816 :                 uint32_t in;
    2479             : 
    2480        4816 :                 if (!capable(CAP_SYS_ADMIN))
    2481             :                         return -EPERM;
    2482             : 
    2483        4816 :                 if (get_user(in, (uint32_t __user *)arg))
    2484             :                         return -EFAULT;
    2485             : 
    2486        4816 :                 return xfs_fs_goingdown(mp, in);
    2487             :         }
    2488             : 
    2489          14 :         case XFS_IOC_ERROR_INJECTION: {
    2490          14 :                 xfs_error_injection_t in;
    2491             : 
    2492          14 :                 if (!capable(CAP_SYS_ADMIN))
    2493             :                         return -EPERM;
    2494             : 
    2495          14 :                 if (copy_from_user(&in, arg, sizeof(in)))
    2496             :                         return -EFAULT;
    2497             : 
    2498          14 :                 return xfs_errortag_add(mp, in.errtag);
    2499             :         }
    2500             : 
    2501           0 :         case XFS_IOC_ERROR_CLEARALL:
    2502           0 :                 if (!capable(CAP_SYS_ADMIN))
    2503             :                         return -EPERM;
    2504             : 
    2505           0 :                 return xfs_errortag_clearall(mp);
    2506             : 
    2507           0 :         case XFS_IOC_FREE_EOFBLOCKS: {
    2508           0 :                 struct xfs_fs_eofblocks eofb;
    2509           0 :                 struct xfs_icwalk       icw;
    2510             : 
    2511           0 :                 if (!capable(CAP_SYS_ADMIN))
    2512             :                         return -EPERM;
    2513             : 
    2514           0 :                 if (xfs_is_readonly(mp))
    2515             :                         return -EROFS;
    2516             : 
    2517           0 :                 if (copy_from_user(&eofb, arg, sizeof(eofb)))
    2518             :                         return -EFAULT;
    2519             : 
    2520           0 :                 error = xfs_fs_eofblocks_from_user(&eofb, &icw);
    2521           0 :                 if (error)
    2522           0 :                         return error;
    2523             : 
    2524           0 :                 trace_xfs_ioc_free_eofblocks(mp, &icw, _RET_IP_);
    2525             : 
    2526           0 :                 sb_start_write(mp->m_super);
    2527           0 :                 error = xfs_blockgc_free_space(mp, &icw);
    2528           0 :                 sb_end_write(mp->m_super);
    2529           0 :                 return error;
    2530             :         }
    2531             : 
    2532     2313625 :         case XFS_IOC_EXCHANGE_RANGE:
    2533     2313625 :                 return xfs_ioc_exchange_range(filp, arg);
    2534             : 
    2535             :         default:
    2536             :                 return -ENOTTY;
    2537             :         }
    2538             : }

Generated by: LCOV version 1.14