mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	NFS: Replace custom error reporting mechanism with generic one
Replace the NFS custom error reporting mechanism with the generic mapping_set_error(). Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
		
							parent
							
								
									aded8d7b54
								
							
						
					
					
						commit
						6fbda89b25
					
				
					 4 changed files with 26 additions and 46 deletions
				
			
		| 
						 | 
				
			
			@ -199,13 +199,6 @@ EXPORT_SYMBOL_GPL(nfs_file_mmap);
 | 
			
		|||
 * Flush any dirty pages for this process, and check for write errors.
 | 
			
		||||
 * The return status from this call provides a reliable indication of
 | 
			
		||||
 * whether any write errors occurred for this process.
 | 
			
		||||
 *
 | 
			
		||||
 * Notice that it clears the NFS_CONTEXT_ERROR_WRITE before synching to
 | 
			
		||||
 * disk, but it retrieves and clears ctx->error after synching, despite
 | 
			
		||||
 * the two being set at the same time in nfs_context_set_write_error().
 | 
			
		||||
 * This is because the former is used to notify the _next_ call to
 | 
			
		||||
 * nfs_file_write() that a write error occurred, and hence cause it to
 | 
			
		||||
 * fall back to doing a synchronous write.
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
nfs_file_fsync_commit(struct file *file, int datasync)
 | 
			
		||||
| 
						 | 
				
			
			@ -220,11 +213,8 @@ nfs_file_fsync_commit(struct file *file, int datasync)
 | 
			
		|||
	nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
 | 
			
		||||
	do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags);
 | 
			
		||||
	status = nfs_commit_inode(inode, FLUSH_SYNC);
 | 
			
		||||
	if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) {
 | 
			
		||||
		ret = xchg(&ctx->error, 0);
 | 
			
		||||
		if (ret)
 | 
			
		||||
			goto out;
 | 
			
		||||
	}
 | 
			
		||||
	if (status == 0)
 | 
			
		||||
		status = file_check_and_advance_wb_err(file);
 | 
			
		||||
	if (status < 0) {
 | 
			
		||||
		ret = status;
 | 
			
		||||
		goto out;
 | 
			
		||||
| 
						 | 
				
			
			@ -245,13 +235,7 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
 | 
			
		|||
	trace_nfs_fsync_enter(inode);
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		struct nfs_open_context *ctx = nfs_file_open_context(file);
 | 
			
		||||
		ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
 | 
			
		||||
		if (test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags)) {
 | 
			
		||||
			int ret2 = xchg(&ctx->error, 0);
 | 
			
		||||
			if (ret2)
 | 
			
		||||
				ret = ret2;
 | 
			
		||||
		}
 | 
			
		||||
		ret = file_write_and_wait_range(file, start, end);
 | 
			
		||||
		if (ret != 0)
 | 
			
		||||
			break;
 | 
			
		||||
		ret = nfs_file_fsync_commit(file, datasync);
 | 
			
		||||
| 
						 | 
				
			
			@ -600,8 +584,7 @@ static int nfs_need_check_write(struct file *filp, struct inode *inode)
 | 
			
		|||
	struct nfs_open_context *ctx;
 | 
			
		||||
 | 
			
		||||
	ctx = nfs_file_open_context(filp);
 | 
			
		||||
	if (test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags) ||
 | 
			
		||||
	    nfs_ctx_key_to_expire(ctx, inode))
 | 
			
		||||
	if (nfs_ctx_key_to_expire(ctx, inode))
 | 
			
		||||
		return 1;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -773,9 +773,3 @@ static inline bool nfs_error_is_fatal(int err)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
 | 
			
		||||
{
 | 
			
		||||
	ctx->error = error;
 | 
			
		||||
	smp_wmb();
 | 
			
		||||
	set_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -244,6 +244,12 @@ static void nfs_set_pageerror(struct address_space *mapping)
 | 
			
		|||
	nfs_zap_mapping(mapping->host, mapping);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void nfs_mapping_set_error(struct page *page, int error)
 | 
			
		||||
{
 | 
			
		||||
	SetPageError(page);
 | 
			
		||||
	mapping_set_error(page_file_mapping(page), error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * nfs_page_group_search_locked
 | 
			
		||||
 * @head - head request of page group
 | 
			
		||||
| 
						 | 
				
			
			@ -582,9 +588,9 @@ nfs_lock_and_join_requests(struct page *page)
 | 
			
		|||
	return ERR_PTR(ret);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void nfs_write_error_remove_page(struct nfs_page *req)
 | 
			
		||||
static void nfs_write_error(struct nfs_page *req, int error)
 | 
			
		||||
{
 | 
			
		||||
	SetPageError(req->wb_page);
 | 
			
		||||
	nfs_mapping_set_error(req->wb_page, error);
 | 
			
		||||
	nfs_end_page_writeback(req);
 | 
			
		||||
	nfs_release_request(req);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -608,6 +614,7 @@ nfs_error_is_fatal_on_server(int err)
 | 
			
		|||
static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
 | 
			
		||||
				struct page *page)
 | 
			
		||||
{
 | 
			
		||||
	struct address_space *mapping;
 | 
			
		||||
	struct nfs_page *req;
 | 
			
		||||
	int ret = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -621,19 +628,19 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
 | 
			
		|||
	nfs_set_page_writeback(page);
 | 
			
		||||
	WARN_ON_ONCE(test_bit(PG_CLEAN, &req->wb_flags));
 | 
			
		||||
 | 
			
		||||
	ret = req->wb_context->error;
 | 
			
		||||
	/* If there is a fatal error that covers this write, just exit */
 | 
			
		||||
	if (nfs_error_is_fatal_on_server(ret))
 | 
			
		||||
	ret = 0;
 | 
			
		||||
	mapping = page_file_mapping(page);
 | 
			
		||||
	if (test_bit(AS_ENOSPC, &mapping->flags) ||
 | 
			
		||||
	    test_bit(AS_EIO, &mapping->flags))
 | 
			
		||||
		goto out_launder;
 | 
			
		||||
 | 
			
		||||
	ret = 0;
 | 
			
		||||
	if (!nfs_pageio_add_request(pgio, req)) {
 | 
			
		||||
		ret = pgio->pg_error;
 | 
			
		||||
		/*
 | 
			
		||||
		 * Remove the problematic req upon fatal errors on the server
 | 
			
		||||
		 */
 | 
			
		||||
		if (nfs_error_is_fatal(ret)) {
 | 
			
		||||
			nfs_context_set_write_error(req->wb_context, ret);
 | 
			
		||||
			if (nfs_error_is_fatal_on_server(ret))
 | 
			
		||||
				goto out_launder;
 | 
			
		||||
		} else
 | 
			
		||||
| 
						 | 
				
			
			@ -645,7 +652,7 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
 | 
			
		|||
out:
 | 
			
		||||
	return ret;
 | 
			
		||||
out_launder:
 | 
			
		||||
	nfs_write_error_remove_page(req);
 | 
			
		||||
	nfs_write_error(req, ret);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -998,7 +1005,7 @@ static void nfs_write_completion(struct nfs_pgio_header *hdr)
 | 
			
		|||
		if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) &&
 | 
			
		||||
		    (hdr->good_bytes < bytes)) {
 | 
			
		||||
			nfs_set_pageerror(page_file_mapping(req->wb_page));
 | 
			
		||||
			nfs_context_set_write_error(req->wb_context, hdr->error);
 | 
			
		||||
			nfs_mapping_set_error(req->wb_page, hdr->error);
 | 
			
		||||
			goto remove_req;
 | 
			
		||||
		}
 | 
			
		||||
		if (nfs_write_need_commit(hdr)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1422,14 +1429,10 @@ static void nfs_async_write_error(struct list_head *head, int error)
 | 
			
		|||
	while (!list_empty(head)) {
 | 
			
		||||
		req = nfs_list_entry(head->next);
 | 
			
		||||
		nfs_list_remove_request(req);
 | 
			
		||||
		if (nfs_error_is_fatal(error)) {
 | 
			
		||||
			nfs_context_set_write_error(req->wb_context, error);
 | 
			
		||||
			if (nfs_error_is_fatal_on_server(error)) {
 | 
			
		||||
				nfs_write_error_remove_page(req);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		nfs_redirty_request(req);
 | 
			
		||||
		if (nfs_error_is_fatal(error))
 | 
			
		||||
			nfs_write_error(req, error);
 | 
			
		||||
		else
 | 
			
		||||
			nfs_redirty_request(req);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1843,9 +1846,10 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data)
 | 
			
		|||
			req->wb_bytes,
 | 
			
		||||
			(long long)req_offset(req));
 | 
			
		||||
		if (status < 0) {
 | 
			
		||||
			nfs_context_set_write_error(req->wb_context, status);
 | 
			
		||||
			if (req->wb_page)
 | 
			
		||||
			if (req->wb_page) {
 | 
			
		||||
				nfs_mapping_set_error(req->wb_page, status);
 | 
			
		||||
				nfs_inode_remove_request(req);
 | 
			
		||||
			}
 | 
			
		||||
			dprintk_cont(", error = %d\n", status);
 | 
			
		||||
			goto next;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,7 +76,6 @@ struct nfs_open_context {
 | 
			
		|||
	fmode_t mode;
 | 
			
		||||
 | 
			
		||||
	unsigned long flags;
 | 
			
		||||
#define NFS_CONTEXT_ERROR_WRITE		(0)
 | 
			
		||||
#define NFS_CONTEXT_RESEND_WRITES	(1)
 | 
			
		||||
#define NFS_CONTEXT_BAD			(2)
 | 
			
		||||
#define NFS_CONTEXT_UNLOCK	(3)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue