Loading fs/read_write.c +23 −31 Original line number Diff line number Diff line Loading @@ -695,25 +695,23 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to) } EXPORT_SYMBOL(iov_shorten); static ssize_t do_iter_readv_writev(struct file *filp, int rw, const struct iovec *iov, unsigned long nr_segs, size_t len, loff_t *ppos, iter_fn_t fn) static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, loff_t *ppos, iter_fn_t fn) { struct kiocb kiocb; struct iov_iter iter; ssize_t ret; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; iov_iter_init(&iter, rw, iov, nr_segs, len); ret = fn(&kiocb, &iter); ret = fn(&kiocb, iter); BUG_ON(ret == -EIOCBQUEUED); *ppos = kiocb.ki_pos; return ret; } static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn) static ssize_t do_sync_readv_writev(struct file *filp, struct iov_iter *iter, loff_t *ppos, iov_fn_t fn) { struct kiocb kiocb; ssize_t ret; Loading @@ -721,30 +719,23 @@ static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos); ret = fn(&kiocb, iter->iov, iter->nr_segs, kiocb.ki_pos); BUG_ON(ret == -EIOCBQUEUED); *ppos = kiocb.ki_pos; return ret; } /* Do it by hand, with file-ops */ static ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, unsigned long nr_segs, loff_t *ppos, io_fn_t fn) static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter, loff_t *ppos, io_fn_t fn) { struct iovec *vector = iov; ssize_t ret = 0; while (nr_segs > 0) { void __user *base; size_t len; while (iov_iter_count(iter)) { struct iovec iovec = iov_iter_iovec(iter); ssize_t nr; base = vector->iov_base; len = vector->iov_len; vector++; nr_segs--; nr = fn(filp, base, len, ppos); nr = fn(filp, iovec.iov_base, iovec.iov_len, ppos); if (nr < 0) { if (!ret) Loading @@ -752,8 +743,9 @@ static ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, break; } ret += nr; if (nr != len) if (nr != iovec.iov_len) break; iov_iter_advance(iter, nr); } return ret; Loading Loading @@ -844,6 +836,7 @@ static ssize_t do_readv_writev(int type, struct file *file, size_t tot_len; struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; struct iov_iter iter; ssize_t ret; io_fn_t fn; iov_fn_t fnv; Loading @@ -853,6 +846,7 @@ static ssize_t do_readv_writev(int type, struct file *file, ARRAY_SIZE(iovstack), iovstack, &iov); if (ret <= 0) goto out; iov_iter_init(&iter, type, iov, nr_segs, ret); tot_len = ret; ret = rw_verify_area(type, file, pos, tot_len); Loading @@ -872,13 +866,11 @@ static ssize_t do_readv_writev(int type, struct file *file, } if (iter_fn) ret = do_iter_readv_writev(file, type, iov, nr_segs, tot_len, pos, iter_fn); ret = do_iter_readv_writev(file, &iter, pos, iter_fn); else if (fnv) ret = do_sync_readv_writev(file, iov, nr_segs, tot_len, pos, fnv); ret = do_sync_readv_writev(file, &iter, pos, fnv); else ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn); ret = do_loop_readv_writev(file, &iter, pos, fn); if (type != READ) file_end_write(file); Loading Loading @@ -1024,6 +1016,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, compat_ssize_t tot_len; struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; struct iov_iter iter; ssize_t ret; io_fn_t fn; iov_fn_t fnv; Loading @@ -1033,6 +1026,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, UIO_FASTIOV, iovstack, &iov); if (ret <= 0) goto out; iov_iter_init(&iter, type, iov, nr_segs, ret); tot_len = ret; ret = rw_verify_area(type, file, pos, tot_len); Loading @@ -1052,13 +1046,11 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, } if (iter_fn) ret = do_iter_readv_writev(file, type, iov, nr_segs, tot_len, pos, iter_fn); ret = do_iter_readv_writev(file, &iter, pos, iter_fn); else if (fnv) ret = do_sync_readv_writev(file, iov, nr_segs, tot_len, pos, fnv); ret = do_sync_readv_writev(file, &iter, pos, fnv); else ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn); ret = do_loop_readv_writev(file, &iter, pos, fn); if (type != READ) file_end_write(file); Loading Loading
fs/read_write.c +23 −31 Original line number Diff line number Diff line Loading @@ -695,25 +695,23 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to) } EXPORT_SYMBOL(iov_shorten); static ssize_t do_iter_readv_writev(struct file *filp, int rw, const struct iovec *iov, unsigned long nr_segs, size_t len, loff_t *ppos, iter_fn_t fn) static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter, loff_t *ppos, iter_fn_t fn) { struct kiocb kiocb; struct iov_iter iter; ssize_t ret; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; iov_iter_init(&iter, rw, iov, nr_segs, len); ret = fn(&kiocb, &iter); ret = fn(&kiocb, iter); BUG_ON(ret == -EIOCBQUEUED); *ppos = kiocb.ki_pos; return ret; } static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn) static ssize_t do_sync_readv_writev(struct file *filp, struct iov_iter *iter, loff_t *ppos, iov_fn_t fn) { struct kiocb kiocb; ssize_t ret; Loading @@ -721,30 +719,23 @@ static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos); ret = fn(&kiocb, iter->iov, iter->nr_segs, kiocb.ki_pos); BUG_ON(ret == -EIOCBQUEUED); *ppos = kiocb.ki_pos; return ret; } /* Do it by hand, with file-ops */ static ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, unsigned long nr_segs, loff_t *ppos, io_fn_t fn) static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter, loff_t *ppos, io_fn_t fn) { struct iovec *vector = iov; ssize_t ret = 0; while (nr_segs > 0) { void __user *base; size_t len; while (iov_iter_count(iter)) { struct iovec iovec = iov_iter_iovec(iter); ssize_t nr; base = vector->iov_base; len = vector->iov_len; vector++; nr_segs--; nr = fn(filp, base, len, ppos); nr = fn(filp, iovec.iov_base, iovec.iov_len, ppos); if (nr < 0) { if (!ret) Loading @@ -752,8 +743,9 @@ static ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, break; } ret += nr; if (nr != len) if (nr != iovec.iov_len) break; iov_iter_advance(iter, nr); } return ret; Loading Loading @@ -844,6 +836,7 @@ static ssize_t do_readv_writev(int type, struct file *file, size_t tot_len; struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; struct iov_iter iter; ssize_t ret; io_fn_t fn; iov_fn_t fnv; Loading @@ -853,6 +846,7 @@ static ssize_t do_readv_writev(int type, struct file *file, ARRAY_SIZE(iovstack), iovstack, &iov); if (ret <= 0) goto out; iov_iter_init(&iter, type, iov, nr_segs, ret); tot_len = ret; ret = rw_verify_area(type, file, pos, tot_len); Loading @@ -872,13 +866,11 @@ static ssize_t do_readv_writev(int type, struct file *file, } if (iter_fn) ret = do_iter_readv_writev(file, type, iov, nr_segs, tot_len, pos, iter_fn); ret = do_iter_readv_writev(file, &iter, pos, iter_fn); else if (fnv) ret = do_sync_readv_writev(file, iov, nr_segs, tot_len, pos, fnv); ret = do_sync_readv_writev(file, &iter, pos, fnv); else ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn); ret = do_loop_readv_writev(file, &iter, pos, fn); if (type != READ) file_end_write(file); Loading Loading @@ -1024,6 +1016,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, compat_ssize_t tot_len; struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; struct iov_iter iter; ssize_t ret; io_fn_t fn; iov_fn_t fnv; Loading @@ -1033,6 +1026,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, UIO_FASTIOV, iovstack, &iov); if (ret <= 0) goto out; iov_iter_init(&iter, type, iov, nr_segs, ret); tot_len = ret; ret = rw_verify_area(type, file, pos, tot_len); Loading @@ -1052,13 +1046,11 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, } if (iter_fn) ret = do_iter_readv_writev(file, type, iov, nr_segs, tot_len, pos, iter_fn); ret = do_iter_readv_writev(file, &iter, pos, iter_fn); else if (fnv) ret = do_sync_readv_writev(file, iov, nr_segs, tot_len, pos, fnv); ret = do_sync_readv_writev(file, &iter, pos, fnv); else ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn); ret = do_loop_readv_writev(file, &iter, pos, fn); if (type != READ) file_end_write(file); Loading