Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit df3accb8 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFS: Pass error information to the pgio error cleanup routine



Allow the caller to pass error information when cleaning up a failed
I/O request so that we can conditionally take action to cancel the
request altogether if the error turned out to be fatal.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 078b5fd9
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -428,7 +428,7 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
	hdr->release(hdr);
	hdr->release(hdr);
}
}


static void nfs_read_sync_pgio_error(struct list_head *head)
static void nfs_read_sync_pgio_error(struct list_head *head, int error)
{
{
	struct nfs_page *req;
	struct nfs_page *req;


@@ -820,7 +820,7 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
	hdr->release(hdr);
	hdr->release(hdr);
}
}


static void nfs_write_sync_pgio_error(struct list_head *head)
static void nfs_write_sync_pgio_error(struct list_head *head, int error)
{
{
	struct nfs_page *req;
	struct nfs_page *req;


+3 −2
Original line number Original line Diff line number Diff line
@@ -993,7 +993,7 @@ nfs_pageio_cleanup_request(struct nfs_pageio_descriptor *desc,
	LIST_HEAD(head);
	LIST_HEAD(head);


	nfs_list_move_request(req, &head);
	nfs_list_move_request(req, &head);
	desc->pg_completion_ops->error_cleanup(&head);
	desc->pg_completion_ops->error_cleanup(&head, desc->pg_error);
}
}


/**
/**
@@ -1129,7 +1129,8 @@ static void nfs_pageio_error_cleanup(struct nfs_pageio_descriptor *desc)


	for (midx = 0; midx < desc->pg_mirror_count; midx++) {
	for (midx = 0; midx < desc->pg_mirror_count; midx++) {
		mirror = &desc->pg_mirrors[midx];
		mirror = &desc->pg_mirrors[midx];
		desc->pg_completion_ops->error_cleanup(&mirror->pg_list);
		desc->pg_completion_ops->error_cleanup(&mirror->pg_list,
				desc->pg_error);
	}
	}
}
}


+1 −1
Original line number Original line Diff line number Diff line
@@ -205,7 +205,7 @@ static void nfs_initiate_read(struct nfs_pgio_header *hdr,
}
}


static void
static void
nfs_async_read_error(struct list_head *head)
nfs_async_read_error(struct list_head *head, int error)
{
{
	struct nfs_page	*req;
	struct nfs_page	*req;


+9 −2
Original line number Original line Diff line number Diff line
@@ -1412,20 +1412,27 @@ static void nfs_redirty_request(struct nfs_page *req)
	nfs_release_request(req);
	nfs_release_request(req);
}
}


static void nfs_async_write_error(struct list_head *head)
static void nfs_async_write_error(struct list_head *head, int error)
{
{
	struct nfs_page	*req;
	struct nfs_page	*req;


	while (!list_empty(head)) {
	while (!list_empty(head)) {
		req = nfs_list_entry(head->next);
		req = nfs_list_entry(head->next);
		nfs_list_remove_request(req);
		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);
		nfs_redirty_request(req);
	}
	}
}
}


static void nfs_async_write_reschedule_io(struct nfs_pgio_header *hdr)
static void nfs_async_write_reschedule_io(struct nfs_pgio_header *hdr)
{
{
	nfs_async_write_error(&hdr->pages);
	nfs_async_write_error(&hdr->pages, 0);
	filemap_fdatawrite_range(hdr->inode->i_mapping, hdr->args.offset,
	filemap_fdatawrite_range(hdr->inode->i_mapping, hdr->args.offset,
			hdr->args.offset + hdr->args.count - 1);
			hdr->args.offset + hdr->args.count - 1);
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -1549,7 +1549,7 @@ struct nfs_commit_data {
};
};


struct nfs_pgio_completion_ops {
struct nfs_pgio_completion_ops {
	void	(*error_cleanup)(struct list_head *head);
	void	(*error_cleanup)(struct list_head *head, int);
	void	(*init_hdr)(struct nfs_pgio_header *hdr);
	void	(*init_hdr)(struct nfs_pgio_header *hdr);
	void	(*completion)(struct nfs_pgio_header *hdr);
	void	(*completion)(struct nfs_pgio_header *hdr);
	void	(*reschedule_io)(struct nfs_pgio_header *hdr);
	void	(*reschedule_io)(struct nfs_pgio_header *hdr);