LCOV - code coverage report
Current view: top level - fs/xfs - xfs_ioctl.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-acha @ Mon Jul 31 20:08:06 PDT 2023 Lines: 842 1049 80.3 %
Date: 2023-07-31 20:08:07 Functions: 42 45 93.3 %

          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 "scrub/xfs_scrub.h"
      35             : #include "xfs_sb.h"
      36             : #include "xfs_ag.h"
      37             : #include "xfs_health.h"
      38             : #include "xfs_reflink.h"
      39             : #include "xfs_ioctl.h"
      40             : #include "xfs_parent_utils.h"
      41             : #include "xfs_xattr.h"
      42             : #include "xfs_xchgrange.h"
      43             : #include "xfs_file.h"
      44             : 
      45             : #include <linux/mount.h>
      46             : #include <linux/namei.h>
      47             : #include <linux/fileattr.h>
      48             : 
      49             : /*
      50             :  * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to
      51             :  * a file or fs handle.
      52             :  *
      53             :  * XFS_IOC_PATH_TO_FSHANDLE
      54             :  *    returns fs handle for a mount point or path within that mount point
      55             :  * XFS_IOC_FD_TO_HANDLE
      56             :  *    returns full handle for a FD opened in user space
      57             :  * XFS_IOC_PATH_TO_HANDLE
      58             :  *    returns full handle for a path
      59             :  */
      60             : int
      61       38446 : xfs_find_handle(
      62             :         unsigned int            cmd,
      63             :         xfs_fsop_handlereq_t    *hreq)
      64             : {
      65       38446 :         int                     hsize;
      66       38446 :         xfs_handle_t            handle;
      67       38446 :         struct inode            *inode;
      68       38446 :         struct fd               f = {NULL};
      69       38446 :         struct path             path;
      70       38446 :         int                     error;
      71       38446 :         struct xfs_inode        *ip;
      72             : 
      73       38446 :         if (cmd == XFS_IOC_FD_TO_HANDLE) {
      74         436 :                 f = fdget(hreq->fd);
      75         436 :                 if (!f.file)
      76             :                         return -EBADF;
      77         436 :                 inode = file_inode(f.file);
      78             :         } else {
      79       38010 :                 error = user_path_at(AT_FDCWD, hreq->path, 0, &path);
      80       38010 :                 if (error)
      81             :                         return error;
      82       38010 :                 inode = d_inode(path.dentry);
      83             :         }
      84       38446 :         ip = XFS_I(inode);
      85             : 
      86             :         /*
      87             :          * We can only generate handles for inodes residing on a XFS filesystem,
      88             :          * and only for regular files, directories or symbolic links.
      89             :          */
      90       38446 :         error = -EINVAL;
      91       38446 :         if (inode->i_sb->s_magic != XFS_SB_MAGIC)
      92           0 :                 goto out_put;
      93             : 
      94       38446 :         error = -EBADF;
      95       38446 :         if (!S_ISREG(inode->i_mode) &&
      96           0 :             !S_ISDIR(inode->i_mode) &&
      97             :             !S_ISLNK(inode->i_mode))
      98           0 :                 goto out_put;
      99             : 
     100             : 
     101       38446 :         memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
     102             : 
     103       38446 :         if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
     104             :                 /*
     105             :                  * This handle only contains an fsid, zero the rest.
     106             :                  */
     107       34974 :                 memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
     108       34974 :                 hsize = sizeof(xfs_fsid_t);
     109             :         } else {
     110        3472 :                 handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
     111             :                                         sizeof(handle.ha_fid.fid_len);
     112        3472 :                 handle.ha_fid.fid_pad = 0;
     113        3472 :                 handle.ha_fid.fid_gen = inode->i_generation;
     114        3472 :                 handle.ha_fid.fid_ino = ip->i_ino;
     115        3472 :                 hsize = sizeof(xfs_handle_t);
     116             :         }
     117             : 
     118       38446 :         error = -EFAULT;
     119      115338 :         if (copy_to_user(hreq->ohandle, &handle, hsize) ||
     120       38446 :             copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
     121           0 :                 goto out_put;
     122             : 
     123             :         error = 0;
     124             : 
     125       38446 :  out_put:
     126       38446 :         if (cmd == XFS_IOC_FD_TO_HANDLE)
     127         436 :                 fdput(f);
     128             :         else
     129       38010 :                 path_put(&path);
     130             :         return error;
     131             : }
     132             : 
     133             : /*
     134             :  * No need to do permission checks on the various pathname components
     135             :  * as the handle operations are privileged.
     136             :  */
     137             : STATIC int
     138   191490661 : xfs_handle_acceptable(
     139             :         void                    *context,
     140             :         struct dentry           *dentry)
     141             : {
     142   191490661 :         return 1;
     143             : }
     144             : 
     145             : /*
     146             :  * Convert userspace handle data into a dentry.
     147             :  */
     148             : struct dentry *
     149   191518654 : xfs_handle_to_dentry(
     150             :         struct file             *parfilp,
     151             :         void __user             *uhandle,
     152             :         u32                     hlen)
     153             : {
     154   191518654 :         xfs_handle_t            handle;
     155   191518654 :         struct xfs_fid64        fid;
     156             : 
     157             :         /*
     158             :          * Only allow handle opens under a directory.
     159             :          */
     160   191518654 :         if (!S_ISDIR(file_inode(parfilp)->i_mode))
     161             :                 return ERR_PTR(-ENOTDIR);
     162             : 
     163   191522069 :         if (hlen != sizeof(xfs_handle_t))
     164             :                 return ERR_PTR(-EINVAL);
     165   191522376 :         if (copy_from_user(&handle, uhandle, hlen))
     166             :                 return ERR_PTR(-EFAULT);
     167   191525157 :         if (handle.ha_fid.fid_len !=
     168             :             sizeof(handle.ha_fid) - sizeof(handle.ha_fid.fid_len))
     169             :                 return ERR_PTR(-EINVAL);
     170             : 
     171   191523403 :         memset(&fid, 0, sizeof(struct fid));
     172   191523403 :         fid.ino = handle.ha_fid.fid_ino;
     173   191523403 :         fid.gen = handle.ha_fid.fid_gen;
     174             : 
     175   191523403 :         return exportfs_decode_fh(parfilp->f_path.mnt, (struct fid *)&fid, 3,
     176             :                         FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG,
     177             :                         xfs_handle_acceptable, NULL);
     178             : }
     179             : 
     180             : STATIC struct dentry *
     181   191514935 : xfs_handlereq_to_dentry(
     182             :         struct file             *parfilp,
     183             :         xfs_fsop_handlereq_t    *hreq)
     184             : {
     185   191514935 :         return xfs_handle_to_dentry(parfilp, hreq->ihandle, hreq->ihandlen);
     186             : }
     187             : 
     188             : int
     189    38493548 : xfs_open_by_handle(
     190             :         struct file             *parfilp,
     191             :         xfs_fsop_handlereq_t    *hreq)
     192             : {
     193    38493548 :         const struct cred       *cred = current_cred();
     194    38493548 :         int                     error;
     195    38493548 :         int                     fd;
     196    38493548 :         int                     permflag;
     197    38493548 :         struct file             *filp;
     198    38493548 :         struct inode            *inode;
     199    38493548 :         struct dentry           *dentry;
     200    38493548 :         fmode_t                 fmode;
     201    38493548 :         struct path             path;
     202             : 
     203    38493548 :         if (!capable(CAP_SYS_ADMIN))
     204             :                 return -EPERM;
     205             : 
     206    38493156 :         dentry = xfs_handlereq_to_dentry(parfilp, hreq);
     207    38493074 :         if (IS_ERR(dentry))
     208        2096 :                 return PTR_ERR(dentry);
     209    38490978 :         inode = d_inode(dentry);
     210             : 
     211             :         /* Restrict xfs_open_by_handle to directories & regular files. */
     212    38490978 :         if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
     213           0 :                 error = -EPERM;
     214           0 :                 goto out_dput;
     215             :         }
     216             : 
     217             : #if BITS_PER_LONG != 32
     218    38490978 :         hreq->oflags |= O_LARGEFILE;
     219             : #endif
     220             : 
     221    38490978 :         permflag = hreq->oflags;
     222    38490978 :         fmode = OPEN_FMODE(permflag);
     223    38490978 :         if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
     224    38490968 :             (fmode & FMODE_WRITE) && IS_APPEND(inode)) {
     225          12 :                 error = -EPERM;
     226          12 :                 goto out_dput;
     227             :         }
     228             : 
     229    38490966 :         if ((fmode & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
     230          16 :                 error = -EPERM;
     231          16 :                 goto out_dput;
     232             :         }
     233             : 
     234             :         /* Can't write directories. */
     235    38490950 :         if (S_ISDIR(inode->i_mode) && (fmode & FMODE_WRITE)) {
     236           0 :                 error = -EISDIR;
     237           0 :                 goto out_dput;
     238             :         }
     239             : 
     240    38490950 :         fd = get_unused_fd_flags(0);
     241    38491955 :         if (fd < 0) {
     242           0 :                 error = fd;
     243           0 :                 goto out_dput;
     244             :         }
     245             : 
     246    38491955 :         path.mnt = parfilp->f_path.mnt;
     247    38491955 :         path.dentry = dentry;
     248    38491955 :         filp = dentry_open(&path, hreq->oflags, cred);
     249    38489940 :         dput(dentry);
     250    38490566 :         if (IS_ERR(filp)) {
     251           0 :                 put_unused_fd(fd);
     252           0 :                 return PTR_ERR(filp);
     253             :         }
     254             : 
     255    38490566 :         if (S_ISREG(inode->i_mode)) {
     256    25458509 :                 filp->f_flags |= O_NOATIME;
     257    25458509 :                 filp->f_mode |= FMODE_NOCMTIME;
     258             :         }
     259             : 
     260    38490566 :         fd_install(fd, filp);
     261    38490566 :         return fd;
     262             : 
     263          28 :  out_dput:
     264          28 :         dput(dentry);
     265          28 :         return error;
     266             : }
     267             : 
     268             : int
     269         184 : xfs_readlink_by_handle(
     270             :         struct file             *parfilp,
     271             :         xfs_fsop_handlereq_t    *hreq)
     272             : {
     273         184 :         struct dentry           *dentry;
     274         184 :         __u32                   olen;
     275         184 :         int                     error;
     276             : 
     277         184 :         if (!capable(CAP_SYS_ADMIN))
     278             :                 return -EPERM;
     279             : 
     280         184 :         dentry = xfs_handlereq_to_dentry(parfilp, hreq);
     281         184 :         if (IS_ERR(dentry))
     282           0 :                 return PTR_ERR(dentry);
     283             : 
     284             :         /* Restrict this handle operation to symlinks only. */
     285         184 :         if (!d_is_symlink(dentry)) {
     286           2 :                 error = -EINVAL;
     287           2 :                 goto out_dput;
     288             :         }
     289             : 
     290         182 :         if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) {
     291           0 :                 error = -EFAULT;
     292           0 :                 goto out_dput;
     293             :         }
     294             : 
     295         182 :         error = vfs_readlink(dentry, hreq->ohandle, olen);
     296             : 
     297         184 :  out_dput:
     298         184 :         dput(dentry);
     299         184 :         return error;
     300             : }
     301             : 
     302             : /*
     303             :  * Format an attribute and copy it out to the user's buffer.
     304             :  * Take care to check values and protect against them changing later,
     305             :  * we may be reading them directly out of a user buffer.
     306             :  */
     307             : static void
     308   240011532 : xfs_ioc_attr_put_listent(
     309             :         struct xfs_attr_list_context *context,
     310             :         int                     flags,
     311             :         unsigned char           *name,
     312             :         int                     namelen,
     313             :         void                    *value,
     314             :         int                     valuelen)
     315             : {
     316   240011532 :         struct xfs_attrlist     *alist = context->buffer;
     317   240011532 :         struct xfs_attrlist_ent *aep;
     318   240011532 :         int                     arraytop;
     319             : 
     320   240011532 :         ASSERT(!context->seen_enough);
     321   240011532 :         ASSERT(context->count >= 0);
     322   240011532 :         ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
     323   240011532 :         ASSERT(context->firstu >= sizeof(*alist));
     324   240011532 :         ASSERT(context->firstu <= context->bufsize);
     325             : 
     326             :         /*
     327             :          * Only list entries in the right namespace.
     328             :          */
     329   240011532 :         if (context->attr_filter != (flags & XFS_ATTR_NSP_ONDISK_MASK))
     330             :                 return;
     331             : 
     332    21830901 :         arraytop = sizeof(*alist) +
     333    21830901 :                         context->count * sizeof(alist->al_offset[0]);
     334             : 
     335             :         /* decrement by the actual bytes used by the attr */
     336    21830901 :         context->firstu -= round_up(offsetof(struct xfs_attrlist_ent, a_name) +
     337             :                         namelen + 1, sizeof(uint32_t));
     338    21830901 :         if (context->firstu < arraytop) {
     339         365 :                 trace_xfs_attr_list_full(context);
     340         365 :                 alist->al_more = 1;
     341         365 :                 context->seen_enough = 1;
     342         365 :                 return;
     343             :         }
     344             : 
     345    21830536 :         aep = context->buffer + context->firstu;
     346    21830536 :         aep->a_valuelen = valuelen;
     347    43661072 :         memcpy(aep->a_name, name, namelen);
     348    21830536 :         aep->a_name[namelen] = 0;
     349    21830536 :         alist->al_offset[context->count++] = context->firstu;
     350    21830536 :         alist->al_count = context->count;
     351    21830536 :         trace_xfs_attr_list_add(context);
     352             : }
     353             : 
     354             : static unsigned int
     355             : xfs_attr_filter(
     356             :         u32                     ioc_flags)
     357             : {
     358   153022354 :         if (ioc_flags & XFS_IOC_ATTR_ROOT)
     359             :                 return XFS_ATTR_ROOT;
     360   102011656 :         if (ioc_flags & XFS_IOC_ATTR_SECURE)
     361    51010555 :                 return XFS_ATTR_SECURE;
     362             :         return 0;
     363             : }
     364             : 
     365             : static unsigned int
     366             : xfs_attr_flags(
     367             :         u32                     ioc_flags)
     368             : {
     369         140 :         if (ioc_flags & XFS_IOC_ATTR_CREATE)
     370             :                 return XATTR_CREATE;
     371         140 :         if (ioc_flags & XFS_IOC_ATTR_REPLACE)
     372           0 :                 return XATTR_REPLACE;
     373             :         return 0;
     374             : }
     375             : 
     376             : int
     377   153011981 : xfs_ioc_attr_list(
     378             :         struct xfs_inode                *dp,
     379             :         void __user                     *ubuf,
     380             :         size_t                          bufsize,
     381             :         int                             flags,
     382             :         struct xfs_attrlist_cursor __user *ucursor)
     383             : {
     384   153011981 :         struct xfs_attr_list_context    context = { };
     385   153011981 :         struct xfs_attrlist             *alist;
     386   153011981 :         void                            *buffer;
     387   153011981 :         int                             error;
     388             : 
     389   153011981 :         if (bufsize < sizeof(struct xfs_attrlist) ||
     390             :             bufsize > XFS_XATTR_LIST_MAX)
     391             :                 return -EINVAL;
     392             : 
     393             :         /*
     394             :          * Reject flags, only allow namespaces.
     395             :          */
     396   153011981 :         if (flags & ~(XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
     397             :                 return -EINVAL;
     398   153011981 :         if (flags == (XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
     399             :                 return -EINVAL;
     400             : 
     401             :         /*
     402             :          * Validate the cursor.
     403             :          */
     404   153011981 :         if (copy_from_user(&context.cursor, ucursor, sizeof(context.cursor)))
     405             :                 return -EFAULT;
     406   153011903 :         if (context.cursor.pad1 || context.cursor.pad2)
     407             :                 return -EINVAL;
     408   153011903 :         if (!context.cursor.initted &&
     409   153011538 :             (context.cursor.hashval || context.cursor.blkno ||
     410   153011538 :              context.cursor.offset))
     411             :                 return -EINVAL;
     412             : 
     413   153011903 :         buffer = kvzalloc(bufsize, GFP_KERNEL);
     414   153022214 :         if (!buffer)
     415             :                 return -ENOMEM;
     416             : 
     417             :         /*
     418             :          * Initialize the output buffer.
     419             :          */
     420   153022214 :         context.dp = dp;
     421   153022214 :         context.resynch = 1;
     422   153022214 :         context.attr_filter = xfs_attr_filter(flags);
     423   153022214 :         context.buffer = buffer;
     424   153022214 :         context.bufsize = round_down(bufsize, sizeof(uint32_t));
     425   153022214 :         context.firstu = context.bufsize;
     426   153022214 :         context.put_listent = xfs_ioc_attr_put_listent;
     427             : 
     428   153022214 :         alist = context.buffer;
     429   153022214 :         alist->al_count = 0;
     430   153022214 :         alist->al_more = 0;
     431   153022214 :         alist->al_offset[0] = context.bufsize;
     432             : 
     433   153022214 :         error = xfs_attr_list(&context);
     434   153018267 :         if (error)
     435           0 :                 goto out_free;
     436             : 
     437   459031390 :         if (copy_to_user(ubuf, buffer, bufsize) ||
     438             :             copy_to_user(ucursor, &context.cursor, sizeof(context.cursor)))
     439             :                 error = -EFAULT;
     440   153007345 : out_free:
     441   153007345 :         kmem_free(buffer);
     442   153007345 :         return error;
     443             : }
     444             : 
     445             : STATIC int
     446   153030539 : xfs_attrlist_by_handle(
     447             :         struct file             *parfilp,
     448             :         struct xfs_fsop_attrlist_handlereq __user *p)
     449             : {
     450   153030539 :         struct xfs_fsop_attrlist_handlereq al_hreq;
     451   153030539 :         struct dentry           *dentry;
     452   153030539 :         int                     error = -ENOMEM;
     453             : 
     454   153030539 :         if (!capable(CAP_SYS_ADMIN))
     455             :                 return -EPERM;
     456   153033750 :         if (copy_from_user(&al_hreq, p, sizeof(al_hreq)))
     457             :                 return -EFAULT;
     458             : 
     459   153029050 :         dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
     460   153004653 :         if (IS_ERR(dentry))
     461         202 :                 return PTR_ERR(dentry);
     462             : 
     463   153004451 :         error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), al_hreq.buffer,
     464   153004451 :                                   al_hreq.buflen, al_hreq.flags, &p->pos);
     465   153017685 :         dput(dentry);
     466   153017685 :         return error;
     467             : }
     468             : 
     469             : static int
     470         140 : xfs_attrmulti_attr_get(
     471             :         struct inode            *inode,
     472             :         unsigned char           *name,
     473             :         unsigned char           __user *ubuf,
     474             :         uint32_t                *len,
     475             :         uint32_t                flags)
     476             : {
     477         420 :         struct xfs_da_args      args = {
     478             :                 .dp             = XFS_I(inode),
     479             :                 .attr_filter    = xfs_attr_filter(flags),
     480             :                 .attr_flags     = xfs_attr_flags(flags),
     481             :                 .name           = name,
     482             :                 .namelen        = strlen(name),
     483         140 :                 .valuelen       = *len,
     484         140 :                 .owner          = XFS_I(inode)->i_ino,
     485             :         };
     486         140 :         int                     error;
     487             : 
     488         140 :         if (*len > XFS_XATTR_SIZE_MAX)
     489             :                 return -EINVAL;
     490             : 
     491         140 :         error = xfs_attr_get(&args);
     492         140 :         if (error)
     493           0 :                 goto out_kfree;
     494             : 
     495         140 :         *len = args.valuelen;
     496         280 :         if (copy_to_user(ubuf, args.value, args.valuelen))
     497           0 :                 error = -EFAULT;
     498             : 
     499         140 : out_kfree:
     500         140 :         kmem_free(args.value);
     501         140 :         return error;
     502             : }
     503             : 
     504             : static int
     505           0 : xfs_attrmulti_attr_set(
     506             :         struct inode            *inode,
     507             :         unsigned char           *name,
     508             :         const unsigned char     __user *ubuf,
     509             :         uint32_t                len,
     510             :         uint32_t                flags)
     511             : {
     512           0 :         struct xfs_da_args      args = {
     513             :                 .dp             = XFS_I(inode),
     514             :                 .attr_filter    = xfs_attr_filter(flags),
     515             :                 .attr_flags     = xfs_attr_flags(flags),
     516             :                 .name           = name,
     517             :                 .namelen        = strlen(name),
     518           0 :                 .owner          = XFS_I(inode)->i_ino,
     519             :         };
     520           0 :         int                     error;
     521             : 
     522           0 :         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
     523             :                 return -EPERM;
     524             : 
     525           0 :         if (ubuf) {
     526           0 :                 if (len > XFS_XATTR_SIZE_MAX)
     527             :                         return -EINVAL;
     528           0 :                 args.value = memdup_user(ubuf, len);
     529           0 :                 if (IS_ERR(args.value))
     530           0 :                         return PTR_ERR(args.value);
     531           0 :                 args.valuelen = len;
     532             :         }
     533             : 
     534           0 :         error = xfs_attr_change(&args);
     535           0 :         if (!error && (flags & XFS_IOC_ATTR_ROOT))
     536           0 :                 xfs_forget_acl(inode, name);
     537           0 :         kfree(args.value);
     538           0 :         return error;
     539             : }
     540             : 
     541             : int
     542         140 : xfs_ioc_attrmulti_one(
     543             :         struct file             *parfilp,
     544             :         struct inode            *inode,
     545             :         uint32_t                opcode,
     546             :         void __user             *uname,
     547             :         void __user             *value,
     548             :         uint32_t                *len,
     549             :         uint32_t                flags)
     550             : {
     551         140 :         unsigned char           *name;
     552         140 :         int                     error;
     553             : 
     554         140 :         if ((flags & XFS_IOC_ATTR_ROOT) && (flags & XFS_IOC_ATTR_SECURE))
     555             :                 return -EINVAL;
     556             : 
     557         140 :         name = strndup_user(uname, MAXNAMELEN);
     558         140 :         if (IS_ERR(name))
     559           0 :                 return PTR_ERR(name);
     560             : 
     561         140 :         switch (opcode) {
     562         140 :         case ATTR_OP_GET:
     563         140 :                 error = xfs_attrmulti_attr_get(inode, name, value, len, flags);
     564         140 :                 break;
     565           0 :         case ATTR_OP_REMOVE:
     566           0 :                 value = NULL;
     567           0 :                 *len = 0;
     568           0 :                 fallthrough;
     569           0 :         case ATTR_OP_SET:
     570           0 :                 error = mnt_want_write_file(parfilp);
     571           0 :                 if (error)
     572             :                         break;
     573           0 :                 error = xfs_attrmulti_attr_set(inode, name, value, *len, flags);
     574           0 :                 mnt_drop_write_file(parfilp);
     575           0 :                 break;
     576             :         default:
     577             :                 error = -EINVAL;
     578             :                 break;
     579             :         }
     580             : 
     581         140 :         kfree(name);
     582         140 :         return error;
     583             : }
     584             : 
     585             : STATIC int
     586         132 : xfs_attrmulti_by_handle(
     587             :         struct file             *parfilp,
     588             :         void                    __user *arg)
     589             : {
     590         132 :         int                     error;
     591         132 :         xfs_attr_multiop_t      *ops;
     592         132 :         xfs_fsop_attrmulti_handlereq_t am_hreq;
     593         132 :         struct dentry           *dentry;
     594         132 :         unsigned int            i, size;
     595             : 
     596         132 :         if (!capable(CAP_SYS_ADMIN))
     597             :                 return -EPERM;
     598         132 :         if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t)))
     599             :                 return -EFAULT;
     600             : 
     601             :         /* overflow check */
     602         132 :         if (am_hreq.opcount >= INT_MAX / sizeof(xfs_attr_multiop_t))
     603             :                 return -E2BIG;
     604             : 
     605         132 :         dentry = xfs_handlereq_to_dentry(parfilp, &am_hreq.hreq);
     606         132 :         if (IS_ERR(dentry))
     607           0 :                 return PTR_ERR(dentry);
     608             : 
     609         132 :         error = -E2BIG;
     610         132 :         size = am_hreq.opcount * sizeof(xfs_attr_multiop_t);
     611         132 :         if (!size || size > 16 * PAGE_SIZE)
     612           0 :                 goto out_dput;
     613             : 
     614         132 :         ops = memdup_user(am_hreq.ops, size);
     615         132 :         if (IS_ERR(ops)) {
     616           0 :                 error = PTR_ERR(ops);
     617           0 :                 goto out_dput;
     618             :         }
     619             : 
     620             :         error = 0;
     621         272 :         for (i = 0; i < am_hreq.opcount; i++) {
     622         140 :                 ops[i].am_error = xfs_ioc_attrmulti_one(parfilp,
     623         140 :                                 d_inode(dentry), ops[i].am_opcode,
     624             :                                 ops[i].am_attrname, ops[i].am_attrvalue,
     625         140 :                                 &ops[i].am_length, ops[i].am_flags);
     626             :         }
     627             : 
     628         264 :         if (copy_to_user(am_hreq.ops, ops, size))
     629           0 :                 error = -EFAULT;
     630             : 
     631         132 :         kfree(ops);
     632         132 :  out_dput:
     633         132 :         dput(dentry);
     634         132 :         return error;
     635             : }
     636             : 
     637             : /* Return 0 on success or positive error */
     638             : int
     639 59885325853 : xfs_fsbulkstat_one_fmt(
     640             :         struct xfs_ibulk                *breq,
     641             :         const struct xfs_bulkstat       *bstat)
     642             : {
     643 59885325853 :         struct xfs_bstat                bs1;
     644             : 
     645 59885325853 :         xfs_bulkstat_to_bstat(breq->mp, &bs1, bstat);
     646 60026125959 :         if (copy_to_user(breq->ubuffer, &bs1, sizeof(bs1)))
     647             :                 return -EFAULT;
     648 59923251206 :         return xfs_ibulk_advance(breq, sizeof(struct xfs_bstat));
     649             : }
     650             : 
     651             : int
     652       11506 : xfs_fsinumbers_fmt(
     653             :         struct xfs_ibulk                *breq,
     654             :         const struct xfs_inumbers       *igrp)
     655             : {
     656       11506 :         struct xfs_inogrp               ig1;
     657             : 
     658       11506 :         xfs_inumbers_to_inogrp(&ig1, igrp);
     659       11506 :         if (copy_to_user(breq->ubuffer, &ig1, sizeof(struct xfs_inogrp)))
     660             :                 return -EFAULT;
     661       11506 :         return xfs_ibulk_advance(breq, sizeof(struct xfs_inogrp));
     662             : }
     663             : 
     664             : STATIC int
     665   394183315 : xfs_ioc_fsbulkstat(
     666             :         struct file             *file,
     667             :         unsigned int            cmd,
     668             :         void                    __user *arg)
     669             : {
     670   394183315 :         struct xfs_mount        *mp = XFS_I(file_inode(file))->i_mount;
     671   394183315 :         struct xfs_fsop_bulkreq bulkreq;
     672   394183315 :         struct xfs_ibulk        breq = {
     673             :                 .mp             = mp,
     674             :                 .idmap          = file_mnt_idmap(file),
     675             :                 .ocount         = 0,
     676             :         };
     677   394196333 :         xfs_ino_t               lastino;
     678   394196333 :         int                     error;
     679             : 
     680             :         /* done = 1 if there are more stats to get and if bulkstat */
     681             :         /* should be called again (unused here, but used in dmapi) */
     682             : 
     683   394196333 :         if (!capable(CAP_SYS_ADMIN))
     684             :                 return -EPERM;
     685             : 
     686   788353578 :         if (xfs_is_shutdown(mp))
     687             :                 return -EIO;
     688             : 
     689   394164692 :         if (copy_from_user(&bulkreq, arg, sizeof(struct xfs_fsop_bulkreq)))
     690             :                 return -EFAULT;
     691             : 
     692   394170613 :         if (copy_from_user(&lastino, bulkreq.lastip, sizeof(__s64)))
     693             :                 return -EFAULT;
     694             : 
     695   394177596 :         if (bulkreq.icount <= 0)
     696             :                 return -EINVAL;
     697             : 
     698   394177596 :         if (bulkreq.ubuffer == NULL)
     699             :                 return -EINVAL;
     700             : 
     701   394177596 :         breq.ubuffer = bulkreq.ubuffer;
     702   394177596 :         breq.icount = bulkreq.icount;
     703             : 
     704             :         /*
     705             :          * FSBULKSTAT_SINGLE expects that *lastip contains the inode number
     706             :          * that we want to stat.  However, FSINUMBERS and FSBULKSTAT expect
     707             :          * that *lastip contains either zero or the number of the last inode to
     708             :          * be examined by the previous call and return results starting with
     709             :          * the next inode after that.  The new bulk request back end functions
     710             :          * take the inode to start with, so we have to compute the startino
     711             :          * parameter from lastino to maintain correct function.  lastino == 0
     712             :          * is a special case because it has traditionally meant "first inode
     713             :          * in filesystem".
     714             :          */
     715   394177596 :         if (cmd == XFS_IOC_FSINUMBERS) {
     716        3110 :                 breq.startino = lastino ? lastino + 1 : 0;
     717        3110 :                 error = xfs_inumbers(&breq, xfs_fsinumbers_fmt);
     718        3110 :                 lastino = breq.startino - 1;
     719   394174486 :         } else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE) {
     720     1148799 :                 breq.startino = lastino;
     721     1148799 :                 breq.icount = 1;
     722     1148799 :                 error = xfs_bulkstat_one(&breq, xfs_fsbulkstat_one_fmt);
     723             :         } else {        /* XFS_IOC_FSBULKSTAT */
     724   393025687 :                 breq.startino = lastino ? lastino + 1 : 0;
     725   393025687 :                 error = xfs_bulkstat(&breq, xfs_fsbulkstat_one_fmt);
     726   393015372 :                 lastino = breq.startino - 1;
     727             :         }
     728             : 
     729   394167280 :         if (error)
     730             :                 return error;
     731             : 
     732   787154908 :         if (bulkreq.lastip != NULL &&
     733             :             copy_to_user(bulkreq.lastip, &lastino, sizeof(xfs_ino_t)))
     734             :                 return -EFAULT;
     735             : 
     736   786601599 :         if (bulkreq.ocount != NULL &&
     737             :             copy_to_user(bulkreq.ocount, &breq.ocount, sizeof(__s32)))
     738           0 :                 return -EFAULT;
     739             : 
     740             :         return 0;
     741             : }
     742             : 
     743             : /* Return 0 on success or positive error */
     744             : static int
     745   178357488 : xfs_bulkstat_fmt(
     746             :         struct xfs_ibulk                *breq,
     747             :         const struct xfs_bulkstat       *bstat)
     748             : {
     749   356698448 :         if (copy_to_user(breq->ubuffer, bstat, sizeof(struct xfs_bulkstat)))
     750           0 :                 return -EFAULT;
     751   178340960 :         return xfs_ibulk_advance(breq, sizeof(struct xfs_bulkstat));
     752             : }
     753             : 
     754             : /*
     755             :  * Check the incoming bulk request @hdr from userspace and initialize the
     756             :  * internal @breq bulk request appropriately.  Returns 0 if the bulk request
     757             :  * should proceed; -ECANCELED if there's nothing to do; or the usual
     758             :  * negative error code.
     759             :  */
     760             : static int
     761     9898352 : xfs_bulk_ireq_setup(
     762             :         struct xfs_mount        *mp,
     763             :         const struct xfs_bulk_ireq *hdr,
     764             :         struct xfs_ibulk        *breq,
     765             :         void __user             *ubuffer)
     766             : {
     767     9898352 :         if (hdr->icount == 0 ||
     768    19797672 :             (hdr->flags & ~XFS_BULK_IREQ_FLAGS_ALL) ||
     769     9898352 :             memchr_inv(hdr->reserved, 0, sizeof(hdr->reserved)))
     770           0 :                 return -EINVAL;
     771             : 
     772     9899320 :         breq->startino = hdr->ino;
     773     9899320 :         breq->ubuffer = ubuffer;
     774     9899320 :         breq->icount = hdr->icount;
     775     9899320 :         breq->ocount = 0;
     776     9899320 :         breq->flags = 0;
     777             : 
     778             :         /*
     779             :          * The @ino parameter is a special value, so we must look it up here.
     780             :          * We're not allowed to have IREQ_AGNO, and we only return one inode
     781             :          * worth of data.
     782             :          */
     783     9899320 :         if (hdr->flags & XFS_BULK_IREQ_SPECIAL) {
     784           4 :                 if (hdr->flags & XFS_BULK_IREQ_AGNO)
     785             :                         return -EINVAL;
     786             : 
     787           4 :                 switch (hdr->ino) {
     788           4 :                 case XFS_BULK_IREQ_SPECIAL_ROOT:
     789           4 :                         breq->startino = mp->m_sb.sb_rootino;
     790           4 :                         break;
     791             :                 default:
     792             :                         return -EINVAL;
     793             :                 }
     794           4 :                 breq->icount = 1;
     795             :         }
     796             : 
     797             :         /*
     798             :          * The IREQ_AGNO flag means that we only want results from a given AG.
     799             :          * If @hdr->ino is zero, we start iterating in that AG.  If @hdr->ino is
     800             :          * beyond the specified AG then we return no results.
     801             :          */
     802     9899320 :         if (hdr->flags & XFS_BULK_IREQ_AGNO) {
     803     3132371 :                 if (hdr->agno >= mp->m_sb.sb_agcount)
     804             :                         return -EINVAL;
     805             : 
     806     3132371 :                 if (breq->startino == 0)
     807      151390 :                         breq->startino = XFS_AGINO_TO_INO(mp, hdr->agno, 0);
     808     2980981 :                 else if (XFS_INO_TO_AGNO(mp, breq->startino) < hdr->agno)
     809             :                         return -EINVAL;
     810             : 
     811     3132371 :                 breq->flags |= XFS_IBULK_SAME_AG;
     812             : 
     813             :                 /* Asking for an inode past the end of the AG?  We're done! */
     814     3132371 :                 if (XFS_INO_TO_AGNO(mp, breq->startino) > hdr->agno)
     815             :                         return -ECANCELED;
     816     6766949 :         } else if (hdr->agno)
     817             :                 return -EINVAL;
     818             : 
     819             :         /* Asking for an inode past the end of the FS?  We're done! */
     820     9899320 :         if (XFS_INO_TO_AGNO(mp, breq->startino) >= mp->m_sb.sb_agcount)
     821             :                 return -ECANCELED;
     822             : 
     823     9899310 :         if (hdr->flags & XFS_BULK_IREQ_NREXT64)
     824     6782731 :                 breq->flags |= XFS_IBULK_NREXT64;
     825             : 
     826             :         return 0;
     827             : }
     828             : 
     829             : /*
     830             :  * Update the userspace bulk request @hdr to reflect the end state of the
     831             :  * internal bulk request @breq.
     832             :  */
     833             : static void
     834             : xfs_bulk_ireq_teardown(
     835             :         struct xfs_bulk_ireq    *hdr,
     836             :         struct xfs_ibulk        *breq)
     837             : {
     838     9899459 :         hdr->ino = breq->startino;
     839     9899459 :         hdr->ocount = breq->ocount;
     840             : }
     841             : 
     842             : /* Handle the v5 bulkstat ioctl. */
     843             : STATIC int
     844     6782805 : xfs_ioc_bulkstat(
     845             :         struct file                     *file,
     846             :         unsigned int                    cmd,
     847             :         struct xfs_bulkstat_req __user  *arg)
     848             : {
     849     6782805 :         struct xfs_mount                *mp = XFS_I(file_inode(file))->i_mount;
     850     6782805 :         struct xfs_bulk_ireq            hdr;
     851     6782805 :         struct xfs_ibulk                breq = {
     852             :                 .mp                     = mp,
     853             :                 .idmap                  = file_mnt_idmap(file),
     854             :         };
     855     6782811 :         int                             error;
     856             : 
     857     6782811 :         if (!capable(CAP_SYS_ADMIN))
     858             :                 return -EPERM;
     859             : 
     860    13565546 :         if (xfs_is_shutdown(mp))
     861             :                 return -EIO;
     862             : 
     863     6782773 :         if (copy_from_user(&hdr, &arg->hdr, sizeof(hdr)))
     864             :                 return -EFAULT;
     865             : 
     866     6782754 :         error = xfs_bulk_ireq_setup(mp, &hdr, &breq, arg->bulkstat);
     867     6782755 :         if (error == -ECANCELED)
     868          10 :                 goto out_teardown;
     869     6782745 :         if (error < 0)
     870             :                 return error;
     871             : 
     872     6782745 :         error = xfs_bulkstat(&breq, xfs_bulkstat_fmt);
     873     6782776 :         if (error)
     874             :                 return error;
     875             : 
     876     6782774 : out_teardown:
     877     6782784 :         xfs_bulk_ireq_teardown(&hdr, &breq);
     878     6782784 :         if (copy_to_user(&arg->hdr, &hdr, sizeof(hdr)))
     879           0 :                 return -EFAULT;
     880             : 
     881             :         return 0;
     882             : }
     883             : 
     884             : STATIC int
     885     4687606 : xfs_inumbers_fmt(
     886             :         struct xfs_ibulk                *breq,
     887             :         const struct xfs_inumbers       *igrp)
     888             : {
     889     9378413 :         if (copy_to_user(breq->ubuffer, igrp, sizeof(struct xfs_inumbers)))
     890           0 :                 return -EFAULT;
     891     4690807 :         return xfs_ibulk_advance(breq, sizeof(struct xfs_inumbers));
     892             : }
     893             : 
     894             : /* Handle the v5 inumbers ioctl. */
     895             : STATIC int
     896     3116941 : xfs_ioc_inumbers(
     897             :         struct xfs_mount                *mp,
     898             :         unsigned int                    cmd,
     899             :         struct xfs_inumbers_req __user  *arg)
     900             : {
     901     3116941 :         struct xfs_bulk_ireq            hdr;
     902     3116941 :         struct xfs_ibulk                breq = {
     903             :                 .mp                     = mp,
     904             :         };
     905     3116941 :         int                             error;
     906             : 
     907     3116941 :         if (!capable(CAP_SYS_ADMIN))
     908             :                 return -EPERM;
     909             : 
     910     6233484 :         if (xfs_is_shutdown(mp))
     911             :                 return -EIO;
     912             : 
     913     3116742 :         if (copy_from_user(&hdr, &arg->hdr, sizeof(hdr)))
     914             :                 return -EFAULT;
     915             : 
     916     3116626 :         error = xfs_bulk_ireq_setup(mp, &hdr, &breq, arg->inumbers);
     917     3116004 :         if (error == -ECANCELED)
     918           0 :                 goto out_teardown;
     919     3116004 :         if (error < 0)
     920             :                 return error;
     921             : 
     922     3116004 :         error = xfs_inumbers(&breq, xfs_inumbers_fmt);
     923     3116675 :         if (error)
     924             :                 return error;
     925             : 
     926     3116675 : out_teardown:
     927     3116675 :         xfs_bulk_ireq_teardown(&hdr, &breq);
     928     3116675 :         if (copy_to_user(&arg->hdr, &hdr, sizeof(hdr)))
     929           0 :                 return -EFAULT;
     930             : 
     931             :         return 0;
     932             : }
     933             : 
     934             : STATIC int
     935     1992283 : xfs_ioc_fsgeometry(
     936             :         struct xfs_mount        *mp,
     937             :         void                    __user *arg,
     938             :         int                     struct_version)
     939             : {
     940     1992283 :         struct xfs_fsop_geom    fsgeo;
     941     1992283 :         size_t                  len;
     942             : 
     943     1992283 :         xfs_fs_geometry(mp, &fsgeo, struct_version);
     944             : 
     945     2004944 :         if (struct_version <= 3)
     946             :                 len = sizeof(struct xfs_fsop_geom_v1);
     947     2004806 :         else if (struct_version == 4)
     948             :                 len = sizeof(struct xfs_fsop_geom_v4);
     949             :         else {
     950     1994431 :                 xfs_fsop_geom_health(mp, &fsgeo);
     951     1994431 :                 len = sizeof(fsgeo);
     952             :         }
     953             : 
     954     4041528 :         if (copy_to_user(arg, &fsgeo, len))
     955           0 :                 return -EFAULT;
     956             :         return 0;
     957             : }
     958             : 
     959             : STATIC int
     960       15411 : xfs_ioc_ag_geometry(
     961             :         struct xfs_mount        *mp,
     962             :         void                    __user *arg)
     963             : {
     964       15411 :         struct xfs_perag        *pag;
     965       15411 :         struct xfs_ag_geometry  ageo;
     966       15411 :         int                     error;
     967             : 
     968       15411 :         if (copy_from_user(&ageo, arg, sizeof(ageo)))
     969             :                 return -EFAULT;
     970       15411 :         if (ageo.ag_flags)
     971             :                 return -EINVAL;
     972       15411 :         if (memchr_inv(&ageo.ag_reserved, 0, sizeof(ageo.ag_reserved)))
     973             :                 return -EINVAL;
     974             : 
     975       15411 :         pag = xfs_perag_get(mp, ageo.ag_number);
     976       15411 :         if (!pag)
     977             :                 return -EINVAL;
     978             : 
     979       15411 :         error = xfs_ag_get_geometry(pag, &ageo);
     980       15411 :         xfs_perag_put(pag);
     981       15411 :         if (error)
     982             :                 return error;
     983             : 
     984       15411 :         if (copy_to_user(arg, &ageo, sizeof(ageo)))
     985           0 :                 return -EFAULT;
     986             :         return 0;
     987             : }
     988             : 
     989             : /*
     990             :  * Linux extended inode flags interface.
     991             :  */
     992             : 
     993             : static void
     994     2335342 : xfs_fill_fsxattr(
     995             :         struct xfs_inode        *ip,
     996             :         int                     whichfork,
     997             :         struct fileattr         *fa)
     998             : {
     999     2335342 :         struct xfs_mount        *mp = ip->i_mount;
    1000     2335342 :         struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
    1001             : 
    1002     2335322 :         fileattr_fill_xflags(fa, xfs_ip2xflags(ip));
    1003             : 
    1004     2335146 :         if (ip->i_diflags & XFS_DIFLAG_EXTSIZE) {
    1005          36 :                 fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);
    1006     2335110 :         } else if (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) {
    1007             :                 /*
    1008             :                  * Don't let a misaligned extent size hint on a directory
    1009             :                  * escape to userspace if it won't pass the setattr checks
    1010             :                  * later.
    1011             :                  */
    1012           8 :                 if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
    1013           0 :                     ip->i_extsize % mp->m_sb.sb_rextsize > 0) {
    1014           0 :                         fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE |
    1015             :                                             FS_XFLAG_EXTSZINHERIT);
    1016           0 :                         fa->fsx_extsize = 0;
    1017             :                 } else {
    1018           8 :                         fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);
    1019             :                 }
    1020             :         }
    1021             : 
    1022     2335146 :         if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)
    1023         256 :                 fa->fsx_cowextsize = XFS_FSB_TO_B(mp, ip->i_cowextsize);
    1024     2335146 :         fa->fsx_projid = ip->i_projid;
    1025     4670492 :         if (ifp && !xfs_need_iread_extents(ifp))
    1026     2328594 :                 fa->fsx_nextents = xfs_iext_count(ifp);
    1027             :         else
    1028       13504 :                 fa->fsx_nextents = xfs_ifork_nextents(ifp);
    1029     2335113 : }
    1030             : 
    1031             : STATIC int
    1032        4795 : xfs_ioc_fsgetxattra(
    1033             :         xfs_inode_t             *ip,
    1034             :         void                    __user *arg)
    1035             : {
    1036        4795 :         struct fileattr         fa;
    1037             : 
    1038        4795 :         xfs_ilock(ip, XFS_ILOCK_SHARED);
    1039        4795 :         xfs_fill_fsxattr(ip, XFS_ATTR_FORK, &fa);
    1040        4795 :         xfs_iunlock(ip, XFS_ILOCK_SHARED);
    1041             : 
    1042        4795 :         return copy_fsxattr_to_user(&fa, arg);
    1043             : }
    1044             : 
    1045             : int
    1046     2330533 : xfs_fileattr_get(
    1047             :         struct dentry           *dentry,
    1048             :         struct fileattr         *fa)
    1049             : {
    1050     2330533 :         struct xfs_inode        *ip = XFS_I(d_inode(dentry));
    1051             : 
    1052     2330533 :         if (d_is_special(dentry))
    1053             :                 return -ENOTTY;
    1054             : 
    1055     2330533 :         xfs_ilock(ip, XFS_ILOCK_SHARED);
    1056     2330465 :         xfs_fill_fsxattr(ip, XFS_DATA_FORK, fa);
    1057     2330331 :         xfs_iunlock(ip, XFS_ILOCK_SHARED);
    1058             : 
    1059     2330331 :         return 0;
    1060             : }
    1061             : 
    1062             : STATIC uint16_t
    1063     1514155 : xfs_flags2diflags(
    1064             :         struct xfs_inode        *ip,
    1065             :         unsigned int            xflags)
    1066             : {
    1067             :         /* can't set PREALLOC this way, just preserve it */
    1068     1514155 :         uint16_t                di_flags =
    1069     1514155 :                 (ip->i_diflags & XFS_DIFLAG_PREALLOC);
    1070             : 
    1071     1514155 :         if (xflags & FS_XFLAG_IMMUTABLE)
    1072          74 :                 di_flags |= XFS_DIFLAG_IMMUTABLE;
    1073     1514155 :         if (xflags & FS_XFLAG_APPEND)
    1074          50 :                 di_flags |= XFS_DIFLAG_APPEND;
    1075     1514155 :         if (xflags & FS_XFLAG_SYNC)
    1076          24 :                 di_flags |= XFS_DIFLAG_SYNC;
    1077     1514155 :         if (xflags & FS_XFLAG_NOATIME)
    1078          10 :                 di_flags |= XFS_DIFLAG_NOATIME;
    1079     1514155 :         if (xflags & FS_XFLAG_NODUMP)
    1080          14 :                 di_flags |= XFS_DIFLAG_NODUMP;
    1081     1514155 :         if (xflags & FS_XFLAG_NODEFRAG)
    1082           0 :                 di_flags |= XFS_DIFLAG_NODEFRAG;
    1083     1514155 :         if (xflags & FS_XFLAG_FILESTREAM)
    1084         919 :                 di_flags |= XFS_DIFLAG_FILESTREAM;
    1085     1514155 :         if (S_ISDIR(VFS_I(ip)->i_mode)) {
    1086       12418 :                 if (xflags & FS_XFLAG_RTINHERIT)
    1087          39 :                         di_flags |= XFS_DIFLAG_RTINHERIT;
    1088       12418 :                 if (xflags & FS_XFLAG_NOSYMLINKS)
    1089           6 :                         di_flags |= XFS_DIFLAG_NOSYMLINKS;
    1090       12418 :                 if (xflags & FS_XFLAG_EXTSZINHERIT)
    1091          42 :                         di_flags |= XFS_DIFLAG_EXTSZINHERIT;
    1092       12418 :                 if (xflags & FS_XFLAG_PROJINHERIT)
    1093        1158 :                         di_flags |= XFS_DIFLAG_PROJINHERIT;
    1094     1501737 :         } else if (S_ISREG(VFS_I(ip)->i_mode)) {
    1095     1501735 :                 if (xflags & FS_XFLAG_REALTIME)
    1096      318702 :                         di_flags |= XFS_DIFLAG_REALTIME;
    1097     1501735 :                 if (xflags & FS_XFLAG_EXTSIZE)
    1098          60 :                         di_flags |= XFS_DIFLAG_EXTSIZE;
    1099             :         }
    1100             : 
    1101     1514155 :         return di_flags;
    1102             : }
    1103             : 
    1104             : STATIC uint64_t
    1105     1032784 : xfs_flags2diflags2(
    1106             :         struct xfs_inode        *ip,
    1107             :         unsigned int            xflags)
    1108             : {
    1109     1032784 :         uint64_t                di_flags2 =
    1110     1032784 :                 (ip->i_diflags2 & (XFS_DIFLAG2_REFLINK |
    1111             :                                    XFS_DIFLAG2_BIGTIME |
    1112             :                                    XFS_DIFLAG2_NREXT64));
    1113             : 
    1114     1032784 :         if (xflags & FS_XFLAG_DAX)
    1115          24 :                 di_flags2 |= XFS_DIFLAG2_DAX;
    1116     1032784 :         if (xflags & FS_XFLAG_COWEXTSIZE)
    1117         276 :                 di_flags2 |= XFS_DIFLAG2_COWEXTSIZE;
    1118             : 
    1119     1032784 :         return di_flags2;
    1120             : }
    1121             : 
    1122             : static int
    1123      551425 : xfs_ioctl_setattr_xflags(
    1124             :         struct xfs_trans        *tp,
    1125             :         struct xfs_inode        *ip,
    1126             :         struct fileattr         *fa)
    1127             : {
    1128      551425 :         struct xfs_mount        *mp = ip->i_mount;
    1129      551425 :         uint64_t                i_flags2;
    1130             : 
    1131             :         /* Can't change realtime flag if any extents are allocated. */
    1132      551425 :         if ((ip->i_df.if_nextents || ip->i_delayed_blks) &&
    1133      685518 :             XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & FS_XFLAG_REALTIME))
    1134             :                 return -EINVAL;
    1135             : 
    1136             :         /* If realtime flag is set then must have realtime device */
    1137      551425 :         if (fa->fsx_xflags & FS_XFLAG_REALTIME) {
    1138      106234 :                 if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||
    1139      106234 :                     (ip->i_extsize % mp->m_sb.sb_rextsize))
    1140             :                         return -EINVAL;
    1141             :         }
    1142             : 
    1143             :         /* Clear reflink if we are actually able to set the rt flag. */
    1144      551425 :         if ((fa->fsx_xflags & FS_XFLAG_REALTIME) && xfs_is_reflink_inode(ip))
    1145           0 :                 ip->i_diflags2 &= ~XFS_DIFLAG2_REFLINK;
    1146             : 
    1147             :         /* diflags2 only valid for v3 inodes. */
    1148      551425 :         i_flags2 = xfs_flags2diflags2(ip, fa->fsx_xflags);
    1149      551425 :         if (i_flags2 && !xfs_has_v3inodes(mp))
    1150             :                 return -EINVAL;
    1151             : 
    1152      551425 :         ip->i_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);
    1153      551425 :         ip->i_diflags2 = i_flags2;
    1154             : 
    1155      551425 :         xfs_diflags_to_iflags(ip, false);
    1156      551422 :         xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
    1157      551424 :         xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
    1158      551426 :         XFS_STATS_INC(mp, xs_ig_attrchg);
    1159      551426 :         return 0;
    1160             : }
    1161             : 
    1162             : static void
    1163      551432 : xfs_ioctl_setattr_prepare_dax(
    1164             :         struct xfs_inode        *ip,
    1165             :         struct fileattr         *fa)
    1166             : {
    1167      551432 :         struct xfs_mount        *mp = ip->i_mount;
    1168      551432 :         struct inode            *inode = VFS_I(ip);
    1169             : 
    1170      551432 :         if (S_ISDIR(inode->i_mode))
    1171             :                 return;
    1172             : 
    1173      543683 :         if (xfs_has_dax_always(mp) || xfs_has_dax_never(mp))
    1174             :                 return;
    1175             : 
    1176      543683 :         if (((fa->fsx_xflags & FS_XFLAG_DAX) &&
    1177      543683 :             !(ip->i_diflags2 & XFS_DIFLAG2_DAX)) ||
    1178      543681 :             (!(fa->fsx_xflags & FS_XFLAG_DAX) &&
    1179      543681 :              (ip->i_diflags2 & XFS_DIFLAG2_DAX)))
    1180           4 :                 d_mark_dontcache(inode);
    1181             : }
    1182             : 
    1183             : /*
    1184             :  * Set up the transaction structure for the setattr operation, checking that we
    1185             :  * have permission to do so. On success, return a clean transaction and the
    1186             :  * inode locked exclusively ready for further operation specific checks. On
    1187             :  * failure, return an error without modifying or locking the inode.
    1188             :  */
    1189             : static struct xfs_trans *
    1190      551431 : xfs_ioctl_setattr_get_trans(
    1191             :         struct xfs_inode        *ip,
    1192             :         struct xfs_dquot        *pdqp)
    1193             : {
    1194      551431 :         struct xfs_mount        *mp = ip->i_mount;
    1195      551431 :         struct xfs_trans        *tp;
    1196      551431 :         int                     error = -EROFS;
    1197             : 
    1198     1102862 :         if (xfs_is_readonly(mp))
    1199           0 :                 goto out_error;
    1200      551431 :         error = -EIO;
    1201     1102862 :         if (xfs_is_shutdown(mp))
    1202           1 :                 goto out_error;
    1203             : 
    1204      551430 :         error = xfs_trans_alloc_ichange(ip, NULL, NULL, pdqp,
    1205             :                         has_capability_noaudit(current, CAP_FOWNER), &tp);
    1206      551426 :         if (error)
    1207           0 :                 goto out_error;
    1208             : 
    1209      551426 :         if (xfs_has_wsync(mp))
    1210         152 :                 xfs_trans_set_sync(tp);
    1211             : 
    1212      551426 :         return tp;
    1213             : 
    1214           1 : out_error:
    1215           1 :         return ERR_PTR(error);
    1216             : }
    1217             : 
    1218             : /*
    1219             :  * Validate a proposed extent size hint.  For regular files, the hint can only
    1220             :  * be changed if no extents are allocated.
    1221             :  */
    1222             : static int
    1223      551424 : xfs_ioctl_setattr_check_extsize(
    1224             :         struct xfs_inode        *ip,
    1225             :         struct fileattr         *fa)
    1226             : {
    1227      551424 :         struct xfs_mount        *mp = ip->i_mount;
    1228      551424 :         xfs_failaddr_t          failaddr;
    1229      551424 :         uint16_t                new_diflags;
    1230             : 
    1231      551424 :         if (!fa->fsx_valid)
    1232             :                 return 0;
    1233             : 
    1234      481369 :         if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_df.if_nextents &&
    1235      375228 :             XFS_FSB_TO_B(mp, ip->i_extsize) != fa->fsx_extsize)
    1236             :                 return -EINVAL;
    1237             : 
    1238      481367 :         if (fa->fsx_extsize & mp->m_blockmask)
    1239             :                 return -EINVAL;
    1240             : 
    1241      481365 :         new_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);
    1242             : 
    1243             :         /*
    1244             :          * Inode verifiers do not check that the extent size hint is an integer
    1245             :          * multiple of the rt extent size on a directory with both rtinherit
    1246             :          * and extszinherit flags set.  Don't let sysadmins misconfigure
    1247             :          * directories.
    1248             :          */
    1249      481365 :         if ((new_diflags & XFS_DIFLAG_RTINHERIT) &&
    1250             :             (new_diflags & XFS_DIFLAG_EXTSZINHERIT)) {
    1251           0 :                 unsigned int    rtextsize_bytes;
    1252             : 
    1253           0 :                 rtextsize_bytes = XFS_FSB_TO_B(mp, mp->m_sb.sb_rextsize);
    1254           0 :                 if (fa->fsx_extsize % rtextsize_bytes)
    1255             :                         return -EINVAL;
    1256             :         }
    1257             : 
    1258      481365 :         failaddr = xfs_inode_validate_extsize(ip->i_mount,
    1259      481365 :                         XFS_B_TO_FSB(mp, fa->fsx_extsize),
    1260             :                         VFS_I(ip)->i_mode, new_diflags);
    1261      481365 :         return failaddr != NULL ? -EINVAL : 0;
    1262             : }
    1263             : 
    1264             : static int
    1265      551420 : xfs_ioctl_setattr_check_cowextsize(
    1266             :         struct xfs_inode        *ip,
    1267             :         struct fileattr         *fa)
    1268             : {
    1269      551420 :         struct xfs_mount        *mp = ip->i_mount;
    1270      551420 :         xfs_failaddr_t          failaddr;
    1271      551420 :         uint64_t                new_diflags2;
    1272      551420 :         uint16_t                new_diflags;
    1273             : 
    1274      551420 :         if (!fa->fsx_valid)
    1275             :                 return 0;
    1276             : 
    1277      481365 :         if (fa->fsx_cowextsize & mp->m_blockmask)
    1278             :                 return -EINVAL;
    1279             : 
    1280      481365 :         new_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);
    1281      481365 :         new_diflags2 = xfs_flags2diflags2(ip, fa->fsx_xflags);
    1282             : 
    1283      481365 :         failaddr = xfs_inode_validate_cowextsize(ip->i_mount,
    1284      481365 :                         XFS_B_TO_FSB(mp, fa->fsx_cowextsize),
    1285             :                         VFS_I(ip)->i_mode, new_diflags, new_diflags2);
    1286      481371 :         return failaddr != NULL ? -EINVAL : 0;
    1287             : }
    1288             : 
    1289             : static int
    1290             : xfs_ioctl_setattr_check_projid(
    1291             :         struct xfs_inode        *ip,
    1292             :         struct fileattr         *fa)
    1293             : {
    1294      552270 :         if (!fa->fsx_valid)
    1295             :                 return 0;
    1296             : 
    1297             :         /* Disallow 32bit project ids if 32bit IDs are not enabled. */
    1298      482214 :         if (fa->fsx_projid > (uint16_t)-1 &&
    1299           0 :             !xfs_has_projid32(ip->i_mount))
    1300             :                 return -EINVAL;
    1301             :         return 0;
    1302             : }
    1303             : 
    1304             : int
    1305      563835 : xfs_fileattr_set(
    1306             :         struct mnt_idmap        *idmap,
    1307             :         struct dentry           *dentry,
    1308             :         struct fileattr         *fa)
    1309             : {
    1310      563835 :         struct xfs_inode        *ip = XFS_I(d_inode(dentry));
    1311      563835 :         struct xfs_mount        *mp = ip->i_mount;
    1312      563835 :         struct xfs_trans        *tp;
    1313      563835 :         struct xfs_dquot        *pdqp = NULL;
    1314      563835 :         struct xfs_dquot        *olddquot = NULL;
    1315      563835 :         int                     error;
    1316             : 
    1317      563835 :         trace_xfs_ioctl_setattr(ip);
    1318             : 
    1319      563837 :         if (d_is_special(dentry))
    1320             :                 return -ENOTTY;
    1321             : 
    1322      563837 :         if (!fa->fsx_valid) {
    1323       81622 :                 if (fa->flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL |
    1324             :                                   FS_NOATIME_FL | FS_NODUMP_FL |
    1325             :                                   FS_SYNC_FL | FS_DAX_FL | FS_PROJINHERIT_FL))
    1326             :                         return -EOPNOTSUPP;
    1327             :         }
    1328             : 
    1329      552270 :         error = xfs_ioctl_setattr_check_projid(ip, fa);
    1330             :         if (error)
    1331             :                 return error;
    1332             : 
    1333             :         /*
    1334             :          * If disk quotas is on, we make sure that the dquots do exist on disk,
    1335             :          * before we start any other transactions. Trying to do this later
    1336             :          * is messy. We don't care to take a readlock to look at the ids
    1337             :          * in inode here, because we can't hold it across the trans_reserve.
    1338             :          * If the IDs do change before we take the ilock, we're covered
    1339             :          * because the i_*dquot fields will get updated anyway.
    1340             :          */
    1341      552270 :         if (fa->fsx_valid && XFS_IS_QUOTA_ON(mp)) {
    1342      365033 :                 error = xfs_qm_vop_dqalloc(ip, VFS_I(ip)->i_uid,
    1343             :                                 VFS_I(ip)->i_gid, fa->fsx_projid,
    1344             :                                 XFS_QMOPT_PQUOTA, NULL, NULL, &pdqp);
    1345      365038 :                 if (error)
    1346             :                         return error;
    1347             :         }
    1348             : 
    1349      551434 :         xfs_ioctl_setattr_prepare_dax(ip, fa);
    1350             : 
    1351      551432 :         tp = xfs_ioctl_setattr_get_trans(ip, pdqp);
    1352      551428 :         if (IS_ERR(tp)) {
    1353           1 :                 error = PTR_ERR(tp);
    1354           1 :                 goto error_free_dquots;
    1355             :         }
    1356             : 
    1357      551427 :         error = xfs_ioctl_setattr_check_extsize(ip, fa);
    1358      551425 :         if (error)
    1359           4 :                 goto error_trans_cancel;
    1360             : 
    1361      551421 :         error = xfs_ioctl_setattr_check_cowextsize(ip, fa);
    1362      551420 :         if (error)
    1363           0 :                 goto error_trans_cancel;
    1364             : 
    1365      551420 :         error = xfs_ioctl_setattr_xflags(tp, ip, fa);
    1366      551426 :         if (error)
    1367           0 :                 goto error_trans_cancel;
    1368             : 
    1369      551426 :         if (!fa->fsx_valid)
    1370       70055 :                 goto skip_xattr;
    1371             :         /*
    1372             :          * Change file ownership.  Must be the owner or privileged.  CAP_FSETID
    1373             :          * overrides the following restrictions:
    1374             :          *
    1375             :          * The set-user-ID and set-group-ID bits of a file will be cleared upon
    1376             :          * successful return from chown()
    1377             :          */
    1378             : 
    1379      481379 :         if ((VFS_I(ip)->i_mode & (S_ISUID|S_ISGID)) &&
    1380           8 :             !capable_wrt_inode_uidgid(idmap, VFS_I(ip), CAP_FSETID))
    1381           0 :                 VFS_I(ip)->i_mode &= ~(S_ISUID|S_ISGID);
    1382             : 
    1383             :         /* Change the ownerships and register project quota modifications */
    1384      481371 :         if (ip->i_projid != fa->fsx_projid) {
    1385      420332 :                 if (XFS_IS_PQUOTA_ON(mp)) {
    1386      316455 :                         olddquot = xfs_qm_vop_chown(tp, ip,
    1387             :                                                 &ip->i_pdquot, pdqp);
    1388             :                 }
    1389      420332 :                 ip->i_projid = fa->fsx_projid;
    1390             :         }
    1391             : 
    1392             :         /*
    1393             :          * Only set the extent size hint if we've already determined that the
    1394             :          * extent size hint should be set on the inode. If no extent size flags
    1395             :          * are set on the inode then unconditionally clear the extent size hint.
    1396             :          */
    1397      481371 :         if (ip->i_diflags & (XFS_DIFLAG_EXTSIZE | XFS_DIFLAG_EXTSZINHERIT))
    1398          34 :                 ip->i_extsize = XFS_B_TO_FSB(mp, fa->fsx_extsize);
    1399             :         else
    1400      481337 :                 ip->i_extsize = 0;
    1401             : 
    1402      481371 :         if (xfs_has_v3inodes(mp)) {
    1403      481371 :                 if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)
    1404         138 :                         ip->i_cowextsize = XFS_B_TO_FSB(mp, fa->fsx_cowextsize);
    1405             :                 else
    1406      481233 :                         ip->i_cowextsize = 0;
    1407             :         }
    1408             : 
    1409           0 : skip_xattr:
    1410      551426 :         error = xfs_trans_commit(tp);
    1411             : 
    1412             :         /*
    1413             :          * Release any dquot(s) the inode had kept before chown.
    1414             :          */
    1415      551424 :         xfs_qm_dqrele(olddquot);
    1416      551424 :         xfs_qm_dqrele(pdqp);
    1417             : 
    1418      551424 :         return error;
    1419             : 
    1420           4 : error_trans_cancel:
    1421           4 :         xfs_trans_cancel(tp);
    1422           5 : error_free_dquots:
    1423           5 :         xfs_qm_dqrele(pdqp);
    1424           5 :         return error;
    1425             : }
    1426             : 
    1427             : static bool
    1428     4233798 : xfs_getbmap_format(
    1429             :         struct kgetbmap         *p,
    1430             :         struct getbmapx __user  *u,
    1431             :         size_t                  recsize)
    1432             : {
    1433     4233798 :         if (put_user(p->bmv_offset, &u->bmv_offset) ||
    1434     4233874 :             put_user(p->bmv_block, &u->bmv_block) ||
    1435     4233632 :             put_user(p->bmv_length, &u->bmv_length) ||
    1436     4233811 :             put_user(0, &u->bmv_count) ||
    1437     4233732 :             put_user(0, &u->bmv_entries))
    1438           0 :                 return false;
    1439     4233738 :         if (recsize < sizeof(struct getbmapx))
    1440             :                 return true;
    1441     4096287 :         if (put_user(0, &u->bmv_iflags) ||
    1442     4096264 :             put_user(p->bmv_oflags, &u->bmv_oflags) ||
    1443     4096145 :             put_user(0, &u->bmv_unused1) ||
    1444     4096263 :             put_user(0, &u->bmv_unused2))
    1445           0 :                 return false;
    1446             :         return true;
    1447             : }
    1448             : 
    1449             : STATIC int
    1450     1111879 : xfs_ioc_getbmap(
    1451             :         struct file             *file,
    1452             :         unsigned int            cmd,
    1453             :         void                    __user *arg)
    1454             : {
    1455     1111879 :         struct getbmapx         bmx = { 0 };
    1456     1111879 :         struct kgetbmap         *buf;
    1457     1111879 :         size_t                  recsize;
    1458     1111879 :         int                     error, i;
    1459             : 
    1460     1111879 :         switch (cmd) {
    1461           0 :         case XFS_IOC_GETBMAPA:
    1462           0 :                 bmx.bmv_iflags = BMV_IF_ATTRFORK;
    1463             :                 fallthrough;
    1464             :         case XFS_IOC_GETBMAP:
    1465             :                 /* struct getbmap is a strict subset of struct getbmapx. */
    1466             :                 recsize = sizeof(struct getbmap);
    1467             :                 break;
    1468             :         case XFS_IOC_GETBMAPX:
    1469             :                 recsize = sizeof(struct getbmapx);
    1470             :                 break;
    1471             :         default:
    1472             :                 return -EINVAL;
    1473             :         }
    1474             : 
    1475     2223422 :         if (copy_from_user(&bmx, arg, recsize))
    1476             :                 return -EFAULT;
    1477             : 
    1478     1111543 :         if (bmx.bmv_count < 2)
    1479             :                 return -EINVAL;
    1480     1111543 :         if (bmx.bmv_count >= INT_MAX / recsize)
    1481             :                 return -ENOMEM;
    1482             : 
    1483     1111543 :         buf = kvcalloc(bmx.bmv_count, sizeof(*buf), GFP_KERNEL);
    1484     1111625 :         if (!buf)
    1485             :                 return -ENOMEM;
    1486             : 
    1487     1111625 :         error = xfs_getbmap(XFS_I(file_inode(file)), &bmx, buf);
    1488     1111733 :         if (error)
    1489           0 :                 goto out_free_buf;
    1490             : 
    1491     1111733 :         error = -EFAULT;
    1492     2223355 :         if (copy_to_user(arg, &bmx, recsize))
    1493           0 :                 goto out_free_buf;
    1494     1111622 :         arg += recsize;
    1495             : 
    1496     5345277 :         for (i = 0; i < bmx.bmv_entries; i++) {
    1497     4233610 :                 if (!xfs_getbmap_format(buf + i, arg, recsize))
    1498           0 :                         goto out_free_buf;
    1499     4233655 :                 arg += recsize;
    1500             :         }
    1501             : 
    1502             :         error = 0;
    1503     1111667 : out_free_buf:
    1504     1111667 :         kmem_free(buf);
    1505     1111667 :         return error;
    1506             : }
    1507             : 
    1508             : STATIC int
    1509       88217 : xfs_ioc_getfsmap(
    1510             :         struct xfs_inode        *ip,
    1511             :         struct fsmap_head       __user *arg)
    1512             : {
    1513       88217 :         struct xfs_fsmap_head   xhead = {0};
    1514       88217 :         struct fsmap_head       head;
    1515       88217 :         struct fsmap            *recs;
    1516       88217 :         unsigned int            count;
    1517       88217 :         __u32                   last_flags = 0;
    1518       88217 :         bool                    done = false;
    1519       88217 :         int                     error;
    1520             : 
    1521       88217 :         if (copy_from_user(&head, arg, sizeof(struct fsmap_head)))
    1522             :                 return -EFAULT;
    1523      174793 :         if (memchr_inv(head.fmh_reserved, 0, sizeof(head.fmh_reserved)) ||
    1524             :             memchr_inv(head.fmh_keys[0].fmr_reserved, 0,
    1525       87298 :                        sizeof(head.fmh_keys[0].fmr_reserved)) ||
    1526             :             memchr_inv(head.fmh_keys[1].fmr_reserved, 0,
    1527             :                        sizeof(head.fmh_keys[1].fmr_reserved)))
    1528           0 :                 return -EINVAL;
    1529             : 
    1530             :         /*
    1531             :          * Use an internal memory buffer so that we don't have to copy fsmap
    1532             :          * data to userspace while holding locks.  Start by trying to allocate
    1533             :          * up to 128k for the buffer, but fall back to a single page if needed.
    1534             :          */
    1535       87298 :         count = min_t(unsigned int, head.fmh_count,
    1536             :                         131072 / sizeof(struct fsmap));
    1537       87298 :         recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL);
    1538       87655 :         if (!recs) {
    1539           0 :                 count = min_t(unsigned int, head.fmh_count,
    1540             :                                 PAGE_SIZE / sizeof(struct fsmap));
    1541           0 :                 recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL);
    1542           0 :                 if (!recs)
    1543             :                         return -ENOMEM;
    1544             :         }
    1545             : 
    1546       87655 :         xhead.fmh_iflags = head.fmh_iflags;
    1547       87655 :         xfs_fsmap_to_internal(&xhead.fmh_keys[0], &head.fmh_keys[0]);
    1548       87375 :         xfs_fsmap_to_internal(&xhead.fmh_keys[1], &head.fmh_keys[1]);
    1549             : 
    1550       87285 :         trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]);
    1551       87284 :         trace_xfs_getfsmap_high_key(ip->i_mount, &xhead.fmh_keys[1]);
    1552             : 
    1553       87861 :         head.fmh_entries = 0;
    1554      113027 :         do {
    1555      113027 :                 struct fsmap __user     *user_recs;
    1556      113027 :                 struct fsmap            *last_rec;
    1557             : 
    1558      113027 :                 user_recs = &arg->fmh_recs[head.fmh_entries];
    1559      113027 :                 xhead.fmh_entries = 0;
    1560      113027 :                 xhead.fmh_count = min_t(unsigned int, count,
    1561             :                                         head.fmh_count - head.fmh_entries);
    1562             : 
    1563             :                 /* Run query, record how many entries we got. */
    1564      113027 :                 error = xfs_getfsmap(ip->i_mount, &xhead, recs);
    1565      113475 :                 switch (error) {
    1566             :                 case 0:
    1567             :                         /*
    1568             :                          * There are no more records in the result set.  Copy
    1569             :                          * whatever we got to userspace and break out.
    1570             :                          */
    1571             :                         done = true;
    1572             :                         break;
    1573       43171 :                 case -ECANCELED:
    1574             :                         /*
    1575             :                          * The internal memory buffer is full.  Copy whatever
    1576             :                          * records we got to userspace and go again if we have
    1577             :                          * not yet filled the userspace buffer.
    1578             :                          */
    1579       43171 :                         error = 0;
    1580       43171 :                         break;
    1581           0 :                 default:
    1582           0 :                         goto out_free;
    1583             :                 }
    1584      113475 :                 head.fmh_entries += xhead.fmh_entries;
    1585      113475 :                 head.fmh_oflags = xhead.fmh_oflags;
    1586             : 
    1587             :                 /*
    1588             :                  * If the caller wanted a record count or there aren't any
    1589             :                  * new records to return, we're done.
    1590             :                  */
    1591      113475 :                 if (head.fmh_count == 0 || xhead.fmh_entries == 0)
    1592             :                         break;
    1593             : 
    1594             :                 /* Copy all the records we got out to userspace. */
    1595      113483 :                 if (copy_to_user(user_recs, recs,
    1596      113475 :                                  xhead.fmh_entries * sizeof(struct fsmap))) {
    1597           0 :                         error = -EFAULT;
    1598           0 :                         goto out_free;
    1599             :                 }
    1600             : 
    1601             :                 /* Remember the last record flags we copied to userspace. */
    1602      113483 :                 last_rec = &recs[xhead.fmh_entries - 1];
    1603      113483 :                 last_flags = last_rec->fmr_flags;
    1604             : 
    1605             :                 /* Set up the low key for the next iteration. */
    1606      113483 :                 xfs_fsmap_to_internal(&xhead.fmh_keys[0], last_rec);
    1607      113482 :                 trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]);
    1608      113468 :         } while (!done && head.fmh_entries < head.fmh_count);
    1609             : 
    1610             :         /*
    1611             :          * If there are no more records in the query result set and we're not
    1612             :          * in counting mode, mark the last record returned with the LAST flag.
    1613             :          */
    1614       88302 :         if (done && head.fmh_count > 0 && head.fmh_entries > 0) {
    1615       70295 :                 struct fsmap __user     *user_rec;
    1616             : 
    1617       70295 :                 last_flags |= FMR_OF_LAST;
    1618       70295 :                 user_rec = &arg->fmh_recs[head.fmh_entries - 1];
    1619             : 
    1620       70295 :                 if (copy_to_user(&user_rec->fmr_flags, &last_flags,
    1621             :                                         sizeof(last_flags))) {
    1622           0 :                         error = -EFAULT;
    1623           0 :                         goto out_free;
    1624             :                 }
    1625             :         }
    1626             : 
    1627             :         /* copy back header */
    1628       88302 :         if (copy_to_user(arg, &head, sizeof(struct fsmap_head))) {
    1629           0 :                 error = -EFAULT;
    1630           0 :                 goto out_free;
    1631             :         }
    1632             : 
    1633       88299 : out_free:
    1634       88299 :         kmem_free(recs);
    1635       88299 :         return error;
    1636             : }
    1637             : 
    1638             : STATIC int
    1639   645703043 : xfs_ioc_scrub_metadata(
    1640             :         struct file                     *file,
    1641             :         void                            __user *arg)
    1642             : {
    1643   645703043 :         struct xfs_scrub_metadata       scrub;
    1644   645703043 :         int                             error;
    1645             : 
    1646   645703043 :         if (!capable(CAP_SYS_ADMIN))
    1647             :                 return -EPERM;
    1648             : 
    1649   645747980 :         if (copy_from_user(&scrub, arg, sizeof(scrub)))
    1650             :                 return -EFAULT;
    1651             : 
    1652   645787116 :         error = xfs_scrub_metadata(file, &scrub);
    1653   645647217 :         if (error)
    1654             :                 return error;
    1655             : 
    1656   534390362 :         if (copy_to_user(arg, &scrub, sizeof(scrub)))
    1657           0 :                 return -EFAULT;
    1658             : 
    1659             :         return 0;
    1660             : }
    1661             : 
    1662             : /*
    1663             :  * IOCTL routine to get the parent pointers of an inode and return it to user
    1664             :  * space.  Caller must pass a buffer space containing a struct xfs_getparents,
    1665             :  * followed by a region large enough to contain an array of struct
    1666             :  * xfs_getparents_rec of a size specified in gp_bufsize.  If the inode contains
    1667             :  * more parent pointers than can fit in the buffer space, caller may re-call
    1668             :  * the function using the returned gp_cursor to resume iteration.  The
    1669             :  * number of xfs_getparents_rec returned will be stored in gp_count.
    1670             :  *
    1671             :  * Returns 0 on success or non-zero on failure
    1672             :  */
    1673             : STATIC int
    1674   263681330 : xfs_ioc_get_parent_pointer(
    1675             :         struct file                     *filp,
    1676             :         void                            __user *arg)
    1677             : {
    1678   263681330 :         struct xfs_getparents           *ppi = NULL;
    1679   263681330 :         int                             error = 0;
    1680   263681330 :         struct xfs_inode                *file_ip = XFS_I(file_inode(filp));
    1681   263681330 :         struct xfs_inode                *call_ip = file_ip;
    1682   263681330 :         struct xfs_mount                *mp = file_ip->i_mount;
    1683   263681330 :         void                            __user *o_pptr;
    1684   263681330 :         struct xfs_getparents_rec       *i_pptr;
    1685   263681330 :         unsigned int                    bytes;
    1686             : 
    1687   263681330 :         if (!capable(CAP_SYS_ADMIN))
    1688             :                 return -EPERM;
    1689             : 
    1690             :         /* Allocate an xfs_getparents to put the user data */
    1691   263690452 :         ppi = kvmalloc(sizeof(struct xfs_getparents), GFP_KERNEL);
    1692   263691020 :         if (!ppi)
    1693             :                 return -ENOMEM;
    1694             : 
    1695             :         /* Copy the data from the user */
    1696   263691020 :         error = copy_from_user(ppi, arg, sizeof(struct xfs_getparents));
    1697   263680162 :         if (error) {
    1698           0 :                 error = -EFAULT;
    1699           0 :                 goto out;
    1700             :         }
    1701             : 
    1702             :         /* Check size of buffer requested by user */
    1703   263680162 :         if (ppi->gp_bufsize > XFS_XATTR_LIST_MAX) {
    1704           0 :                 error = -ENOMEM;
    1705           0 :                 goto out;
    1706             :         }
    1707   263680162 :         if (ppi->gp_bufsize < sizeof(struct xfs_getparents)) {
    1708           0 :                 error = -EINVAL;
    1709           0 :                 goto out;
    1710             :         }
    1711             : 
    1712   263680162 :         if (ppi->gp_flags & ~XFS_GETPARENTS_FLAG_ALL) {
    1713           0 :                 error = -EINVAL;
    1714           0 :                 goto out;
    1715             :         }
    1716   263680162 :         ppi->gp_flags &= ~(XFS_GETPARENTS_OFLAG_ROOT | XFS_GETPARENTS_OFLAG_DONE);
    1717             : 
    1718             :         /*
    1719             :          * Now that we know how big the trailing buffer is, expand
    1720             :          * our kernel xfs_getparents to be the same size
    1721             :          */
    1722   263680162 :         ppi = kvrealloc(ppi, sizeof(struct xfs_getparents), ppi->gp_bufsize,
    1723             :                         GFP_KERNEL | __GFP_ZERO);
    1724   263557386 :         if (!ppi)
    1725             :                 return -ENOMEM;
    1726             : 
    1727   263557386 :         if (ppi->gp_flags & XFS_GETPARENTS_IFLAG_HANDLE) {
    1728   263556952 :                 struct xfs_handle       *hanp = &ppi->gp_handle;
    1729             : 
    1730   527113904 :                 if (memcmp(&hanp->ha_fsid, mp->m_fixedfsid,
    1731             :                                                         sizeof(xfs_fsid_t))) {
    1732           0 :                         error = -EINVAL;
    1733           0 :                         goto out;
    1734             :                 }
    1735             : 
    1736   263556952 :                 if (hanp->ha_fid.fid_ino != file_ip->i_ino) {
    1737   241305025 :                         error = xfs_iget(mp, NULL, hanp->ha_fid.fid_ino,
    1738             :                                         XFS_IGET_UNTRUSTED, 0, &call_ip);
    1739   241321044 :                         if (error)
    1740        1459 :                                 goto out;
    1741             :                 }
    1742             : 
    1743   263571512 :                 if (VFS_I(call_ip)->i_generation != hanp->ha_fid.fid_gen) {
    1744       54865 :                         error = -EINVAL;
    1745       54865 :                         goto out;
    1746             :                 }
    1747             :         }
    1748             : 
    1749             :         /* Get the parent pointers */
    1750   263517081 :         error = xfs_getparent_pointers(call_ip, ppi);
    1751   263603694 :         if (error)
    1752           0 :                 goto out;
    1753             : 
    1754             :         /*
    1755             :          * If we ran out of buffer space before copying any parent pointers at
    1756             :          * all, the caller's buffer was too short.  Tell userspace that, erm,
    1757             :          * the message is too long.
    1758             :          */
    1759   263603694 :         if (ppi->gp_count == 0 && !(ppi->gp_flags & XFS_GETPARENTS_OFLAG_DONE)) {
    1760           0 :                 error = -EMSGSIZE;
    1761           0 :                 goto out;
    1762             :         }
    1763             : 
    1764             :         /* Copy the parent pointer head back to the user */
    1765   263603694 :         bytes = xfs_getparents_arraytop(ppi, ppi->gp_count);
    1766   263603694 :         error = copy_to_user(arg, ppi, bytes);
    1767   263616549 :         if (error) {
    1768           0 :                 error = -EFAULT;
    1769           0 :                 goto out;
    1770             :         }
    1771             : 
    1772   263616549 :         if (ppi->gp_count == 0)
    1773    22322575 :                 goto out;
    1774             : 
    1775             :         /* Copy the parent pointer records back to the user. */
    1776   241293974 :         o_pptr = (__user char*)arg + ppi->gp_offsets[ppi->gp_count - 1];
    1777   241293974 :         i_pptr = xfs_getparents_rec(ppi, ppi->gp_count - 1);
    1778   241293974 :         bytes = ((char *)ppi + ppi->gp_bufsize) - (char *)i_pptr;
    1779   241293974 :         error = copy_to_user(o_pptr, i_pptr, bytes);
    1780   241285584 :         if (error) {
    1781           0 :                 error = -EFAULT;
    1782           0 :                 goto out;
    1783             :         }
    1784             : 
    1785   241285584 : out:
    1786   263664483 :         if (call_ip != file_ip)
    1787   241372880 :                 xfs_irele(call_ip);
    1788   263679512 :         kvfree(ppi);
    1789   263679512 :         return error;
    1790             : }
    1791             : 
    1792             : int
    1793           0 : xfs_ioc_swapext(
    1794             :         struct xfs_swapext      *sxp)
    1795             : {
    1796           0 :         struct xfs_exch_range   fxr = { 0 };
    1797           0 :         struct fd               fd2, fd1;
    1798           0 :         int                     error = 0;
    1799             : 
    1800           0 :         fd2 = fdget((int)sxp->sx_fdtarget);
    1801           0 :         if (!fd2.file)
    1802             :                 return -EINVAL;
    1803             : 
    1804           0 :         fd1 = fdget((int)sxp->sx_fdtmp);
    1805           0 :         if (!fd1.file) {
    1806           0 :                 error = -EINVAL;
    1807           0 :                 goto dest_fdput;
    1808             :         }
    1809             : 
    1810           0 :         fxr.file1_fd = sxp->sx_fdtmp;
    1811           0 :         fxr.length = sxp->sx_length;
    1812           0 :         fxr.flags = XFS_EXCH_RANGE_NONATOMIC | XFS_EXCH_RANGE_FILE2_FRESH |
    1813             :                     XFS_EXCH_RANGE_FULL_FILES;
    1814           0 :         fxr.file2_ino = sxp->sx_stat.bs_ino;
    1815           0 :         fxr.file2_mtime = sxp->sx_stat.bs_mtime.tv_sec;
    1816           0 :         fxr.file2_ctime = sxp->sx_stat.bs_ctime.tv_sec;
    1817           0 :         fxr.file2_mtime_nsec = sxp->sx_stat.bs_mtime.tv_nsec;
    1818           0 :         fxr.file2_ctime_nsec = sxp->sx_stat.bs_ctime.tv_nsec;
    1819             : 
    1820           0 :         error = xfs_exch_range(fd1.file, fd2.file, &fxr);
    1821             : 
    1822             :         /*
    1823             :          * The old implementation returned EFAULT if the swap range was not
    1824             :          * the entirety of both files.
    1825             :          */
    1826           0 :         if (error == -EDOM)
    1827           0 :                 error = -EFAULT;
    1828           0 :         fdput(fd1);
    1829           0 : dest_fdput:
    1830           0 :         fdput(fd2);
    1831           0 :         return error;
    1832             : }
    1833             : 
    1834             : static int
    1835        7863 : xfs_ioc_getlabel(
    1836             :         struct xfs_mount        *mp,
    1837             :         char                    __user *user_label)
    1838             : {
    1839        7863 :         struct xfs_sb           *sbp = &mp->m_sb;
    1840        7863 :         char                    label[XFSLABEL_MAX + 1];
    1841             : 
    1842             :         /* Paranoia */
    1843        7863 :         BUILD_BUG_ON(sizeof(sbp->sb_fname) > FSLABEL_MAX);
    1844             : 
    1845             :         /* 1 larger than sb_fname, so this ensures a trailing NUL char */
    1846        7863 :         memset(label, 0, sizeof(label));
    1847        7863 :         spin_lock(&mp->m_sb_lock);
    1848        7863 :         strncpy(label, sbp->sb_fname, XFSLABEL_MAX);
    1849        7863 :         spin_unlock(&mp->m_sb_lock);
    1850             : 
    1851        7863 :         if (copy_to_user(user_label, label, sizeof(label)))
    1852           0 :                 return -EFAULT;
    1853             :         return 0;
    1854             : }
    1855             : 
    1856             : static int
    1857          54 : xfs_ioc_setlabel(
    1858             :         struct file             *filp,
    1859             :         struct xfs_mount        *mp,
    1860             :         char                    __user *newlabel)
    1861             : {
    1862          54 :         struct xfs_sb           *sbp = &mp->m_sb;
    1863          54 :         struct block_device     *bdev = xfs_buftarg_bdev(mp->m_ddev_targp);
    1864          54 :         char                    label[XFSLABEL_MAX + 1];
    1865          54 :         size_t                  len;
    1866          54 :         int                     error;
    1867             : 
    1868          54 :         if (!capable(CAP_SYS_ADMIN))
    1869             :                 return -EPERM;
    1870             :         /*
    1871             :          * The generic ioctl allows up to FSLABEL_MAX chars, but XFS is much
    1872             :          * smaller, at 12 bytes.  We copy one more to be sure we find the
    1873             :          * (required) NULL character to test the incoming label length.
    1874             :          * NB: The on disk label doesn't need to be null terminated.
    1875             :          */
    1876          54 :         if (copy_from_user(label, newlabel, XFSLABEL_MAX + 1))
    1877             :                 return -EFAULT;
    1878          54 :         len = strnlen(label, XFSLABEL_MAX + 1);
    1879          54 :         if (len > sizeof(sbp->sb_fname))
    1880             :                 return -EINVAL;
    1881             : 
    1882          52 :         error = mnt_want_write_file(filp);
    1883          52 :         if (error)
    1884             :                 return error;
    1885             : 
    1886          52 :         spin_lock(&mp->m_sb_lock);
    1887          52 :         memset(sbp->sb_fname, 0, sizeof(sbp->sb_fname));
    1888         104 :         memcpy(sbp->sb_fname, label, len);
    1889          52 :         spin_unlock(&mp->m_sb_lock);
    1890             : 
    1891             :         /*
    1892             :          * Now we do several things to satisfy userspace.
    1893             :          * In addition to normal logging of the primary superblock, we also
    1894             :          * immediately write these changes to sector zero for the primary, then
    1895             :          * update all backup supers (as xfs_db does for a label change), then
    1896             :          * invalidate the block device page cache.  This is so that any prior
    1897             :          * buffered reads from userspace (i.e. from blkid) are invalidated,
    1898             :          * and userspace will see the newly-written label.
    1899             :          */
    1900          52 :         error = xfs_sync_sb_buf(mp);
    1901          52 :         if (error)
    1902           0 :                 goto out;
    1903             :         /*
    1904             :          * growfs also updates backup supers so lock against that.
    1905             :          */
    1906          52 :         mutex_lock(&mp->m_growlock);
    1907          52 :         error = xfs_update_secondary_sbs(mp);
    1908          52 :         mutex_unlock(&mp->m_growlock);
    1909             : 
    1910          52 :         invalidate_bdev(bdev);
    1911             : 
    1912          52 : out:
    1913          52 :         mnt_drop_write_file(filp);
    1914          52 :         return error;
    1915             : }
    1916             : 
    1917             : static inline int
    1918           0 : xfs_fs_eofblocks_from_user(
    1919             :         struct xfs_fs_eofblocks         *src,
    1920             :         struct xfs_icwalk               *dst)
    1921             : {
    1922           0 :         if (src->eof_version != XFS_EOFBLOCKS_VERSION)
    1923             :                 return -EINVAL;
    1924             : 
    1925           0 :         if (src->eof_flags & ~XFS_EOF_FLAGS_VALID)
    1926             :                 return -EINVAL;
    1927             : 
    1928           0 :         if (memchr_inv(&src->pad32, 0, sizeof(src->pad32)) ||
    1929           0 :             memchr_inv(src->pad64, 0, sizeof(src->pad64)))
    1930           0 :                 return -EINVAL;
    1931             : 
    1932           0 :         dst->icw_flags = 0;
    1933           0 :         if (src->eof_flags & XFS_EOF_FLAGS_SYNC)
    1934           0 :                 dst->icw_flags |= XFS_ICWALK_FLAG_SYNC;
    1935           0 :         if (src->eof_flags & XFS_EOF_FLAGS_UID)
    1936           0 :                 dst->icw_flags |= XFS_ICWALK_FLAG_UID;
    1937           0 :         if (src->eof_flags & XFS_EOF_FLAGS_GID)
    1938           0 :                 dst->icw_flags |= XFS_ICWALK_FLAG_GID;
    1939           0 :         if (src->eof_flags & XFS_EOF_FLAGS_PRID)
    1940           0 :                 dst->icw_flags |= XFS_ICWALK_FLAG_PRID;
    1941           0 :         if (src->eof_flags & XFS_EOF_FLAGS_MINFILESIZE)
    1942           0 :                 dst->icw_flags |= XFS_ICWALK_FLAG_MINFILESIZE;
    1943             : 
    1944           0 :         dst->icw_prid = src->eof_prid;
    1945           0 :         dst->icw_min_file_size = src->eof_min_file_size;
    1946             : 
    1947           0 :         dst->icw_uid = INVALID_UID;
    1948           0 :         if (src->eof_flags & XFS_EOF_FLAGS_UID) {
    1949           0 :                 dst->icw_uid = make_kuid(current_user_ns(), src->eof_uid);
    1950           0 :                 if (!uid_valid(dst->icw_uid))
    1951             :                         return -EINVAL;
    1952             :         }
    1953             : 
    1954           0 :         dst->icw_gid = INVALID_GID;
    1955           0 :         if (src->eof_flags & XFS_EOF_FLAGS_GID) {
    1956           0 :                 dst->icw_gid = make_kgid(current_user_ns(), src->eof_gid);
    1957           0 :                 if (!gid_valid(dst->icw_gid))
    1958           0 :                         return -EINVAL;
    1959             :         }
    1960             :         return 0;
    1961             : }
    1962             : 
    1963             : static long
    1964     1703906 : xfs_ioc_exchange_range(
    1965             :         struct file                     *file2,
    1966             :         struct xfs_exch_range __user    *argp)
    1967             : {
    1968     1703906 :         struct xfs_exch_range           args;
    1969     1703906 :         struct fd                       file1;
    1970     1703906 :         int                             error;
    1971             : 
    1972     1703906 :         if (copy_from_user(&args, argp, sizeof(args)))
    1973             :                 return -EFAULT;
    1974             : 
    1975     1703894 :         file1 = fdget(args.file1_fd);
    1976     1703904 :         if (!file1.file)
    1977             :                 return -EBADF;
    1978             : 
    1979     1703904 :         error = -EXDEV;
    1980     1703904 :         if (file1.file->f_path.mnt != file2->f_path.mnt)
    1981           4 :                 goto fdput;
    1982             : 
    1983     1703900 :         error = xfs_exch_range(file1.file, file2, &args);
    1984     1703897 : fdput:
    1985     1703897 :         fdput(file1);
    1986     1703897 :         return error;
    1987             : }
    1988             : 
    1989             : /*
    1990             :  * These long-unused ioctls were removed from the official ioctl API in 5.17,
    1991             :  * but retain these definitions so that we can log warnings about them.
    1992             :  */
    1993             : #define XFS_IOC_ALLOCSP         _IOW ('X', 10, struct xfs_flock64)
    1994             : #define XFS_IOC_FREESP          _IOW ('X', 11, struct xfs_flock64)
    1995             : #define XFS_IOC_ALLOCSP64       _IOW ('X', 36, struct xfs_flock64)
    1996             : #define XFS_IOC_FREESP64        _IOW ('X', 37, struct xfs_flock64)
    1997             : 
    1998             : /*
    1999             :  * Note: some of the ioctl's return positive numbers as a
    2000             :  * byte count indicating success, such as readlink_by_handle.
    2001             :  * So we don't "sign flip" like most other routines.  This means
    2002             :  * true errors need to be returned as a negative value.
    2003             :  */
    2004             : long
    2005  1519095969 : xfs_file_ioctl(
    2006             :         struct file             *filp,
    2007             :         unsigned int            cmd,
    2008             :         unsigned long           p)
    2009             : {
    2010  1519095969 :         struct inode            *inode = file_inode(filp);
    2011  1519095969 :         struct xfs_inode        *ip = XFS_I(inode);
    2012  1519095969 :         struct xfs_mount        *mp = ip->i_mount;
    2013  1519095969 :         void                    __user *arg = (void __user *)p;
    2014  1519095969 :         int                     error;
    2015             : 
    2016  1519095969 :         trace_xfs_file_ioctl(ip);
    2017             : 
    2018  1519375693 :         switch (cmd) {
    2019       38117 :         case FITRIM:
    2020       38117 :                 return xfs_ioc_trim(mp, arg);
    2021        7863 :         case FS_IOC_GETFSLABEL:
    2022        7863 :                 return xfs_ioc_getlabel(mp, arg);
    2023          54 :         case FS_IOC_SETFSLABEL:
    2024          54 :                 return xfs_ioc_setlabel(filp, mp, arg);
    2025             :         case XFS_IOC_ALLOCSP:
    2026             :         case XFS_IOC_FREESP:
    2027             :         case XFS_IOC_ALLOCSP64:
    2028             :         case XFS_IOC_FREESP64:
    2029           2 :                 xfs_warn_once(mp,
    2030             :         "%s should use fallocate; XFS_IOC_{ALLOC,FREE}SP ioctl unsupported",
    2031             :                                 current->comm);
    2032             :                 return -ENOTTY;
    2033     9268257 :         case XFS_IOC_DIOINFO: {
    2034     9268257 :                 struct xfs_buftarg      *target = xfs_inode_buftarg(ip);
    2035     9268257 :                 struct dioattr          da;
    2036             : 
    2037     9268257 :                 da.d_mem =  da.d_miniosz = target->bt_logical_sectorsize;
    2038     9268257 :                 da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
    2039             : 
    2040     9268257 :                 if (copy_to_user(arg, &da, sizeof(da)))
    2041           0 :                         return -EFAULT;
    2042             :                 return 0;
    2043             :         }
    2044             : 
    2045   394188421 :         case XFS_IOC_FSBULKSTAT_SINGLE:
    2046             :         case XFS_IOC_FSBULKSTAT:
    2047             :         case XFS_IOC_FSINUMBERS:
    2048   394188421 :                 return xfs_ioc_fsbulkstat(filp, cmd, arg);
    2049             : 
    2050     6782812 :         case XFS_IOC_BULKSTAT:
    2051     6782812 :                 return xfs_ioc_bulkstat(filp, cmd, arg);
    2052     3116766 :         case XFS_IOC_INUMBERS:
    2053     3116766 :                 return xfs_ioc_inumbers(mp, cmd, arg);
    2054             : 
    2055         144 :         case XFS_IOC_FSGEOMETRY_V1:
    2056         144 :                 return xfs_ioc_fsgeometry(mp, arg, 3);
    2057           0 :         case XFS_IOC_FSGEOMETRY_V4:
    2058           0 :                 return xfs_ioc_fsgeometry(mp, arg, 4);
    2059     1995856 :         case XFS_IOC_FSGEOMETRY:
    2060     1995856 :                 return xfs_ioc_fsgeometry(mp, arg, 5);
    2061             : 
    2062       15411 :         case XFS_IOC_AG_GEOMETRY:
    2063       15411 :                 return xfs_ioc_ag_geometry(mp, arg);
    2064             : 
    2065           0 :         case XFS_IOC_GETVERSION:
    2066           0 :                 return put_user(inode->i_generation, (int __user *)arg);
    2067             : 
    2068        4795 :         case XFS_IOC_FSGETXATTRA:
    2069        4795 :                 return xfs_ioc_fsgetxattra(ip, arg);
    2070   263696461 :         case XFS_IOC_GETPARENTS:
    2071   263696461 :                 return xfs_ioc_get_parent_pointer(filp, arg);
    2072     1111616 :         case XFS_IOC_GETBMAP:
    2073             :         case XFS_IOC_GETBMAPA:
    2074             :         case XFS_IOC_GETBMAPX:
    2075     1111616 :                 return xfs_ioc_getbmap(filp, cmd, arg);
    2076             : 
    2077       87524 :         case FS_IOC_GETFSMAP:
    2078       87524 :                 return xfs_ioc_getfsmap(ip, arg);
    2079             : 
    2080   645715859 :         case XFS_IOC_SCRUB_METADATA:
    2081   645715859 :                 return xfs_ioc_scrub_metadata(filp, arg);
    2082             : 
    2083             :         case XFS_IOC_FD_TO_HANDLE:
    2084             :         case XFS_IOC_PATH_TO_HANDLE:
    2085             :         case XFS_IOC_PATH_TO_FSHANDLE: {
    2086       38446 :                 xfs_fsop_handlereq_t    hreq;
    2087             : 
    2088       38446 :                 if (copy_from_user(&hreq, arg, sizeof(hreq)))
    2089             :                         return -EFAULT;
    2090       38446 :                 return xfs_find_handle(cmd, &hreq);
    2091             :         }
    2092             :         case XFS_IOC_OPEN_BY_HANDLE: {
    2093    38493769 :                 xfs_fsop_handlereq_t    hreq;
    2094             : 
    2095    38493769 :                 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
    2096             :                         return -EFAULT;
    2097    38493962 :                 return xfs_open_by_handle(filp, &hreq);
    2098             :         }
    2099             : 
    2100             :         case XFS_IOC_READLINK_BY_HANDLE: {
    2101         184 :                 xfs_fsop_handlereq_t    hreq;
    2102             : 
    2103         184 :                 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
    2104             :                         return -EFAULT;
    2105         184 :                 return xfs_readlink_by_handle(filp, &hreq);
    2106             :         }
    2107   153035565 :         case XFS_IOC_ATTRLIST_BY_HANDLE:
    2108   153035565 :                 return xfs_attrlist_by_handle(filp, arg);
    2109             : 
    2110         132 :         case XFS_IOC_ATTRMULTI_BY_HANDLE:
    2111         132 :                 return xfs_attrmulti_by_handle(filp, arg);
    2112             : 
    2113             :         case XFS_IOC_SWAPEXT: {
    2114           0 :                 struct xfs_swapext      sxp;
    2115             : 
    2116           0 :                 if (copy_from_user(&sxp, arg, sizeof(struct xfs_swapext)))
    2117             :                         return -EFAULT;
    2118             : 
    2119           0 :                 return xfs_ioc_swapext(&sxp);
    2120             :         }
    2121             : 
    2122       13068 :         case XFS_IOC_FSCOUNTS: {
    2123       13068 :                 xfs_fsop_counts_t out;
    2124             : 
    2125       13068 :                 xfs_fs_counts(mp, &out);
    2126             : 
    2127       13068 :                 if (copy_to_user(arg, &out, sizeof(out)))
    2128           2 :                         return -EFAULT;
    2129             :                 return 0;
    2130             :         }
    2131             : 
    2132          20 :         case XFS_IOC_SET_RESBLKS: {
    2133          20 :                 xfs_fsop_resblks_t inout;
    2134          20 :                 uint64_t           in;
    2135             : 
    2136          20 :                 if (!capable(CAP_SYS_ADMIN))
    2137             :                         return -EPERM;
    2138             : 
    2139          40 :                 if (xfs_is_readonly(mp))
    2140             :                         return -EROFS;
    2141             : 
    2142          20 :                 if (copy_from_user(&inout, arg, sizeof(inout)))
    2143             :                         return -EFAULT;
    2144             : 
    2145          18 :                 error = mnt_want_write_file(filp);
    2146          18 :                 if (error)
    2147           0 :                         return error;
    2148             : 
    2149             :                 /* input parameter is passed in resblks field of structure */
    2150          18 :                 in = inout.resblks;
    2151          18 :                 error = xfs_reserve_blocks(mp, &in, &inout);
    2152          18 :                 mnt_drop_write_file(filp);
    2153          18 :                 if (error)
    2154           0 :                         return error;
    2155             : 
    2156          18 :                 if (copy_to_user(arg, &inout, sizeof(inout)))
    2157           0 :                         return -EFAULT;
    2158             :                 return 0;
    2159             :         }
    2160             : 
    2161           6 :         case XFS_IOC_GET_RESBLKS: {
    2162           6 :                 xfs_fsop_resblks_t out;
    2163             : 
    2164           6 :                 if (!capable(CAP_SYS_ADMIN))
    2165             :                         return -EPERM;
    2166             : 
    2167           6 :                 error = xfs_reserve_blocks(mp, NULL, &out);
    2168           6 :                 if (error)
    2169           0 :                         return error;
    2170             : 
    2171           6 :                 if (copy_to_user(arg, &out, sizeof(out)))
    2172           0 :                         return -EFAULT;
    2173             : 
    2174             :                 return 0;
    2175             :         }
    2176             : 
    2177             :         case XFS_IOC_FSGROWFSDATA: {
    2178         362 :                 struct xfs_growfs_data in;
    2179             : 
    2180         362 :                 if (copy_from_user(&in, arg, sizeof(in)))
    2181             :                         return -EFAULT;
    2182             : 
    2183         362 :                 error = mnt_want_write_file(filp);
    2184         362 :                 if (error)
    2185           0 :                         return error;
    2186         362 :                 error = xfs_growfs_data(mp, &in);
    2187         362 :                 mnt_drop_write_file(filp);
    2188         362 :                 return error;
    2189             :         }
    2190             : 
    2191             :         case XFS_IOC_FSGROWFSLOG: {
    2192           0 :                 struct xfs_growfs_log in;
    2193             : 
    2194           0 :                 if (copy_from_user(&in, arg, sizeof(in)))
    2195             :                         return -EFAULT;
    2196             : 
    2197           0 :                 error = mnt_want_write_file(filp);
    2198           0 :                 if (error)
    2199           0 :                         return error;
    2200           0 :                 error = xfs_growfs_log(mp, &in);
    2201           0 :                 mnt_drop_write_file(filp);
    2202           0 :                 return error;
    2203             :         }
    2204             : 
    2205             :         case XFS_IOC_FSGROWFSRT: {
    2206           4 :                 xfs_growfs_rt_t in;
    2207             : 
    2208           4 :                 if (copy_from_user(&in, arg, sizeof(in)))
    2209             :                         return -EFAULT;
    2210             : 
    2211           4 :                 error = mnt_want_write_file(filp);
    2212           4 :                 if (error)
    2213           0 :                         return error;
    2214           4 :                 error = xfs_growfs_rt(mp, &in);
    2215           4 :                 mnt_drop_write_file(filp);
    2216           4 :                 return error;
    2217             :         }
    2218             : 
    2219        4709 :         case XFS_IOC_GOINGDOWN: {
    2220        4709 :                 uint32_t in;
    2221             : 
    2222        4709 :                 if (!capable(CAP_SYS_ADMIN))
    2223             :                         return -EPERM;
    2224             : 
    2225        4709 :                 if (get_user(in, (uint32_t __user *)arg))
    2226             :                         return -EFAULT;
    2227             : 
    2228        4709 :                 return xfs_fs_goingdown(mp, in);
    2229             :         }
    2230             : 
    2231          14 :         case XFS_IOC_ERROR_INJECTION: {
    2232          14 :                 xfs_error_injection_t in;
    2233             : 
    2234          14 :                 if (!capable(CAP_SYS_ADMIN))
    2235             :                         return -EPERM;
    2236             : 
    2237          14 :                 if (copy_from_user(&in, arg, sizeof(in)))
    2238             :                         return -EFAULT;
    2239             : 
    2240          14 :                 return xfs_errortag_add(mp, in.errtag);
    2241             :         }
    2242             : 
    2243           0 :         case XFS_IOC_ERROR_CLEARALL:
    2244           0 :                 if (!capable(CAP_SYS_ADMIN))
    2245             :                         return -EPERM;
    2246             : 
    2247           0 :                 return xfs_errortag_clearall(mp);
    2248             : 
    2249           0 :         case XFS_IOC_FREE_EOFBLOCKS: {
    2250           0 :                 struct xfs_fs_eofblocks eofb;
    2251           0 :                 struct xfs_icwalk       icw;
    2252             : 
    2253           0 :                 if (!capable(CAP_SYS_ADMIN))
    2254             :                         return -EPERM;
    2255             : 
    2256           0 :                 if (xfs_is_readonly(mp))
    2257             :                         return -EROFS;
    2258             : 
    2259           0 :                 if (copy_from_user(&eofb, arg, sizeof(eofb)))
    2260             :                         return -EFAULT;
    2261             : 
    2262           0 :                 error = xfs_fs_eofblocks_from_user(&eofb, &icw);
    2263           0 :                 if (error)
    2264           0 :                         return error;
    2265             : 
    2266           0 :                 trace_xfs_ioc_free_eofblocks(mp, &icw, _RET_IP_);
    2267             : 
    2268           0 :                 sb_start_write(mp->m_super);
    2269           0 :                 error = xfs_blockgc_free_space(mp, &icw);
    2270           0 :                 sb_end_write(mp->m_super);
    2271           0 :                 return error;
    2272             :         }
    2273             : 
    2274     1703898 :         case XFS_IOC_EXCHANGE_RANGE:
    2275     1703898 :                 return xfs_ioc_exchange_range(filp, arg);
    2276             : 
    2277             :         default:
    2278             :                 return -ENOTTY;
    2279             :         }
    2280             : }

Generated by: LCOV version 1.14