Commit aa1e1176 authored by Trond Myklebust's avatar Trond Myklebust Committed by Linus Torvalds

[PATCH] A basic NFSv4 client for 2.5.x

This is a nontrivial change to the NFS client.

Synchronous READ operations are currently done via the ->read() nfs_rpc_op.
Therefore, the synchronous READ path can easily be adapted for NFSv4.  On
the other hand, the asynchronous READ path contains several NFSv3-specific
features, which make it difficult to adapt for NFSv4.

In this patch and the next, we modify the async READ path to be
version-agnostic.  This patch just changes the 'struct nfs_read_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 42394298
...@@ -38,11 +38,18 @@ struct nfs_read_data { ...@@ -38,11 +38,18 @@ struct nfs_read_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_readargs args; /* XDR argument struct */
struct nfs_readres res; /* ... and result struct */
struct nfs_fattr fattr; /* fattr storage */ struct nfs_fattr fattr; /* fattr storage */
struct list_head pages; /* Coalesced read requests */ struct list_head pages; /* Coalesced read requests */
struct page *pagevec[NFS_READ_MAXIOV]; struct page *pagevec[NFS_READ_MAXIOV];
union {
struct {
struct nfs_readargs args;
struct nfs_readres res;
} v3; /* also v2 */
#ifdef CONFIG_NFS_V4
/* NFSv4 data will come here... */
#endif
} u;
}; };
/* /*
...@@ -64,7 +71,7 @@ static __inline__ struct nfs_read_data *nfs_readdata_alloc(void) ...@@ -64,7 +71,7 @@ static __inline__ struct nfs_read_data *nfs_readdata_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;
} }
...@@ -190,11 +197,13 @@ nfs_readpage_async(struct file *file, struct inode *inode, struct page *page) ...@@ -190,11 +197,13 @@ nfs_readpage_async(struct file *file, struct inode *inode, struct page *page)
static void static void
nfs_read_rpcsetup(struct list_head *head, struct nfs_read_data *data) nfs_read_rpcsetup(struct list_head *head, struct nfs_read_data *data)
{ {
struct nfs_readargs *args = &data->u.v3.args;
struct nfs_readres *res = &data->u.v3.res;
struct nfs_page *req; struct nfs_page *req;
struct page **pages; struct page **pages;
unsigned int count; unsigned int count;
pages = data->args.pages; pages = &args->pages[0];
count = 0; count = 0;
while (!list_empty(head)) { while (!list_empty(head)) {
struct nfs_page *req = nfs_list_entry(head->next); struct nfs_page *req = nfs_list_entry(head->next);
...@@ -206,13 +215,13 @@ nfs_read_rpcsetup(struct list_head *head, struct nfs_read_data *data) ...@@ -206,13 +215,13 @@ nfs_read_rpcsetup(struct list_head *head, struct nfs_read_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); args->fh = NFS_FH(req->wb_inode);
data->args.offset = req_offset(req) + req->wb_offset; args->offset = req_offset(req) + req->wb_offset;
data->args.pgbase = req->wb_offset; args->pgbase = req->wb_offset;
data->args.count = count; args->count = count;
data->res.fattr = &data->fattr; res->fattr = &data->fattr;
data->res.count = count; res->count = count;
data->res.eof = 0; res->eof = 0;
} }
static void static void
...@@ -264,8 +273,8 @@ nfs_pagein_one(struct list_head *head, struct inode *inode) ...@@ -264,8 +273,8 @@ nfs_pagein_one(struct list_head *head, struct inode *inode)
#else #else
msg.rpc_proc = NFSPROC_READ; msg.rpc_proc = NFSPROC_READ;
#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;
/* Start the async call */ /* Start the async call */
...@@ -273,8 +282,8 @@ nfs_pagein_one(struct list_head *head, struct inode *inode) ...@@ -273,8 +282,8 @@ nfs_pagein_one(struct list_head *head, struct inode *inode)
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);
...@@ -404,7 +413,8 @@ nfs_readpage_result(struct rpc_task *task) ...@@ -404,7 +413,8 @@ nfs_readpage_result(struct rpc_task *task)
{ {
struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata; struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata;
struct inode *inode = data->inode; struct inode *inode = data->inode;
unsigned int count = data->res.count; unsigned int count = data->u.v3.res.count;
int eof = data->u.v3.res.eof;
dprintk("NFS: %4d nfs_readpage_result, (status %d)\n", dprintk("NFS: %4d nfs_readpage_result, (status %d)\n",
task->tk_pid, task->tk_status); task->tk_pid, task->tk_status);
...@@ -424,7 +434,7 @@ nfs_readpage_result(struct rpc_task *task) ...@@ -424,7 +434,7 @@ nfs_readpage_result(struct rpc_task *task)
memset(p + count, 0, PAGE_CACHE_SIZE - count); memset(p + count, 0, PAGE_CACHE_SIZE - count);
kunmap(page); kunmap(page);
count = 0; count = 0;
if (data->res.eof) if (eof)
SetPageUptodate(page); SetPageUptodate(page);
else else
SetPageError(page); SetPageError(page);
......
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