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-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 851 1051 81.0 %
Date: 2023-07-31 20:08:12 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      117338 : xfs_find_handle(
      62             :         unsigned int            cmd,
      63             :         xfs_fsop_handlereq_t    *hreq)
      64             : {
      65      117338 :         int                     hsize;
      66      117338 :         xfs_handle_t            handle;
      67      117338 :         struct inode            *inode;
      68      117338 :         struct fd               f = {NULL};
      69      117338 :         struct path             path;
      70      117338 :         int                     error;
      71      117338 :         struct xfs_inode        *ip;
      72             : 
      73      117338 :         if (cmd == XFS_IOC_FD_TO_HANDLE) {
      74        2398 :                 f = fdget(hreq->fd);
      75        2398 :                 if (!f.file)
      76             :                         return -EBADF;
      77        2398 :                 inode = file_inode(f.file);
      78             :         } else {
      79      114940 :                 error = user_path_at(AT_FDCWD, hreq->path, 0, &path);
      80      114940 :                 if (error)
      81             :                         return error;
      82      114940 :                 inode = d_inode(path.dentry);
      83             :         }
      84      117338 :         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      117338 :         error = -EINVAL;
      91      117338 :         if (inode->i_sb->s_magic != XFS_SB_MAGIC)
      92           0 :                 goto out_put;
      93             : 
      94      117338 :         error = -EBADF;
      95      117338 :         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      117338 :         memcpy(&handle.ha_fsid, ip->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
     102             : 
     103      117338 :         if (cmd == XFS_IOC_PATH_TO_FSHANDLE) {
     104             :                 /*
     105             :                  * This handle only contains an fsid, zero the rest.
     106             :                  */
     107       98346 :                 memset(&handle.ha_fid, 0, sizeof(handle.ha_fid));
     108       98346 :                 hsize = sizeof(xfs_fsid_t);
     109             :         } else {
     110       18992 :                 handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
     111             :                                         sizeof(handle.ha_fid.fid_len);
     112       18992 :                 handle.ha_fid.fid_pad = 0;
     113       18992 :                 handle.ha_fid.fid_gen = inode->i_generation;
     114       18992 :                 handle.ha_fid.fid_ino = ip->i_ino;
     115       18992 :                 hsize = sizeof(xfs_handle_t);
     116             :         }
     117             : 
     118      117338 :         error = -EFAULT;
     119      352014 :         if (copy_to_user(hreq->ohandle, &handle, hsize) ||
     120      117338 :             copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32)))
     121           0 :                 goto out_put;
     122             : 
     123             :         error = 0;
     124             : 
     125      117338 :  out_put:
     126      117338 :         if (cmd == XFS_IOC_FD_TO_HANDLE)
     127        2398 :                 fdput(f);
     128             :         else
     129      114940 :                 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   397741231 : xfs_handle_acceptable(
     139             :         void                    *context,
     140             :         struct dentry           *dentry)
     141             : {
     142   397741231 :         return 1;
     143             : }
     144             : 
     145             : /*
     146             :  * Convert userspace handle data into a dentry.
     147             :  */
     148             : struct dentry *
     149   389563469 : xfs_handle_to_dentry(
     150             :         struct file             *parfilp,
     151             :         void __user             *uhandle,
     152             :         u32                     hlen)
     153             : {
     154   389563469 :         xfs_handle_t            handle;
     155   389563469 :         struct xfs_fid64        fid;
     156             : 
     157             :         /*
     158             :          * Only allow handle opens under a directory.
     159             :          */
     160   389563469 :         if (!S_ISDIR(file_inode(parfilp)->i_mode))
     161             :                 return ERR_PTR(-ENOTDIR);
     162             : 
     163   388904183 :         if (hlen != sizeof(xfs_handle_t))
     164             :                 return ERR_PTR(-EINVAL);
     165   387359372 :         if (copy_from_user(&handle, uhandle, hlen))
     166             :                 return ERR_PTR(-EFAULT);
     167   390501180 :         if (handle.ha_fid.fid_len !=
     168             :             sizeof(handle.ha_fid) - sizeof(handle.ha_fid.fid_len))
     169             :                 return ERR_PTR(-EINVAL);
     170             : 
     171   392428171 :         memset(&fid, 0, sizeof(struct fid));
     172   392428171 :         fid.ino = handle.ha_fid.fid_ino;
     173   392428171 :         fid.gen = handle.ha_fid.fid_gen;
     174             : 
     175   392428171 :         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   393573814 : xfs_handlereq_to_dentry(
     182             :         struct file             *parfilp,
     183             :         xfs_fsop_handlereq_t    *hreq)
     184             : {
     185   393573814 :         return xfs_handle_to_dentry(parfilp, hreq->ihandle, hreq->ihandlen);
     186             : }
     187             : 
     188             : int
     189    88184398 : xfs_open_by_handle(
     190             :         struct file             *parfilp,
     191             :         xfs_fsop_handlereq_t    *hreq)
     192             : {
     193    88184398 :         const struct cred       *cred = current_cred();
     194    88184398 :         int                     error;
     195    88184398 :         int                     fd;
     196    88184398 :         int                     permflag;
     197    88184398 :         struct file             *filp;
     198    88184398 :         struct inode            *inode;
     199    88184398 :         struct dentry           *dentry;
     200    88184398 :         fmode_t                 fmode;
     201    88184398 :         struct path             path;
     202             : 
     203    88184398 :         if (!capable(CAP_SYS_ADMIN))
     204             :                 return -EPERM;
     205             : 
     206    87783507 :         dentry = xfs_handlereq_to_dentry(parfilp, hreq);
     207    88322871 :         if (IS_ERR(dentry))
     208       11443 :                 return PTR_ERR(dentry);
     209    88311428 :         inode = d_inode(dentry);
     210             : 
     211             :         /* Restrict xfs_open_by_handle to directories & regular files. */
     212    88311428 :         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    88311428 :         hreq->oflags |= O_LARGEFILE;
     219             : #endif
     220             : 
     221    88311428 :         permflag = hreq->oflags;
     222    88311428 :         fmode = OPEN_FMODE(permflag);
     223    88311428 :         if ((!(permflag & O_APPEND) || (permflag & O_TRUNC)) &&
     224    88311384 :             (fmode & FMODE_WRITE) && IS_APPEND(inode)) {
     225          66 :                 error = -EPERM;
     226          66 :                 goto out_dput;
     227             :         }
     228             : 
     229    88311362 :         if ((fmode & FMODE_WRITE) && IS_IMMUTABLE(inode)) {
     230          88 :                 error = -EPERM;
     231          88 :                 goto out_dput;
     232             :         }
     233             : 
     234             :         /* Can't write directories. */
     235    88311274 :         if (S_ISDIR(inode->i_mode) && (fmode & FMODE_WRITE)) {
     236           0 :                 error = -EISDIR;
     237           0 :                 goto out_dput;
     238             :         }
     239             : 
     240    88311274 :         fd = get_unused_fd_flags(0);
     241    89116718 :         if (fd < 0) {
     242           0 :                 error = fd;
     243           0 :                 goto out_dput;
     244             :         }
     245             : 
     246    89116718 :         path.mnt = parfilp->f_path.mnt;
     247    89116718 :         path.dentry = dentry;
     248    89116718 :         filp = dentry_open(&path, hreq->oflags, cred);
     249    88200118 :         dput(dentry);
     250    88224300 :         if (IS_ERR(filp)) {
     251           0 :                 put_unused_fd(fd);
     252           0 :                 return PTR_ERR(filp);
     253             :         }
     254             : 
     255    88224300 :         if (S_ISREG(inode->i_mode)) {
     256    67308932 :                 filp->f_flags |= O_NOATIME;
     257    67308932 :                 filp->f_mode |= FMODE_NOCMTIME;
     258             :         }
     259             : 
     260    88224300 :         fd_install(fd, filp);
     261    88224300 :         return fd;
     262             : 
     263         154 :  out_dput:
     264         154 :         dput(dentry);
     265         154 :         return error;
     266             : }
     267             : 
     268             : int
     269        1000 : xfs_readlink_by_handle(
     270             :         struct file             *parfilp,
     271             :         xfs_fsop_handlereq_t    *hreq)
     272             : {
     273        1000 :         struct dentry           *dentry;
     274        1000 :         __u32                   olen;
     275        1000 :         int                     error;
     276             : 
     277        1000 :         if (!capable(CAP_SYS_ADMIN))
     278             :                 return -EPERM;
     279             : 
     280        1000 :         dentry = xfs_handlereq_to_dentry(parfilp, hreq);
     281        1000 :         if (IS_ERR(dentry))
     282           0 :                 return PTR_ERR(dentry);
     283             : 
     284             :         /* Restrict this handle operation to symlinks only. */
     285        1000 :         if (!d_is_symlink(dentry)) {
     286          11 :                 error = -EINVAL;
     287          11 :                 goto out_dput;
     288             :         }
     289             : 
     290         989 :         if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) {
     291           0 :                 error = -EFAULT;
     292           0 :                 goto out_dput;
     293             :         }
     294             : 
     295         989 :         error = vfs_readlink(dentry, hreq->ohandle, olen);
     296             : 
     297        1000 :  out_dput:
     298        1000 :         dput(dentry);
     299        1000 :         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   410970694 : 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   410970694 :         struct xfs_attrlist     *alist = context->buffer;
     317   410970694 :         struct xfs_attrlist_ent *aep;
     318   410970694 :         int                     arraytop;
     319             : 
     320   410970694 :         ASSERT(!context->seen_enough);
     321   410970694 :         ASSERT(context->count >= 0);
     322   410970694 :         ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
     323   410970694 :         ASSERT(context->firstu >= sizeof(*alist));
     324   410970694 :         ASSERT(context->firstu <= context->bufsize);
     325             : 
     326             :         /*
     327             :          * Only list entries in the right namespace.
     328             :          */
     329   410970694 :         if (context->attr_filter != (flags & XFS_ATTR_NSP_ONDISK_MASK))
     330             :                 return;
     331             : 
     332    25827273 :         arraytop = sizeof(*alist) +
     333    25827273 :                         context->count * sizeof(alist->al_offset[0]);
     334             : 
     335             :         /* decrement by the actual bytes used by the attr */
     336    25827273 :         context->firstu -= round_up(offsetof(struct xfs_attrlist_ent, a_name) +
     337             :                         namelen + 1, sizeof(uint32_t));
     338    25827273 :         if (context->firstu < arraytop) {
     339        1088 :                 trace_xfs_attr_list_full(context);
     340        1088 :                 alist->al_more = 1;
     341        1088 :                 context->seen_enough = 1;
     342        1088 :                 return;
     343             :         }
     344             : 
     345    25826185 :         aep = context->buffer + context->firstu;
     346    25826185 :         aep->a_valuelen = valuelen;
     347    51652370 :         memcpy(aep->a_name, name, namelen);
     348    25826185 :         aep->a_name[namelen] = 0;
     349    25826185 :         alist->al_offset[context->count++] = context->firstu;
     350    25826185 :         alist->al_count = context->count;
     351    25826185 :         trace_xfs_attr_list_add(context);
     352             : }
     353             : 
     354             : static unsigned int
     355             : xfs_attr_filter(
     356             :         u32                     ioc_flags)
     357             : {
     358   310627754 :         if (ioc_flags & XFS_IOC_ATTR_ROOT)
     359             :                 return XFS_ATTR_ROOT;
     360   206863972 :         if (ioc_flags & XFS_IOC_ATTR_SECURE)
     361   103807390 :                 return XFS_ATTR_SECURE;
     362             :         return 0;
     363             : }
     364             : 
     365             : static unsigned int
     366             : xfs_attr_flags(
     367             :         u32                     ioc_flags)
     368             : {
     369         770 :         if (ioc_flags & XFS_IOC_ATTR_CREATE)
     370             :                 return XATTR_CREATE;
     371         770 :         if (ioc_flags & XFS_IOC_ATTR_REPLACE)
     372           0 :                 return XATTR_REPLACE;
     373             :         return 0;
     374             : }
     375             : 
     376             : int
     377   308641094 : 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   308641094 :         struct xfs_attr_list_context    context = { };
     385   308641094 :         struct xfs_attrlist             *alist;
     386   308641094 :         void                            *buffer;
     387   308641094 :         int                             error;
     388             : 
     389   308641094 :         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   308641094 :         if (flags & ~(XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
     397             :                 return -EINVAL;
     398   308641094 :         if (flags == (XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
     399             :                 return -EINVAL;
     400             : 
     401             :         /*
     402             :          * Validate the cursor.
     403             :          */
     404   308641094 :         if (copy_from_user(&context.cursor, ucursor, sizeof(context.cursor)))
     405             :                 return -EFAULT;
     406   303857049 :         if (context.cursor.pad1 || context.cursor.pad2)
     407             :                 return -EINVAL;
     408   303857049 :         if (!context.cursor.initted &&
     409   303855961 :             (context.cursor.hashval || context.cursor.blkno ||
     410   303855961 :              context.cursor.offset))
     411             :                 return -EINVAL;
     412             : 
     413   303857049 :         buffer = kvzalloc(bufsize, GFP_KERNEL);
     414   310626984 :         if (!buffer)
     415             :                 return -ENOMEM;
     416             : 
     417             :         /*
     418             :          * Initialize the output buffer.
     419             :          */
     420   310626984 :         context.dp = dp;
     421   310626984 :         context.resynch = 1;
     422   310626984 :         context.attr_filter = xfs_attr_filter(flags);
     423   310626984 :         context.buffer = buffer;
     424   310626984 :         context.bufsize = round_down(bufsize, sizeof(uint32_t));
     425   310626984 :         context.firstu = context.bufsize;
     426   310626984 :         context.put_listent = xfs_ioc_attr_put_listent;
     427             : 
     428   310626984 :         alist = context.buffer;
     429   310626984 :         alist->al_count = 0;
     430   310626984 :         alist->al_more = 0;
     431   310626984 :         alist->al_offset[0] = context.bufsize;
     432             : 
     433   310626984 :         error = xfs_attr_list(&context);
     434   298140708 :         if (error)
     435           0 :                 goto out_free;
     436             : 
     437   912013857 :         if (copy_to_user(ubuf, buffer, bufsize) ||
     438             :             copy_to_user(ucursor, &context.cursor, sizeof(context.cursor)))
     439             :                 error = -EFAULT;
     440   306255323 : out_free:
     441   306255323 :         kmem_free(buffer);
     442   306255323 :         return error;
     443             : }
     444             : 
     445             : STATIC int
     446   303988493 : xfs_attrlist_by_handle(
     447             :         struct file             *parfilp,
     448             :         struct xfs_fsop_attrlist_handlereq __user *p)
     449             : {
     450   303988493 :         struct xfs_fsop_attrlist_handlereq al_hreq;
     451   303988493 :         struct dentry           *dentry;
     452   303988493 :         int                     error = -ENOMEM;
     453             : 
     454   303988493 :         if (!capable(CAP_SYS_ADMIN))
     455             :                 return -EPERM;
     456   305525117 :         if (copy_from_user(&al_hreq, p, sizeof(al_hreq)))
     457             :                 return -EFAULT;
     458             : 
     459   307954561 :         dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
     460   309218250 :         if (IS_ERR(dentry))
     461         476 :                 return PTR_ERR(dentry);
     462             : 
     463   309217774 :         error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), al_hreq.buffer,
     464   309217774 :                                   al_hreq.buflen, al_hreq.flags, &p->pos);
     465   312692748 :         dput(dentry);
     466   312692748 :         return error;
     467             : }
     468             : 
     469             : static int
     470         770 : 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        2310 :         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         770 :                 .valuelen       = *len,
     484         770 :                 .owner          = XFS_I(inode)->i_ino,
     485             :         };
     486         770 :         int                     error;
     487             : 
     488         770 :         if (*len > XFS_XATTR_SIZE_MAX)
     489             :                 return -EINVAL;
     490             : 
     491         770 :         error = xfs_attr_get(&args);
     492         770 :         if (error)
     493           0 :                 goto out_kfree;
     494             : 
     495         770 :         *len = args.valuelen;
     496        1540 :         if (copy_to_user(ubuf, args.value, args.valuelen))
     497           0 :                 error = -EFAULT;
     498             : 
     499         770 : out_kfree:
     500         770 :         kmem_free(args.value);
     501         770 :         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         770 : 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         770 :         unsigned char           *name;
     552         770 :         int                     error;
     553             : 
     554         770 :         if ((flags & XFS_IOC_ATTR_ROOT) && (flags & XFS_IOC_ATTR_SECURE))
     555             :                 return -EINVAL;
     556             : 
     557         770 :         name = strndup_user(uname, MAXNAMELEN);
     558         770 :         if (IS_ERR(name))
     559           0 :                 return PTR_ERR(name);
     560             : 
     561         770 :         switch (opcode) {
     562         770 :         case ATTR_OP_GET:
     563         770 :                 error = xfs_attrmulti_attr_get(inode, name, value, len, flags);
     564         770 :                 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         770 :         kfree(name);
     582         770 :         return error;
     583             : }
     584             : 
     585             : STATIC int
     586         733 : xfs_attrmulti_by_handle(
     587             :         struct file             *parfilp,
     588             :         void                    __user *arg)
     589             : {
     590         733 :         int                     error;
     591         733 :         xfs_attr_multiop_t      *ops;
     592         733 :         xfs_fsop_attrmulti_handlereq_t am_hreq;
     593         733 :         struct dentry           *dentry;
     594         733 :         unsigned int            i, size;
     595             : 
     596         733 :         if (!capable(CAP_SYS_ADMIN))
     597             :                 return -EPERM;
     598         733 :         if (copy_from_user(&am_hreq, arg, sizeof(xfs_fsop_attrmulti_handlereq_t)))
     599             :                 return -EFAULT;
     600             : 
     601             :         /* overflow check */
     602         733 :         if (am_hreq.opcount >= INT_MAX / sizeof(xfs_attr_multiop_t))
     603             :                 return -E2BIG;
     604             : 
     605         733 :         dentry = xfs_handlereq_to_dentry(parfilp, &am_hreq.hreq);
     606         733 :         if (IS_ERR(dentry))
     607           0 :                 return PTR_ERR(dentry);
     608             : 
     609         733 :         error = -E2BIG;
     610         733 :         size = am_hreq.opcount * sizeof(xfs_attr_multiop_t);
     611         733 :         if (!size || size > 16 * PAGE_SIZE)
     612           0 :                 goto out_dput;
     613             : 
     614         733 :         ops = memdup_user(am_hreq.ops, size);
     615         733 :         if (IS_ERR(ops)) {
     616           0 :                 error = PTR_ERR(ops);
     617           0 :                 goto out_dput;
     618             :         }
     619             : 
     620             :         error = 0;
     621        1503 :         for (i = 0; i < am_hreq.opcount; i++) {
     622         770 :                 ops[i].am_error = xfs_ioc_attrmulti_one(parfilp,
     623             :                                 d_inode(dentry), ops[i].am_opcode,
     624             :                                 ops[i].am_attrname, ops[i].am_attrvalue,
     625         770 :                                 &ops[i].am_length, ops[i].am_flags);
     626             :         }
     627             : 
     628        1466 :         if (copy_to_user(am_hreq.ops, ops, size))
     629           0 :                 error = -EFAULT;
     630             : 
     631         733 :         kfree(ops);
     632         733 :  out_dput:
     633         733 :         dput(dentry);
     634         733 :         return error;
     635             : }
     636             : 
     637             : /* Return 0 on success or positive error */
     638             : int
     639 72403776113 : xfs_fsbulkstat_one_fmt(
     640             :         struct xfs_ibulk                *breq,
     641             :         const struct xfs_bulkstat       *bstat)
     642             : {
     643 72403776113 :         struct xfs_bstat                bs1;
     644             : 
     645 72403776113 :         xfs_bulkstat_to_bstat(breq->mp, &bs1, bstat);
     646 72361850476 :         if (copy_to_user(breq->ubuffer, &bs1, sizeof(bs1)))
     647             :                 return -EFAULT;
     648 72632300141 :         return xfs_ibulk_advance(breq, sizeof(struct xfs_bstat));
     649             : }
     650             : 
     651             : int
     652       71975 : xfs_fsinumbers_fmt(
     653             :         struct xfs_ibulk                *breq,
     654             :         const struct xfs_inumbers       *igrp)
     655             : {
     656       71975 :         struct xfs_inogrp               ig1;
     657             : 
     658       71975 :         xfs_inumbers_to_inogrp(&ig1, igrp);
     659       71975 :         if (copy_to_user(breq->ubuffer, &ig1, sizeof(struct xfs_inogrp)))
     660             :                 return -EFAULT;
     661       71975 :         return xfs_ibulk_advance(breq, sizeof(struct xfs_inogrp));
     662             : }
     663             : 
     664             : STATIC int
     665   477862008 : xfs_ioc_fsbulkstat(
     666             :         struct file             *file,
     667             :         unsigned int            cmd,
     668             :         void                    __user *arg)
     669             : {
     670   477862008 :         struct xfs_mount        *mp = XFS_I(file_inode(file))->i_mount;
     671   477862008 :         struct xfs_fsop_bulkreq bulkreq;
     672   477862008 :         struct xfs_ibulk        breq = {
     673             :                 .mp             = mp,
     674             :                 .idmap          = file_mnt_idmap(file),
     675             :                 .ocount         = 0,
     676             :         };
     677   477887845 :         xfs_ino_t               lastino;
     678   477887845 :         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   477887845 :         if (!capable(CAP_SYS_ADMIN))
     684             :                 return -EPERM;
     685             : 
     686   955713552 :         if (xfs_is_shutdown(mp))
     687             :                 return -EIO;
     688             : 
     689   477845872 :         if (copy_from_user(&bulkreq, arg, sizeof(struct xfs_fsop_bulkreq)))
     690             :                 return -EFAULT;
     691             : 
     692   477900218 :         if (copy_from_user(&lastino, bulkreq.lastip, sizeof(__s64)))
     693             :                 return -EFAULT;
     694             : 
     695   477844273 :         if (bulkreq.icount <= 0)
     696             :                 return -EINVAL;
     697             : 
     698   477844273 :         if (bulkreq.ubuffer == NULL)
     699             :                 return -EINVAL;
     700             : 
     701   477844273 :         breq.ubuffer = bulkreq.ubuffer;
     702   477844273 :         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   477844273 :         if (cmd == XFS_IOC_FSINUMBERS) {
     716       16943 :                 breq.startino = lastino ? lastino + 1 : 0;
     717       16943 :                 error = xfs_inumbers(&breq, xfs_fsinumbers_fmt);
     718       16943 :                 lastino = breq.startino - 1;
     719   477827330 :         } else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE) {
     720     1808433 :                 breq.startino = lastino;
     721     1808433 :                 breq.icount = 1;
     722     1808433 :                 error = xfs_bulkstat_one(&breq, xfs_fsbulkstat_one_fmt);
     723             :         } else {        /* XFS_IOC_FSBULKSTAT */
     724   476018897 :                 breq.startino = lastino ? lastino + 1 : 0;
     725   476018897 :                 error = xfs_bulkstat(&breq, xfs_fsbulkstat_one_fmt);
     726   476088967 :                 lastino = breq.startino - 1;
     727             :         }
     728             : 
     729   477914477 :         if (error)
     730             :                 return error;
     731             : 
     732   953969467 :         if (bulkreq.lastip != NULL &&
     733             :             copy_to_user(bulkreq.lastip, &lastino, sizeof(xfs_ino_t)))
     734             :                 return -EFAULT;
     735             : 
     736   953120001 :         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   338410159 : xfs_bulkstat_fmt(
     746             :         struct xfs_ibulk                *breq,
     747             :         const struct xfs_bulkstat       *bstat)
     748             : {
     749   676871345 :         if (copy_to_user(breq->ubuffer, bstat, sizeof(struct xfs_bulkstat)))
     750           0 :                 return -EFAULT;
     751   338461186 :         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    16606369 : 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    16606369 :         if (hdr->icount == 0 ||
     768    33213282 :             (hdr->flags & ~XFS_BULK_IREQ_FLAGS_ALL) ||
     769    16606369 :             memchr_inv(hdr->reserved, 0, sizeof(hdr->reserved)))
     770           0 :                 return -EINVAL;
     771             : 
     772    16606913 :         breq->startino = hdr->ino;
     773    16606913 :         breq->ubuffer = ubuffer;
     774    16606913 :         breq->icount = hdr->icount;
     775    16606913 :         breq->ocount = 0;
     776    16606913 :         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    16606913 :         if (hdr->flags & XFS_BULK_IREQ_SPECIAL) {
     784          21 :                 if (hdr->flags & XFS_BULK_IREQ_AGNO)
     785             :                         return -EINVAL;
     786             : 
     787          21 :                 switch (hdr->ino) {
     788          21 :                 case XFS_BULK_IREQ_SPECIAL_ROOT:
     789          21 :                         breq->startino = mp->m_sb.sb_rootino;
     790          21 :                         break;
     791             :                 default:
     792             :                         return -EINVAL;
     793             :                 }
     794          21 :                 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    16606913 :         if (hdr->flags & XFS_BULK_IREQ_AGNO) {
     803     5741985 :                 if (hdr->agno >= mp->m_sb.sb_agcount)
     804             :                         return -EINVAL;
     805             : 
     806     5741985 :                 if (breq->startino == 0)
     807      435777 :                         breq->startino = XFS_AGINO_TO_INO(mp, hdr->agno, 0);
     808     5306208 :                 else if (XFS_INO_TO_AGNO(mp, breq->startino) < hdr->agno)
     809             :                         return -EINVAL;
     810             : 
     811     5741985 :                 breq->flags |= XFS_IBULK_SAME_AG;
     812             : 
     813             :                 /* Asking for an inode past the end of the AG?  We're done! */
     814     5741985 :                 if (XFS_INO_TO_AGNO(mp, breq->startino) > hdr->agno)
     815             :                         return -ECANCELED;
     816    10864928 :         } else if (hdr->agno)
     817             :                 return -EINVAL;
     818             : 
     819             :         /* Asking for an inode past the end of the FS?  We're done! */
     820    16606898 :         if (XFS_INO_TO_AGNO(mp, breq->startino) >= mp->m_sb.sb_agcount)
     821             :                 return -ECANCELED;
     822             : 
     823    16606843 :         if (hdr->flags & XFS_BULK_IREQ_NREXT64)
     824    10898392 :                 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    16601250 :         hdr->ino = breq->startino;
     839    16601250 :         hdr->ocount = breq->ocount;
     840             : }
     841             : 
     842             : /* Handle the v5 bulkstat ioctl. */
     843             : STATIC int
     844    10952460 : xfs_ioc_bulkstat(
     845             :         struct file                     *file,
     846             :         unsigned int                    cmd,
     847             :         struct xfs_bulkstat_req __user  *arg)
     848             : {
     849    10952460 :         struct xfs_mount                *mp = XFS_I(file_inode(file))->i_mount;
     850    10952460 :         struct xfs_bulk_ireq            hdr;
     851    10952460 :         struct xfs_ibulk                breq = {
     852             :                 .mp                     = mp,
     853             :                 .idmap                  = file_mnt_idmap(file),
     854             :         };
     855    10952343 :         int                             error;
     856             : 
     857    10952343 :         if (!capable(CAP_SYS_ADMIN))
     858             :                 return -EPERM;
     859             : 
     860    21904796 :         if (xfs_is_shutdown(mp))
     861             :                 return -EIO;
     862             : 
     863    10952398 :         if (copy_from_user(&hdr, &arg->hdr, sizeof(hdr)))
     864             :                 return -EFAULT;
     865             : 
     866    10952592 :         error = xfs_bulk_ireq_setup(mp, &hdr, &breq, arg->bulkstat);
     867    10951586 :         if (error == -ECANCELED)
     868          55 :                 goto out_teardown;
     869    10951531 :         if (error < 0)
     870             :                 return error;
     871             : 
     872    10951531 :         error = xfs_bulkstat(&breq, xfs_bulkstat_fmt);
     873    10952643 :         if (error)
     874             :                 return error;
     875             : 
     876    10952632 : out_teardown:
     877    10952687 :         xfs_bulk_ireq_teardown(&hdr, &breq);
     878    10952687 :         if (copy_to_user(&arg->hdr, &hdr, sizeof(hdr)))
     879           0 :                 return -EFAULT;
     880             : 
     881             :         return 0;
     882             : }
     883             : 
     884             : STATIC int
     885     8051828 : xfs_inumbers_fmt(
     886             :         struct xfs_ibulk                *breq,
     887             :         const struct xfs_inumbers       *igrp)
     888             : {
     889    16113561 :         if (copy_to_user(breq->ubuffer, igrp, sizeof(struct xfs_inumbers)))
     890           0 :                 return -EFAULT;
     891     8061733 :         return xfs_ibulk_advance(breq, sizeof(struct xfs_inumbers));
     892             : }
     893             : 
     894             : /* Handle the v5 inumbers ioctl. */
     895             : STATIC int
     896     5656079 : xfs_ioc_inumbers(
     897             :         struct xfs_mount                *mp,
     898             :         unsigned int                    cmd,
     899             :         struct xfs_inumbers_req __user  *arg)
     900             : {
     901     5656079 :         struct xfs_bulk_ireq            hdr;
     902     5656079 :         struct xfs_ibulk                breq = {
     903             :                 .mp                     = mp,
     904             :         };
     905     5656079 :         int                             error;
     906             : 
     907     5656079 :         if (!capable(CAP_SYS_ADMIN))
     908             :                 return -EPERM;
     909             : 
     910    11310586 :         if (xfs_is_shutdown(mp))
     911             :                 return -EIO;
     912             : 
     913     5655293 :         if (copy_from_user(&hdr, &arg->hdr, sizeof(hdr)))
     914             :                 return -EFAULT;
     915             : 
     916     5655760 :         error = xfs_bulk_ireq_setup(mp, &hdr, &breq, arg->inumbers);
     917     5650098 :         if (error == -ECANCELED)
     918          15 :                 goto out_teardown;
     919     5650083 :         if (error < 0)
     920             :                 return error;
     921             : 
     922     5650083 :         error = xfs_inumbers(&breq, xfs_inumbers_fmt);
     923     5648548 :         if (error)
     924             :                 return error;
     925             : 
     926     5648548 : out_teardown:
     927     5648563 :         xfs_bulk_ireq_teardown(&hdr, &breq);
     928     5648563 :         if (copy_to_user(&arg->hdr, &hdr, sizeof(hdr)))
     929           0 :                 return -EFAULT;
     930             : 
     931             :         return 0;
     932             : }
     933             : 
     934             : STATIC int
     935     5660700 : xfs_ioc_fsgeometry(
     936             :         struct xfs_mount        *mp,
     937             :         void                    __user *arg,
     938             :         int                     struct_version)
     939             : {
     940     5660700 :         struct xfs_fsop_geom    fsgeo;
     941     5660700 :         size_t                  len;
     942             : 
     943     5660700 :         xfs_fs_geometry(mp, &fsgeo, struct_version);
     944             : 
     945     5641852 :         if (struct_version <= 3)
     946             :                 len = sizeof(struct xfs_fsop_geom_v1);
     947     5641164 :         else if (struct_version == 4)
     948             :                 len = sizeof(struct xfs_fsop_geom_v4);
     949             :         else {
     950     5641486 :                 xfs_fsop_geom_health(mp, &fsgeo);
     951     5641486 :                 len = sizeof(fsgeo);
     952             :         }
     953             : 
     954    11315917 :         if (copy_to_user(arg, &fsgeo, len))
     955           0 :                 return -EFAULT;
     956             :         return 0;
     957             : }
     958             : 
     959             : STATIC int
     960       70463 : xfs_ioc_ag_geometry(
     961             :         struct xfs_mount        *mp,
     962             :         void                    __user *arg)
     963             : {
     964       70463 :         struct xfs_perag        *pag;
     965       70463 :         struct xfs_ag_geometry  ageo;
     966       70463 :         int                     error;
     967             : 
     968       70463 :         if (copy_from_user(&ageo, arg, sizeof(ageo)))
     969             :                 return -EFAULT;
     970       70463 :         if (ageo.ag_flags)
     971             :                 return -EINVAL;
     972       70463 :         if (memchr_inv(&ageo.ag_reserved, 0, sizeof(ageo.ag_reserved)))
     973             :                 return -EINVAL;
     974             : 
     975       70463 :         pag = xfs_perag_get(mp, ageo.ag_number);
     976       70463 :         if (!pag)
     977             :                 return -EINVAL;
     978             : 
     979       70463 :         error = xfs_ag_get_geometry(pag, &ageo);
     980       70463 :         xfs_perag_put(pag);
     981       70463 :         if (error)
     982             :                 return error;
     983             : 
     984       70463 :         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     3793398 : xfs_fill_fsxattr(
     995             :         struct xfs_inode        *ip,
     996             :         int                     whichfork,
     997             :         struct fileattr         *fa)
     998             : {
     999     3793398 :         struct xfs_mount        *mp = ip->i_mount;
    1000     3793398 :         struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
    1001             : 
    1002     3793339 :         fileattr_fill_xflags(fa, xfs_ip2xflags(ip));
    1003             : 
    1004     3793302 :         if (ip->i_diflags & XFS_DIFLAG_EXTSIZE) {
    1005         107 :                 fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);
    1006     3793195 :         } 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          42 :                 if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
    1013          18 :                     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          42 :                         fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);
    1019             :                 }
    1020             :         }
    1021             : 
    1022     3793302 :         if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)
    1023         716 :                 fa->fsx_cowextsize = XFS_FSB_TO_B(mp, ip->i_cowextsize);
    1024     3793302 :         fa->fsx_projid = ip->i_projid;
    1025     7584624 :         if (ifp && !xfs_need_iread_extents(ifp))
    1026     3791264 :                 fa->fsx_nextents = xfs_iext_count(ifp);
    1027             :         else
    1028        2163 :                 fa->fsx_nextents = xfs_ifork_nextents(ifp);
    1029     3793346 : }
    1030             : 
    1031             : STATIC int
    1032       27107 : xfs_ioc_fsgetxattra(
    1033             :         xfs_inode_t             *ip,
    1034             :         void                    __user *arg)
    1035             : {
    1036       27107 :         struct fileattr         fa;
    1037             : 
    1038       27107 :         xfs_ilock(ip, XFS_ILOCK_SHARED);
    1039       27107 :         xfs_fill_fsxattr(ip, XFS_ATTR_FORK, &fa);
    1040       27107 :         xfs_iunlock(ip, XFS_ILOCK_SHARED);
    1041             : 
    1042       27107 :         return copy_fsxattr_to_user(&fa, arg);
    1043             : }
    1044             : 
    1045             : int
    1046     3766325 : xfs_fileattr_get(
    1047             :         struct dentry           *dentry,
    1048             :         struct fileattr         *fa)
    1049             : {
    1050     3766325 :         struct xfs_inode        *ip = XFS_I(d_inode(dentry));
    1051             : 
    1052     3766325 :         if (d_is_special(dentry))
    1053             :                 return -ENOTTY;
    1054             : 
    1055     3766325 :         xfs_ilock(ip, XFS_ILOCK_SHARED);
    1056     3766319 :         xfs_fill_fsxattr(ip, XFS_DATA_FORK, fa);
    1057     3766232 :         xfs_iunlock(ip, XFS_ILOCK_SHARED);
    1058             : 
    1059     3766232 :         return 0;
    1060             : }
    1061             : 
    1062             : STATIC uint16_t
    1063     2471783 : xfs_flags2diflags(
    1064             :         struct xfs_inode        *ip,
    1065             :         unsigned int            xflags)
    1066             : {
    1067             :         /* can't set PREALLOC this way, just preserve it */
    1068     2471783 :         uint16_t                di_flags =
    1069     2471783 :                 (ip->i_diflags & XFS_DIFLAG_PREALLOC);
    1070             : 
    1071     2471783 :         if (xflags & FS_XFLAG_IMMUTABLE)
    1072         367 :                 di_flags |= XFS_DIFLAG_IMMUTABLE;
    1073     2471783 :         if (xflags & FS_XFLAG_APPEND)
    1074         276 :                 di_flags |= XFS_DIFLAG_APPEND;
    1075     2471783 :         if (xflags & FS_XFLAG_SYNC)
    1076         133 :                 di_flags |= XFS_DIFLAG_SYNC;
    1077     2471783 :         if (xflags & FS_XFLAG_NOATIME)
    1078          56 :                 di_flags |= XFS_DIFLAG_NOATIME;
    1079     2471783 :         if (xflags & FS_XFLAG_NODUMP)
    1080          77 :                 di_flags |= XFS_DIFLAG_NODUMP;
    1081     2471783 :         if (xflags & FS_XFLAG_NODEFRAG)
    1082           2 :                 di_flags |= XFS_DIFLAG_NODEFRAG;
    1083     2471783 :         if (xflags & FS_XFLAG_FILESTREAM)
    1084        5075 :                 di_flags |= XFS_DIFLAG_FILESTREAM;
    1085     2471783 :         if (S_ISDIR(VFS_I(ip)->i_mode)) {
    1086       51089 :                 if (xflags & FS_XFLAG_RTINHERIT)
    1087       19030 :                         di_flags |= XFS_DIFLAG_RTINHERIT;
    1088       51089 :                 if (xflags & FS_XFLAG_NOSYMLINKS)
    1089          33 :                         di_flags |= XFS_DIFLAG_NOSYMLINKS;
    1090       51089 :                 if (xflags & FS_XFLAG_EXTSZINHERIT)
    1091         209 :                         di_flags |= XFS_DIFLAG_EXTSZINHERIT;
    1092       51089 :                 if (xflags & FS_XFLAG_PROJINHERIT)
    1093        3474 :                         di_flags |= XFS_DIFLAG_PROJINHERIT;
    1094     2420694 :         } else if (S_ISREG(VFS_I(ip)->i_mode)) {
    1095     2420694 :                 if (xflags & FS_XFLAG_REALTIME)
    1096      741213 :                         di_flags |= XFS_DIFLAG_REALTIME;
    1097     2420694 :                 if (xflags & FS_XFLAG_EXTSIZE)
    1098         180 :                         di_flags |= XFS_DIFLAG_EXTSIZE;
    1099             :         }
    1100             : 
    1101     2471783 :         return di_flags;
    1102             : }
    1103             : 
    1104             : STATIC uint64_t
    1105     1740783 : xfs_flags2diflags2(
    1106             :         struct xfs_inode        *ip,
    1107             :         unsigned int            xflags)
    1108             : {
    1109     1740783 :         uint64_t                di_flags2 =
    1110     1740783 :                 (ip->i_diflags2 & (XFS_DIFLAG2_REFLINK |
    1111             :                                    XFS_DIFLAG2_BIGTIME |
    1112             :                                    XFS_DIFLAG2_NREXT64));
    1113             : 
    1114     1740783 :         if (xflags & FS_XFLAG_DAX)
    1115         134 :                 di_flags2 |= XFS_DIFLAG2_DAX;
    1116     1740783 :         if (xflags & FS_XFLAG_COWEXTSIZE)
    1117         736 :                 di_flags2 |= XFS_DIFLAG2_COWEXTSIZE;
    1118             : 
    1119     1740783 :         return di_flags2;
    1120             : }
    1121             : 
    1122             : static int
    1123     1009773 : xfs_ioctl_setattr_xflags(
    1124             :         struct xfs_trans        *tp,
    1125             :         struct xfs_inode        *ip,
    1126             :         struct fileattr         *fa)
    1127             : {
    1128     1009773 :         struct xfs_mount        *mp = ip->i_mount;
    1129     1009773 :         uint64_t                i_flags2;
    1130             : 
    1131             :         /* Can't change realtime flag if any extents are allocated. */
    1132     1009773 :         if ((ip->i_df.if_nextents || ip->i_delayed_blks) &&
    1133      959250 :             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     1009773 :         if (fa->fsx_xflags & FS_XFLAG_REALTIME) {
    1138      315575 :                 if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||
    1139      315575 :                     (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     1009773 :         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     1009773 :         i_flags2 = xfs_flags2diflags2(ip, fa->fsx_xflags);
    1149     1009773 :         if (i_flags2 && !xfs_has_v3inodes(mp))
    1150             :                 return -EINVAL;
    1151             : 
    1152     1009773 :         ip->i_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);
    1153     1009773 :         ip->i_diflags2 = i_flags2;
    1154             : 
    1155     1009773 :         xfs_diflags_to_iflags(ip, false);
    1156     1009773 :         xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
    1157     1009777 :         xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
    1158     1009793 :         XFS_STATS_INC(mp, xs_ig_attrchg);
    1159     1009792 :         return 0;
    1160             : }
    1161             : 
    1162             : static void
    1163     1009805 : xfs_ioctl_setattr_prepare_dax(
    1164             :         struct xfs_inode        *ip,
    1165             :         struct fileattr         *fa)
    1166             : {
    1167     1009805 :         struct xfs_mount        *mp = ip->i_mount;
    1168     1009805 :         struct inode            *inode = VFS_I(ip);
    1169             : 
    1170     1009805 :         if (S_ISDIR(inode->i_mode))
    1171             :                 return;
    1172             : 
    1173      979442 :         if (xfs_has_dax_always(mp) || xfs_has_dax_never(mp))
    1174             :                 return;
    1175             : 
    1176      979442 :         if (((fa->fsx_xflags & FS_XFLAG_DAX) &&
    1177      979442 :             !(ip->i_diflags2 & XFS_DIFLAG2_DAX)) ||
    1178      979429 :             (!(fa->fsx_xflags & FS_XFLAG_DAX) &&
    1179      979429 :              (ip->i_diflags2 & XFS_DIFLAG2_DAX)))
    1180          22 :                 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     1009798 : xfs_ioctl_setattr_get_trans(
    1191             :         struct xfs_inode        *ip,
    1192             :         struct xfs_dquot        *pdqp)
    1193             : {
    1194     1009798 :         struct xfs_mount        *mp = ip->i_mount;
    1195     1009798 :         struct xfs_trans        *tp;
    1196     1009798 :         int                     error = -EROFS;
    1197             : 
    1198     2019596 :         if (xfs_is_readonly(mp))
    1199           0 :                 goto out_error;
    1200     1009798 :         error = -EIO;
    1201     2019596 :         if (xfs_is_shutdown(mp))
    1202           0 :                 goto out_error;
    1203             : 
    1204     1009798 :         error = xfs_trans_alloc_ichange(ip, NULL, NULL, pdqp,
    1205     1009798 :                         has_capability_noaudit(current, CAP_FOWNER), &tp);
    1206     1009795 :         if (error)
    1207           0 :                 goto out_error;
    1208             : 
    1209     1009795 :         if (xfs_has_wsync(mp))
    1210         456 :                 xfs_trans_set_sync(tp);
    1211             : 
    1212     1009795 :         return tp;
    1213             : 
    1214           0 : out_error:
    1215           0 :         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     1009787 : xfs_ioctl_setattr_check_extsize(
    1224             :         struct xfs_inode        *ip,
    1225             :         struct fileattr         *fa)
    1226             : {
    1227     1009787 :         struct xfs_mount        *mp = ip->i_mount;
    1228     1009787 :         xfs_failaddr_t          failaddr;
    1229     1009787 :         uint16_t                new_diflags;
    1230             : 
    1231     1009787 :         if (!fa->fsx_valid)
    1232             :                 return 0;
    1233             : 
    1234      731029 :         if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_df.if_nextents &&
    1235      538764 :             XFS_FSB_TO_B(mp, ip->i_extsize) != fa->fsx_extsize)
    1236             :                 return -EINVAL;
    1237             : 
    1238      731023 :         if (fa->fsx_extsize & mp->m_blockmask)
    1239             :                 return -EINVAL;
    1240             : 
    1241      731018 :         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      731018 :         if ((new_diflags & XFS_DIFLAG_RTINHERIT) &&
    1250             :             (new_diflags & XFS_DIFLAG_EXTSZINHERIT)) {
    1251          28 :                 unsigned int    rtextsize_bytes;
    1252             : 
    1253          28 :                 rtextsize_bytes = XFS_FSB_TO_B(mp, mp->m_sb.sb_rextsize);
    1254          28 :                 if (fa->fsx_extsize % rtextsize_bytes)
    1255             :                         return -EINVAL;
    1256             :         }
    1257             : 
    1258     1462026 :         failaddr = xfs_inode_validate_extsize(ip->i_mount,
    1259      731013 :                         XFS_B_TO_FSB(mp, fa->fsx_extsize),
    1260      731013 :                         VFS_I(ip)->i_mode, new_diflags);
    1261      731010 :         return failaddr != NULL ? -EINVAL : 0;
    1262             : }
    1263             : 
    1264             : static int
    1265     1009766 : xfs_ioctl_setattr_check_cowextsize(
    1266             :         struct xfs_inode        *ip,
    1267             :         struct fileattr         *fa)
    1268             : {
    1269     1009766 :         struct xfs_mount        *mp = ip->i_mount;
    1270     1009766 :         xfs_failaddr_t          failaddr;
    1271     1009766 :         uint64_t                new_diflags2;
    1272     1009766 :         uint16_t                new_diflags;
    1273             : 
    1274     1009766 :         if (!fa->fsx_valid)
    1275             :                 return 0;
    1276             : 
    1277      731008 :         if (fa->fsx_cowextsize & mp->m_blockmask)
    1278             :                 return -EINVAL;
    1279             : 
    1280      731008 :         new_diflags = xfs_flags2diflags(ip, fa->fsx_xflags);
    1281      731008 :         new_diflags2 = xfs_flags2diflags2(ip, fa->fsx_xflags);
    1282             : 
    1283     1462016 :         failaddr = xfs_inode_validate_cowextsize(ip->i_mount,
    1284      731008 :                         XFS_B_TO_FSB(mp, fa->fsx_cowextsize),
    1285      731008 :                         VFS_I(ip)->i_mode, new_diflags, new_diflags2);
    1286      731009 :         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     1011114 :         if (!fa->fsx_valid)
    1295             :                 return 0;
    1296             : 
    1297             :         /* Disallow 32bit project ids if 32bit IDs are not enabled. */
    1298      732354 :         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     1032501 : xfs_fileattr_set(
    1306             :         struct mnt_idmap        *idmap,
    1307             :         struct dentry           *dentry,
    1308             :         struct fileattr         *fa)
    1309             : {
    1310     1032501 :         struct xfs_inode        *ip = XFS_I(d_inode(dentry));
    1311     1032501 :         struct xfs_mount        *mp = ip->i_mount;
    1312     1032501 :         struct xfs_trans        *tp;
    1313     1032501 :         struct xfs_dquot        *pdqp = NULL;
    1314     1032501 :         struct xfs_dquot        *olddquot = NULL;
    1315     1032501 :         int                     error;
    1316             : 
    1317     1032501 :         trace_xfs_ioctl_setattr(ip);
    1318             : 
    1319     1032491 :         if (d_is_special(dentry))
    1320             :                 return -ENOTTY;
    1321             : 
    1322     1032491 :         if (!fa->fsx_valid) {
    1323      300135 :                 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     1011114 :         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     1011114 :         if (fa->fsx_valid && XFS_IS_QUOTA_ON(mp)) {
    1342      480393 :                 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      480403 :                 if (error)
    1346             :                         return error;
    1347             :         }
    1348             : 
    1349     1009800 :         xfs_ioctl_setattr_prepare_dax(ip, fa);
    1350             : 
    1351     1009806 :         tp = xfs_ioctl_setattr_get_trans(ip, pdqp);
    1352     1009789 :         if (IS_ERR(tp)) {
    1353           0 :                 error = PTR_ERR(tp);
    1354           0 :                 goto error_free_dquots;
    1355             :         }
    1356             : 
    1357     1009789 :         error = xfs_ioctl_setattr_check_extsize(ip, fa);
    1358     1009780 :         if (error)
    1359          16 :                 goto error_trans_cancel;
    1360             : 
    1361     1009764 :         error = xfs_ioctl_setattr_check_cowextsize(ip, fa);
    1362     1009762 :         if (error)
    1363           0 :                 goto error_trans_cancel;
    1364             : 
    1365     1009762 :         error = xfs_ioctl_setattr_xflags(tp, ip, fa);
    1366     1009793 :         if (error)
    1367           0 :                 goto error_trans_cancel;
    1368             : 
    1369     1009793 :         if (!fa->fsx_valid)
    1370      278758 :                 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      731079 :         if ((VFS_I(ip)->i_mode & (S_ISUID|S_ISGID)) &&
    1380          44 :             !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      731035 :         if (ip->i_projid != fa->fsx_projid) {
    1385      604980 :                 if (XFS_IS_PQUOTA_ON(mp)) {
    1386      406888 :                         olddquot = xfs_qm_vop_chown(tp, ip,
    1387             :                                                 &ip->i_pdquot, pdqp);
    1388             :                 }
    1389      604978 :                 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      731033 :         if (ip->i_diflags & (XFS_DIFLAG_EXTSIZE | XFS_DIFLAG_EXTSZINHERIT))
    1398         128 :                 ip->i_extsize = XFS_B_TO_FSB(mp, fa->fsx_extsize);
    1399             :         else
    1400      730905 :                 ip->i_extsize = 0;
    1401             : 
    1402      731033 :         if (xfs_has_v3inodes(mp)) {
    1403      731031 :                 if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)
    1404         368 :                         ip->i_cowextsize = XFS_B_TO_FSB(mp, fa->fsx_cowextsize);
    1405             :                 else
    1406      730663 :                         ip->i_cowextsize = 0;
    1407             :         }
    1408             : 
    1409           3 : skip_xattr:
    1410     1009791 :         error = xfs_trans_commit(tp);
    1411             : 
    1412             :         /*
    1413             :          * Release any dquot(s) the inode had kept before chown.
    1414             :          */
    1415     1009798 :         xfs_qm_dqrele(olddquot);
    1416     1009797 :         xfs_qm_dqrele(pdqp);
    1417             : 
    1418     1009797 :         return error;
    1419             : 
    1420          16 : error_trans_cancel:
    1421          16 :         xfs_trans_cancel(tp);
    1422          16 : error_free_dquots:
    1423          16 :         xfs_qm_dqrele(pdqp);
    1424          16 :         return error;
    1425             : }
    1426             : 
    1427             : static bool
    1428     3725221 : xfs_getbmap_format(
    1429             :         struct kgetbmap         *p,
    1430             :         struct getbmapx __user  *u,
    1431             :         size_t                  recsize)
    1432             : {
    1433     3725221 :         if (put_user(p->bmv_offset, &u->bmv_offset) ||
    1434     3725153 :             put_user(p->bmv_block, &u->bmv_block) ||
    1435     3725148 :             put_user(p->bmv_length, &u->bmv_length) ||
    1436     3725146 :             put_user(0, &u->bmv_count) ||
    1437     3725146 :             put_user(0, &u->bmv_entries))
    1438           0 :                 return false;
    1439     3725141 :         if (recsize < sizeof(struct getbmapx))
    1440             :                 return true;
    1441     3094128 :         if (put_user(0, &u->bmv_iflags) ||
    1442     3094125 :             put_user(p->bmv_oflags, &u->bmv_oflags) ||
    1443     3094139 :             put_user(0, &u->bmv_unused1) ||
    1444     3094132 :             put_user(0, &u->bmv_unused2))
    1445           0 :                 return false;
    1446             :         return true;
    1447             : }
    1448             : 
    1449             : STATIC int
    1450      779949 : xfs_ioc_getbmap(
    1451             :         struct file             *file,
    1452             :         unsigned int            cmd,
    1453             :         void                    __user *arg)
    1454             : {
    1455      779949 :         struct getbmapx         bmx = { 0 };
    1456      779949 :         struct kgetbmap         *buf;
    1457      779949 :         size_t                  recsize;
    1458      779949 :         int                     error, i;
    1459             : 
    1460      779949 :         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     1559851 :         if (copy_from_user(&bmx, arg, recsize))
    1476             :                 return -EFAULT;
    1477             : 
    1478      779902 :         if (bmx.bmv_count < 2)
    1479             :                 return -EINVAL;
    1480      779902 :         if (bmx.bmv_count >= INT_MAX / recsize)
    1481             :                 return -ENOMEM;
    1482             : 
    1483      779902 :         buf = kvcalloc(bmx.bmv_count, sizeof(*buf), GFP_KERNEL);
    1484      779982 :         if (!buf)
    1485             :                 return -ENOMEM;
    1486             : 
    1487      779982 :         error = xfs_getbmap(XFS_I(file_inode(file)), &bmx, buf);
    1488      779968 :         if (error)
    1489           0 :                 goto out_free_buf;
    1490             : 
    1491      779968 :         error = -EFAULT;
    1492     1559908 :         if (copy_to_user(arg, &bmx, recsize))
    1493           0 :                 goto out_free_buf;
    1494      779940 :         arg += recsize;
    1495             : 
    1496     4505078 :         for (i = 0; i < bmx.bmv_entries; i++) {
    1497     3725184 :                 if (!xfs_getbmap_format(buf + i, arg, recsize))
    1498           0 :                         goto out_free_buf;
    1499     3725138 :                 arg += recsize;
    1500             :         }
    1501             : 
    1502             :         error = 0;
    1503      779894 : out_free_buf:
    1504      779894 :         kmem_free(buf);
    1505      779894 :         return error;
    1506             : }
    1507             : 
    1508             : STATIC int
    1509      229096 : xfs_ioc_getfsmap(
    1510             :         struct xfs_inode        *ip,
    1511             :         struct fsmap_head       __user *arg)
    1512             : {
    1513      229096 :         struct xfs_fsmap_head   xhead = {0};
    1514      229096 :         struct fsmap_head       head;
    1515      229096 :         struct fsmap            *recs;
    1516      229096 :         unsigned int            count;
    1517      229096 :         __u32                   last_flags = 0;
    1518      229096 :         bool                    done = false;
    1519      229096 :         int                     error;
    1520             : 
    1521      229096 :         if (copy_from_user(&head, arg, sizeof(struct fsmap_head)))
    1522             :                 return -EFAULT;
    1523      459252 :         if (memchr_inv(head.fmh_reserved, 0, sizeof(head.fmh_reserved)) ||
    1524             :             memchr_inv(head.fmh_keys[0].fmr_reserved, 0,
    1525      229446 :                        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      229446 :         count = min_t(unsigned int, head.fmh_count,
    1536             :                         131072 / sizeof(struct fsmap));
    1537      229446 :         recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL);
    1538      229270 :         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      229270 :         xhead.fmh_iflags = head.fmh_iflags;
    1547      229270 :         xfs_fsmap_to_internal(&xhead.fmh_keys[0], &head.fmh_keys[0]);
    1548      228414 :         xfs_fsmap_to_internal(&xhead.fmh_keys[1], &head.fmh_keys[1]);
    1549             : 
    1550      228340 :         trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]);
    1551      228122 :         trace_xfs_getfsmap_high_key(ip->i_mount, &xhead.fmh_keys[1]);
    1552             : 
    1553      227888 :         head.fmh_entries = 0;
    1554      299348 :         do {
    1555      299348 :                 struct fsmap __user     *user_recs;
    1556      299348 :                 struct fsmap            *last_rec;
    1557             : 
    1558      299348 :                 user_recs = &arg->fmh_recs[head.fmh_entries];
    1559      299348 :                 xhead.fmh_entries = 0;
    1560      299348 :                 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      299348 :                 error = xfs_getfsmap(ip->i_mount, &xhead, recs);
    1565      296359 :                 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      116820 :                 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      116820 :                         error = 0;
    1580      116820 :                         break;
    1581           1 :                 default:
    1582           1 :                         goto out_free;
    1583             :                 }
    1584      296358 :                 head.fmh_entries += xhead.fmh_entries;
    1585      296358 :                 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      296358 :                 if (head.fmh_count == 0 || xhead.fmh_entries == 0)
    1592             :                         break;
    1593             : 
    1594             :                 /* Copy all the records we got out to userspace. */
    1595      299626 :                 if (copy_to_user(user_recs, recs,
    1596      296356 :                                  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      299626 :                 last_rec = &recs[xhead.fmh_entries - 1];
    1603      299626 :                 last_flags = last_rec->fmr_flags;
    1604             : 
    1605             :                 /* Set up the low key for the next iteration. */
    1606      299626 :                 xfs_fsmap_to_internal(&xhead.fmh_keys[0], last_rec);
    1607      297570 :                 trace_xfs_getfsmap_low_key(ip->i_mount, &xhead.fmh_keys[0]);
    1608      296393 :         } 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      224935 :         if (done && head.fmh_count > 0 && head.fmh_entries > 0) {
    1615      178480 :                 struct fsmap __user     *user_rec;
    1616             : 
    1617      178480 :                 last_flags |= FMR_OF_LAST;
    1618      178480 :                 user_rec = &arg->fmh_recs[head.fmh_entries - 1];
    1619             : 
    1620      178480 :                 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      227763 :         if (copy_to_user(arg, &head, sizeof(struct fsmap_head))) {
    1629           0 :                 error = -EFAULT;
    1630           0 :                 goto out_free;
    1631             :         }
    1632             : 
    1633      227244 : out_free:
    1634      227245 :         kmem_free(recs);
    1635      227245 :         return error;
    1636             : }
    1637             : 
    1638             : STATIC int
    1639  1084300398 : xfs_ioc_scrub_metadata(
    1640             :         struct file                     *file,
    1641             :         void                            __user *arg)
    1642             : {
    1643  1084300398 :         struct xfs_scrub_metadata       scrub;
    1644  1084300398 :         int                             error;
    1645             : 
    1646  1084300398 :         if (!capable(CAP_SYS_ADMIN))
    1647             :                 return -EPERM;
    1648             : 
    1649  1084353790 :         if (copy_from_user(&scrub, arg, sizeof(scrub)))
    1650             :                 return -EFAULT;
    1651             : 
    1652  1086920226 :         error = xfs_scrub_metadata(file, &scrub);
    1653  1087767120 :         if (error)
    1654             :                 return error;
    1655             : 
    1656   877758756 :         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   509116943 : xfs_ioc_get_parent_pointer(
    1675             :         struct file                     *filp,
    1676             :         void                            __user *arg)
    1677             : {
    1678   509116943 :         struct xfs_getparents           *ppi = NULL;
    1679   509116943 :         int                             error = 0;
    1680   509116943 :         struct xfs_inode                *file_ip = XFS_I(file_inode(filp));
    1681   509116943 :         struct xfs_inode                *call_ip = file_ip;
    1682   509116943 :         struct xfs_mount                *mp = file_ip->i_mount;
    1683   509116943 :         void                            __user *o_pptr;
    1684   509116943 :         struct xfs_getparents_rec       *i_pptr;
    1685   509116943 :         unsigned int                    bytes;
    1686             : 
    1687   509116943 :         if (!capable(CAP_SYS_ADMIN))
    1688             :                 return -EPERM;
    1689             : 
    1690             :         /* Allocate an xfs_getparents to put the user data */
    1691   509113993 :         ppi = kvmalloc(sizeof(struct xfs_getparents), GFP_KERNEL);
    1692   509078094 :         if (!ppi)
    1693             :                 return -ENOMEM;
    1694             : 
    1695             :         /* Copy the data from the user */
    1696   509078094 :         error = copy_from_user(ppi, arg, sizeof(struct xfs_getparents));
    1697   509120946 :         if (error) {
    1698           0 :                 error = -EFAULT;
    1699           0 :                 goto out;
    1700             :         }
    1701             : 
    1702             :         /* Check size of buffer requested by user */
    1703   509120946 :         if (ppi->gp_bufsize > XFS_XATTR_LIST_MAX) {
    1704           0 :                 error = -ENOMEM;
    1705           0 :                 goto out;
    1706             :         }
    1707   509120946 :         if (ppi->gp_bufsize < sizeof(struct xfs_getparents)) {
    1708           0 :                 error = -EINVAL;
    1709           0 :                 goto out;
    1710             :         }
    1711             : 
    1712   509120946 :         if (ppi->gp_flags & ~XFS_GETPARENTS_FLAG_ALL) {
    1713           0 :                 error = -EINVAL;
    1714           0 :                 goto out;
    1715             :         }
    1716   509120946 :         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   509120946 :         ppi = kvrealloc(ppi, sizeof(struct xfs_getparents), ppi->gp_bufsize,
    1723             :                         GFP_KERNEL | __GFP_ZERO);
    1724   508549343 :         if (!ppi)
    1725             :                 return -ENOMEM;
    1726             : 
    1727   508549343 :         if (ppi->gp_flags & XFS_GETPARENTS_IFLAG_HANDLE) {
    1728   508546956 :                 struct xfs_handle       *hanp = &ppi->gp_handle;
    1729             : 
    1730  1017093912 :                 if (memcmp(&hanp->ha_fsid, mp->m_fixedfsid,
    1731             :                                                         sizeof(xfs_fsid_t))) {
    1732           0 :                         error = -EINVAL;
    1733           0 :                         goto out;
    1734             :                 }
    1735             : 
    1736   508546956 :                 if (hanp->ha_fid.fid_ino != file_ip->i_ino) {
    1737   429759008 :                         error = xfs_iget(mp, NULL, hanp->ha_fid.fid_ino,
    1738             :                                         XFS_IGET_UNTRUSTED, 0, &call_ip);
    1739   430344155 :                         if (error)
    1740        4128 :                                 goto out;
    1741             :                 }
    1742             : 
    1743   509127975 :                 if (VFS_I(call_ip)->i_generation != hanp->ha_fid.fid_gen) {
    1744       78045 :                         error = -EINVAL;
    1745       78045 :                         goto out;
    1746             :                 }
    1747             :         }
    1748             : 
    1749             :         /* Get the parent pointers */
    1750   509052317 :         error = xfs_getparent_pointers(call_ip, ppi);
    1751   508592882 :         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   508592882 :         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   508592882 :         bytes = xfs_getparents_arraytop(ppi, ppi->gp_count);
    1766   508592882 :         error = copy_to_user(arg, ppi, bytes);
    1767   508677353 :         if (error) {
    1768           0 :                 error = -EFAULT;
    1769           0 :                 goto out;
    1770             :         }
    1771             : 
    1772   508677353 :         if (ppi->gp_count == 0)
    1773    78932885 :                 goto out;
    1774             : 
    1775             :         /* Copy the parent pointer records back to the user. */
    1776   429744468 :         o_pptr = (__user char*)arg + ppi->gp_offsets[ppi->gp_count - 1];
    1777   429744468 :         i_pptr = xfs_getparents_rec(ppi, ppi->gp_count - 1);
    1778   429744468 :         bytes = ((char *)ppi + ppi->gp_bufsize) - (char *)i_pptr;
    1779   429744468 :         error = copy_to_user(o_pptr, i_pptr, bytes);
    1780   429805759 :         if (error) {
    1781           0 :                 error = -EFAULT;
    1782           0 :                 goto out;
    1783             :         }
    1784             : 
    1785   429805759 : out:
    1786   508820817 :         if (call_ip != file_ip)
    1787   429939908 :                 xfs_irele(call_ip);
    1788   509021315 :         kvfree(ppi);
    1789   509021315 :         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       18810 : xfs_ioc_getlabel(
    1836             :         struct xfs_mount        *mp,
    1837             :         char                    __user *user_label)
    1838             : {
    1839       18810 :         struct xfs_sb           *sbp = &mp->m_sb;
    1840       18810 :         char                    label[XFSLABEL_MAX + 1];
    1841             : 
    1842             :         /* Paranoia */
    1843       18810 :         BUILD_BUG_ON(sizeof(sbp->sb_fname) > FSLABEL_MAX);
    1844             : 
    1845             :         /* 1 larger than sb_fname, so this ensures a trailing NUL char */
    1846       18810 :         memset(label, 0, sizeof(label));
    1847       18810 :         spin_lock(&mp->m_sb_lock);
    1848       18810 :         strncpy(label, sbp->sb_fname, XFSLABEL_MAX);
    1849       18810 :         spin_unlock(&mp->m_sb_lock);
    1850             : 
    1851       18810 :         if (copy_to_user(user_label, label, sizeof(label)))
    1852           0 :                 return -EFAULT;
    1853             :         return 0;
    1854             : }
    1855             : 
    1856             : static int
    1857         297 : xfs_ioc_setlabel(
    1858             :         struct file             *filp,
    1859             :         struct xfs_mount        *mp,
    1860             :         char                    __user *newlabel)
    1861             : {
    1862         297 :         struct xfs_sb           *sbp = &mp->m_sb;
    1863         297 :         struct block_device     *bdev = xfs_buftarg_bdev(mp->m_ddev_targp);
    1864         297 :         char                    label[XFSLABEL_MAX + 1];
    1865         297 :         size_t                  len;
    1866         297 :         int                     error;
    1867             : 
    1868         297 :         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         297 :         if (copy_from_user(label, newlabel, XFSLABEL_MAX + 1))
    1877             :                 return -EFAULT;
    1878         297 :         len = strnlen(label, XFSLABEL_MAX + 1);
    1879         297 :         if (len > sizeof(sbp->sb_fname))
    1880             :                 return -EINVAL;
    1881             : 
    1882         286 :         error = mnt_want_write_file(filp);
    1883         286 :         if (error)
    1884             :                 return error;
    1885             : 
    1886         286 :         spin_lock(&mp->m_sb_lock);
    1887         286 :         memset(sbp->sb_fname, 0, sizeof(sbp->sb_fname));
    1888         572 :         memcpy(sbp->sb_fname, label, len);
    1889         286 :         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         286 :         error = xfs_sync_sb_buf(mp);
    1901         286 :         if (error)
    1902           0 :                 goto out;
    1903             :         /*
    1904             :          * growfs also updates backup supers so lock against that.
    1905             :          */
    1906         286 :         mutex_lock(&mp->m_growlock);
    1907         286 :         error = xfs_update_secondary_sbs(mp);
    1908         286 :         mutex_unlock(&mp->m_growlock);
    1909             : 
    1910         286 :         invalidate_bdev(bdev);
    1911             : 
    1912         286 : out:
    1913         286 :         mnt_drop_write_file(filp);
    1914         286 :         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     3531321 : xfs_ioc_exchange_range(
    1965             :         struct file                     *file2,
    1966             :         struct xfs_exch_range __user    *argp)
    1967             : {
    1968     3531321 :         struct xfs_exch_range           args;
    1969     3531321 :         struct fd                       file1;
    1970     3531321 :         int                             error;
    1971             : 
    1972     3531321 :         if (copy_from_user(&args, argp, sizeof(args)))
    1973             :                 return -EFAULT;
    1974             : 
    1975     3531278 :         file1 = fdget(args.file1_fd);
    1976     3531282 :         if (!file1.file)
    1977             :                 return -EBADF;
    1978             : 
    1979     3531282 :         error = -EXDEV;
    1980     3531282 :         if (file1.file->f_path.mnt != file2->f_path.mnt)
    1981          12 :                 goto fdput;
    1982             : 
    1983     3531270 :         error = xfs_exch_range(file1.file, file2, &args);
    1984     3531292 : fdput:
    1985     3531292 :         fdput(file1);
    1986     3531292 :         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  2510283935 : xfs_file_ioctl(
    2006             :         struct file             *filp,
    2007             :         unsigned int            cmd,
    2008             :         unsigned long           p)
    2009             : {
    2010  2510283935 :         struct inode            *inode = file_inode(filp);
    2011  2510283935 :         struct xfs_inode        *ip = XFS_I(inode);
    2012  2510283935 :         struct xfs_mount        *mp = ip->i_mount;
    2013  2510283935 :         void                    __user *arg = (void __user *)p;
    2014  2510283935 :         int                     error;
    2015             : 
    2016  2510283935 :         trace_xfs_file_ioctl(ip);
    2017             : 
    2018  2506781069 :         switch (cmd) {
    2019      125408 :         case FITRIM:
    2020      125408 :                 return xfs_ioc_trim(mp, arg);
    2021       18810 :         case FS_IOC_GETFSLABEL:
    2022       18810 :                 return xfs_ioc_getlabel(mp, arg);
    2023         297 :         case FS_IOC_SETFSLABEL:
    2024         297 :                 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          11 :                 xfs_warn_once(mp,
    2030             :         "%s should use fallocate; XFS_IOC_{ALLOC,FREE}SP ioctl unsupported",
    2031             :                                 current->comm);
    2032             :                 return -ENOTTY;
    2033    13472403 :         case XFS_IOC_DIOINFO: {
    2034    13472403 :                 struct xfs_buftarg      *target = xfs_inode_buftarg(ip);
    2035    13472403 :                 struct dioattr          da;
    2036             : 
    2037    13472403 :                 da.d_mem =  da.d_miniosz = target->bt_logical_sectorsize;
    2038    13472403 :                 da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
    2039             : 
    2040    13472403 :                 if (copy_to_user(arg, &da, sizeof(da)))
    2041           0 :                         return -EFAULT;
    2042             :                 return 0;
    2043             :         }
    2044             : 
    2045   477923019 :         case XFS_IOC_FSBULKSTAT_SINGLE:
    2046             :         case XFS_IOC_FSBULKSTAT:
    2047             :         case XFS_IOC_FSINUMBERS:
    2048   477923019 :                 return xfs_ioc_fsbulkstat(filp, cmd, arg);
    2049             : 
    2050    10952450 :         case XFS_IOC_BULKSTAT:
    2051    10952450 :                 return xfs_ioc_bulkstat(filp, cmd, arg);
    2052     5655885 :         case XFS_IOC_INUMBERS:
    2053     5655885 :                 return xfs_ioc_inumbers(mp, cmd, arg);
    2054             : 
    2055         772 :         case XFS_IOC_FSGEOMETRY_V1:
    2056         772 :                 return xfs_ioc_fsgeometry(mp, arg, 3);
    2057           0 :         case XFS_IOC_FSGEOMETRY_V4:
    2058           0 :                 return xfs_ioc_fsgeometry(mp, arg, 4);
    2059     5655149 :         case XFS_IOC_FSGEOMETRY:
    2060     5655149 :                 return xfs_ioc_fsgeometry(mp, arg, 5);
    2061             : 
    2062       70463 :         case XFS_IOC_AG_GEOMETRY:
    2063       70463 :                 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       27107 :         case XFS_IOC_FSGETXATTRA:
    2069       27107 :                 return xfs_ioc_fsgetxattra(ip, arg);
    2070   509148551 :         case XFS_IOC_GETPARENTS:
    2071   509148551 :                 return xfs_ioc_get_parent_pointer(filp, arg);
    2072      779979 :         case XFS_IOC_GETBMAP:
    2073             :         case XFS_IOC_GETBMAPA:
    2074             :         case XFS_IOC_GETBMAPX:
    2075      779979 :                 return xfs_ioc_getbmap(filp, cmd, arg);
    2076             : 
    2077      229292 :         case FS_IOC_GETFSMAP:
    2078      229292 :                 return xfs_ioc_getfsmap(ip, arg);
    2079             : 
    2080  1084161309 :         case XFS_IOC_SCRUB_METADATA:
    2081  1084161309 :                 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      117338 :                 xfs_fsop_handlereq_t    hreq;
    2087             : 
    2088      117338 :                 if (copy_from_user(&hreq, arg, sizeof(hreq)))
    2089             :                         return -EFAULT;
    2090      117338 :                 return xfs_find_handle(cmd, &hreq);
    2091             :         }
    2092             :         case XFS_IOC_OPEN_BY_HANDLE: {
    2093    88257569 :                 xfs_fsop_handlereq_t    hreq;
    2094             : 
    2095    88257569 :                 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
    2096             :                         return -EFAULT;
    2097    88523835 :                 return xfs_open_by_handle(filp, &hreq);
    2098             :         }
    2099             : 
    2100             :         case XFS_IOC_READLINK_BY_HANDLE: {
    2101        1000 :                 xfs_fsop_handlereq_t    hreq;
    2102             : 
    2103        1000 :                 if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
    2104             :                         return -EFAULT;
    2105        1000 :                 return xfs_readlink_by_handle(filp, &hreq);
    2106             :         }
    2107   306386009 :         case XFS_IOC_ATTRLIST_BY_HANDLE:
    2108   306386009 :                 return xfs_attrlist_by_handle(filp, arg);
    2109             : 
    2110         733 :         case XFS_IOC_ATTRMULTI_BY_HANDLE:
    2111         733 :                 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       47149 :         case XFS_IOC_FSCOUNTS: {
    2123       47149 :                 xfs_fsop_counts_t out;
    2124             : 
    2125       47149 :                 xfs_fs_counts(mp, &out);
    2126             : 
    2127       47149 :                 if (copy_to_user(arg, &out, sizeof(out)))
    2128          11 :                         return -EFAULT;
    2129             :                 return 0;
    2130             :         }
    2131             : 
    2132         107 :         case XFS_IOC_SET_RESBLKS: {
    2133         107 :                 xfs_fsop_resblks_t inout;
    2134         107 :                 uint64_t           in;
    2135             : 
    2136         107 :                 if (!capable(CAP_SYS_ADMIN))
    2137             :                         return -EPERM;
    2138             : 
    2139         214 :                 if (xfs_is_readonly(mp))
    2140             :                         return -EROFS;
    2141             : 
    2142         107 :                 if (copy_from_user(&inout, arg, sizeof(inout)))
    2143             :                         return -EFAULT;
    2144             : 
    2145          96 :                 error = mnt_want_write_file(filp);
    2146          96 :                 if (error)
    2147           0 :                         return error;
    2148             : 
    2149             :                 /* input parameter is passed in resblks field of structure */
    2150          96 :                 in = inout.resblks;
    2151          96 :                 error = xfs_reserve_blocks(mp, &in, &inout);
    2152          96 :                 mnt_drop_write_file(filp);
    2153          96 :                 if (error)
    2154           0 :                         return error;
    2155             : 
    2156          96 :                 if (copy_to_user(arg, &inout, sizeof(inout)))
    2157           0 :                         return -EFAULT;
    2158             :                 return 0;
    2159             :         }
    2160             : 
    2161          33 :         case XFS_IOC_GET_RESBLKS: {
    2162          33 :                 xfs_fsop_resblks_t out;
    2163             : 
    2164          33 :                 if (!capable(CAP_SYS_ADMIN))
    2165             :                         return -EPERM;
    2166             : 
    2167          33 :                 error = xfs_reserve_blocks(mp, NULL, &out);
    2168          33 :                 if (error)
    2169           0 :                         return error;
    2170             : 
    2171          33 :                 if (copy_to_user(arg, &out, sizeof(out)))
    2172           0 :                         return -EFAULT;
    2173             : 
    2174             :                 return 0;
    2175             :         }
    2176             : 
    2177             :         case XFS_IOC_FSGROWFSDATA: {
    2178        1834 :                 struct xfs_growfs_data in;
    2179             : 
    2180        1834 :                 if (copy_from_user(&in, arg, sizeof(in)))
    2181             :                         return -EFAULT;
    2182             : 
    2183        1834 :                 error = mnt_want_write_file(filp);
    2184        1834 :                 if (error)
    2185           0 :                         return error;
    2186        1834 :                 error = xfs_growfs_data(mp, &in);
    2187        1834 :                 mnt_drop_write_file(filp);
    2188        1834 :                 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          47 :                 xfs_growfs_rt_t in;
    2207             : 
    2208          47 :                 if (copy_from_user(&in, arg, sizeof(in)))
    2209             :                         return -EFAULT;
    2210             : 
    2211          47 :                 error = mnt_want_write_file(filp);
    2212          47 :                 if (error)
    2213           0 :                         return error;
    2214          47 :                 error = xfs_growfs_rt(mp, &in);
    2215          47 :                 mnt_drop_write_file(filp);
    2216          47 :                 return error;
    2217             :         }
    2218             : 
    2219        5859 :         case XFS_IOC_GOINGDOWN: {
    2220        5859 :                 uint32_t in;
    2221             : 
    2222        5859 :                 if (!capable(CAP_SYS_ADMIN))
    2223             :                         return -EPERM;
    2224             : 
    2225        5859 :                 if (get_user(in, (uint32_t __user *)arg))
    2226             :                         return -EFAULT;
    2227             : 
    2228        5859 :                 return xfs_fs_goingdown(mp, in);
    2229             :         }
    2230             : 
    2231          40 :         case XFS_IOC_ERROR_INJECTION: {
    2232          40 :                 xfs_error_injection_t in;
    2233             : 
    2234          40 :                 if (!capable(CAP_SYS_ADMIN))
    2235             :                         return -EPERM;
    2236             : 
    2237          40 :                 if (copy_from_user(&in, arg, sizeof(in)))
    2238             :                         return -EFAULT;
    2239             : 
    2240          40 :                 return xfs_errortag_add(mp, in.errtag);
    2241             :         }
    2242             : 
    2243        1351 :         case XFS_IOC_ERROR_CLEARALL:
    2244        1351 :                 if (!capable(CAP_SYS_ADMIN))
    2245             :                         return -EPERM;
    2246             : 
    2247        1351 :                 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     3531299 :         case XFS_IOC_EXCHANGE_RANGE:
    2275     3531299 :                 return xfs_ioc_exchange_range(filp, arg);
    2276             : 
    2277             :         default:
    2278             :                 return -ENOTTY;
    2279             :         }
    2280             : }

Generated by: LCOV version 1.14