Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ee4fa5c authored by sandeen@sandeen.net's avatar sandeen@sandeen.net Committed by Lachlan McIlroy
Browse files

[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: default avatarEric Sandeen <sandeen@sandeen.net>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarLachlan McIlroy <lachlan@sgi.com>
parent 471d5910
Loading
Loading
Loading
Loading
+24 −12
Original line number Diff line number Diff line
@@ -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_compat_ioc_bulkstat(
	xfs_mount_t		  *mp,
	unsigned int		  cmd,
	void			__user *arg)
	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: {
+20 −4
Original line number Diff line number Diff line
@@ -203,12 +203,12 @@ xfs_bulkstat_one_fmt(
 * Return 0 if ok, else errno.
 */
int		   	    		/* error status */
xfs_bulkstat_one(
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.
+12 −0
Original line number Diff line number Diff line
@@ -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,