[pnfs] [PATCH 10/11] pnfs: remove error return from nfs_read_rpcsetup

Benny Halevy bhalevy at panasas.com
Sun Apr 13 11:52:41 EDT 2008


On Apr. 10, 2008, 17:05 +0300, Fred Isaman <iisaman at citi.umich.edu> wrote:
> This is expected to be an async call, in fact nfs_pagein_multi relies
> on this.  Further, if my understanding of the code is correct, "passing
> the error up" is pointless, since they are eventually ignored.
> do_generic_file_read calls nfs_readpages through the readahead code,
> ignoring any error there because it is just readahead.  Later, a cache
> miss will cause nfs_readpage to be called, but nfs_readpage_async ignores
> any errors and always returns 0
> 
> Signed-off-by: Fred Isaman <iisaman at citi.umich.edu>

NACK for now.
As mentioned on previous patch, I'm looking into this
and will propose a generic fix to Trond.

Benny

> ---
>  fs/nfs/internal.h |    2 +-
>  fs/nfs/read.c     |   42 ++++++++++++++----------------------------
>  2 files changed, 15 insertions(+), 29 deletions(-)
> 
> diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
> index 07eea8e..00afd05 100644
> --- a/fs/nfs/internal.h
> +++ b/fs/nfs/internal.h
> @@ -203,7 +203,7 @@ extern int nfs4_path_walk(struct nfs_server *server,
>  #endif
>  
>  /* read.c */
> -extern int nfs_initiate_read(struct nfs_read_data *data, struct rpc_clnt *clnt,
> +extern void nfs_initiate_read(struct nfs_read_data *data, struct rpc_clnt *clnt,
>  			     const struct rpc_call_ops *call_ops);
>  extern int nfs_read_validate(struct rpc_task *task, void *calldata);
>  extern void nfs_readdata_release(void *data);
> diff --git a/fs/nfs/read.c b/fs/nfs/read.c
> index 019abb9..7381951 100644
> --- a/fs/nfs/read.c
> +++ b/fs/nfs/read.c
> @@ -159,7 +159,7 @@ static void nfs_readpage_release(struct nfs_page *req)
>  	nfs_release_request(req);
>  }
>  
> -int nfs_initiate_read(struct nfs_read_data *data, struct rpc_clnt *clnt,
> +void nfs_initiate_read(struct nfs_read_data *data, struct rpc_clnt *clnt,
>  		      const struct rpc_call_ops *call_ops)
>  {
>  	struct inode *inode = data->inode;
> @@ -190,22 +190,19 @@ int nfs_initiate_read(struct nfs_read_data *data, struct rpc_clnt *clnt,
>  			(unsigned long long)data->args.offset);
>  
>  	task = rpc_run_task(&task_setup_data);
> -	if (unlikely(IS_ERR(task)))
> -		return PTR_ERR(task);
> -	rpc_put_task(task);
> -	return 0;
> +	if (!IS_ERR(task))
> +		rpc_put_task(task);
>  }
>  EXPORT_SYMBOL(nfs_initiate_read);
>  
>  /*
>   * Set up the NFS read request struct
>   */
> -static int nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
> +static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
>  		const struct rpc_call_ops *call_ops,
>  		unsigned int count, unsigned int offset)
>  {
>  	struct inode *inode = req->wb_context->path.dentry->d_inode;
> -	int ret;
>  
>  	data->req	  = req;
>  	data->inode	  = inode;
> @@ -223,11 +220,9 @@ static int nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
>  	data->res.eof     = 0;
>  	nfs_fattr_init(&data->fattr);
>  
> -	ret = pnfs_try_to_read_data(data, call_ops);
> -	if (ret == 0)
> -		return data->pnfs_error;
> -
> -	return nfs_initiate_read(data, NFS_CLIENT(inode), call_ops);
> +	if (pnfs_try_to_read_data(data, call_ops) == 0)
> +		return;
> +	nfs_initiate_read(data, NFS_CLIENT(inode), call_ops);
>  }
>  
>  static void
> @@ -263,7 +258,7 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigne
>  	struct nfs_read_data *data;
>  	size_t rsize = NFS_SERVER(inode)->rsize, nbytes;
>  	unsigned int offset;
> -	int requests = 0, status = -ENOMEM;
> +	int requests = 0;
>  	LIST_HEAD(list);
>  
>  	nfs_list_remove_request(req);
> @@ -294,15 +289,8 @@ static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigne
>  
>  		if (nbytes < rsize)
>  			rsize = nbytes;
> -		status = nfs_read_rpcsetup(req, data, &nfs_read_partial_ops,
> -					   rsize, offset);
> -		if (status) {
> -			/* FIXME - this is broken. Cleanup code assumes
> -			 * nothing  outstanding.  Further, if triggered on
> -			 * last list entry, req will be double-freed.
> -			 */
> -			goto out_bad;
> -		}
> +		nfs_read_rpcsetup(req, data, &nfs_read_partial_ops,
> +				  rsize, offset);
>  		offset += rsize;
>  		nbytes -= rsize;
>  	} while (nbytes != 0);
> @@ -317,7 +305,7 @@ out_bad:
>  	}
>  	SetPageError(page);
>  	nfs_readpage_release(req);
> -	return status;
> +	return -ENOMEM;
>  }
>  
>  static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int flags)
> @@ -325,7 +313,6 @@ static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned
>  	struct nfs_page		*req;
>  	struct page		**pages;
>  	struct nfs_read_data	*data;
> -	int			status = -ENOMEM;
>  
>  	data = nfs_readdata_alloc(npages);
>  	if (!data)
> @@ -343,12 +330,11 @@ static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned
>  	}
>  	req = nfs_list_entry(data->pages.next);
>  
> -	status = nfs_read_rpcsetup(req, data, &nfs_read_full_ops, count, 0);
> -	if (!status)
> -		return 0;
> +	nfs_read_rpcsetup(req, data, &nfs_read_full_ops, count, 0);
> +	return 0;
>  out_bad:
>  	nfs_async_read_error(head);
> -	return status;
> +	return -ENOMEM;
>  }
>  
>  /*



More information about the pNFS mailing list