[PATCH 437/437] REMOVE ->read() and ->write()

Jens Axboe
2024-04-11T15:43:52Z

Test patch just to check coverage.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
fs/file_table.c | 4 +--
fs/open.c | 4 +--
fs/read_write.c | 16 +++--------
include/linux/fs.h | 2 --
io_uring/rw.c | 70 ----------------------------------------------
5 files changed, 8 insertions(+), 88 deletions(-)

diff --git a/fs/file_table.c b/fs/file_table.c
index 4f03beed4737..54cf21766633 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -292,10 +292,10 @@ static void file_init_path(struct file *file, const struct path *path,
if (fop->llseek)
file->f_mode |= FMODE_LSEEK;
if ((file->f_mode & FMODE_READ) &&
- likely(fop->read || fop->read_iter))
+ likely(fop->read_iter))
file->f_mode |= FMODE_CAN_READ;
if ((file->f_mode & FMODE_WRITE) &&
- likely(fop->write || fop->write_iter))
+ likely(fop->write_iter))
file->f_mode |= FMODE_CAN_WRITE;
file->f_iocb_flags = iocb_flags(file);
file->f_mode |= FMODE_OPENED;
diff --git a/fs/open.c b/fs/open.c
index ee8460c83c77..63caada91fc5 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -958,10 +958,10 @@ static int do_dentry_open(struct file *f,
}
f->f_mode |= FMODE_OPENED;
if ((f->f_mode & FMODE_READ) &&
- likely(f->f_op->read || f->f_op->read_iter))
+ likely(f->f_op->read_iter))
f->f_mode |= FMODE_CAN_READ;
if ((f->f_mode & FMODE_WRITE) &&
- likely(f->f_op->write || f->f_op->write_iter))
+ likely(f->f_op->write_iter))
f->f_mode |= FMODE_CAN_WRITE;
if ((f->f_mode & FMODE_LSEEK) && !f->f_op->llseek)
f->f_mode &= ~FMODE_LSEEK;
diff --git a/fs/read_write.c b/fs/read_write.c
index efddd395d436..caec0998f28a 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -425,7 +425,7 @@ ssize_t __kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
* Also fail if ->read_iter and ->read are both wired up as that
* implies very convoluted semantics.
*/
- if (unlikely(!file->f_op->read_iter || file->f_op->read))
+ if (unlikely(!file->f_op->read_iter))
return warn_unsupported(file, "read");

init_sync_kiocb(&kiocb, file);
@@ -470,9 +470,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
if (count > MAX_RW_COUNT)
count = MAX_RW_COUNT;

- if (file->f_op->read)
- ret = file->f_op->read(file, buf, count, pos);
- else if (file->f_op->read_iter)
+ if (file->f_op->read_iter)
ret = new_sync_read(file, buf, count, pos);
else
ret = -EINVAL;
@@ -515,7 +513,7 @@ ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *po
* Also fail if ->write_iter and ->write are both wired up as that
* implies very convoluted semantics.
*/
- if (unlikely(!file->f_op->write_iter || file->f_op->write))
+ if (unlikely(!file->f_op->write_iter))
return warn_unsupported(file, "write");

init_sync_kiocb(&kiocb, file);
@@ -584,9 +582,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
if (count > MAX_RW_COUNT)
count = MAX_RW_COUNT;
file_start_write(file);
- if (file->f_op->write)
- ret = file->f_op->write(file, buf, count, pos);
- else if (file->f_op->write_iter)
+ if (file->f_op->write_iter)
ret = new_sync_write(file, buf, count, pos);
else
ret = -EINVAL;
@@ -972,8 +968,6 @@ static ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,

if (file->f_op->read_iter)
ret = do_iter_readv_writev(file, &iter, pos, READ, flags);
- else
- ret = do_loop_readv(file, &iter, pos, flags, file->f_op->read);
out:
if (ret >= 0)
fsnotify_access(file);
@@ -1011,8 +1005,6 @@ static ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
file_start_write(file);
if (file->f_op->write_iter)
ret = do_iter_readv_writev(file, &iter, pos, WRITE, flags);
- else
- ret = do_loop_writev(file, &iter, pos, flags, file->f_op->write);
if (ret > 0)
fsnotify_modify(file);
file_end_write(file);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 55fc02b99cf6..7606ed6b9dbc 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2009,8 +2009,6 @@ struct offset_ctx;
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
- ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
- ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
int (*iopoll)(struct kiocb *kiocb, struct io_comp_batch *,
diff --git a/io_uring/rw.c b/io_uring/rw.c
index c8d48287439e..9178b1bccb8b 100644
--- a/io_uring/rw.c
+++ b/io_uring/rw.c
@@ -474,72 +474,6 @@ static inline loff_t *io_kiocb_ppos(struct kiocb *kiocb)
return (kiocb->ki_filp->f_mode & FMODE_STREAM) ? NULL : &kiocb->ki_pos;
}

-/*
- * For files that don't have ->read_iter() and ->write_iter(), handle them
- * by looping over ->read() or ->write() manually.
- */
-static ssize_t loop_rw_iter(int ddir, struct io_rw *rw, struct iov_iter *iter)
-{
- struct kiocb *kiocb = &rw->kiocb;
- struct file *file = kiocb->ki_filp;
- ssize_t ret = 0;
- loff_t *ppos;
-
- /*
- * Don't support polled IO through this interface, and we can't
- * support non-blocking either. For the latter, this just causes
- * the kiocb to be handled from an async context.
- */
- if (kiocb->ki_flags & IOCB_HIPRI)
- return -EOPNOTSUPP;
- if ((kiocb->ki_flags & IOCB_NOWAIT) &&
- !(kiocb->ki_filp->f_flags & O_NONBLOCK))
- return -EAGAIN;
-
- ppos = io_kiocb_ppos(kiocb);
-
- while (iov_iter_count(iter)) {
- void __user *addr;
- size_t len;
- ssize_t nr;
-
- if (iter_is_ubuf(iter)) {
- addr = iter->ubuf + iter->iov_offset;
- len = iov_iter_count(iter);
- } else if (!iov_iter_is_bvec(iter)) {
- addr = iter_iov_addr(iter);
- len = iter_iov_len(iter);
- } else {
- addr = u64_to_user_ptr(rw->addr);
- len = rw->len;
- }
-
- if (ddir == READ)
- nr = file->f_op->read(file, addr, len, ppos);
- else
- nr = file->f_op->write(file, addr, len, ppos);
-
- if (nr < 0) {
- if (!ret)
- ret = nr;
- break;
- }
- ret += nr;
- if (!iov_iter_is_bvec(iter)) {
- iov_iter_advance(iter, nr);
- } else {
- rw->addr += nr;
- rw->len -= nr;
- if (!rw->len)
- break;
- }
- if (nr != len)
- break;
- }
-
- return ret;
-}
-
static void io_req_map_rw(struct io_kiocb *req, const struct iovec *iovec,
const struct iovec *fast_iov, struct iov_iter *iter)
{
@@ -702,8 +636,6 @@ static inline int io_iter_do_read(struct io_rw *rw, struct iov_iter *iter)

if (likely(file->f_op->read_iter))
return call_read_iter(file, &rw->kiocb, iter);
- else if (file->f_op->read)
- return loop_rw_iter(READ, rw, iter);
else
return -EINVAL;
}
@@ -1055,8 +987,6 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags)

if (likely(req->file->f_op->write_iter))
ret2 = call_write_iter(req->file, kiocb, &s->iter);
- else if (req->file->f_op->write)
- ret2 = loop_rw_iter(WRITE, rw, &s->iter);
else
ret2 = -EINVAL;

--
2.43.0