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

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

Generated by: LCOV version 1.14