xfs_fs_geometry(mp, &fsgeo, 3); /* The 32-bit variant simply has some padding at the end */ if (copy_to_user(arg32, &fsgeo, sizeof(struct compat_xfs_fsop_geom_v1))) return -EFAULT; return 0;
}
/* * Output structure handling functions. Depending on the command, * either the xfs_bstat and xfs_inogrp structures are written out * to userpace memory via bulkreq.ubuffer. Normally the compat * functions and structure size are the correct ones to use ...
*/
inumbers_fmt_pf inumbers_func = xfs_fsinumbers_fmt_compat;
bulkstat_one_fmt_pf bs_one_func = xfs_fsbulkstat_one_fmt_compat;
#ifdef CONFIG_X86_X32_ABI if (in_x32_syscall()) { /* * ... but on x32 the input xfs_fsop_bulkreq has pointers * which must be handled in the "compat" (32-bit) way, while * the xfs_bstat and xfs_inogrp structures follow native 64- * bit layout convention. So adjust accordingly, otherwise * the data written out in compat layout will not match what * x32 userspace expects.
*/
inumbers_func = xfs_fsinumbers_fmt;
bs_one_func = xfs_fsbulkstat_one_fmt;
} #endif
/* done = 1 if there are more stats to get and if bulkstat */ /* should be called again (unused here, but used in dmapi) */
if (!capable(CAP_SYS_ADMIN)) return -EPERM;
if (xfs_is_shutdown(mp)) return -EIO;
if (get_user(addr, &p32->lastip)) return -EFAULT;
bulkreq.lastip = compat_ptr(addr); if (get_user(bulkreq.icount, &p32->icount) ||
get_user(addr, &p32->ubuffer)) return -EFAULT;
bulkreq.ubuffer = compat_ptr(addr); if (get_user(addr, &p32->ocount)) return -EFAULT;
bulkreq.ocount = compat_ptr(addr);
if (copy_from_user(&lastino, bulkreq.lastip, sizeof(__s64))) return -EFAULT;
/* * FSBULKSTAT_SINGLE expects that *lastip contains the inode number * that we want to stat. However, FSINUMBERS and FSBULKSTAT expect * that *lastip contains either zero or the number of the last inode to * be examined by the previous call and return results starting with * the next inode after that. The new bulk request back end functions * take the inode to start with, so we have to compute the startino * parameter from lastino to maintain correct function. lastino == 0 * is a special case because it has traditionally meant "first inode * in filesystem".
*/ if (cmd == XFS_IOC_FSINUMBERS_32) {
breq.startino = lastino ? lastino + 1 : 0;
error = xfs_inumbers(&breq, inumbers_func);
lastino = breq.startino - 1;
} elseif (cmd == XFS_IOC_FSBULKSTAT_SINGLE_32) {
breq.startino = lastino;
breq.icount = 1;
error = xfs_bulkstat_one(&breq, bs_one_func);
lastino = breq.startino;
} elseif (cmd == XFS_IOC_FSBULKSTAT_32) {
breq.startino = lastino ? lastino + 1 : 0;
error = xfs_bulkstat(&breq, bs_one_func);
lastino = breq.startino - 1;
} else {
error = -EINVAL;
} if (error) return error;
if (bulkreq.lastip != NULL &&
copy_to_user(bulkreq.lastip, &lastino, sizeof(xfs_ino_t))) return -EFAULT;
if (bulkreq.ocount != NULL &&
copy_to_user(bulkreq.ocount, &breq.ocount, sizeof(__s32))) return -EFAULT;
switch (cmd) { #ifdefined(BROKEN_X86_ALIGNMENT) case XFS_IOC_FSGEOMETRY_V1_32: return xfs_compat_ioc_fsgeometry_v1(ip->i_mount, arg); case XFS_IOC_FSGROWFSDATA_32: { struct xfs_growfs_data in;
if (xfs_compat_growfs_data_copyin(&in, arg)) return -EFAULT;
error = mnt_want_write_file(filp); if (error) return error;
error = xfs_growfs_data(ip->i_mount, &in);
mnt_drop_write_file(filp); return error;
} case XFS_IOC_FSGROWFSRT_32: { struct xfs_growfs_rt in;
if (xfs_compat_growfs_rt_copyin(&in, arg)) return -EFAULT;
error = mnt_want_write_file(filp); if (error) return error;
error = xfs_growfs_rt(ip->i_mount, &in);
mnt_drop_write_file(filp); return error;
} #endif /* long changes size, but xfs only copiese out 32 bits */ case XFS_IOC_GETVERSION_32:
cmd = _NATIVE_IOC(cmd, long); return xfs_file_ioctl(filp, cmd, p); case XFS_IOC_SWAPEXT_32: { struct xfs_swapext sxp; struct compat_xfs_swapext __user *sxu = arg;
/* Bulk copy in up to the sx_stat field, then copy bstat */ if (copy_from_user(&sxp, sxu,
offsetof(struct xfs_swapext, sx_stat)) ||
xfs_ioctl32_bstat_copyin(&sxp.sx_stat, &sxu->sx_stat)) return -EFAULT;
error = mnt_want_write_file(filp); if (error) return error;
error = xfs_ioc_swapext(&sxp);
mnt_drop_write_file(filp); return error;
} case XFS_IOC_FSBULKSTAT_32: case XFS_IOC_FSBULKSTAT_SINGLE_32: case XFS_IOC_FSINUMBERS_32: return xfs_compat_ioc_fsbulkstat(filp, cmd, arg); case XFS_IOC_FD_TO_HANDLE_32: case XFS_IOC_PATH_TO_HANDLE_32: case XFS_IOC_PATH_TO_FSHANDLE_32: { struct xfs_fsop_handlereq hreq;
if (xfs_compat_handlereq_copyin(&hreq, arg)) return -EFAULT;
cmd = _NATIVE_IOC(cmd, struct xfs_fsop_handlereq); return xfs_find_handle(cmd, &hreq);
} case XFS_IOC_OPEN_BY_HANDLE_32: { struct xfs_fsop_handlereq hreq;
if (xfs_compat_handlereq_copyin(&hreq, arg)) return -EFAULT; return xfs_open_by_handle(filp, &hreq);
} case XFS_IOC_READLINK_BY_HANDLE_32: { struct xfs_fsop_handlereq hreq;
if (xfs_compat_handlereq_copyin(&hreq, arg)) return -EFAULT; return xfs_readlink_by_handle(filp, &hreq);
} case XFS_IOC_ATTRLIST_BY_HANDLE_32: return xfs_compat_attrlist_by_handle(filp, arg); case XFS_IOC_ATTRMULTI_BY_HANDLE_32: return xfs_compat_attrmulti_by_handle(filp, arg); default: /* try the native version */ return xfs_file_ioctl(filp, cmd, (unsignedlong)arg);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.