[BACK]Return to xfs_ioctl32.c CVS log [TXT][DIR] Up to [Development] / xfs-linux / linux-2.4

File: [Development] / xfs-linux / linux-2.4 / Attic / xfs_ioctl32.c (download)

Revision 1.2, Fri Sep 23 03:51:28 2005 UTC (12 years ago) by nathans.longdrop.melbourne.sgi.com
Branch: MAIN
Changes since 1.1: +12 -28 lines

Update license/copyright notices to match the prefered SGI boilerplate.
Merge of xfs-linux-melb:xfs-kern:23903a by kenmcd.

/*
 * Copyright (c) 2005 Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include "xfs.h"
#include <asm/ioctl.h>

#define  _NATIVE_IOC(cmd, type) \
	   _IOC(_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), sizeof(type))

#if defined(CONFIG_PPC64) || defined(CONFIG_X86_64)
extern int register_ioctl32_conversion(unsigned int cmd,
					int (*handler)(unsigned int,
							unsigned int,
							unsigned long,
							struct file *));
extern int unregister_ioctl32_conversion(unsigned int cmd);

#if defined(CONFIG_X86_64)
#define BROKEN_X86_ALIGNMENT

extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);

/* on ia32 l_start is on a 32-bit boundary */
typedef struct xfs_flock64_32 {
	__s16		l_type;
	__s16		l_whence;
	__s64		l_start	__attribute__((packed));
				/* len == 0 means until end of file */
	__s64		l_len	__attribute__((packed));
	__s32		l_sysid;
	__u32		l_pid;
	__s32		l_pad[4];	/* reserve area	*/
} xfs_flock64_32_t;

#define XFS_IOC_ALLOCSP_32	_IOW ('X', 10, struct xfs_flock64_32)
#define XFS_IOC_FREESP_32	_IOW ('X', 11, struct xfs_flock64_32)
#define XFS_IOC_ALLOCSP64_32	_IOW ('X', 36, struct xfs_flock64_32)
#define XFS_IOC_FREESP64_32	_IOW ('X', 37, struct xfs_flock64_32)
#define XFS_IOC_RESVSP_32	_IOW ('X', 40, struct xfs_flock64_32)
#define XFS_IOC_UNRESVSP_32	_IOW ('X', 41, struct xfs_flock64_32)
#define XFS_IOC_RESVSP64_32	_IOW ('X', 42, struct xfs_flock64_32)
#define XFS_IOC_UNRESVSP64_32	_IOW ('X', 43, struct xfs_flock64_32)

/* copy xfs_flock64 into aligned version */
static int do_xfs_flock_ioctl(unsigned int fd, unsigned int cmd,
				unsigned long arg, struct file * file)
{
	int ret, i;
	mm_segment_t old_fs;
	struct xfs_flock64 flock;
	struct xfs_flock64_32 copy;

	if (copy_from_user(&copy, (struct xfs_flock64_32*) arg, 
			sizeof(struct xfs_flock64_32)))
		return -EFAULT;

	flock.l_type = copy.l_type;
	flock.l_whence = copy.l_whence;
	flock.l_start = copy.l_start;
	flock.l_len = copy.l_len;
	flock.l_sysid = copy.l_sysid;
	flock.l_pid = copy.l_pid;
	memcpy(flock.l_pad, copy.l_pad, 4*sizeof(s32));

	old_fs = get_fs();
	set_fs(KERNEL_DS);
	ret = sys_ioctl(fd, _NATIVE_IOC(cmd, struct xfs_flock64),
			(unsigned long)&flock);
	set_fs(old_fs);

	return ret;
}

#else /* PPC64, no alignment problems */
#define do_xfs_flock_ioctl NULL

#define XFS_IOC_ALLOCSP_32	XFS_IOC_ALLOCSP
#define XFS_IOC_FREESP_32	XFS_IOC_FREESP
#define XFS_IOC_ALLOCSP64_32	XFS_IOC_ALLOCSP64
#define XFS_IOC_FREESP64_32	XFS_IOC_FREESP64
#define XFS_IOC_RESVSP_32	XFS_IOC_RESVSP
#define XFS_IOC_UNRESVSP_32	XFS_IOC_UNRESVSP
#define XFS_IOC_RESVSP64_32	XFS_IOC_RESVSP64
#define XFS_IOC_UNRESVSP64_32	XFS_IOC_UNRESVSP64

#endif /* alignment handling for flock ioctls */

static struct {
	int		code;
	int		(*handler)(unsigned int,
				   unsigned int,
				   unsigned long,
				   struct file *);
} converters[] = {
	/* compatible */
	{ XFS_IOC_GETXFLAGS,		NULL },
	{ XFS_IOC_SETXFLAGS,		NULL },
	{ XFS_IOC_GETVERSION,		NULL },
	{ XFS_IOC_DIOINFO,		NULL },
	{ XFS_IOC_FSGETXATTR,		NULL },
	{ XFS_IOC_FSSETXATTR,		NULL },
	{ XFS_IOC_GETBMAP,		NULL },
	{ XFS_IOC_FSSETDM,		NULL },
	{ XFS_IOC_GETBMAPA,		NULL },
	{ XFS_IOC_FSGETXATTRA,		NULL },
	{ XFS_IOC_GETBMAPX,		NULL },
	{ XFS_IOC_FSGEOMETRY_V1,	NULL },
#ifndef BROKEN_X86_ALIGNMENT
	{ XFS_IOC_FSBULKSTAT,		NULL },
	{ XFS_IOC_FSBULKSTAT_SINGLE,	NULL },
	{ XFS_IOC_FSINUMBERS,		NULL },
	{ XFS_IOC_SWAPEXT,		NULL },
#endif
	{ XFS_IOC_FSGROWFSDATA,		NULL },
	{ XFS_IOC_FSGROWFSLOG,		NULL },
	{ XFS_IOC_FSGROWFSRT,		NULL },
	{ XFS_IOC_FSCOUNTS,		NULL },
	{ XFS_IOC_SET_RESBLKS,		NULL },
	{ XFS_IOC_GET_RESBLKS,		NULL },
	{ XFS_IOC_ERROR_INJECTION,	NULL },
	{ XFS_IOC_ERROR_CLEARALL,	NULL },
	{ XFS_IOC_FREEZE,		NULL },
	{ XFS_IOC_THAW,			NULL },
	{ XFS_IOC_FSGEOMETRY,		NULL },
	{ XFS_IOC_GOINGDOWN,		NULL },
	/* need handler */
        { XFS_IOC_ALLOCSP_32,	do_xfs_flock_ioctl },
        { XFS_IOC_FREESP_32,	do_xfs_flock_ioctl },
        { XFS_IOC_RESVSP_32,	do_xfs_flock_ioctl },
        { XFS_IOC_UNRESVSP_32,	do_xfs_flock_ioctl },
        { XFS_IOC_ALLOCSP64_32,	do_xfs_flock_ioctl },
        { XFS_IOC_FREESP64_32,	do_xfs_flock_ioctl },
        { XFS_IOC_RESVSP64_32,	do_xfs_flock_ioctl },
        { XFS_IOC_UNRESVSP64_32,do_xfs_flock_ioctl },
/* not handled
	{ XFS_IOC_PATH_TO_FSHANDLE,	NULL },
	{ XFS_IOC_PATH_TO_HANDLE,	NULL },
	{ XFS_IOC_FD_TO_HANDLE,		NULL },
	{ XFS_IOC_OPEN_BY_HANDLE,	NULL },
	{ XFS_IOC_READLINK_BY_HANDLE,	NULL },
	{ XFS_IOC_FSSETDM_BY_HANDLE,	NULL },
	{ XFS_IOC_ATTRLIST_BY_HANDLE,	NULL },
	{ XFS_IOC_ATTRMULTI_BY_HANDLE,	NULL },
*/
	{ -1 }
};

int
xfs_register_ioctl_converters(void)
{
	int	i, err = 0;

	for (i = 0; err >= 0 && converters[i].code != -1; i++) {
		err = register_ioctl32_conversion(converters[i].code,
				converters[i].handler);
	}

	if (err < 0)
		printk(KERN_ERR "xfs: Failed to register ioctl32 "
				"conversion handlers\n");
	return err;
}

int
xfs_unregister_ioctl_converters(void)
{
	int	i, err = 0;

	for (i = 0; err >= 0 && converters[i].code != -1; i++) {
		err = unregister_ioctl32_conversion(converters[i].code);
	}

	if (err < 0)
		printk(KERN_ERR "xfs: Failed to unregister ioctl32 "
				"conversion handlers\n");
	return err;
}

#else /* not ppc64 or x86_64 */

/*
 * No ioctl conversion on other platforms
 */
int
xfs_register_ioctl_converters(void)
{
	return 0;
}

int
xfs_unregister_ioctl_converters(void)
{
	return 0;
}

#endif /* 32-bit compat ioctls for ppc64 and x86_64 */