[pnfs] [PATCH 05/14] 2.6-latest pnfs client read path layoutget

Benny Halevy bhalevy at panasas.com
Mon Nov 19 11:41:38 EST 2007


andros at umich.edu wrote:
> From: Andy Adamson <andros at umich.edu>
> 
> Use the pNFS ds_rsize for read pageio and ask for a layout.
> 
> Signed-off by: Andy Adamson<andros at umich.edu>
> ---
>  fs/nfs/nfs4proc.c |    1 -
>  fs/nfs/pnfs.c     |   35 +++++++++++++++++++++++++++++++++--
>  fs/nfs/pnfs.h     |   20 +++++++++++++++++++-
>  fs/nfs/read.c     |    7 +++++++
>  4 files changed, 59 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index 79f8e93..7e1eb68 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -5252,7 +5252,6 @@ const struct nfs_rpc_ops pnfs_v41_clientops = {
>  	.file_open      = nfs_open,
>  	.file_release   = nfs_release,
>  	.lock		= nfs4_proc_lock,
> -	.rsize		= pnfs_rsize,
>  	.wsize		= pnfs_wsize,
>  	.rpages		= pnfs_rpages,
>  	.wpages		= pnfs_wpages,
> diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
> index 3f765ad..90b78db 100644
> --- a/fs/nfs/pnfs.c
> +++ b/fs/nfs/pnfs.c
> @@ -439,6 +439,38 @@ pnfs_inject_layout(struct nfs_inode* nfsi,
>  	return io_ops->set_layout(layid, inode, lgr);
>  }
>  
> +void
> +pnfs_update_layout_read(struct inode *inode,
> +			struct nfs_open_context *ctx,
> +			struct list_head *pages,
> +			loff_t offset,
> +			size_t *rsize)
> +{
> +	struct nfs_server *nfss = NFS_SERVER(inode);
> +	struct page *page;
> +	size_t count = 0;
> +	int status = 0;
> +
> +	dprintk("--> %s inode %p ctx %p pages %p offset %lu\n",
> +		__func__, inode, ctx, pages, (unsigned long)offset);
> +
> +	if (!pnfs_enabled_sb(nfss))
> +		return;
> +
> +	/* Calculate the total read-ahead count */
> +	list_for_each_entry(page, pages, lru)
> +		count += pnfs_page_length(page, inode);
> +
> +	dprintk("%s count %ld\n", __func__,(long int)count);
> +
> +	*rsize = pnfs_rsize(inode, count);

I'd consider implementing pnfs_rsize inline here since if
count >= 0 && below_threshold(inode, count, 0) I don't see 
the point of getting the layout.

> +
> +	status = virtual_update_layout(inode, ctx, count,
> +						offset, IOMODE_RW);
> +	dprintk("%s *rsize %Zd virt update returned %d\n",
> +					__func__, *rsize, status);
> +}
> +
>  /* Check to see if the module is handling which layouts need to be
>   * retrieved from the server.  If they are not, then use retrieve based
>   * upon the returned data ranges from get_layout.
> @@ -1483,12 +1515,11 @@ struct pnfs_client_operations pnfs_ops = {
>  };
>  
>  int
> -pnfs_rsize(struct inode *inode, unsigned int count, struct nfs_read_data *rdata)
> +pnfs_rsize(struct inode *inode, unsigned int count)
>  {
>  	if (count >= 0 && below_threshold(inode, count, 0))
>  		return NFS_SERVER(inode)->rsize;
>  
> -	rdata->pnfsflags |= PNFS_USE_DS;
>  	return NFS_SERVER(inode)->ds_rsize;
>  }
>  
> diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
> index edfc732..681443c 100644
> --- a/fs/nfs/pnfs.h
> +++ b/fs/nfs/pnfs.h
> @@ -46,13 +46,31 @@ int pnfs_use_nfsv4_rproto(struct inode *inode, ssize_t count);
>  unsigned int pnfs_getiosize(struct nfs_server *server);
>  int pnfs_commit(struct inode* inode, struct list_head *head, int sync, struct nfs_write_data *data);
>  int pnfs_try_to_commit(struct inode *, struct nfs_write_data *, struct list_head *, int);
> -int pnfs_rsize(struct inode *, unsigned int, struct nfs_read_data *);
> +int pnfs_rsize(struct inode *, unsigned int);
>  int pnfs_wsize(struct inode *, unsigned int, struct nfs_write_data *);
>  int pnfs_rpages(struct inode *);
>  int pnfs_wpages(struct inode *);
>  void pnfs_readpage_result_norpc(struct rpc_task *task, void *calldata);
>  void pnfs_writeback_done_norpc(struct rpc_task *, void *);
>  void pnfs_commit_done_norpc(struct rpc_task *, void *);
> +void pnfs_update_layout_read(struct inode *, struct nfs_open_context *, struct list_head *, loff_t, size_t *);
> +
> +
> +static inline
> +unsigned int pnfs_page_length(struct page *page, struct inode *inode)
> +{
> +	loff_t i_size = i_size_read(inode);
> +
> +	if (i_size > 0) {
> +		pgoff_t end_index = (i_size - 1) >> PAGE_CACHE_SHIFT;

4 lines below should be indented one notch to the right.

> +	if (page->index < end_index)
> +		return PAGE_CACHE_SIZE;
> +	if (page->index == end_index)

why not just "else"?

> +		return ((i_size - 1) & ~PAGE_CACHE_MASK) + 1;
> +	}
> +	return 0;
> +}
> +
>  #endif /* CONFIG_PNFS */
>  
>  #endif /* FS_NFS_PNFS_H */
> diff --git a/fs/nfs/read.c b/fs/nfs/read.c
> index dd98eca..7b07865 100644
> --- a/fs/nfs/read.c
> +++ b/fs/nfs/read.c
> @@ -22,6 +22,10 @@
>  
>  #include <asm/system.h>
>  #include <linux/module.h>
> +#ifdef CONFIG_PNFS

At some point we'd want to separate the client side config option
from the server's.

> +#include <linux/pnfs_xdr.h>
> +#include "pnfs.h"
> +#endif /* CONFIG_PNFS */
>  
>  #include "nfs4_fs.h"
>  #include "internal.h"
> @@ -635,6 +639,9 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
>  			return -EBADF;
>  	} else
>  		desc.ctx = get_nfs_open_context(nfs_file_open_context(filp));
> +#ifdef CONFIG_PNFS
> +	pnfs_update_layout_read(inode, desc.ctx, pages, filp->f_pos, &rsize);
> +#endif /* CONFIG_PNFS */
>  	if (rsize < PAGE_CACHE_SIZE)
>  		nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0);
>  	else



More information about the pNFS mailing list