[pnfs] [PATCH 09/10] pnfs: Enable O_DIRECT read path.

Benny Halevy bhalevy at panasas.com
Wed Jul 9 03:55:07 EDT 2008


On Jul. 09, 2008, 0:54 +0300, Dean Hildebrand <seattleplus at gmail.com> wrote:
> Signed-off-by: Dean Hildebrand <dhildeb at us.ibm.com>
> ---
>  fs/nfs/direct.c |   37 +++++++++++++++++++++++++++++++++++--
>  1 files changed, 35 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
> index 854ed47..a397a9c 100644
> --- a/fs/nfs/direct.c
> +++ b/fs/nfs/direct.c
> @@ -55,6 +55,7 @@
>  
>  #include "internal.h"
>  #include "iostat.h"
> +#include "pnfs.h"
>  
>  #define NFSDBG_FACILITY		NFSDBG_VFS
>  
> @@ -189,12 +190,22 @@ static ssize_t nfs_direct_wait(struct nfs_direct_req *dreq)
>  {
>  	ssize_t result = -EIOCBQUEUED;
>  
> +	if (!pnfs_use_rpc(NFS_SERVER(dreq->inode))) {
> +		/* FIXME: Right now non-rpc layout types must perform
> +		 * syncronous direct i/o.
> +		 * New pNFS callback to wait on outstanding requests?
> +		 */
> +		result = 0;

Hmm, why not just set result = dreq->error?
and place the label right before the next condition?

> +		goto set_result;
> +	}
> +
>  	/* Async requests don't wait here */
>  	if (dreq->iocb)
>  		goto out;
>  
>  	result = wait_for_completion_killable(&dreq->completion);
>  
> +set_result:
>  	if (!result)
>  		result = dreq->error;
>  	if (!result)
> @@ -329,6 +340,16 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
>  	unsigned int pgbase;
>  	int result;
>  	ssize_t started = 0;
> +	size_t pnfs_stripe_rem = count;
> +
> +	/* pnfs_stripe_rem will be set to the remaining bytes in
> +	 * the first stripe_unit (which for standard nfs is count)
> +	 */
> +	pnfs_direct_init_io(inode, ctx, count, pos, 0, &rsize,
> +			    &pnfs_stripe_rem);
> +
> +	dprintk("%s: pos %llu count %Zu wsize %Zu\n",
> +		__func__, pos, count, rsize);
>  
>  	do {
>  		struct nfs_read_data *data;
> @@ -336,6 +357,10 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
>  
>  		pgbase = user_addr & ~PAGE_MASK;
>  		bytes = min(rsize,count);
> +#if defined(CONFIG_PNFS)
> +		bytes = min(bytes, pnfs_stripe_rem);
> +		pnfs_stripe_rem = rsize;
> +#endif /* CONFIG_PNFS */
>  
>  		result = -ENOMEM;
>  		data = nfs_readdata_alloc(nfs_page_array_len(pgbase, bytes));
> @@ -377,8 +402,16 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
>  		data->res.eof = 0;
>  		data->res.count = bytes;
>  
> -		if (nfs_direct_read_execute(data, &task_setup_data, &msg))
> -		    break;
> +		result = pnfs_try_to_read_data(data, &nfs_read_direct_ops);
> +#if defined(CONFIG_PNFS)
> +		if (result == PNFS_ATTEMPTED && data->pdata.pnfs_error) {
> +			result = data->pdata.pnfs_error;
> +			break;
> +		}
> +#endif /* CONFIG_PNFS */
> +		if (result == PNFS_NOT_ATTEMPTED &&
> +		    nfs_direct_read_execute(data, &task_setup_data, &msg))
> +			break;
>  
>  		started += bytes;
>  		user_addr += bytes;



More information about the pNFS mailing list