From: Jens Axboe Date: Fri, 5 Apr 2024 19:17:56 +0000 (-0600) Subject: fs: finally remove ->read() and ->write() from file_operations X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=refs%2Fheads%2Frw_iter;p=linux-2.6-block.git fs: finally remove ->read() and ->write() from file_operations There are no longer any in-kernel users of these, kill it with fire. Signed-off-by: Jens Axboe --- diff --git a/fs/file_table.c b/fs/file_table.c index eed5ffad9997..b6b791674905 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -299,10 +299,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 acaeb3e25c88..008282375d69 100644 --- a/fs/open.c +++ b/fs/open.c @@ -961,10 +961,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 895f6d833285..8579f6ef5b55 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -518,7 +518,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); @@ -563,9 +563,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; @@ -608,7 +606,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); @@ -677,9 +675,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; @@ -1065,8 +1061,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); @@ -1104,8 +1098,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 3bb107188934..fa37de84d2b1 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2066,8 +2066,6 @@ struct file_operations { struct module *owner; fop_flags_t fop_flags; 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 80ae3c2ebb70..78ebb2d40861 100644 --- a/io_uring/rw.c +++ b/io_uring/rw.c @@ -623,72 +623,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; -} - /* * This is our waitqueue callback handler, registered through __folio_lock_async() * when we initially tried to do the IO with the iocb armed our waitqueue. @@ -769,10 +703,7 @@ static inline int io_iter_do_read(struct io_rw *rw, struct iov_iter *iter) if (likely(file->f_op->read_iter)) return file->f_op->read_iter(&rw->kiocb, iter); - else if (file->f_op->read) - return loop_rw_iter(READ, rw, iter); - else - return -EINVAL; + return -EINVAL; } static bool need_complete_io(struct io_kiocb *req) @@ -1055,12 +986,9 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags) kiocb_start_write(kiocb); kiocb->ki_flags |= IOCB_WRITE; + ret2 = -EINVAL; if (likely(req->file->f_op->write_iter)) ret2 = req->file->f_op->write_iter(kiocb, &io->iter); - else if (req->file->f_op->write) - ret2 = loop_rw_iter(WRITE, rw, &io->iter); - else - ret2 = -EINVAL; if (req->flags & REQ_F_REISSUE) { req->flags &= ~REQ_F_REISSUE;