diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-04 00:11:32 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-04-11 22:29:42 -0400 |
commit | 4961772560d2f19695c73ece943716033ad62ac2 (patch) | |
tree | adab72c5c2e3fd9a374d9650f53cd6813570c313 /drivers/infiniband/hw | |
parent | 9a219bc70b54523c8f14a3c957179854785ee97c (diff) |
infinibad: weird APIs switched to ->write_iter()
Things Not To Do When Writing A Driver, part 1001st:
have writev() and write() on the same file doing completely
different things. As in, "interpret very different sets of
commands".
We _can_ handle that, but it's a bloody bad idea.
Don't do that in new drivers. Ever.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_file_ops.c | 18 | ||||
-rw-r--r-- | drivers/infiniband/hw/qib/qib_file_ops.c | 20 |
2 files changed, 23 insertions, 15 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c index aed8afee56da..450d15965005 100644 --- a/drivers/infiniband/hw/ipath/ipath_file_ops.c +++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/io.h> | 42 | #include <linux/io.h> |
43 | #include <linux/jiffies.h> | 43 | #include <linux/jiffies.h> |
44 | #include <linux/cpu.h> | 44 | #include <linux/cpu.h> |
45 | #include <linux/uio.h> | ||
45 | #include <asm/pgtable.h> | 46 | #include <asm/pgtable.h> |
46 | 47 | ||
47 | #include "ipath_kernel.h" | 48 | #include "ipath_kernel.h" |
@@ -52,15 +53,19 @@ static int ipath_open(struct inode *, struct file *); | |||
52 | static int ipath_close(struct inode *, struct file *); | 53 | static int ipath_close(struct inode *, struct file *); |
53 | static ssize_t ipath_write(struct file *, const char __user *, size_t, | 54 | static ssize_t ipath_write(struct file *, const char __user *, size_t, |
54 | loff_t *); | 55 | loff_t *); |
55 | static ssize_t ipath_writev(struct kiocb *, const struct iovec *, | 56 | static ssize_t ipath_write_iter(struct kiocb *, struct iov_iter *from); |
56 | unsigned long , loff_t); | ||
57 | static unsigned int ipath_poll(struct file *, struct poll_table_struct *); | 57 | static unsigned int ipath_poll(struct file *, struct poll_table_struct *); |
58 | static int ipath_mmap(struct file *, struct vm_area_struct *); | 58 | static int ipath_mmap(struct file *, struct vm_area_struct *); |
59 | 59 | ||
60 | /* | ||
61 | * This is really, really weird shit - write() and writev() here | ||
62 | * have completely unrelated semantics. Sucky userland ABI, | ||
63 | * film at 11. | ||
64 | */ | ||
60 | static const struct file_operations ipath_file_ops = { | 65 | static const struct file_operations ipath_file_ops = { |
61 | .owner = THIS_MODULE, | 66 | .owner = THIS_MODULE, |
62 | .write = ipath_write, | 67 | .write = ipath_write, |
63 | .aio_write = ipath_writev, | 68 | .write_iter = ipath_write_iter, |
64 | .open = ipath_open, | 69 | .open = ipath_open, |
65 | .release = ipath_close, | 70 | .release = ipath_close, |
66 | .poll = ipath_poll, | 71 | .poll = ipath_poll, |
@@ -2413,18 +2418,17 @@ bail: | |||
2413 | return ret; | 2418 | return ret; |
2414 | } | 2419 | } |
2415 | 2420 | ||
2416 | static ssize_t ipath_writev(struct kiocb *iocb, const struct iovec *iov, | 2421 | static ssize_t ipath_write_iter(struct kiocb *iocb, struct iov_iter *from) |
2417 | unsigned long dim, loff_t off) | ||
2418 | { | 2422 | { |
2419 | struct file *filp = iocb->ki_filp; | 2423 | struct file *filp = iocb->ki_filp; |
2420 | struct ipath_filedata *fp = filp->private_data; | 2424 | struct ipath_filedata *fp = filp->private_data; |
2421 | struct ipath_portdata *pd = port_fp(filp); | 2425 | struct ipath_portdata *pd = port_fp(filp); |
2422 | struct ipath_user_sdma_queue *pq = fp->pq; | 2426 | struct ipath_user_sdma_queue *pq = fp->pq; |
2423 | 2427 | ||
2424 | if (!dim) | 2428 | if (!iter_is_iovec(from) || !from->nr_segs) |
2425 | return -EINVAL; | 2429 | return -EINVAL; |
2426 | 2430 | ||
2427 | return ipath_user_sdma_writev(pd->port_dd, pq, iov, dim); | 2431 | return ipath_user_sdma_writev(pd->port_dd, pq, from->iov, from->nr_segs); |
2428 | } | 2432 | } |
2429 | 2433 | ||
2430 | static struct class *ipath_class; | 2434 | static struct class *ipath_class; |
diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c index 14046f5a37fa..9ea6c440a00c 100644 --- a/drivers/infiniband/hw/qib/qib_file_ops.c +++ b/drivers/infiniband/hw/qib/qib_file_ops.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <asm/pgtable.h> | 43 | #include <asm/pgtable.h> |
44 | #include <linux/delay.h> | 44 | #include <linux/delay.h> |
45 | #include <linux/export.h> | 45 | #include <linux/export.h> |
46 | #include <linux/uio.h> | ||
46 | 47 | ||
47 | #include "qib.h" | 48 | #include "qib.h" |
48 | #include "qib_common.h" | 49 | #include "qib_common.h" |
@@ -54,15 +55,19 @@ | |||
54 | static int qib_open(struct inode *, struct file *); | 55 | static int qib_open(struct inode *, struct file *); |
55 | static int qib_close(struct inode *, struct file *); | 56 | static int qib_close(struct inode *, struct file *); |
56 | static ssize_t qib_write(struct file *, const char __user *, size_t, loff_t *); | 57 | static ssize_t qib_write(struct file *, const char __user *, size_t, loff_t *); |
57 | static ssize_t qib_aio_write(struct kiocb *, const struct iovec *, | 58 | static ssize_t qib_write_iter(struct kiocb *, struct iov_iter *); |
58 | unsigned long, loff_t); | ||
59 | static unsigned int qib_poll(struct file *, struct poll_table_struct *); | 59 | static unsigned int qib_poll(struct file *, struct poll_table_struct *); |
60 | static int qib_mmapf(struct file *, struct vm_area_struct *); | 60 | static int qib_mmapf(struct file *, struct vm_area_struct *); |
61 | 61 | ||
62 | /* | ||
63 | * This is really, really weird shit - write() and writev() here | ||
64 | * have completely unrelated semantics. Sucky userland ABI, | ||
65 | * film at 11. | ||
66 | */ | ||
62 | static const struct file_operations qib_file_ops = { | 67 | static const struct file_operations qib_file_ops = { |
63 | .owner = THIS_MODULE, | 68 | .owner = THIS_MODULE, |
64 | .write = qib_write, | 69 | .write = qib_write, |
65 | .aio_write = qib_aio_write, | 70 | .write_iter = qib_write_iter, |
66 | .open = qib_open, | 71 | .open = qib_open, |
67 | .release = qib_close, | 72 | .release = qib_close, |
68 | .poll = qib_poll, | 73 | .poll = qib_poll, |
@@ -2248,17 +2253,16 @@ bail: | |||
2248 | return ret; | 2253 | return ret; |
2249 | } | 2254 | } |
2250 | 2255 | ||
2251 | static ssize_t qib_aio_write(struct kiocb *iocb, const struct iovec *iov, | 2256 | static ssize_t qib_write_iter(struct kiocb *iocb, struct iov_iter *from) |
2252 | unsigned long dim, loff_t off) | ||
2253 | { | 2257 | { |
2254 | struct qib_filedata *fp = iocb->ki_filp->private_data; | 2258 | struct qib_filedata *fp = iocb->ki_filp->private_data; |
2255 | struct qib_ctxtdata *rcd = ctxt_fp(iocb->ki_filp); | 2259 | struct qib_ctxtdata *rcd = ctxt_fp(iocb->ki_filp); |
2256 | struct qib_user_sdma_queue *pq = fp->pq; | 2260 | struct qib_user_sdma_queue *pq = fp->pq; |
2257 | 2261 | ||
2258 | if (!dim || !pq) | 2262 | if (!iter_is_iovec(from) || !from->nr_segs || !pq) |
2259 | return -EINVAL; | 2263 | return -EINVAL; |
2260 | 2264 | ||
2261 | return qib_user_sdma_writev(rcd, pq, iov, dim); | 2265 | return qib_user_sdma_writev(rcd, pq, from->iov, from->nr_segs); |
2262 | } | 2266 | } |
2263 | 2267 | ||
2264 | static struct class *qib_class; | 2268 | static struct class *qib_class; |