Commit 44b83799 authored by Fred Isaman's avatar Fred Isaman Committed by Trond Myklebust

NFSv4.1: trigger LAYOUTGET for writes

Signed-off-by: default avatarFred Isaman <iisaman@netapp.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 5053aa56
...@@ -873,6 +873,28 @@ pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *inode) ...@@ -873,6 +873,28 @@ pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *inode)
pgio->pg_test = (ld && ld->pg_test) ? pnfs_read_pg_test : NULL; pgio->pg_test = (ld && ld->pg_test) ? pnfs_read_pg_test : NULL;
} }
static int pnfs_write_pg_test(struct nfs_pageio_descriptor *pgio,
struct nfs_page *prev,
struct nfs_page *req)
{
if (pgio->pg_count == prev->wb_bytes) {
/* This is first coelesce call for a series of nfs_pages */
pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
prev->wb_context,
IOMODE_RW);
}
return NFS_SERVER(pgio->pg_inode)->pnfs_curr_ld->pg_test(pgio, prev, req);
}
void
pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *inode)
{
struct pnfs_layoutdriver_type *ld;
ld = NFS_SERVER(inode)->pnfs_curr_ld;
pgio->pg_test = (ld && ld->pg_test) ? pnfs_write_pg_test : NULL;
}
/* /*
* Call the appropriate parallel I/O subsystem read function. * Call the appropriate parallel I/O subsystem read function.
*/ */
......
...@@ -123,6 +123,7 @@ void unset_pnfs_layoutdriver(struct nfs_server *); ...@@ -123,6 +123,7 @@ void unset_pnfs_layoutdriver(struct nfs_server *);
enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *, enum pnfs_try_status pnfs_try_to_read_data(struct nfs_read_data *,
const struct rpc_call_ops *); const struct rpc_call_ops *);
void pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *); void pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *);
void pnfs_pageio_init_write(struct nfs_pageio_descriptor *, struct inode *);
int pnfs_layout_process(struct nfs4_layoutget *lgp); int pnfs_layout_process(struct nfs4_layoutget *lgp);
void pnfs_free_lseg_list(struct list_head *tmp_list); void pnfs_free_lseg_list(struct list_head *tmp_list);
void pnfs_destroy_layout(struct nfs_inode *); void pnfs_destroy_layout(struct nfs_inode *);
...@@ -235,6 +236,12 @@ pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *ino) ...@@ -235,6 +236,12 @@ pnfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *ino)
pgio->pg_test = NULL; pgio->pg_test = NULL;
} }
static inline void
pnfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, struct inode *ino)
{
pgio->pg_test = NULL;
}
#endif /* CONFIG_NFS_V4_1 */ #endif /* CONFIG_NFS_V4_1 */
#endif /* FS_NFS_PNFS_H */ #endif /* FS_NFS_PNFS_H */
...@@ -919,6 +919,8 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned ...@@ -919,6 +919,8 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned
} while (nbytes != 0); } while (nbytes != 0);
atomic_set(&req->wb_complete, requests); atomic_set(&req->wb_complete, requests);
BUG_ON(lseg);
lseg = pnfs_update_layout(inode, req->wb_context, IOMODE_RW);
ClearPageError(page); ClearPageError(page);
offset = 0; offset = 0;
nbytes = count; nbytes = count;
...@@ -940,6 +942,7 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned ...@@ -940,6 +942,7 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned
nbytes -= wsize; nbytes -= wsize;
} while (nbytes != 0); } while (nbytes != 0);
put_lseg(lseg);
return ret; return ret;
out_bad: out_bad:
...@@ -965,11 +968,18 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned i ...@@ -965,11 +968,18 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned i
struct nfs_page *req; struct nfs_page *req;
struct page **pages; struct page **pages;
struct nfs_write_data *data; struct nfs_write_data *data;
int ret;
data = nfs_writedata_alloc(npages); data = nfs_writedata_alloc(npages);
if (!data) if (!data) {
goto out_bad; while (!list_empty(head)) {
req = nfs_list_entry(head->next);
nfs_list_remove_request(req);
nfs_redirty_request(req);
}
ret = -ENOMEM;
goto out;
}
pages = data->pagevec; pages = data->pagevec;
while (!list_empty(head)) { while (!list_empty(head)) {
req = nfs_list_entry(head->next); req = nfs_list_entry(head->next);
...@@ -979,16 +989,14 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned i ...@@ -979,16 +989,14 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned i
*pages++ = req->wb_page; *pages++ = req->wb_page;
} }
req = nfs_list_entry(data->pages.next); req = nfs_list_entry(data->pages.next);
if ((!lseg) && list_is_singular(&data->pages))
lseg = pnfs_update_layout(inode, req->wb_context, IOMODE_RW);
/* Set up the argument struct */ /* Set up the argument struct */
return nfs_write_rpcsetup(req, data, &nfs_write_full_ops, count, 0, lseg, how); ret = nfs_write_rpcsetup(req, data, &nfs_write_full_ops, count, 0, lseg, how);
out_bad: out:
while (!list_empty(head)) { put_lseg(lseg); /* Cleans any gotten in ->pg_test */
req = nfs_list_entry(head->next); return ret;
nfs_list_remove_request(req);
nfs_redirty_request(req);
}
return -ENOMEM;
} }
static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
...@@ -996,7 +1004,7 @@ static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, ...@@ -996,7 +1004,7 @@ static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
{ {
size_t wsize = NFS_SERVER(inode)->wsize; size_t wsize = NFS_SERVER(inode)->wsize;
pgio->pg_test = NULL; pnfs_pageio_init_write(pgio, inode);
if (wsize < PAGE_CACHE_SIZE) if (wsize < PAGE_CACHE_SIZE)
nfs_pageio_init(pgio, inode, nfs_flush_multi, wsize, ioflags); nfs_pageio_init(pgio, inode, nfs_flush_multi, wsize, ioflags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment