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,
> 
> _

Reply via email to