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

Generated by: LCOV version 1.14