LCOV - code coverage report
Current view: top level - fs/xfs - xfs_ioctl32.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 0 248 0.0 %
Date: 2023-07-31 20:08:12 Functions: 0 14 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (c) 2004-2005 Silicon Graphics, Inc.
       4             :  * All Rights Reserved.
       5             :  */
       6             : #include <linux/mount.h>
       7             : #include <linux/fsmap.h>
       8             : #include "xfs.h"
       9             : #include "xfs_fs.h"
      10             : #include "xfs_shared.h"
      11             : #include "xfs_format.h"
      12             : #include "xfs_log_format.h"
      13             : #include "xfs_trans_resv.h"
      14             : #include "xfs_mount.h"
      15             : #include "xfs_inode.h"
      16             : #include "xfs_iwalk.h"
      17             : #include "xfs_itable.h"
      18             : #include "xfs_fsops.h"
      19             : #include "xfs_rtalloc.h"
      20             : #include "xfs_da_format.h"
      21             : #include "xfs_da_btree.h"
      22             : #include "xfs_attr.h"
      23             : #include "xfs_ioctl.h"
      24             : #include "xfs_ioctl32.h"
      25             : #include "xfs_trace.h"
      26             : #include "xfs_sb.h"
      27             : 
      28             : #define  _NATIVE_IOC(cmd, type) \
      29             :           _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(type))
      30             : 
      31             : #ifdef BROKEN_X86_ALIGNMENT
      32             : STATIC int
      33           0 : xfs_compat_ioc_fsgeometry_v1(
      34             :         struct xfs_mount          *mp,
      35             :         compat_xfs_fsop_geom_v1_t __user *arg32)
      36             : {
      37           0 :         struct xfs_fsop_geom      fsgeo;
      38             : 
      39           0 :         xfs_fs_geometry(mp, &fsgeo, 3);
      40             :         /* The 32-bit variant simply has some padding at the end */
      41           0 :         if (copy_to_user(arg32, &fsgeo, sizeof(struct compat_xfs_fsop_geom_v1)))
      42           0 :                 return -EFAULT;
      43             :         return 0;
      44             : }
      45             : 
      46             : STATIC int
      47           0 : xfs_compat_growfs_data_copyin(
      48             :         struct xfs_growfs_data   *in,
      49             :         compat_xfs_growfs_data_t __user *arg32)
      50             : {
      51           0 :         if (get_user(in->newblocks, &arg32->newblocks) ||
      52           0 :             get_user(in->imaxpct,   &arg32->imaxpct))
      53           0 :                 return -EFAULT;
      54             :         return 0;
      55             : }
      56             : 
      57             : STATIC int
      58           0 : xfs_compat_growfs_rt_copyin(
      59             :         struct xfs_growfs_rt     *in,
      60             :         compat_xfs_growfs_rt_t  __user *arg32)
      61             : {
      62           0 :         if (get_user(in->newblocks, &arg32->newblocks) ||
      63           0 :             get_user(in->extsize,   &arg32->extsize))
      64           0 :                 return -EFAULT;
      65             :         return 0;
      66             : }
      67             : 
      68             : STATIC int
      69           0 : xfs_fsinumbers_fmt_compat(
      70             :         struct xfs_ibulk                *breq,
      71             :         const struct xfs_inumbers       *ig)
      72             : {
      73           0 :         struct compat_xfs_inogrp __user *p32 = breq->ubuffer;
      74           0 :         struct xfs_inogrp               ig1;
      75           0 :         struct xfs_inogrp               *igrp = &ig1;
      76             : 
      77           0 :         xfs_inumbers_to_inogrp(&ig1, ig);
      78             : 
      79           0 :         if (put_user(igrp->xi_startino,   &p32->xi_startino) ||
      80           0 :             put_user(igrp->xi_alloccount, &p32->xi_alloccount) ||
      81           0 :             put_user(igrp->xi_allocmask,  &p32->xi_allocmask))
      82           0 :                 return -EFAULT;
      83             : 
      84           0 :         return xfs_ibulk_advance(breq, sizeof(struct compat_xfs_inogrp));
      85             : }
      86             : 
      87             : #else
      88             : #define xfs_fsinumbers_fmt_compat xfs_fsinumbers_fmt
      89             : #endif  /* BROKEN_X86_ALIGNMENT */
      90             : 
      91             : STATIC int
      92           0 : xfs_ioctl32_bstime_copyin(
      93             :         xfs_bstime_t            *bstime,
      94             :         compat_xfs_bstime_t     __user *bstime32)
      95             : {
      96           0 :         old_time32_t            sec32;  /* tv_sec differs on 64 vs. 32 */
      97             : 
      98           0 :         if (get_user(sec32,             &bstime32->tv_sec)       ||
      99           0 :             get_user(bstime->tv_nsec,        &bstime32->tv_nsec))
     100           0 :                 return -EFAULT;
     101           0 :         bstime->tv_sec = sec32;
     102           0 :         return 0;
     103             : }
     104             : 
     105             : /*
     106             :  * struct xfs_bstat has differing alignment on intel, & bstime_t sizes
     107             :  * everywhere
     108             :  */
     109             : STATIC int
     110           0 : xfs_ioctl32_bstat_copyin(
     111             :         struct xfs_bstat                *bstat,
     112             :         struct compat_xfs_bstat __user  *bstat32)
     113             : {
     114           0 :         if (get_user(bstat->bs_ino,  &bstat32->bs_ino)        ||
     115           0 :             get_user(bstat->bs_mode, &bstat32->bs_mode)       ||
     116           0 :             get_user(bstat->bs_nlink,        &bstat32->bs_nlink)      ||
     117           0 :             get_user(bstat->bs_uid,  &bstat32->bs_uid)        ||
     118           0 :             get_user(bstat->bs_gid,  &bstat32->bs_gid)        ||
     119           0 :             get_user(bstat->bs_rdev, &bstat32->bs_rdev)       ||
     120           0 :             get_user(bstat->bs_blksize,      &bstat32->bs_blksize)    ||
     121           0 :             get_user(bstat->bs_size, &bstat32->bs_size)       ||
     122           0 :             xfs_ioctl32_bstime_copyin(&bstat->bs_atime, &bstat32->bs_atime) ||
     123           0 :             xfs_ioctl32_bstime_copyin(&bstat->bs_mtime, &bstat32->bs_mtime) ||
     124           0 :             xfs_ioctl32_bstime_copyin(&bstat->bs_ctime, &bstat32->bs_ctime) ||
     125           0 :             get_user(bstat->bs_blocks,       &bstat32->bs_size)       ||
     126           0 :             get_user(bstat->bs_xflags,       &bstat32->bs_size)       ||
     127           0 :             get_user(bstat->bs_extsize,      &bstat32->bs_extsize)    ||
     128           0 :             get_user(bstat->bs_extents,      &bstat32->bs_extents)    ||
     129           0 :             get_user(bstat->bs_gen,  &bstat32->bs_gen)        ||
     130           0 :             get_user(bstat->bs_projid_lo, &bstat32->bs_projid_lo) ||
     131           0 :             get_user(bstat->bs_projid_hi, &bstat32->bs_projid_hi) ||
     132           0 :             get_user(bstat->bs_forkoff,      &bstat32->bs_forkoff)    ||
     133           0 :             get_user(bstat->bs_dmevmask, &bstat32->bs_dmevmask)       ||
     134           0 :             get_user(bstat->bs_dmstate,      &bstat32->bs_dmstate)    ||
     135           0 :             get_user(bstat->bs_aextents, &bstat32->bs_aextents))
     136           0 :                 return -EFAULT;
     137             :         return 0;
     138             : }
     139             : 
     140             : /* XFS_IOC_FSBULKSTAT and friends */
     141             : 
     142             : STATIC int
     143           0 : xfs_bstime_store_compat(
     144             :         compat_xfs_bstime_t     __user *p32,
     145             :         const xfs_bstime_t      *p)
     146             : {
     147           0 :         __s32                   sec32;
     148             : 
     149           0 :         sec32 = p->tv_sec;
     150           0 :         if (put_user(sec32, &p32->tv_sec) ||
     151           0 :             put_user(p->tv_nsec, &p32->tv_nsec))
     152           0 :                 return -EFAULT;
     153             :         return 0;
     154             : }
     155             : 
     156             : /* Return 0 on success or positive error (to xfs_bulkstat()) */
     157             : STATIC int
     158           0 : xfs_fsbulkstat_one_fmt_compat(
     159             :         struct xfs_ibulk                *breq,
     160             :         const struct xfs_bulkstat       *bstat)
     161             : {
     162           0 :         struct compat_xfs_bstat __user  *p32 = breq->ubuffer;
     163           0 :         struct xfs_bstat                bs1;
     164           0 :         struct xfs_bstat                *buffer = &bs1;
     165             : 
     166           0 :         xfs_bulkstat_to_bstat(breq->mp, &bs1, bstat);
     167             : 
     168           0 :         if (put_user(buffer->bs_ino,   &p32->bs_ino)          ||
     169           0 :             put_user(buffer->bs_mode,          &p32->bs_mode) ||
     170           0 :             put_user(buffer->bs_nlink,         &p32->bs_nlink)        ||
     171           0 :             put_user(buffer->bs_uid,   &p32->bs_uid)          ||
     172           0 :             put_user(buffer->bs_gid,   &p32->bs_gid)          ||
     173           0 :             put_user(buffer->bs_rdev,          &p32->bs_rdev) ||
     174           0 :             put_user(buffer->bs_blksize,  &p32->bs_blksize)   ||
     175           0 :             put_user(buffer->bs_size,          &p32->bs_size) ||
     176           0 :             xfs_bstime_store_compat(&p32->bs_atime, &buffer->bs_atime) ||
     177           0 :             xfs_bstime_store_compat(&p32->bs_mtime, &buffer->bs_mtime) ||
     178           0 :             xfs_bstime_store_compat(&p32->bs_ctime, &buffer->bs_ctime) ||
     179           0 :             put_user(buffer->bs_blocks,        &p32->bs_blocks)       ||
     180           0 :             put_user(buffer->bs_xflags,        &p32->bs_xflags)       ||
     181           0 :             put_user(buffer->bs_extsize,  &p32->bs_extsize)   ||
     182           0 :             put_user(buffer->bs_extents,  &p32->bs_extents)   ||
     183           0 :             put_user(buffer->bs_gen,   &p32->bs_gen)          ||
     184           0 :             put_user(buffer->bs_projid,        &p32->bs_projid)       ||
     185           0 :             put_user(buffer->bs_projid_hi,   &p32->bs_projid_hi)      ||
     186           0 :             put_user(buffer->bs_forkoff,  &p32->bs_forkoff)   ||
     187           0 :             put_user(buffer->bs_dmevmask, &p32->bs_dmevmask)  ||
     188           0 :             put_user(buffer->bs_dmstate,  &p32->bs_dmstate)   ||
     189           0 :             put_user(buffer->bs_aextents, &p32->bs_aextents))
     190           0 :                 return -EFAULT;
     191             : 
     192           0 :         return xfs_ibulk_advance(breq, sizeof(struct compat_xfs_bstat));
     193             : }
     194             : 
     195             : /* copied from xfs_ioctl.c */
     196             : STATIC int
     197           0 : xfs_compat_ioc_fsbulkstat(
     198             :         struct file             *file,
     199             :         unsigned int              cmd,
     200             :         struct compat_xfs_fsop_bulkreq __user *p32)
     201             : {
     202           0 :         struct xfs_mount        *mp = XFS_I(file_inode(file))->i_mount;
     203           0 :         u32                     addr;
     204           0 :         struct xfs_fsop_bulkreq bulkreq;
     205           0 :         struct xfs_ibulk        breq = {
     206             :                 .mp             = mp,
     207             :                 .idmap          = file_mnt_idmap(file),
     208             :                 .ocount         = 0,
     209             :         };
     210           0 :         xfs_ino_t               lastino;
     211           0 :         int                     error;
     212             : 
     213             :         /*
     214             :          * Output structure handling functions.  Depending on the command,
     215             :          * either the xfs_bstat and xfs_inogrp structures are written out
     216             :          * to userpace memory via bulkreq.ubuffer.  Normally the compat
     217             :          * functions and structure size are the correct ones to use ...
     218             :          */
     219           0 :         inumbers_fmt_pf         inumbers_func = xfs_fsinumbers_fmt_compat;
     220           0 :         bulkstat_one_fmt_pf     bs_one_func = xfs_fsbulkstat_one_fmt_compat;
     221             : 
     222             : #ifdef CONFIG_X86_X32_ABI
     223           0 :         if (in_x32_syscall()) {
     224             :                 /*
     225             :                  * ... but on x32 the input xfs_fsop_bulkreq has pointers
     226             :                  * which must be handled in the "compat" (32-bit) way, while
     227             :                  * the xfs_bstat and xfs_inogrp structures follow native 64-
     228             :                  * bit layout convention.  So adjust accordingly, otherwise
     229             :                  * the data written out in compat layout will not match what
     230             :                  * x32 userspace expects.
     231             :                  */
     232             :                 inumbers_func = xfs_fsinumbers_fmt;
     233             :                 bs_one_func = xfs_fsbulkstat_one_fmt;
     234             :         }
     235             : #endif
     236             : 
     237             :         /* done = 1 if there are more stats to get and if bulkstat */
     238             :         /* should be called again (unused here, but used in dmapi) */
     239             : 
     240           0 :         if (!capable(CAP_SYS_ADMIN))
     241             :                 return -EPERM;
     242             : 
     243           0 :         if (xfs_is_shutdown(mp))
     244             :                 return -EIO;
     245             : 
     246           0 :         if (get_user(addr, &p32->lastip))
     247             :                 return -EFAULT;
     248           0 :         bulkreq.lastip = compat_ptr(addr);
     249           0 :         if (get_user(bulkreq.icount, &p32->icount) ||
     250           0 :             get_user(addr, &p32->ubuffer))
     251           0 :                 return -EFAULT;
     252           0 :         bulkreq.ubuffer = compat_ptr(addr);
     253           0 :         if (get_user(addr, &p32->ocount))
     254             :                 return -EFAULT;
     255           0 :         bulkreq.ocount = compat_ptr(addr);
     256             : 
     257           0 :         if (copy_from_user(&lastino, bulkreq.lastip, sizeof(__s64)))
     258             :                 return -EFAULT;
     259             : 
     260           0 :         if (bulkreq.icount <= 0)
     261             :                 return -EINVAL;
     262             : 
     263           0 :         if (bulkreq.ubuffer == NULL)
     264             :                 return -EINVAL;
     265             : 
     266           0 :         breq.ubuffer = bulkreq.ubuffer;
     267           0 :         breq.icount = bulkreq.icount;
     268             : 
     269             :         /*
     270             :          * FSBULKSTAT_SINGLE expects that *lastip contains the inode number
     271             :          * that we want to stat.  However, FSINUMBERS and FSBULKSTAT expect
     272             :          * that *lastip contains either zero or the number of the last inode to
     273             :          * be examined by the previous call and return results starting with
     274             :          * the next inode after that.  The new bulk request back end functions
     275             :          * take the inode to start with, so we have to compute the startino
     276             :          * parameter from lastino to maintain correct function.  lastino == 0
     277             :          * is a special case because it has traditionally meant "first inode
     278             :          * in filesystem".
     279             :          */
     280           0 :         if (cmd == XFS_IOC_FSINUMBERS_32) {
     281           0 :                 breq.startino = lastino ? lastino + 1 : 0;
     282           0 :                 error = xfs_inumbers(&breq, inumbers_func);
     283           0 :                 lastino = breq.startino - 1;
     284           0 :         } else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE_32) {
     285           0 :                 breq.startino = lastino;
     286           0 :                 breq.icount = 1;
     287           0 :                 error = xfs_bulkstat_one(&breq, bs_one_func);
     288           0 :                 lastino = breq.startino;
     289           0 :         } else if (cmd == XFS_IOC_FSBULKSTAT_32) {
     290           0 :                 breq.startino = lastino ? lastino + 1 : 0;
     291           0 :                 error = xfs_bulkstat(&breq, bs_one_func);
     292           0 :                 lastino = breq.startino - 1;
     293             :         } else {
     294             :                 error = -EINVAL;
     295             :         }
     296           0 :         if (error)
     297           0 :                 return error;
     298             : 
     299           0 :         if (bulkreq.lastip != NULL &&
     300             :             copy_to_user(bulkreq.lastip, &lastino, sizeof(xfs_ino_t)))
     301             :                 return -EFAULT;
     302             : 
     303           0 :         if (bulkreq.ocount != NULL &&
     304             :             copy_to_user(bulkreq.ocount, &breq.ocount, sizeof(__s32)))
     305           0 :                 return -EFAULT;
     306             : 
     307             :         return 0;
     308             : }
     309             : 
     310             : STATIC int
     311           0 : xfs_compat_handlereq_copyin(
     312             :         xfs_fsop_handlereq_t            *hreq,
     313             :         compat_xfs_fsop_handlereq_t     __user *arg32)
     314             : {
     315           0 :         compat_xfs_fsop_handlereq_t     hreq32;
     316             : 
     317           0 :         if (copy_from_user(&hreq32, arg32, sizeof(compat_xfs_fsop_handlereq_t)))
     318             :                 return -EFAULT;
     319             : 
     320           0 :         hreq->fd = hreq32.fd;
     321           0 :         hreq->path = compat_ptr(hreq32.path);
     322           0 :         hreq->oflags = hreq32.oflags;
     323           0 :         hreq->ihandle = compat_ptr(hreq32.ihandle);
     324           0 :         hreq->ihandlen = hreq32.ihandlen;
     325           0 :         hreq->ohandle = compat_ptr(hreq32.ohandle);
     326           0 :         hreq->ohandlen = compat_ptr(hreq32.ohandlen);
     327             : 
     328           0 :         return 0;
     329             : }
     330             : 
     331             : STATIC struct dentry *
     332           0 : xfs_compat_handlereq_to_dentry(
     333             :         struct file             *parfilp,
     334             :         compat_xfs_fsop_handlereq_t *hreq)
     335             : {
     336           0 :         return xfs_handle_to_dentry(parfilp,
     337             :                         compat_ptr(hreq->ihandle), hreq->ihandlen);
     338             : }
     339             : 
     340             : STATIC int
     341           0 : xfs_compat_attrlist_by_handle(
     342             :         struct file             *parfilp,
     343             :         compat_xfs_fsop_attrlist_handlereq_t __user *p)
     344             : {
     345           0 :         compat_xfs_fsop_attrlist_handlereq_t al_hreq;
     346           0 :         struct dentry           *dentry;
     347           0 :         int                     error;
     348             : 
     349           0 :         if (!capable(CAP_SYS_ADMIN))
     350             :                 return -EPERM;
     351           0 :         if (copy_from_user(&al_hreq, p, sizeof(al_hreq)))
     352             :                 return -EFAULT;
     353             : 
     354           0 :         dentry = xfs_compat_handlereq_to_dentry(parfilp, &al_hreq.hreq);
     355           0 :         if (IS_ERR(dentry))
     356           0 :                 return PTR_ERR(dentry);
     357             : 
     358           0 :         error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)),
     359           0 :                         compat_ptr(al_hreq.buffer), al_hreq.buflen,
     360           0 :                         al_hreq.flags, &p->pos);
     361           0 :         dput(dentry);
     362           0 :         return error;
     363             : }
     364             : 
     365             : STATIC int
     366           0 : xfs_compat_attrmulti_by_handle(
     367             :         struct file                             *parfilp,
     368             :         void                                    __user *arg)
     369             : {
     370           0 :         int                                     error;
     371           0 :         compat_xfs_attr_multiop_t               *ops;
     372           0 :         compat_xfs_fsop_attrmulti_handlereq_t   am_hreq;
     373           0 :         struct dentry                           *dentry;
     374           0 :         unsigned int                            i, size;
     375             : 
     376           0 :         if (!capable(CAP_SYS_ADMIN))
     377             :                 return -EPERM;
     378           0 :         if (copy_from_user(&am_hreq, arg,
     379             :                            sizeof(compat_xfs_fsop_attrmulti_handlereq_t)))
     380             :                 return -EFAULT;
     381             : 
     382             :         /* overflow check */
     383           0 :         if (am_hreq.opcount >= INT_MAX / sizeof(compat_xfs_attr_multiop_t))
     384             :                 return -E2BIG;
     385             : 
     386           0 :         dentry = xfs_compat_handlereq_to_dentry(parfilp, &am_hreq.hreq);
     387           0 :         if (IS_ERR(dentry))
     388           0 :                 return PTR_ERR(dentry);
     389             : 
     390           0 :         error = -E2BIG;
     391           0 :         size = am_hreq.opcount * sizeof(compat_xfs_attr_multiop_t);
     392           0 :         if (!size || size > 16 * PAGE_SIZE)
     393           0 :                 goto out_dput;
     394             : 
     395           0 :         ops = memdup_user(compat_ptr(am_hreq.ops), size);
     396           0 :         if (IS_ERR(ops)) {
     397           0 :                 error = PTR_ERR(ops);
     398           0 :                 goto out_dput;
     399             :         }
     400             : 
     401             :         error = 0;
     402           0 :         for (i = 0; i < am_hreq.opcount; i++) {
     403           0 :                 ops[i].am_error = xfs_ioc_attrmulti_one(parfilp,
     404             :                                 d_inode(dentry), ops[i].am_opcode,
     405             :                                 compat_ptr(ops[i].am_attrname),
     406             :                                 compat_ptr(ops[i].am_attrvalue),
     407           0 :                                 &ops[i].am_length, ops[i].am_flags);
     408             :         }
     409             : 
     410           0 :         if (copy_to_user(compat_ptr(am_hreq.ops), ops, size))
     411           0 :                 error = -EFAULT;
     412             : 
     413           0 :         kfree(ops);
     414           0 :  out_dput:
     415           0 :         dput(dentry);
     416           0 :         return error;
     417             : }
     418             : 
     419             : long
     420           0 : xfs_file_compat_ioctl(
     421             :         struct file             *filp,
     422             :         unsigned                cmd,
     423             :         unsigned long           p)
     424             : {
     425           0 :         struct inode            *inode = file_inode(filp);
     426           0 :         struct xfs_inode        *ip = XFS_I(inode);
     427           0 :         void                    __user *arg = compat_ptr(p);
     428             : 
     429           0 :         trace_xfs_file_compat_ioctl(ip);
     430             : 
     431           0 :         switch (cmd) {
     432             : #if defined(BROKEN_X86_ALIGNMENT)
     433           0 :         case XFS_IOC_FSGEOMETRY_V1_32:
     434           0 :                 return xfs_compat_ioc_fsgeometry_v1(ip->i_mount, arg);
     435           0 :         case XFS_IOC_FSGROWFSDATA_32: {
     436           0 :                 struct xfs_growfs_data  in;
     437           0 :                 int                     error;
     438             : 
     439           0 :                 if (xfs_compat_growfs_data_copyin(&in, arg))
     440             :                         return -EFAULT;
     441           0 :                 error = mnt_want_write_file(filp);
     442           0 :                 if (error)
     443           0 :                         return error;
     444           0 :                 error = xfs_growfs_data(ip->i_mount, &in);
     445           0 :                 mnt_drop_write_file(filp);
     446           0 :                 return error;
     447             :         }
     448           0 :         case XFS_IOC_FSGROWFSRT_32: {
     449           0 :                 struct xfs_growfs_rt    in;
     450           0 :                 int                     error;
     451             : 
     452           0 :                 if (xfs_compat_growfs_rt_copyin(&in, arg))
     453             :                         return -EFAULT;
     454           0 :                 error = mnt_want_write_file(filp);
     455           0 :                 if (error)
     456           0 :                         return error;
     457           0 :                 error = xfs_growfs_rt(ip->i_mount, &in);
     458           0 :                 mnt_drop_write_file(filp);
     459           0 :                 return error;
     460             :         }
     461             : #endif
     462             :         /* long changes size, but xfs only copiese out 32 bits */
     463           0 :         case XFS_IOC_GETVERSION_32:
     464           0 :                 cmd = _NATIVE_IOC(cmd, long);
     465           0 :                 return xfs_file_ioctl(filp, cmd, p);
     466           0 :         case XFS_IOC_SWAPEXT_32: {
     467           0 :                 struct xfs_swapext        sxp;
     468           0 :                 struct compat_xfs_swapext __user *sxu = arg;
     469             : 
     470             :                 /* Bulk copy in up to the sx_stat field, then copy bstat */
     471           0 :                 if (copy_from_user(&sxp, sxu,
     472           0 :                                    offsetof(struct xfs_swapext, sx_stat)) ||
     473           0 :                     xfs_ioctl32_bstat_copyin(&sxp.sx_stat, &sxu->sx_stat))
     474           0 :                         return -EFAULT;
     475             : 
     476           0 :                 return xfs_ioc_swapext(&sxp);
     477             :         }
     478           0 :         case XFS_IOC_FSBULKSTAT_32:
     479             :         case XFS_IOC_FSBULKSTAT_SINGLE_32:
     480             :         case XFS_IOC_FSINUMBERS_32:
     481           0 :                 return xfs_compat_ioc_fsbulkstat(filp, cmd, arg);
     482           0 :         case XFS_IOC_FD_TO_HANDLE_32:
     483             :         case XFS_IOC_PATH_TO_HANDLE_32:
     484             :         case XFS_IOC_PATH_TO_FSHANDLE_32: {
     485           0 :                 struct xfs_fsop_handlereq       hreq;
     486             : 
     487           0 :                 if (xfs_compat_handlereq_copyin(&hreq, arg))
     488             :                         return -EFAULT;
     489           0 :                 cmd = _NATIVE_IOC(cmd, struct xfs_fsop_handlereq);
     490           0 :                 return xfs_find_handle(cmd, &hreq);
     491             :         }
     492           0 :         case XFS_IOC_OPEN_BY_HANDLE_32: {
     493           0 :                 struct xfs_fsop_handlereq       hreq;
     494             : 
     495           0 :                 if (xfs_compat_handlereq_copyin(&hreq, arg))
     496             :                         return -EFAULT;
     497           0 :                 return xfs_open_by_handle(filp, &hreq);
     498             :         }
     499           0 :         case XFS_IOC_READLINK_BY_HANDLE_32: {
     500           0 :                 struct xfs_fsop_handlereq       hreq;
     501             : 
     502           0 :                 if (xfs_compat_handlereq_copyin(&hreq, arg))
     503             :                         return -EFAULT;
     504           0 :                 return xfs_readlink_by_handle(filp, &hreq);
     505             :         }
     506           0 :         case XFS_IOC_ATTRLIST_BY_HANDLE_32:
     507           0 :                 return xfs_compat_attrlist_by_handle(filp, arg);
     508           0 :         case XFS_IOC_ATTRMULTI_BY_HANDLE_32:
     509           0 :                 return xfs_compat_attrmulti_by_handle(filp, arg);
     510           0 :         default:
     511             :                 /* try the native version */
     512           0 :                 return xfs_file_ioctl(filp, cmd, (unsigned long)arg);
     513             :         }
     514             : }

Generated by: LCOV version 1.14