On Wed, 13 Sep 2006 22:12:54 +0400 "Vladimir V. Saveliev" <[EMAIL PROTECTED]> wrote:
> Hello, Andrew > > reiser4 in 2.6.18-rc6-mm2 has a bug. It can not do readv. > > The attached patch fixes it by implementing reiser4' aio_read file operation. > Unfortunately, it appeared to get a loop which is very similar to the one of > fs/read_write.c:do_loop_readv_writev(). > Alternatively, if do_loop_readv_writev were EXPORT_SYMBOL-ed > reiser4' aio_read could use it instead. But, there is a problem with > do_loop_readv_writev EXPORT_SYMBOL-ing: > one if its arguments is io_fn_t, which is declared in fs/read_write.h. > If it is ok to move io_fn_t and do_loop_readv_writev declarations to > include/linux/fs.h and to EXPORT_SYMBOL > do_loop_readv_writev the fix will be smaller. Please, let me know what would > you prefer. > Yes, I'd say that do_loop_readv_writev() is suitable for exporting to filesystems, and that doing so is preferable to duplicating it. That'd be two patches, please: one to do the export and one to use it in reiser4. I assume there's a good reason why reiser4 cannot use generic_file_aio_read() or vfs_readv(). Please capture that discussion in the changelog for the first patch, thanks. > From: Vladimir Saveliev <[EMAIL PROTECTED]> > > This patch adds implementation of aio_read file operation for reiser4. > It is needed because in reiser4 there are files which can not be dealt > with via generic page cache routines. > In case of readv, reiser4 has no meaning to find out file type and to choose > proper > way to read it. As result generic page cache read gets called for files which > can not be > read that way. Reiser4' aio_read method is to fix that problem. > > Signed-off-by: Vladimir Saveliev <[EMAIL PROTECTED]> > > > > > diff -puN fs/reiser4/plugin/object.c~reiser4-add-aio_read > fs/reiser4/plugin/object.c > --- linux-2.6.18-rc6-mm2/fs/reiser4/plugin/object.c~reiser4-add-aio_read > 2006-09-13 20:18:23.000000000 +0400 > +++ linux-2.6.18-rc6-mm2-vs/fs/reiser4/plugin/object.c 2006-09-13 > 20:18:23.000000000 +0400 > @@ -101,7 +101,7 @@ file_plugin file_plugins[LAST_FILE_PLUGI > .llseek = generic_file_llseek, > .read = read_unix_file, > .write = do_sync_write, > - .aio_read = generic_file_aio_read, > + .aio_read = aio_read_unix_file, > .aio_write = generic_file_aio_write, > .ioctl = ioctl_unix_file, > .mmap = mmap_unix_file, > diff -puN fs/reiser4/plugin/file/file.c~reiser4-add-aio_read > fs/reiser4/plugin/file/file.c > --- linux-2.6.18-rc6-mm2/fs/reiser4/plugin/file/file.c~reiser4-add-aio_read > 2006-09-13 20:18:23.000000000 +0400 > +++ linux-2.6.18-rc6-mm2-vs/fs/reiser4/plugin/file/file.c 2006-09-13 > 20:52:30.000000000 +0400 > @@ -2011,6 +2011,54 @@ out: > return result; > } > > +/** > + * aio_read_unix_file - aio_read of struct file_operations > + * @iocb: i/o control block > + * @iov: i/o vector > + * @nr_segs: number of segments in the i/o vector > + * @pos: file position to read from > + * > + * When it is called within reiser4 context (this happens when sys_read is > + * reading a file built of extents) - just call generic_file_aio_read to > + * perform read into page cache. When it is called without reiser4 context > + * (sys_readv) - call read_unix_file for each segments of i/o vector, so that > + * read_unix_file will be able to choose whether the file is to be read into > + * page cache or the file is built of tail items and page cache read is not > + * suitable for it. > + */ > +ssize_t aio_read_unix_file(struct kiocb *iocb, const struct iovec *iov, > + unsigned long nr_segs, loff_t pos) > +{ > + ssize_t ret = 0; > + > + if (is_in_reiser4_context()) > + return generic_file_aio_read(iocb, iov, nr_segs, pos); > + > + while (nr_segs > 0) { > + void __user *base; > + size_t len; > + ssize_t nr; > + > + base = iov->iov_base; > + len = iov->iov_len; > + iov++; > + nr_segs--; > + > + nr = read_unix_file(iocb->ki_filp, base, len, &iocb->ki_pos); > + if (nr < 0) { > + if (!ret) > + ret = nr; > + break; > + } > + ret += nr; > + if (nr != len) > + break; > + } > + > + return ret; > + > +} > + > static ssize_t read_unix_file_container_tails( > struct file *file, char __user *buf, size_t read_amount, loff_t *off) > { > diff -puN fs/reiser4/plugin/file/file.h~reiser4-add-aio_read > fs/reiser4/plugin/file/file.h > --- linux-2.6.18-rc6-mm2/fs/reiser4/plugin/file/file.h~reiser4-add-aio_read > 2006-09-13 20:18:23.000000000 +0400 > +++ linux-2.6.18-rc6-mm2-vs/fs/reiser4/plugin/file/file.h 2006-09-13 > 20:18:23.000000000 +0400 > @@ -15,6 +15,8 @@ int setattr_unix_file(struct dentry *, s > /* file operations */ > ssize_t read_unix_file(struct file *, char __user *buf, size_t read_amount, > loff_t *off); > +ssize_t aio_read_unix_file(struct kiocb *, const struct iovec *, > + unsigned long nr_segs, loff_t pos); > ssize_t write_unix_file(struct file *, const char __user *buf, size_t > write_amount, > loff_t * off); > int ioctl_unix_file(struct inode *, struct file *, unsigned int cmd, > > _