[XFS] Make the bulkstat_one compat ioctl handling more sane
Currently the compat formatter was handled by passing in "private_data" for the xfs_bulkstat_one formatter, which was really just another formatter... IMHO this got confusing. Instead, just make a new xfs_bulkstat_one_compat formatter for xfs_bulkstat, and call it via a wrapper. Also, don't translate the ioctl nrs into their native counterparts, that just clouds the issue; we're in a compat handler anyway, just switch on the 32-bit cmds. Signed-off-by: Eric Sandeen <sandeen@sandeen.net> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
This commit is contained in:
parent
471d591031
commit
2ee4fa5cb7
3 changed files with 56 additions and 16 deletions
|
@ -223,14 +223,30 @@ xfs_bulkstat_one_fmt_compat(
|
|||
return sizeof(*p32);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_bulkstat_one_compat(
|
||||
xfs_mount_t *mp, /* mount point for filesystem */
|
||||
xfs_ino_t ino, /* inode number to get data for */
|
||||
void __user *buffer, /* buffer to place output in */
|
||||
int ubsize, /* size of buffer */
|
||||
void *private_data, /* my private data */
|
||||
xfs_daddr_t bno, /* starting bno of inode cluster */
|
||||
int *ubused, /* bytes used by me */
|
||||
void *dibuff, /* on-disk inode buffer */
|
||||
int *stat) /* BULKSTAT_RV_... */
|
||||
{
|
||||
return xfs_bulkstat_one_int(mp, ino, buffer, ubsize,
|
||||
xfs_bulkstat_one_fmt_compat, bno,
|
||||
ubused, dibuff, stat);
|
||||
}
|
||||
|
||||
/* copied from xfs_ioctl.c */
|
||||
STATIC int
|
||||
xfs_ioc_bulkstat_compat(
|
||||
xfs_mount_t *mp,
|
||||
unsigned int cmd,
|
||||
void __user *arg)
|
||||
xfs_compat_ioc_bulkstat(
|
||||
xfs_mount_t *mp,
|
||||
unsigned int cmd,
|
||||
compat_xfs_fsop_bulkreq_t __user *p32)
|
||||
{
|
||||
compat_xfs_fsop_bulkreq_t __user *p32 = (void __user *)arg;
|
||||
u32 addr;
|
||||
xfs_fsop_bulkreq_t bulkreq;
|
||||
int count; /* # of records returned */
|
||||
|
@ -267,14 +283,12 @@ xfs_ioc_bulkstat_compat(
|
|||
if (bulkreq.ubuffer == NULL)
|
||||
return -XFS_ERROR(EINVAL);
|
||||
|
||||
if (cmd == XFS_IOC_FSINUMBERS)
|
||||
if (cmd == XFS_IOC_FSINUMBERS_32)
|
||||
error = xfs_inumbers(mp, &inlast, &count,
|
||||
bulkreq.ubuffer, xfs_inumbers_fmt_compat);
|
||||
else {
|
||||
/* declare a var to get a warning in case the type changes */
|
||||
bulkstat_one_fmt_pf formatter = xfs_bulkstat_one_fmt_compat;
|
||||
error = xfs_bulkstat(mp, &inlast, &count,
|
||||
xfs_bulkstat_one, formatter,
|
||||
xfs_bulkstat_one_compat, NULL,
|
||||
sizeof(compat_xfs_bstat_t), bulkreq.ubuffer,
|
||||
BULKSTAT_FG_QUICK, &done);
|
||||
}
|
||||
|
@ -422,9 +436,7 @@ xfs_compat_ioctl(
|
|||
case XFS_IOC_FSBULKSTAT_32:
|
||||
case XFS_IOC_FSBULKSTAT_SINGLE_32:
|
||||
case XFS_IOC_FSINUMBERS_32:
|
||||
cmd = _NATIVE_IOC(cmd, struct xfs_fsop_bulkreq);
|
||||
return xfs_ioc_bulkstat_compat(XFS_I(inode)->i_mount,
|
||||
cmd, (void __user*)arg);
|
||||
return xfs_compat_ioc_bulkstat(mp, cmd, arg);
|
||||
case XFS_IOC_FD_TO_HANDLE_32:
|
||||
case XFS_IOC_PATH_TO_HANDLE_32:
|
||||
case XFS_IOC_PATH_TO_FSHANDLE_32: {
|
||||
|
|
|
@ -202,13 +202,13 @@ xfs_bulkstat_one_fmt(
|
|||
* Return stat information for one inode.
|
||||
* Return 0 if ok, else errno.
|
||||
*/
|
||||
int /* error status */
|
||||
xfs_bulkstat_one(
|
||||
int /* error status */
|
||||
xfs_bulkstat_one_int(
|
||||
xfs_mount_t *mp, /* mount point for filesystem */
|
||||
xfs_ino_t ino, /* inode number to get data for */
|
||||
void __user *buffer, /* buffer to place output in */
|
||||
int ubsize, /* size of buffer */
|
||||
void *private_data, /* my private data */
|
||||
bulkstat_one_fmt_pf formatter, /* formatter, copy to user */
|
||||
xfs_daddr_t bno, /* starting bno of inode cluster */
|
||||
int *ubused, /* bytes used by me */
|
||||
void *dibuff, /* on-disk inode buffer */
|
||||
|
@ -217,7 +217,6 @@ xfs_bulkstat_one(
|
|||
xfs_bstat_t *buf; /* return buffer */
|
||||
int error = 0; /* error value */
|
||||
xfs_dinode_t *dip; /* dinode inode pointer */
|
||||
bulkstat_one_fmt_pf formatter = private_data ? : xfs_bulkstat_one_fmt;
|
||||
|
||||
dip = (xfs_dinode_t *)dibuff;
|
||||
*stat = BULKSTAT_RV_NOTHING;
|
||||
|
@ -255,6 +254,23 @@ xfs_bulkstat_one(
|
|||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
xfs_bulkstat_one(
|
||||
xfs_mount_t *mp, /* mount point for filesystem */
|
||||
xfs_ino_t ino, /* inode number to get data for */
|
||||
void __user *buffer, /* buffer to place output in */
|
||||
int ubsize, /* size of buffer */
|
||||
void *private_data, /* my private data */
|
||||
xfs_daddr_t bno, /* starting bno of inode cluster */
|
||||
int *ubused, /* bytes used by me */
|
||||
void *dibuff, /* on-disk inode buffer */
|
||||
int *stat) /* BULKSTAT_RV_... */
|
||||
{
|
||||
return xfs_bulkstat_one_int(mp, ino, buffer, ubsize,
|
||||
xfs_bulkstat_one_fmt, bno,
|
||||
ubused, dibuff, stat);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test to see whether we can use the ondisk inode directly, based
|
||||
* on the given bulkstat flags, filling in dipp accordingly.
|
||||
|
|
|
@ -73,6 +73,18 @@ typedef int (*bulkstat_one_fmt_pf)( /* used size in bytes or negative error */
|
|||
void __user *ubuffer, /* buffer to write to */
|
||||
const xfs_bstat_t *buffer); /* buffer to read from */
|
||||
|
||||
int
|
||||
xfs_bulkstat_one_int(
|
||||
xfs_mount_t *mp,
|
||||
xfs_ino_t ino,
|
||||
void __user *buffer,
|
||||
int ubsize,
|
||||
bulkstat_one_fmt_pf formatter,
|
||||
xfs_daddr_t bno,
|
||||
int *ubused,
|
||||
void *dibuff,
|
||||
int *stat);
|
||||
|
||||
int
|
||||
xfs_bulkstat_one(
|
||||
xfs_mount_t *mp,
|
||||
|
|
Loading…
Reference in a new issue