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(©, (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 */