Skip to content

Commit

Permalink
NFS: Remove pNFS bloat from the generic write path
Browse files Browse the repository at this point in the history
We have no business doing any this in the standard write release path.
Get rid of it, and put it in the pNFS layer.

Also, while we're at it, get rid of the completely bogus unlock/relock
semantics that were present in nfs_writeback_release_full(). It is
not only unnecessary, but actually dangerous to release the write lock
just in order to take it again in nfs_page_async_flush(). Better just
to open code the pgio operations in a pnfs helper.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed Jan 6, 2012
1 parent fe0fe83 commit e2fecb2
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 27 deletions.
2 changes: 2 additions & 0 deletions fs/nfs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ extern void nfs_readdata_release(struct nfs_read_data *rdata);
/* write.c */
extern int nfs_generic_flush(struct nfs_pageio_descriptor *desc,
struct list_head *head);
extern void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio,
struct inode *inode, int ioflags);
extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio);
extern void nfs_writedata_release(struct nfs_write_data *wdata);
extern void nfs_commit_free(struct nfs_write_data *p);
Expand Down
30 changes: 28 additions & 2 deletions fs/nfs/pnfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1166,6 +1166,33 @@ pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
}
EXPORT_SYMBOL_GPL(pnfs_generic_pg_test);

static int pnfs_write_done_resend_to_mds(struct inode *inode, struct list_head *head)
{
struct nfs_pageio_descriptor pgio;
LIST_HEAD(failed);

/* Resend all requests through the MDS */
nfs_pageio_init_write_mds(&pgio, inode, FLUSH_STABLE);
while (!list_empty(head)) {
struct nfs_page *req = nfs_list_entry(head->next);

nfs_list_remove_request(req);
if (!nfs_pageio_add_request(&pgio, req))
nfs_list_add_request(req, &failed);
}
nfs_pageio_complete(&pgio);

if (!list_empty(&failed)) {
/* For some reason our attempt to resend pages. Mark the
* overall send request as having failed, and let
* nfs_writeback_release_full deal with the error.
*/
list_move(&failed, head);
return -EIO;
}
return 0;
}

/*
* Called by non rpc-based layout drivers
*/
Expand All @@ -1175,8 +1202,6 @@ void pnfs_ld_write_done(struct nfs_write_data *data)
pnfs_set_layoutcommit(data);
data->mds_ops->rpc_call_done(&data->task, data);
} else {
put_lseg(data->lseg);
data->lseg = NULL;
dprintk("pnfs write error = %d\n", data->pnfs_error);
if (NFS_SERVER(data->inode)->pnfs_curr_ld->flags &
PNFS_LAYOUTRET_ON_ERROR) {
Expand All @@ -1187,6 +1212,7 @@ void pnfs_ld_write_done(struct nfs_write_data *data)
&NFS_I(data->inode)->flags);
pnfs_return_layout(data->inode);
}
data->task.tk_status = pnfs_write_done_resend_to_mds(data->inode, &data->pages);
}
data->mds_ops->rpc_release(data);
}
Expand Down
27 changes: 2 additions & 25 deletions fs/nfs/write.c
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,7 @@ static const struct nfs_pageio_ops nfs_pageio_write_ops = {
.pg_doio = nfs_generic_pg_writepages,
};

static void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio,
void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio,
struct inode *inode, int ioflags)
{
nfs_pageio_init(pgio, inode, &nfs_pageio_write_ops,
Expand Down Expand Up @@ -1166,13 +1166,7 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
static void nfs_writeback_release_full(void *calldata)
{
struct nfs_write_data *data = calldata;
int ret, status = data->task.tk_status;
struct nfs_pageio_descriptor pgio;

if (data->pnfs_error) {
nfs_pageio_init_write_mds(&pgio, data->inode, FLUSH_STABLE);
pgio.pg_recoalesce = 1;
}
int status = data->task.tk_status;

/* Update attributes as result of writeback. */
while (!list_empty(&data->pages)) {
Expand All @@ -1188,11 +1182,6 @@ static void nfs_writeback_release_full(void *calldata)
req->wb_bytes,
(long long)req_offset(req));

if (data->pnfs_error) {
dprintk(", pnfs error = %d\n", data->pnfs_error);
goto next;
}

if (status < 0) {
nfs_set_pageerror(page);
nfs_context_set_write_error(req->wb_context, status);
Expand All @@ -1212,19 +1201,7 @@ static void nfs_writeback_release_full(void *calldata)
next:
nfs_clear_page_tag_locked(req);
nfs_end_page_writeback(page);
if (data->pnfs_error) {
lock_page(page);
nfs_pageio_cond_complete(&pgio, page->index);
ret = nfs_page_async_flush(&pgio, page, 0);
if (ret) {
nfs_set_pageerror(page);
dprintk("rewrite to MDS error = %d\n", ret);
}
unlock_page(page);
}
}
if (data->pnfs_error)
nfs_pageio_complete(&pgio);
nfs_writedata_release(calldata);
}

Expand Down

0 comments on commit e2fecb2

Please sign in to comment.