mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

no_llseek had been defined to NULL two years ago, in commit 868941b144
("fs: remove no_llseek")
To quote that commit,
At -rc1 we'll need do a mechanical removal of no_llseek -
git grep -l -w no_llseek | grep -v porting.rst | while read i; do
sed -i '/\<no_llseek\>/d' $i
done
would do it.
Unfortunately, that hadn't been done. Linus, could you do that now, so
that we could finally put that thing to rest? All instances are of the
form
.llseek = no_llseek,
so it's obviously safe.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
128 lines
2.5 KiB
C
128 lines
2.5 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* IOCTL interface for SCLP
|
|
*
|
|
* Copyright IBM Corp. 2012
|
|
*
|
|
* Author: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
|
*/
|
|
|
|
#include <linux/compat.h>
|
|
#include <linux/uaccess.h>
|
|
#include <linux/miscdevice.h>
|
|
#include <linux/gfp.h>
|
|
#include <linux/init.h>
|
|
#include <linux/ioctl.h>
|
|
#include <linux/fs.h>
|
|
#include <asm/sclp_ctl.h>
|
|
#include <asm/sclp.h>
|
|
|
|
#include "sclp.h"
|
|
|
|
/*
|
|
* Supported command words
|
|
*/
|
|
static unsigned int sclp_ctl_sccb_wlist[] = {
|
|
0x00400002,
|
|
0x00410002,
|
|
};
|
|
|
|
/*
|
|
* Check if command word is supported
|
|
*/
|
|
static int sclp_ctl_cmdw_supported(unsigned int cmdw)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(sclp_ctl_sccb_wlist); i++) {
|
|
if (cmdw == sclp_ctl_sccb_wlist[i])
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void __user *u64_to_uptr(u64 value)
|
|
{
|
|
if (is_compat_task())
|
|
return compat_ptr(value);
|
|
else
|
|
return (void __user *)(unsigned long)value;
|
|
}
|
|
|
|
/*
|
|
* Start SCLP request
|
|
*/
|
|
static int sclp_ctl_ioctl_sccb(void __user *user_area)
|
|
{
|
|
struct sclp_ctl_sccb ctl_sccb;
|
|
struct sccb_header *sccb;
|
|
unsigned long copied;
|
|
int rc;
|
|
|
|
if (copy_from_user(&ctl_sccb, user_area, sizeof(ctl_sccb)))
|
|
return -EFAULT;
|
|
if (!sclp_ctl_cmdw_supported(ctl_sccb.cmdw))
|
|
return -EOPNOTSUPP;
|
|
sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
|
if (!sccb)
|
|
return -ENOMEM;
|
|
copied = PAGE_SIZE -
|
|
copy_from_user(sccb, u64_to_uptr(ctl_sccb.sccb), PAGE_SIZE);
|
|
if (offsetof(struct sccb_header, length) +
|
|
sizeof(sccb->length) > copied || sccb->length > copied) {
|
|
rc = -EFAULT;
|
|
goto out_free;
|
|
}
|
|
if (sccb->length < 8) {
|
|
rc = -EINVAL;
|
|
goto out_free;
|
|
}
|
|
rc = sclp_sync_request(ctl_sccb.cmdw, sccb);
|
|
if (rc)
|
|
goto out_free;
|
|
if (copy_to_user(u64_to_uptr(ctl_sccb.sccb), sccb, sccb->length))
|
|
rc = -EFAULT;
|
|
out_free:
|
|
free_page((unsigned long) sccb);
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* SCLP SCCB ioctl function
|
|
*/
|
|
static long sclp_ctl_ioctl(struct file *filp, unsigned int cmd,
|
|
unsigned long arg)
|
|
{
|
|
void __user *argp;
|
|
|
|
if (is_compat_task())
|
|
argp = compat_ptr(arg);
|
|
else
|
|
argp = (void __user *) arg;
|
|
switch (cmd) {
|
|
case SCLP_CTL_SCCB:
|
|
return sclp_ctl_ioctl_sccb(argp);
|
|
default: /* unknown ioctl number */
|
|
return -ENOTTY;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* File operations
|
|
*/
|
|
static const struct file_operations sclp_ctl_fops = {
|
|
.owner = THIS_MODULE,
|
|
.open = nonseekable_open,
|
|
.unlocked_ioctl = sclp_ctl_ioctl,
|
|
.compat_ioctl = sclp_ctl_ioctl,
|
|
};
|
|
|
|
/*
|
|
* Misc device definition
|
|
*/
|
|
static struct miscdevice sclp_ctl_device = {
|
|
.minor = MISC_DYNAMIC_MINOR,
|
|
.name = "sclp",
|
|
.fops = &sclp_ctl_fops,
|
|
};
|
|
builtin_misc_device(sclp_ctl_device);
|