Commit 011da44b authored by Al Viro's avatar Al Viro Committed by Arnd Bergmann
Browse files

compat: move FS_IOC_RESVSP_32 handling to fs/ioctl.c



... and lose the ridiculous games with compat_alloc_user_space()
there.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parent 34d3d0e6
Loading
Loading
Loading
Loading
+0 −35
Original line number Diff line number Diff line
@@ -467,41 +467,6 @@ static int rtc_ioctl(struct file *file,
	return -ENOIOCTLCMD;
}

/* on ia32 l_start is on a 32-bit boundary */
#if defined(CONFIG_X86_64)
struct space_resv_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 */
};

#define FS_IOC_RESVSP_32		_IOW ('X', 40, struct space_resv_32)
#define FS_IOC_RESVSP64_32	_IOW ('X', 42, struct space_resv_32)

/* just account for different alignment */
static int compat_ioctl_preallocate(struct file *file,
			struct space_resv_32    __user *p32)
{
	struct space_resv	__user *p = compat_alloc_user_space(sizeof(*p));

	if (copy_in_user(&p->l_type,	&p32->l_type,	sizeof(s16)) ||
	    copy_in_user(&p->l_whence,	&p32->l_whence, sizeof(s16)) ||
	    copy_in_user(&p->l_start,	&p32->l_start,	sizeof(s64)) ||
	    copy_in_user(&p->l_len,	&p32->l_len,	sizeof(s64)) ||
	    copy_in_user(&p->l_sysid,	&p32->l_sysid,	sizeof(s32)) ||
	    copy_in_user(&p->l_pid,	&p32->l_pid,	sizeof(u32)) ||
	    copy_in_user(&p->l_pad,	&p32->l_pad,	4*sizeof(u32)))
		return -EFAULT;

	return ioctl_preallocate(file, p);
}
#endif

/*
 * simple reversible transform to make our table more evenly
 * distributed after sorting.
+29 −0
Original line number Diff line number Diff line
@@ -491,6 +491,35 @@ int ioctl_preallocate(struct file *filp, void __user *argp)
	return vfs_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
}

/* on ia32 l_start is on a 32-bit boundary */
#if defined CONFIG_COMPAT && defined(CONFIG_X86_64)
/* just account for different alignment */
int compat_ioctl_preallocate(struct file *file,
				struct space_resv_32 __user *argp)
{
	struct inode *inode = file_inode(file);
	struct space_resv_32 sr;

	if (copy_from_user(&sr, argp, sizeof(sr)))
		return -EFAULT;

	switch (sr.l_whence) {
	case SEEK_SET:
		break;
	case SEEK_CUR:
		sr.l_start += file->f_pos;
		break;
	case SEEK_END:
		sr.l_start += i_size_read(inode);
		break;
	default:
		return -EINVAL;
	}

	return vfs_fallocate(file, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
}
#endif

static int file_ioctl(struct file *filp, unsigned int cmd,
		unsigned long arg)
{
+20 −0
Original line number Diff line number Diff line
@@ -29,4 +29,24 @@ struct space_resv {
					 FALLOC_FL_INSERT_RANGE |	\
					 FALLOC_FL_UNSHARE_RANGE)

/* on ia32 l_start is on a 32-bit boundary */
#if defined(CONFIG_X86_64)
struct space_resv_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 */
};

#define FS_IOC_RESVSP_32		_IOW ('X', 40, struct space_resv_32)
#define FS_IOC_RESVSP64_32	_IOW ('X', 42, struct space_resv_32)

int compat_ioctl_preallocate(struct file *, struct space_resv_32 __user *);

#endif

#endif /* _FALLOC_H_ */