Commit 5dfe032f authored by Trond Myklebust's avatar Trond Myklebust

[PATCH] A basic NFSv4 client for 2.5.x

This is a nontrivial change to the NFS client.

This patch does for the async WRITE and COMMIT paths what patch 14
did for the async READ path, by changing 'struct nfs_write_data'
so that the v2- and v3-specific parts are moved into a private area,
with room for a v4-specific part in parallel.  None of the logic is
changed.
parent 0e32be1d
...@@ -72,12 +72,19 @@ struct nfs_write_data { ...@@ -72,12 +72,19 @@ struct nfs_write_data {
struct rpc_task task; struct rpc_task task;
struct inode *inode; struct inode *inode;
struct rpc_cred *cred; struct rpc_cred *cred;
struct nfs_writeargs args; /* argument struct */
struct nfs_writeres res; /* result struct */
struct nfs_fattr fattr; struct nfs_fattr fattr;
struct nfs_writeverf verf; struct nfs_writeverf verf;
struct list_head pages; /* Coalesced requests we wish to flush */ struct list_head pages; /* Coalesced requests we wish to flush */
struct page *pagevec[NFS_WRITE_MAXIOV]; struct page *pagevec[NFS_WRITE_MAXIOV];
union {
struct {
struct nfs_writeargs args;
struct nfs_writeres res;
} v3;
#ifdef CONFIG_NFS_V4
/* NFSv4 data to come here... */
#endif
} u;
}; };
/* /*
...@@ -106,7 +113,7 @@ static __inline__ struct nfs_write_data *nfs_writedata_alloc(void) ...@@ -106,7 +113,7 @@ static __inline__ struct nfs_write_data *nfs_writedata_alloc(void)
if (p) { if (p) {
memset(p, 0, sizeof(*p)); memset(p, 0, sizeof(*p));
INIT_LIST_HEAD(&p->pages); INIT_LIST_HEAD(&p->pages);
p->args.pages = p->pagevec; p->u.v3.args.pages = p->pagevec;
} }
return p; return p;
} }
...@@ -869,10 +876,10 @@ nfs_write_rpcsetup(struct list_head *head, struct nfs_write_data *data) ...@@ -869,10 +876,10 @@ nfs_write_rpcsetup(struct list_head *head, struct nfs_write_data *data)
/* Set up the RPC argument and reply structs /* Set up the RPC argument and reply structs
* NB: take care not to mess about with data->commit et al. */ * NB: take care not to mess about with data->commit et al. */
pages = data->args.pages; pages = data->u.v3.args.pages;
count = 0; count = 0;
while (!list_empty(head)) { while (!list_empty(head)) {
struct nfs_page *req = nfs_list_entry(head->next); req = nfs_list_entry(head->next);
nfs_list_remove_request(req); nfs_list_remove_request(req);
nfs_list_add_request(req, &data->pages); nfs_list_add_request(req, &data->pages);
*pages++ = req->wb_page; *pages++ = req->wb_page;
...@@ -881,13 +888,13 @@ nfs_write_rpcsetup(struct list_head *head, struct nfs_write_data *data) ...@@ -881,13 +888,13 @@ nfs_write_rpcsetup(struct list_head *head, struct nfs_write_data *data)
req = nfs_list_entry(data->pages.next); req = nfs_list_entry(data->pages.next);
data->inode = req->wb_inode; data->inode = req->wb_inode;
data->cred = req->wb_cred; data->cred = req->wb_cred;
data->args.fh = NFS_FH(req->wb_inode); data->u.v3.args.fh = NFS_FH(req->wb_inode);
data->args.offset = req_offset(req) + req->wb_offset; data->u.v3.args.offset = req_offset(req) + req->wb_offset;
data->args.pgbase = req->wb_offset; data->u.v3.args.pgbase = req->wb_offset;
data->args.count = count; data->u.v3.args.count = count;
data->res.fattr = &data->fattr; data->u.v3.res.fattr = &data->fattr;
data->res.count = count; data->u.v3.res.count = count;
data->res.verf = &data->verf; data->u.v3.res.verf = &data->verf;
} }
...@@ -925,14 +932,14 @@ nfs_flush_one(struct list_head *head, struct inode *inode, int how) ...@@ -925,14 +932,14 @@ nfs_flush_one(struct list_head *head, struct inode *inode, int how)
/* Set up the argument struct */ /* Set up the argument struct */
nfs_write_rpcsetup(head, data); nfs_write_rpcsetup(head, data);
if (nfsvers < 3) if (nfsvers < 3)
data->args.stable = NFS_FILE_SYNC; data->u.v3.args.stable = NFS_FILE_SYNC;
else if (stable) { else if (stable) {
if (!nfsi->ncommit) if (!nfsi->ncommit)
data->args.stable = NFS_FILE_SYNC; data->u.v3.args.stable = NFS_FILE_SYNC;
else else
data->args.stable = NFS_DATA_SYNC; data->u.v3.args.stable = NFS_DATA_SYNC;
} else } else
data->args.stable = NFS_UNSTABLE; data->u.v3.args.stable = NFS_UNSTABLE;
/* Finalize the task. */ /* Finalize the task. */
rpc_init_task(task, clnt, nfs_writeback_done, flags); rpc_init_task(task, clnt, nfs_writeback_done, flags);
...@@ -945,16 +952,16 @@ nfs_flush_one(struct list_head *head, struct inode *inode, int how) ...@@ -945,16 +952,16 @@ nfs_flush_one(struct list_head *head, struct inode *inode, int how)
#else #else
msg.rpc_proc = NFSPROC_WRITE; msg.rpc_proc = NFSPROC_WRITE;
#endif #endif
msg.rpc_argp = &data->args; msg.rpc_argp = &data->u.v3.args;
msg.rpc_resp = &data->res; msg.rpc_resp = &data->u.v3.res;
msg.rpc_cred = data->cred; msg.rpc_cred = data->cred;
dprintk("NFS: %4d initiated write call (req %s/%Ld, %u bytes @ offset %Lu)\n", dprintk("NFS: %4d initiated write call (req %s/%Ld, %u bytes @ offset %Lu)\n",
task->tk_pid, task->tk_pid,
inode->i_sb->s_id, inode->i_sb->s_id,
(long long)NFS_FILEID(inode), (long long)NFS_FILEID(inode),
(unsigned int)data->args.count, (unsigned int)data->u.v3.args.count,
(unsigned long long)data->args.offset); (unsigned long long)data->u.v3.args.offset);
rpc_clnt_sigmask(clnt, &oldset); rpc_clnt_sigmask(clnt, &oldset);
rpc_call_setup(task, &msg, 0); rpc_call_setup(task, &msg, 0);
...@@ -1008,8 +1015,8 @@ static void ...@@ -1008,8 +1015,8 @@ static void
nfs_writeback_done(struct rpc_task *task) nfs_writeback_done(struct rpc_task *task)
{ {
struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
struct nfs_writeargs *argp = &data->args; struct nfs_writeargs *argp = &data->u.v3.args;
struct nfs_writeres *resp = &data->res; struct nfs_writeres *resp = &data->u.v3.res;
struct inode *inode = data->inode; struct inode *inode = data->inode;
struct nfs_page *req; struct nfs_page *req;
struct page *page; struct page *page;
...@@ -1133,11 +1140,11 @@ nfs_commit_rpcsetup(struct list_head *head, struct nfs_write_data *data) ...@@ -1133,11 +1140,11 @@ nfs_commit_rpcsetup(struct list_head *head, struct nfs_write_data *data)
data->inode = inode; data->inode = inode;
data->cred = first->wb_cred; data->cred = first->wb_cred;
data->args.fh = NFS_FH(inode); data->u.v3.args.fh = NFS_FH(inode);
data->args.offset = start; data->u.v3.args.offset = start;
data->res.count = data->args.count = (u32)len; data->u.v3.res.count = data->u.v3.args.count = (u32)len;
data->res.fattr = &data->fattr; data->u.v3.res.fattr = &data->fattr;
data->res.verf = &data->verf; data->u.v3.res.verf = &data->verf;
} }
/* /*
...@@ -1174,8 +1181,8 @@ nfs_commit_list(struct list_head *head, int how) ...@@ -1174,8 +1181,8 @@ nfs_commit_list(struct list_head *head, int how)
task->tk_release = nfs_writedata_release; task->tk_release = nfs_writedata_release;
msg.rpc_proc = NFS3PROC_COMMIT; msg.rpc_proc = NFS3PROC_COMMIT;
msg.rpc_argp = &data->args; msg.rpc_argp = &data->u.v3.args;
msg.rpc_resp = &data->res; msg.rpc_resp = &data->u.v3.res;
msg.rpc_cred = data->cred; msg.rpc_cred = data->cred;
dprintk("NFS: %4d initiated commit call\n", task->tk_pid); dprintk("NFS: %4d initiated commit call\n", task->tk_pid);
...@@ -1203,7 +1210,7 @@ static void ...@@ -1203,7 +1210,7 @@ static void
nfs_commit_done(struct rpc_task *task) nfs_commit_done(struct rpc_task *task)
{ {
struct nfs_write_data *data = (struct nfs_write_data *)task->tk_calldata; struct nfs_write_data *data = (struct nfs_write_data *)task->tk_calldata;
struct nfs_writeres *resp = &data->res; struct nfs_writeres *resp = &data->u.v3.res;
struct nfs_page *req; struct nfs_page *req;
struct inode *inode = data->inode; struct inode *inode = data->inode;
......
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