diff options
Diffstat (limited to 'fs/nfs/read.c')
| -rw-r--r-- | fs/nfs/read.c | 108 | 
1 files changed, 54 insertions, 54 deletions
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index c380cff4108e..f71eeee67e20 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -15,6 +15,7 @@  #include <linux/stat.h>  #include <linux/mm.h>  #include <linux/slab.h> +#include <linux/task_io_accounting_ops.h>  #include <linux/pagemap.h>  #include <linux/sunrpc/clnt.h>  #include <linux/nfs_fs.h> @@ -30,7 +31,7 @@  #define NFSDBG_FACILITY		NFSDBG_PAGECACHE -static const struct nfs_pgio_completion_ops nfs_async_read_completion_ops; +const struct nfs_pgio_completion_ops nfs_async_read_completion_ops;  static const struct nfs_rw_ops nfs_rw_read_ops;  static struct kmem_cache *nfs_rdata_cachep; @@ -73,7 +74,7 @@ void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,  }  EXPORT_SYMBOL_GPL(nfs_pageio_init_read); -static void nfs_pageio_complete_read(struct nfs_pageio_descriptor *pgio) +void nfs_pageio_complete_read(struct nfs_pageio_descriptor *pgio)  {  	struct nfs_pgio_mirror *pgm;  	unsigned long npages; @@ -109,28 +110,17 @@ EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds);  static void nfs_readpage_release(struct nfs_page *req, int error)  { -	struct inode *inode = d_inode(nfs_req_openctx(req)->dentry);  	struct folio *folio = nfs_page_to_folio(req); -	dprintk("NFS: read done (%s/%llu %d@%lld)\n", inode->i_sb->s_id, -		(unsigned long long)NFS_FILEID(inode), req->wb_bytes, -		(long long)req_offset(req)); -  	if (nfs_error_is_fatal_on_server(error) && error != -ETIMEDOUT)  		folio_set_error(folio); -	if (nfs_page_group_sync_on_bit(req, PG_UNLOCKPAGE)) { -		if (folio_test_uptodate(folio)) -			nfs_fscache_write_page(inode, &folio->page); -		folio_unlock(folio); -	} +	if (nfs_page_group_sync_on_bit(req, PG_UNLOCKPAGE)) +		if (nfs_netfs_folio_unlock(folio)) +			folio_unlock(folio); +  	nfs_release_request(req);  } -struct nfs_readdesc { -	struct nfs_pageio_descriptor pgio; -	struct nfs_open_context *ctx; -}; -  static void nfs_page_group_set_uptodate(struct nfs_page *req)  {  	if (nfs_page_group_sync_on_bit(req, PG_UPTODATE)) @@ -152,7 +142,8 @@ static void nfs_read_completion(struct nfs_pgio_header *hdr)  		if (test_bit(NFS_IOHDR_EOF, &hdr->flags)) {  			/* note: regions of the page not covered by a -			 * request are zeroed in readpage_async_filler */ +			 * request are zeroed in nfs_read_add_folio +			 */  			if (bytes > hdr->good_bytes) {  				/* nothing in this request was good, so zero  				 * the full extent of the request */ @@ -180,6 +171,8 @@ static void nfs_read_completion(struct nfs_pgio_header *hdr)  		nfs_list_remove_request(req);  		nfs_readpage_release(req, error);  	} +	nfs_netfs_read_completion(hdr); +  out:  	hdr->release(hdr);  } @@ -190,6 +183,7 @@ static void nfs_initiate_read(struct nfs_pgio_header *hdr,  			      struct rpc_task_setup *task_setup_data, int how)  {  	rpc_ops->read_setup(hdr, msg); +	nfs_netfs_initiate_read(hdr);  	trace_nfs_initiate_read(hdr);  } @@ -205,7 +199,7 @@ nfs_async_read_error(struct list_head *head, int error)  	}  } -static const struct nfs_pgio_completion_ops nfs_async_read_completion_ops = { +const struct nfs_pgio_completion_ops nfs_async_read_completion_ops = {  	.error_cleanup = nfs_async_read_error,  	.completion = nfs_read_completion,  }; @@ -280,7 +274,9 @@ static void nfs_readpage_result(struct rpc_task *task,  		nfs_readpage_retry(task, hdr);  } -static int readpage_async_filler(struct nfs_readdesc *desc, struct folio *folio) +int nfs_read_add_folio(struct nfs_pageio_descriptor *pgio, +		       struct nfs_open_context *ctx, +		       struct folio *folio)  {  	struct inode *inode = folio_file_mapping(folio)->host;  	struct nfs_server *server = NFS_SERVER(inode); @@ -296,29 +292,21 @@ static int readpage_async_filler(struct nfs_readdesc *desc, struct folio *folio)  	aligned_len = min_t(unsigned int, ALIGN(len, rsize), fsize); -	if (!IS_SYNC(inode)) { -		error = nfs_fscache_read_page(inode, &folio->page); -		if (error == 0) -			goto out_unlock; +	new = nfs_page_create_from_folio(ctx, folio, 0, aligned_len); +	if (IS_ERR(new)) { +		error = PTR_ERR(new); +		goto out;  	} -	new = nfs_page_create_from_folio(desc->ctx, folio, 0, aligned_len); -	if (IS_ERR(new)) -		goto out_error; -  	if (len < fsize)  		folio_zero_segment(folio, len, fsize); -	if (!nfs_pageio_add_request(&desc->pgio, new)) { +	if (!nfs_pageio_add_request(pgio, new)) {  		nfs_list_remove_request(new); -		error = desc->pgio.pg_error; +		error = pgio->pg_error;  		nfs_readpage_release(new, error);  		goto out;  	}  	return 0; -out_error: -	error = PTR_ERR(new); -out_unlock: -	folio_unlock(folio);  out:  	return error;  } @@ -331,12 +319,14 @@ out:   */  int nfs_read_folio(struct file *file, struct folio *folio)  { -	struct nfs_readdesc desc;  	struct inode *inode = file_inode(file); +	struct nfs_pageio_descriptor pgio; +	struct nfs_open_context *ctx;  	int ret;  	trace_nfs_aop_readpage(inode, folio);  	nfs_inc_stats(inode, NFSIOS_VFSREADPAGE); +	task_io_account_read(folio_size(folio));  	/*  	 * Try to flush any pending writes to the file.. @@ -355,69 +345,79 @@ int nfs_read_folio(struct file *file, struct folio *folio)  	if (NFS_STALE(inode))  		goto out_unlock; -	desc.ctx = get_nfs_open_context(nfs_file_open_context(file)); +	ret = nfs_netfs_read_folio(file, folio); +	if (!ret) +		goto out; + +	ctx = get_nfs_open_context(nfs_file_open_context(file)); -	xchg(&desc.ctx->error, 0); -	nfs_pageio_init_read(&desc.pgio, inode, false, +	xchg(&ctx->error, 0); +	nfs_pageio_init_read(&pgio, inode, false,  			     &nfs_async_read_completion_ops); -	ret = readpage_async_filler(&desc, folio); +	ret = nfs_read_add_folio(&pgio, ctx, folio);  	if (ret) -		goto out; +		goto out_put; -	nfs_pageio_complete_read(&desc.pgio); -	ret = desc.pgio.pg_error < 0 ? desc.pgio.pg_error : 0; +	nfs_pageio_complete_read(&pgio); +	ret = pgio.pg_error < 0 ? pgio.pg_error : 0;  	if (!ret) {  		ret = folio_wait_locked_killable(folio);  		if (!folio_test_uptodate(folio) && !ret) -			ret = xchg(&desc.ctx->error, 0); +			ret = xchg(&ctx->error, 0);  	} +out_put: +	put_nfs_open_context(ctx);  out: -	put_nfs_open_context(desc.ctx);  	trace_nfs_aop_readpage_done(inode, folio, ret);  	return ret;  out_unlock:  	folio_unlock(folio); -	trace_nfs_aop_readpage_done(inode, folio, ret); -	return ret; +	goto out;  }  void nfs_readahead(struct readahead_control *ractl)  { +	struct nfs_pageio_descriptor pgio; +	struct nfs_open_context *ctx;  	unsigned int nr_pages = readahead_count(ractl);  	struct file *file = ractl->file; -	struct nfs_readdesc desc;  	struct inode *inode = ractl->mapping->host;  	struct folio *folio;  	int ret;  	trace_nfs_aop_readahead(inode, readahead_pos(ractl), nr_pages);  	nfs_inc_stats(inode, NFSIOS_VFSREADPAGES); +	task_io_account_read(readahead_length(ractl));  	ret = -ESTALE;  	if (NFS_STALE(inode))  		goto out; +	ret = nfs_netfs_readahead(ractl); +	if (!ret) +		goto out; +  	if (file == NULL) {  		ret = -EBADF; -		desc.ctx = nfs_find_open_context(inode, NULL, FMODE_READ); -		if (desc.ctx == NULL) +		ctx = nfs_find_open_context(inode, NULL, FMODE_READ); +		if (ctx == NULL)  			goto out;  	} else -		desc.ctx = get_nfs_open_context(nfs_file_open_context(file)); +		ctx = get_nfs_open_context(nfs_file_open_context(file)); -	nfs_pageio_init_read(&desc.pgio, inode, false, +	nfs_pageio_init_read(&pgio, inode, false,  			     &nfs_async_read_completion_ops);  	while ((folio = readahead_folio(ractl)) != NULL) { -		ret = readpage_async_filler(&desc, folio); +		ret = nfs_read_add_folio(&pgio, ctx, folio);  		if (ret)  			break;  	} -	nfs_pageio_complete_read(&desc.pgio); +	nfs_pageio_complete_read(&pgio); -	put_nfs_open_context(desc.ctx); +	put_nfs_open_context(ctx);  out:  	trace_nfs_aop_readahead_done(inode, nr_pages, ret);  }  |