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

Commit b5891b62 authored by Trond Myklebust's avatar Trond Myklebust Committed by Greg Kroah-Hartman
Browse files

NFS: Pass error information to the pgio error cleanup routine



[ Upstream commit df3accb849607a86278a37c35e6b313635ccc48b ]

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>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 812de6de
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -428,7 +428,7 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *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;

@@ -820,7 +820,7 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *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;

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

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

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

	for (midx = 0; midx < desc->pg_mirror_count; 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 Diff line number Diff line
@@ -205,7 +205,7 @@ static void nfs_initiate_read(struct nfs_pgio_header *hdr,
}

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

+9 −2
Original line number Diff line number Diff line
@@ -1394,20 +1394,27 @@ static void nfs_redirty_request(struct nfs_page *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;

	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);
	}
}

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,
			hdr->args.offset + hdr->args.count - 1);
}
+1 −1
Original line number Diff line number Diff line
@@ -1539,7 +1539,7 @@ struct nfs_commit_data {
};

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	(*completion)(struct nfs_pgio_header *hdr);
	void	(*reschedule_io)(struct nfs_pgio_header *hdr);