Commit 193ce3be authored by Linus Torvalds's avatar Linus Torvalds

Merge NFS conflicts

parents f2d816ef 78a21ca0
...@@ -228,7 +228,6 @@ reclaimer(void *ptr) ...@@ -228,7 +228,6 @@ reclaimer(void *ptr)
} }
host->h_reclaiming = 0; host->h_reclaiming = 0;
wake_up(&host->h_gracewait);
/* Now, wake up all processes that sleep on a blocked lock */ /* Now, wake up all processes that sleep on a blocked lock */
for (block = nlm_blocked; block; block = block->b_next) { for (block = nlm_blocked; block; block = block->b_next) {
......
...@@ -217,6 +217,21 @@ nlmclnt_alloc_call(void) ...@@ -217,6 +217,21 @@ nlmclnt_alloc_call(void)
return NULL; return NULL;
} }
static int nlm_wait_on_grace(wait_queue_head_t *queue)
{
DEFINE_WAIT(wait);
int status = -EINTR;
prepare_to_wait(queue, &wait, TASK_INTERRUPTIBLE);
if (!signalled ()) {
schedule_timeout(NLMCLNT_GRACE_WAIT);
if (!signalled ())
status = 0;
}
finish_wait(queue, &wait);
return status;
}
/* /*
* Generic NLM call * Generic NLM call
*/ */
...@@ -241,10 +256,8 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc) ...@@ -241,10 +256,8 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc)
msg.rpc_cred = nfs_file_cred(filp); msg.rpc_cred = nfs_file_cred(filp);
do { do {
if (host->h_reclaiming && !argp->reclaim) { if (host->h_reclaiming && !argp->reclaim)
interruptible_sleep_on(&host->h_gracewait); goto in_grace_period;
continue;
}
/* If we have no RPC client yet, create one. */ /* If we have no RPC client yet, create one. */
if ((clnt = nlm_bind_host(host)) == NULL) if ((clnt = nlm_bind_host(host)) == NULL)
...@@ -279,22 +292,23 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc) ...@@ -279,22 +292,23 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc)
return -ENOLCK; return -ENOLCK;
} }
} else { } else {
if (!argp->reclaim) {
/* We appear to be out of the grace period */
wake_up_all(&host->h_gracewait);
}
dprintk("lockd: server returns status %d\n", resp->status); dprintk("lockd: server returns status %d\n", resp->status);
return 0; /* Okay, call complete */ return 0; /* Okay, call complete */
} }
/* Back off a little and try again */ in_grace_period:
interruptible_sleep_on_timeout(&host->h_gracewait, 15*HZ); /*
* The server has rebooted and appears to be in the grace
/* When the lock requested by F_SETLKW isn't available, * period during which locks are only allowed to be
we will wait until the request can be satisfied. If * reclaimed.
a signal is received during wait, we should return * We can only back off and try again later.
-EINTR. */ */
if (signalled ()) { status = nlm_wait_on_grace(&host->h_gracewait);
status = -EINTR; } while (status == 0);
break;
}
} while (1);
return status; return status;
} }
......
...@@ -128,6 +128,7 @@ nfs_direct_read_seg(struct inode *inode, struct file *file, ...@@ -128,6 +128,7 @@ nfs_direct_read_seg(struct inode *inode, struct file *file,
.inode = inode, .inode = inode,
.args = { .args = {
.fh = NFS_FH(inode), .fh = NFS_FH(inode),
.lockowner = current->files,
}, },
.res = { .res = {
.fattr = &rdata.fattr, .fattr = &rdata.fattr,
...@@ -258,6 +259,7 @@ nfs_direct_write_seg(struct inode *inode, struct file *file, ...@@ -258,6 +259,7 @@ nfs_direct_write_seg(struct inode *inode, struct file *file,
.inode = inode, .inode = inode,
.args = { .args = {
.fh = NFS_FH(inode), .fh = NFS_FH(inode),
.lockowner = current->files,
}, },
.res = { .res = {
.fattr = &wdata.fattr, .fattr = &wdata.fattr,
...@@ -335,8 +337,7 @@ nfs_direct_write_seg(struct inode *inode, struct file *file, ...@@ -335,8 +337,7 @@ nfs_direct_write_seg(struct inode *inode, struct file *file,
VERF_SIZE) != 0) VERF_SIZE) != 0)
goto sync_retry; goto sync_retry;
} }
nfs_end_data_update(inode); nfs_end_data_update_defer(inode);
NFS_FLAGS(inode) |= NFS_INO_INVALID_DATA;
return tot_bytes; return tot_bytes;
...@@ -395,10 +396,6 @@ nfs_direct_write(struct inode *inode, struct file *file, ...@@ -395,10 +396,6 @@ nfs_direct_write(struct inode *inode, struct file *file,
if (result < size) if (result < size)
break; break;
} }
/* Zap the page cache if we managed to write */
if (tot_bytes > 0)
invalidate_remote_inode(inode);
return tot_bytes; return tot_bytes;
} }
......
...@@ -1012,6 +1012,8 @@ void nfs_begin_data_update(struct inode *inode) ...@@ -1012,6 +1012,8 @@ void nfs_begin_data_update(struct inode *inode)
* nfs_end_data_update * nfs_end_data_update
* @inode - pointer to inode * @inode - pointer to inode
* Declare end of the operations that will update file data * Declare end of the operations that will update file data
* This will mark the inode as immediately needing revalidation
* of its attribute cache.
*/ */
void nfs_end_data_update(struct inode *inode) void nfs_end_data_update(struct inode *inode)
{ {
...@@ -1026,6 +1028,27 @@ void nfs_end_data_update(struct inode *inode) ...@@ -1026,6 +1028,27 @@ void nfs_end_data_update(struct inode *inode)
atomic_dec(&nfsi->data_updates); atomic_dec(&nfsi->data_updates);
} }
/**
* nfs_end_data_update_defer
* @inode - pointer to inode
* Declare end of the operations that will update file data
* This will defer marking the inode as needing revalidation
* unless there are no other pending updates.
*/
void nfs_end_data_update_defer(struct inode *inode)
{
struct nfs_inode *nfsi = NFS_I(inode);
if (atomic_dec_and_test(&nfsi->data_updates)) {
/* Mark the attribute cache for revalidation */
nfsi->flags |= NFS_INO_INVALID_ATTR;
/* Directories and symlinks: invalidate page cache too */
if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
nfsi->flags |= NFS_INO_INVALID_DATA;
nfsi->cache_change_attribute ++;
}
}
/** /**
* nfs_refresh_inode - verify consistency of the inode attribute cache * nfs_refresh_inode - verify consistency of the inode attribute cache
* @inode - pointer to inode * @inode - pointer to inode
......
...@@ -231,7 +231,7 @@ nfs_xdr_readargs(struct rpc_rqst *req, u32 *p, struct nfs_readargs *args) ...@@ -231,7 +231,7 @@ nfs_xdr_readargs(struct rpc_rqst *req, u32 *p, struct nfs_readargs *args)
static int static int
nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res) nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
{ {
struct iovec *iov = req->rq_rvec; struct iovec *iov = req->rq_rcv_buf.head;
int status, count, recvd, hdrlen; int status, count, recvd, hdrlen;
if ((status = ntohl(*p++))) if ((status = ntohl(*p++)))
...@@ -250,7 +250,7 @@ nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res) ...@@ -250,7 +250,7 @@ nfs_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen); xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
} }
recvd = req->rq_received - hdrlen; recvd = req->rq_rcv_buf.len - hdrlen;
if (count > recvd) { if (count > recvd) {
printk(KERN_WARNING "NFS: server cheating in read reply: " printk(KERN_WARNING "NFS: server cheating in read reply: "
"count %d > recvd %d\n", count, recvd); "count %d > recvd %d\n", count, recvd);
...@@ -396,7 +396,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, void *dummy) ...@@ -396,7 +396,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, void *dummy)
} }
pglen = rcvbuf->page_len; pglen = rcvbuf->page_len;
recvd = req->rq_received - hdrlen; recvd = rcvbuf->len - hdrlen;
if (pglen > recvd) if (pglen > recvd)
pglen = recvd; pglen = recvd;
page = rcvbuf->pages; page = rcvbuf->pages;
......
...@@ -729,11 +729,10 @@ nfs3_read_done(struct rpc_task *task) ...@@ -729,11 +729,10 @@ nfs3_read_done(struct rpc_task *task)
} }
static void static void
nfs3_proc_read_setup(struct nfs_read_data *data, unsigned int count) nfs3_proc_read_setup(struct nfs_read_data *data)
{ {
struct rpc_task *task = &data->task; struct rpc_task *task = &data->task;
struct inode *inode = data->inode; struct inode *inode = data->inode;
struct nfs_page *req;
int flags; int flags;
struct rpc_message msg = { struct rpc_message msg = {
.rpc_proc = &nfs3_procedures[NFS3PROC_READ], .rpc_proc = &nfs3_procedures[NFS3PROC_READ],
...@@ -742,26 +741,12 @@ nfs3_proc_read_setup(struct nfs_read_data *data, unsigned int count) ...@@ -742,26 +741,12 @@ nfs3_proc_read_setup(struct nfs_read_data *data, unsigned int count)
.rpc_cred = data->cred, .rpc_cred = data->cred,
}; };
req = nfs_list_entry(data->pages.next);
data->args.fh = NFS_FH(inode);
data->args.offset = req_offset(req);
data->args.pgbase = req->wb_pgbase;
data->args.pages = data->pagevec;
data->args.count = count;
data->res.fattr = &data->fattr;
data->res.count = count;
data->res.eof = 0;
/* N.B. Do we need to test? Never called for swapfile inode */ /* N.B. Do we need to test? Never called for swapfile inode */
flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
/* Finalize the task. */ /* Finalize the task. */
rpc_init_task(task, NFS_CLIENT(inode), nfs3_read_done, flags); rpc_init_task(task, NFS_CLIENT(inode), nfs3_read_done, flags);
task->tk_calldata = data; rpc_call_setup(task, &msg, 0);
/* Release requests */
task->tk_release = nfs_readdata_release;
rpc_call_setup(&data->task, &msg, 0);
} }
static void static void
...@@ -778,11 +763,10 @@ nfs3_write_done(struct rpc_task *task) ...@@ -778,11 +763,10 @@ nfs3_write_done(struct rpc_task *task)
} }
static void static void
nfs3_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how) nfs3_proc_write_setup(struct nfs_write_data *data, int how)
{ {
struct rpc_task *task = &data->task; struct rpc_task *task = &data->task;
struct inode *inode = data->inode; struct inode *inode = data->inode;
struct nfs_page *req;
int stable; int stable;
int flags; int flags;
struct rpc_message msg = { struct rpc_message msg = {
...@@ -799,28 +783,14 @@ nfs3_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how) ...@@ -799,28 +783,14 @@ nfs3_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how)
stable = NFS_DATA_SYNC; stable = NFS_DATA_SYNC;
} else } else
stable = NFS_UNSTABLE; stable = NFS_UNSTABLE;
req = nfs_list_entry(data->pages.next);
data->args.fh = NFS_FH(inode);
data->args.offset = req_offset(req);
data->args.pgbase = req->wb_pgbase;
data->args.count = count;
data->args.stable = stable; data->args.stable = stable;
data->args.pages = data->pagevec;
data->res.fattr = &data->fattr;
data->res.count = count;
data->res.verf = &data->verf;
/* Set the initial flags for the task. */ /* Set the initial flags for the task. */
flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
/* Finalize the task. */ /* Finalize the task. */
rpc_init_task(task, NFS_CLIENT(inode), nfs3_write_done, flags); rpc_init_task(task, NFS_CLIENT(inode), nfs3_write_done, flags);
task->tk_calldata = data; rpc_call_setup(task, &msg, 0);
/* Release requests */
task->tk_release = nfs_writedata_release;
rpc_call_setup(&data->task, &msg, 0);
} }
static void static void
...@@ -837,7 +807,7 @@ nfs3_commit_done(struct rpc_task *task) ...@@ -837,7 +807,7 @@ nfs3_commit_done(struct rpc_task *task)
} }
static void static void
nfs3_proc_commit_setup(struct nfs_write_data *data, u64 start, u32 len, int how) nfs3_proc_commit_setup(struct nfs_write_data *data, int how)
{ {
struct rpc_task *task = &data->task; struct rpc_task *task = &data->task;
struct inode *inode = data->inode; struct inode *inode = data->inode;
...@@ -849,23 +819,12 @@ nfs3_proc_commit_setup(struct nfs_write_data *data, u64 start, u32 len, int how) ...@@ -849,23 +819,12 @@ nfs3_proc_commit_setup(struct nfs_write_data *data, u64 start, u32 len, int how)
.rpc_cred = data->cred, .rpc_cred = data->cred,
}; };
data->args.fh = NFS_FH(data->inode);
data->args.offset = start;
data->args.count = len;
data->res.count = len;
data->res.fattr = &data->fattr;
data->res.verf = &data->verf;
/* Set the initial flags for the task. */ /* Set the initial flags for the task. */
flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
/* Finalize the task. */ /* Finalize the task. */
rpc_init_task(task, NFS_CLIENT(inode), nfs3_commit_done, flags); rpc_init_task(task, NFS_CLIENT(inode), nfs3_commit_done, flags);
task->tk_calldata = data; rpc_call_setup(task, &msg, 0);
/* Release requests */
task->tk_release = nfs_commit_release;
rpc_call_setup(&data->task, &msg, 0);
} }
/* /*
......
...@@ -515,7 +515,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, u32 *p, struct nfs3_readdirres *res) ...@@ -515,7 +515,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, u32 *p, struct nfs3_readdirres *res)
} }
pglen = rcvbuf->page_len; pglen = rcvbuf->page_len;
recvd = req->rq_received - hdrlen; recvd = rcvbuf->len - hdrlen;
if (pglen > recvd) if (pglen > recvd)
pglen = recvd; pglen = recvd;
page = rcvbuf->pages; page = rcvbuf->pages;
...@@ -758,7 +758,7 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr) ...@@ -758,7 +758,7 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
static int static int
nfs3_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res) nfs3_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
{ {
struct iovec *iov = req->rq_rvec; struct iovec *iov = req->rq_rcv_buf.head;
int status, count, ocount, recvd, hdrlen; int status, count, ocount, recvd, hdrlen;
status = ntohl(*p++); status = ntohl(*p++);
...@@ -789,7 +789,7 @@ nfs3_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res) ...@@ -789,7 +789,7 @@ nfs3_xdr_readres(struct rpc_rqst *req, u32 *p, struct nfs_readres *res)
xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen); xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
} }
recvd = req->rq_received - hdrlen; recvd = req->rq_rcv_buf.len - hdrlen;
if (count > recvd) { if (count > recvd) {
printk(KERN_WARNING "NFS: server cheating in read reply: " printk(KERN_WARNING "NFS: server cheating in read reply: "
"count %d > recvd %d\n", count, recvd); "count %d > recvd %d\n", count, recvd);
......
This diff is collapsed.
...@@ -105,7 +105,7 @@ nfs4_alloc_client(struct in_addr *addr) ...@@ -105,7 +105,7 @@ nfs4_alloc_client(struct in_addr *addr)
INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp); INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp);
INIT_LIST_HEAD(&clp->cl_superblocks); INIT_LIST_HEAD(&clp->cl_superblocks);
init_waitqueue_head(&clp->cl_waitq); init_waitqueue_head(&clp->cl_waitq);
INIT_RPC_WAITQ(&clp->cl_rpcwaitq, "NFS4 client"); rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client");
clp->cl_state = 1 << NFS4CLNT_NEW; clp->cl_state = 1 << NFS4CLNT_NEW;
} }
return clp; return clp;
......
This diff is collapsed.
...@@ -66,7 +66,8 @@ ...@@ -66,7 +66,8 @@
* is NOT for the length of the hostname. * is NOT for the length of the hostname.
* Hua Qin : Support for mounting root file system via * Hua Qin : Support for mounting root file system via
* NFS over TCP. * NFS over TCP.
*/ * Fabian Frederick: Option parser rebuilt (using parser lib)
*/
#include <linux/config.h> #include <linux/config.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -85,6 +86,7 @@ ...@@ -85,6 +86,7 @@
#include <linux/inet.h> #include <linux/inet.h>
#include <linux/root_dev.h> #include <linux/root_dev.h>
#include <net/ipconfig.h> #include <net/ipconfig.h>
#include <linux/parser.h>
/* Define this to allow debugging output */ /* Define this to allow debugging output */
#undef NFSROOT_DEBUG #undef NFSROOT_DEBUG
...@@ -114,92 +116,158 @@ static int mount_port __initdata = 0; /* Mount daemon port number */ ...@@ -114,92 +116,158 @@ static int mount_port __initdata = 0; /* Mount daemon port number */
***************************************************************************/ ***************************************************************************/
/* enum {
* The following integer options are recognized Opt_port, Opt_rsize, Opt_wsize, Opt_timeo, Opt_retrans, Opt_acregmin,
*/ Opt_acregmax, Opt_acdirmin, Opt_acdirmax, Opt_soft, Opt_hard, Opt_intr,
static struct nfs_int_opts { Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac,
char *name; Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp,
int *val; Opt_broken_suid, Opt_err,
} root_int_opts[] __initdata = {
{ "port", &nfs_port },
{ "rsize", &nfs_data.rsize },
{ "wsize", &nfs_data.wsize },
{ "timeo", &nfs_data.timeo },
{ "retrans", &nfs_data.retrans },
{ "acregmin", &nfs_data.acregmin },
{ "acregmax", &nfs_data.acregmax },
{ "acdirmin", &nfs_data.acdirmin },
{ "acdirmax", &nfs_data.acdirmax },
{ NULL, NULL }
}; };
static match_table_t tokens = {
{Opt_port, "port=%u"},
{Opt_rsize, "rsize=%u"},
{Opt_wsize, "wsize=%u"},
{Opt_timeo, "timeo=%u"},
{Opt_retrans, "retrans=%u"},
{Opt_acregmin, "acregmin=%u"},
{Opt_acregmax, "acregmax=%u"},
{Opt_acdirmin, "acdirmin=%u"},
{Opt_acdirmax, "acdirmax=%u"},
{Opt_soft, "soft"},
{Opt_hard, "hard"},
{Opt_intr, "intr"},
{Opt_nointr, "nointr"},
{Opt_posix, "posix"},
{Opt_noposix, "noposix"},
{Opt_cto, "cto"},
{Opt_nocto, "nocto"},
{Opt_ac, "ac"},
{Opt_noac, "noac"},
{Opt_lock, "lock"},
{Opt_nolock, "nolock"},
{Opt_v2, "v2"},
{Opt_v3, "v3"},
{Opt_udp, "udp"},
{Opt_tcp, "tcp"},
{Opt_broken_suid, "broken_suid"},
{Opt_err, NULL}
/*
* And now the flag options
*/
static struct nfs_bool_opts {
char *name;
int and_mask;
int or_mask;
} root_bool_opts[] __initdata = {
{ "soft", ~NFS_MOUNT_SOFT, NFS_MOUNT_SOFT },
{ "hard", ~NFS_MOUNT_SOFT, 0 },
{ "intr", ~NFS_MOUNT_INTR, NFS_MOUNT_INTR },
{ "nointr", ~NFS_MOUNT_INTR, 0 },
{ "posix", ~NFS_MOUNT_POSIX, NFS_MOUNT_POSIX },
{ "noposix", ~NFS_MOUNT_POSIX, 0 },
{ "cto", ~NFS_MOUNT_NOCTO, 0 },
{ "nocto", ~NFS_MOUNT_NOCTO, NFS_MOUNT_NOCTO },
{ "ac", ~NFS_MOUNT_NOAC, 0 },
{ "noac", ~NFS_MOUNT_NOAC, NFS_MOUNT_NOAC },
{ "lock", ~NFS_MOUNT_NONLM, 0 },
{ "nolock", ~NFS_MOUNT_NONLM, NFS_MOUNT_NONLM },
#ifdef CONFIG_NFS_V3
{ "v2", ~NFS_MOUNT_VER3, 0 },
{ "v3", ~NFS_MOUNT_VER3, NFS_MOUNT_VER3 },
#endif
{ "udp", ~NFS_MOUNT_TCP, 0 },
{ "tcp", ~NFS_MOUNT_TCP, NFS_MOUNT_TCP },
{ "broken_suid",~NFS_MOUNT_BROKEN_SUID, NFS_MOUNT_BROKEN_SUID },
{ NULL, 0, 0 }
}; };
/* /*
* Parse option string. * Parse option string.
*/ */
static void __init root_nfs_parse(char *name, char *buf)
static int __init root_nfs_parse(char *name, char *buf)
{ {
char *options, *val, *cp;
if ((options = strchr(name, ','))) { char *p;
*options++ = 0; substring_t args[MAX_OPT_ARGS];
while ((cp = strsep(&options, ",")) != NULL) { int option;
if (!*cp)
continue; if (!name)
if ((val = strchr(cp, '='))) { return 1;
struct nfs_int_opts *opts = root_int_opts;
*val++ = '\0'; if (name[0] && strcmp(name, "default")){
while (opts->name && strcmp(opts->name, cp)) strlcpy(buf, name, NFS_MAXPATHLEN);
opts++; return 1;
if (opts->name)
*(opts->val) = (int) simple_strtoul(val, NULL, 10);
} else {
struct nfs_bool_opts *opts = root_bool_opts;
while (opts->name && strcmp(opts->name, cp))
opts++;
if (opts->name) {
nfs_data.flags &= opts->and_mask;
nfs_data.flags |= opts->or_mask;
}
} }
while ((p = strsep (&name, ",")) != NULL) {
int token;
if (!*p)
continue;
token = match_token(p, tokens, args);
/* %u tokens only */
if (match_int(&args[0], &option))
return 0;
switch (token) {
case Opt_port:
nfs_port = option;
break;
case Opt_rsize:
nfs_data.rsize = option;
break;
case Opt_wsize:
nfs_data.wsize = option;
break;
case Opt_timeo:
nfs_data.timeo = option;
break;
case Opt_retrans:
nfs_data.retrans = option;
break;
case Opt_acregmin:
nfs_data.acregmin = option;
break;
case Opt_acregmax:
nfs_data.acregmax = option;
break;
case Opt_acdirmin:
nfs_data.acdirmin = option;
break;
case Opt_acdirmax:
nfs_data.acdirmax = option;
break;
case Opt_soft:
nfs_data.flags |= NFS_MOUNT_SOFT;
break;
case Opt_hard:
nfs_data.flags &= ~NFS_MOUNT_SOFT;
break;
case Opt_intr:
nfs_data.flags |= NFS_MOUNT_INTR;
break;
case Opt_nointr:
nfs_data.flags &= ~NFS_MOUNT_INTR;
break;
case Opt_posix:
nfs_data.flags |= NFS_MOUNT_POSIX;
break;
case Opt_noposix:
nfs_data.flags &= ~NFS_MOUNT_POSIX;
break;
case Opt_cto:
nfs_data.flags &= ~NFS_MOUNT_NOCTO;
break;
case Opt_nocto:
nfs_data.flags |= NFS_MOUNT_NOCTO;
break;
case Opt_ac:
nfs_data.flags &= ~NFS_MOUNT_NOAC;
break;
case Opt_noac:
nfs_data.flags |= NFS_MOUNT_NOAC;
break;
case Opt_lock:
nfs_data.flags &= ~NFS_MOUNT_NONLM;
break;
case Opt_nolock:
nfs_data.flags |= NFS_MOUNT_NONLM;
break;
case Opt_v2:
nfs_data.flags &= ~NFS_MOUNT_VER3;
break;
case Opt_v3:
nfs_data.flags |= NFS_MOUNT_VER3;
break;
case Opt_udp:
nfs_data.flags &= ~NFS_MOUNT_TCP;
break;
case Opt_tcp:
nfs_data.flags |= NFS_MOUNT_TCP;
break;
case Opt_broken_suid:
nfs_data.flags |= NFS_MOUNT_BROKEN_SUID;
break;
default :
return 0;
} }
} }
if (name[0] && strcmp(name, "default")) return 1;
strlcpy(buf, name, NFS_MAXPATHLEN);
} }
/* /*
* Prepare the NFS data structure and parse all options. * Prepare the NFS data structure and parse all options.
*/ */
......
...@@ -32,7 +32,7 @@ static inline struct nfs_page * ...@@ -32,7 +32,7 @@ static inline struct nfs_page *
nfs_page_alloc(void) nfs_page_alloc(void)
{ {
struct nfs_page *p; struct nfs_page *p;
p = kmem_cache_alloc(nfs_page_cachep, SLAB_NOFS); p = kmem_cache_alloc(nfs_page_cachep, SLAB_KERNEL);
if (p) { if (p) {
memset(p, 0, sizeof(*p)); memset(p, 0, sizeof(*p));
INIT_LIST_HEAD(&p->wb_list); INIT_LIST_HEAD(&p->wb_list);
...@@ -88,6 +88,7 @@ nfs_create_request(struct file *file, struct inode *inode, ...@@ -88,6 +88,7 @@ nfs_create_request(struct file *file, struct inode *inode,
* long write-back delay. This will be adjusted in * long write-back delay. This will be adjusted in
* update_nfs_request below if the region is not locked. */ * update_nfs_request below if the region is not locked. */
req->wb_page = page; req->wb_page = page;
atomic_set(&req->wb_complete, 0);
req->wb_index = page->index; req->wb_index = page->index;
page_cache_get(page); page_cache_get(page);
req->wb_offset = offset; req->wb_offset = offset;
......
...@@ -559,11 +559,10 @@ nfs_read_done(struct rpc_task *task) ...@@ -559,11 +559,10 @@ nfs_read_done(struct rpc_task *task)
} }
static void static void
nfs_proc_read_setup(struct nfs_read_data *data, unsigned int count) nfs_proc_read_setup(struct nfs_read_data *data)
{ {
struct rpc_task *task = &data->task; struct rpc_task *task = &data->task;
struct inode *inode = data->inode; struct inode *inode = data->inode;
struct nfs_page *req;
int flags; int flags;
struct rpc_message msg = { struct rpc_message msg = {
.rpc_proc = &nfs_procedures[NFSPROC_READ], .rpc_proc = &nfs_procedures[NFSPROC_READ],
...@@ -572,26 +571,12 @@ nfs_proc_read_setup(struct nfs_read_data *data, unsigned int count) ...@@ -572,26 +571,12 @@ nfs_proc_read_setup(struct nfs_read_data *data, unsigned int count)
.rpc_cred = data->cred, .rpc_cred = data->cred,
}; };
req = nfs_list_entry(data->pages.next);
data->args.fh = NFS_FH(inode);
data->args.offset = req_offset(req);
data->args.pgbase = req->wb_pgbase;
data->args.pages = data->pagevec;
data->args.count = count;
data->res.fattr = &data->fattr;
data->res.count = count;
data->res.eof = 0;
/* N.B. Do we need to test? Never called for swapfile inode */ /* N.B. Do we need to test? Never called for swapfile inode */
flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
/* Finalize the task. */ /* Finalize the task. */
rpc_init_task(task, NFS_CLIENT(inode), nfs_read_done, flags); rpc_init_task(task, NFS_CLIENT(inode), nfs_read_done, flags);
task->tk_calldata = data; rpc_call_setup(task, &msg, 0);
/* Release requests */
task->tk_release = nfs_readdata_release;
rpc_call_setup(&data->task, &msg, 0);
} }
static void static void
...@@ -605,11 +590,10 @@ nfs_write_done(struct rpc_task *task) ...@@ -605,11 +590,10 @@ nfs_write_done(struct rpc_task *task)
} }
static void static void
nfs_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how) nfs_proc_write_setup(struct nfs_write_data *data, int how)
{ {
struct rpc_task *task = &data->task; struct rpc_task *task = &data->task;
struct inode *inode = data->inode; struct inode *inode = data->inode;
struct nfs_page *req;
int flags; int flags;
struct rpc_message msg = { struct rpc_message msg = {
.rpc_proc = &nfs_procedures[NFSPROC_WRITE], .rpc_proc = &nfs_procedures[NFSPROC_WRITE],
...@@ -619,32 +603,18 @@ nfs_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how) ...@@ -619,32 +603,18 @@ nfs_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how)
}; };
/* Note: NFSv2 ignores @stable and always uses NFS_FILE_SYNC */ /* Note: NFSv2 ignores @stable and always uses NFS_FILE_SYNC */
req = nfs_list_entry(data->pages.next);
data->args.fh = NFS_FH(inode);
data->args.offset = req_offset(req);
data->args.pgbase = req->wb_pgbase;
data->args.count = count;
data->args.stable = NFS_FILE_SYNC; data->args.stable = NFS_FILE_SYNC;
data->args.pages = data->pagevec;
data->res.fattr = &data->fattr;
data->res.count = count;
data->res.verf = &data->verf;
/* Set the initial flags for the task. */ /* Set the initial flags for the task. */
flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
/* Finalize the task. */ /* Finalize the task. */
rpc_init_task(task, NFS_CLIENT(inode), nfs_write_done, flags); rpc_init_task(task, NFS_CLIENT(inode), nfs_write_done, flags);
task->tk_calldata = data; rpc_call_setup(task, &msg, 0);
/* Release requests */
task->tk_release = nfs_writedata_release;
rpc_call_setup(&data->task, &msg, 0);
} }
static void static void
nfs_proc_commit_setup(struct nfs_write_data *data, u64 start, u32 len, int how) nfs_proc_commit_setup(struct nfs_write_data *data, int how)
{ {
BUG(); BUG();
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -47,6 +47,11 @@ ...@@ -47,6 +47,11 @@
#define NFS4_ACE_SYSTEM_AUDIT_ACE_TYPE 2 #define NFS4_ACE_SYSTEM_AUDIT_ACE_TYPE 2
#define NFS4_ACE_SYSTEM_ALARM_ACE_TYPE 3 #define NFS4_ACE_SYSTEM_ALARM_ACE_TYPE 3
#define ACL4_SUPPORT_ALLOW_ACL 0x01
#define ACL4_SUPPORT_DENY_ACL 0x02
#define ACL4_SUPPORT_AUDIT_ACL 0x04
#define ACL4_SUPPORT_ALARM_ACL 0x08
typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier; typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier;
typedef struct { char data[16]; } nfs4_stateid; typedef struct { char data[16]; } nfs4_stateid;
...@@ -217,64 +222,64 @@ enum lock_type4 { ...@@ -217,64 +222,64 @@ enum lock_type4 {
/* Mandatory Attributes */ /* Mandatory Attributes */
#define FATTR4_WORD0_SUPPORTED_ATTRS (1) #define FATTR4_WORD0_SUPPORTED_ATTRS (1UL << 0)
#define FATTR4_WORD0_TYPE (1 << 1) #define FATTR4_WORD0_TYPE (1UL << 1)
#define FATTR4_WORD0_FH_EXPIRE_TYPE (1 << 2) #define FATTR4_WORD0_FH_EXPIRE_TYPE (1UL << 2)
#define FATTR4_WORD0_CHANGE (1 << 3) #define FATTR4_WORD0_CHANGE (1UL << 3)
#define FATTR4_WORD0_SIZE (1 << 4) #define FATTR4_WORD0_SIZE (1UL << 4)
#define FATTR4_WORD0_LINK_SUPPORT (1 << 5) #define FATTR4_WORD0_LINK_SUPPORT (1UL << 5)
#define FATTR4_WORD0_SYMLINK_SUPPORT (1 << 6) #define FATTR4_WORD0_SYMLINK_SUPPORT (1UL << 6)
#define FATTR4_WORD0_NAMED_ATTR (1 << 7) #define FATTR4_WORD0_NAMED_ATTR (1UL << 7)
#define FATTR4_WORD0_FSID (1 << 8) #define FATTR4_WORD0_FSID (1UL << 8)
#define FATTR4_WORD0_UNIQUE_HANDLES (1 << 9) #define FATTR4_WORD0_UNIQUE_HANDLES (1UL << 9)
#define FATTR4_WORD0_LEASE_TIME (1 << 10) #define FATTR4_WORD0_LEASE_TIME (1UL << 10)
#define FATTR4_WORD0_RDATTR_ERROR (1 << 11) #define FATTR4_WORD0_RDATTR_ERROR (1UL << 11)
/* Recommended Attributes */ /* Recommended Attributes */
#define FATTR4_WORD0_ACL (1 << 12) #define FATTR4_WORD0_ACL (1UL << 12)
#define FATTR4_WORD0_ACLSUPPORT (1 << 13) #define FATTR4_WORD0_ACLSUPPORT (1UL << 13)
#define FATTR4_WORD0_ARCHIVE (1 << 14) #define FATTR4_WORD0_ARCHIVE (1UL << 14)
#define FATTR4_WORD0_CANSETTIME (1 << 15) #define FATTR4_WORD0_CANSETTIME (1UL << 15)
#define FATTR4_WORD0_CASE_INSENSITIVE (1 << 16) #define FATTR4_WORD0_CASE_INSENSITIVE (1UL << 16)
#define FATTR4_WORD0_CASE_PRESERVING (1 << 17) #define FATTR4_WORD0_CASE_PRESERVING (1UL << 17)
#define FATTR4_WORD0_CHOWN_RESTRICTED (1 << 18) #define FATTR4_WORD0_CHOWN_RESTRICTED (1UL << 18)
#define FATTR4_WORD0_FILEHANDLE (1 << 19) #define FATTR4_WORD0_FILEHANDLE (1UL << 19)
#define FATTR4_WORD0_FILEID (1 << 20) #define FATTR4_WORD0_FILEID (1UL << 20)
#define FATTR4_WORD0_FILES_AVAIL (1 << 21) #define FATTR4_WORD0_FILES_AVAIL (1UL << 21)
#define FATTR4_WORD0_FILES_FREE (1 << 22) #define FATTR4_WORD0_FILES_FREE (1UL << 22)
#define FATTR4_WORD0_FILES_TOTAL (1 << 23) #define FATTR4_WORD0_FILES_TOTAL (1UL << 23)
#define FATTR4_WORD0_FS_LOCATIONS (1 << 24) #define FATTR4_WORD0_FS_LOCATIONS (1UL << 24)
#define FATTR4_WORD0_HIDDEN (1 << 25) #define FATTR4_WORD0_HIDDEN (1UL << 25)
#define FATTR4_WORD0_HOMOGENEOUS (1 << 26) #define FATTR4_WORD0_HOMOGENEOUS (1UL << 26)
#define FATTR4_WORD0_MAXFILESIZE (1 << 27) #define FATTR4_WORD0_MAXFILESIZE (1UL << 27)
#define FATTR4_WORD0_MAXLINK (1 << 28) #define FATTR4_WORD0_MAXLINK (1UL << 28)
#define FATTR4_WORD0_MAXNAME (1 << 29) #define FATTR4_WORD0_MAXNAME (1UL << 29)
#define FATTR4_WORD0_MAXREAD (1 << 30) #define FATTR4_WORD0_MAXREAD (1UL << 30)
#define FATTR4_WORD0_MAXWRITE (1 << 31) #define FATTR4_WORD0_MAXWRITE (1UL << 31)
#define FATTR4_WORD1_MIMETYPE (1) #define FATTR4_WORD1_MIMETYPE (1UL << 0)
#define FATTR4_WORD1_MODE (1 << 1) #define FATTR4_WORD1_MODE (1UL << 1)
#define FATTR4_WORD1_NO_TRUNC (1 << 2) #define FATTR4_WORD1_NO_TRUNC (1UL << 2)
#define FATTR4_WORD1_NUMLINKS (1 << 3) #define FATTR4_WORD1_NUMLINKS (1UL << 3)
#define FATTR4_WORD1_OWNER (1 << 4) #define FATTR4_WORD1_OWNER (1UL << 4)
#define FATTR4_WORD1_OWNER_GROUP (1 << 5) #define FATTR4_WORD1_OWNER_GROUP (1UL << 5)
#define FATTR4_WORD1_QUOTA_HARD (1 << 6) #define FATTR4_WORD1_QUOTA_HARD (1UL << 6)
#define FATTR4_WORD1_QUOTA_SOFT (1 << 7) #define FATTR4_WORD1_QUOTA_SOFT (1UL << 7)
#define FATTR4_WORD1_QUOTA_USED (1 << 8) #define FATTR4_WORD1_QUOTA_USED (1UL << 8)
#define FATTR4_WORD1_RAWDEV (1 << 9) #define FATTR4_WORD1_RAWDEV (1UL << 9)
#define FATTR4_WORD1_SPACE_AVAIL (1 << 10) #define FATTR4_WORD1_SPACE_AVAIL (1UL << 10)
#define FATTR4_WORD1_SPACE_FREE (1 << 11) #define FATTR4_WORD1_SPACE_FREE (1UL << 11)
#define FATTR4_WORD1_SPACE_TOTAL (1 << 12) #define FATTR4_WORD1_SPACE_TOTAL (1UL << 12)
#define FATTR4_WORD1_SPACE_USED (1 << 13) #define FATTR4_WORD1_SPACE_USED (1UL << 13)
#define FATTR4_WORD1_SYSTEM (1 << 14) #define FATTR4_WORD1_SYSTEM (1UL << 14)
#define FATTR4_WORD1_TIME_ACCESS (1 << 15) #define FATTR4_WORD1_TIME_ACCESS (1UL << 15)
#define FATTR4_WORD1_TIME_ACCESS_SET (1 << 16) #define FATTR4_WORD1_TIME_ACCESS_SET (1UL << 16)
#define FATTR4_WORD1_TIME_BACKUP (1 << 17) #define FATTR4_WORD1_TIME_BACKUP (1UL << 17)
#define FATTR4_WORD1_TIME_CREATE (1 << 18) #define FATTR4_WORD1_TIME_CREATE (1UL << 18)
#define FATTR4_WORD1_TIME_DELTA (1 << 19) #define FATTR4_WORD1_TIME_DELTA (1UL << 19)
#define FATTR4_WORD1_TIME_METADATA (1 << 20) #define FATTR4_WORD1_TIME_METADATA (1UL << 20)
#define FATTR4_WORD1_TIME_MODIFY (1 << 21) #define FATTR4_WORD1_TIME_MODIFY (1UL << 21)
#define FATTR4_WORD1_TIME_MODIFY_SET (1 << 22) #define FATTR4_WORD1_TIME_MODIFY_SET (1UL << 22)
#define FATTR4_WORD1_MOUNTED_ON_FILEID (1 << 23) #define FATTR4_WORD1_MOUNTED_ON_FILEID (1UL << 23)
#define NFSPROC4_NULL 0 #define NFSPROC4_NULL 0
#define NFSPROC4_COMPOUND 1 #define NFSPROC4_COMPOUND 1
...@@ -287,7 +292,6 @@ enum lock_type4 { ...@@ -287,7 +292,6 @@ enum lock_type4 {
enum { enum {
NFSPROC4_CLNT_NULL = 0, /* Unused */ NFSPROC4_CLNT_NULL = 0, /* Unused */
NFSPROC4_CLNT_COMPOUND, /* Soon to be unused */
NFSPROC4_CLNT_READ, NFSPROC4_CLNT_READ,
NFSPROC4_CLNT_WRITE, NFSPROC4_CLNT_WRITE,
NFSPROC4_CLNT_COMMIT, NFSPROC4_CLNT_COMMIT,
...@@ -304,6 +308,19 @@ enum { ...@@ -304,6 +308,19 @@ enum {
NFSPROC4_CLNT_LOCK, NFSPROC4_CLNT_LOCK,
NFSPROC4_CLNT_LOCKT, NFSPROC4_CLNT_LOCKT,
NFSPROC4_CLNT_LOCKU, NFSPROC4_CLNT_LOCKU,
NFSPROC4_CLNT_ACCESS,
NFSPROC4_CLNT_GETATTR,
NFSPROC4_CLNT_LOOKUP,
NFSPROC4_CLNT_LOOKUP_ROOT,
NFSPROC4_CLNT_REMOVE,
NFSPROC4_CLNT_RENAME,
NFSPROC4_CLNT_LINK,
NFSPROC4_CLNT_CREATE,
NFSPROC4_CLNT_PATHCONF,
NFSPROC4_CLNT_STATFS,
NFSPROC4_CLNT_READLINK,
NFSPROC4_CLNT_READDIR,
NFSPROC4_CLNT_SERVER_CAPS,
}; };
#endif #endif
......
...@@ -69,6 +69,8 @@ ...@@ -69,6 +69,8 @@
#define FLUSH_SYNC 1 /* file being synced, or contention */ #define FLUSH_SYNC 1 /* file being synced, or contention */
#define FLUSH_WAIT 2 /* wait for completion */ #define FLUSH_WAIT 2 /* wait for completion */
#define FLUSH_STABLE 4 /* commit to stable storage */ #define FLUSH_STABLE 4 /* commit to stable storage */
#define FLUSH_LOWPRI 8 /* low priority background flush */
#define FLUSH_HIGHPRI 16 /* high priority memory reclaim flush */
#ifdef __KERNEL__ #ifdef __KERNEL__
...@@ -275,6 +277,7 @@ extern void nfs_begin_attr_update(struct inode *); ...@@ -275,6 +277,7 @@ extern void nfs_begin_attr_update(struct inode *);
extern void nfs_end_attr_update(struct inode *); extern void nfs_end_attr_update(struct inode *);
extern void nfs_begin_data_update(struct inode *); extern void nfs_begin_data_update(struct inode *);
extern void nfs_end_data_update(struct inode *); extern void nfs_end_data_update(struct inode *);
extern void nfs_end_data_update_defer(struct inode *);
/* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */ /* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
extern u32 root_nfs_parse_addr(char *name); /*__init*/ extern u32 root_nfs_parse_addr(char *name); /*__init*/
...@@ -335,10 +338,8 @@ extern int nfs_writepages(struct address_space *, struct writeback_control *); ...@@ -335,10 +338,8 @@ extern int nfs_writepages(struct address_space *, struct writeback_control *);
extern int nfs_flush_incompatible(struct file *file, struct page *page); extern int nfs_flush_incompatible(struct file *file, struct page *page);
extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int); extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int);
extern void nfs_writeback_done(struct rpc_task *task); extern void nfs_writeback_done(struct rpc_task *task);
extern void nfs_writedata_release(struct rpc_task *task);
#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
extern void nfs_commit_release(struct rpc_task *task);
extern void nfs_commit_done(struct rpc_task *); extern void nfs_commit_done(struct rpc_task *);
#endif #endif
...@@ -376,14 +377,18 @@ nfs_wb_all(struct inode *inode) ...@@ -376,14 +377,18 @@ nfs_wb_all(struct inode *inode)
/* /*
* Write back all requests on one page - we do this before reading it. * Write back all requests on one page - we do this before reading it.
*/ */
static inline int static inline int nfs_wb_page_priority(struct inode *inode, struct page* page, int how)
nfs_wb_page(struct inode *inode, struct page* page)
{ {
int error = nfs_sync_inode(inode, page->index, 1, int error = nfs_sync_inode(inode, page->index, 1,
FLUSH_WAIT | FLUSH_STABLE); how | FLUSH_WAIT | FLUSH_STABLE);
return (error < 0) ? error : 0; return (error < 0) ? error : 0;
} }
static inline int nfs_wb_page(struct inode *inode, struct page* page)
{
return nfs_wb_page_priority(inode, page, 0);
}
/* Hack for future NFS swap support */ /* Hack for future NFS swap support */
#ifndef IS_SWAPFILE #ifndef IS_SWAPFILE
# define IS_SWAPFILE(inode) (0) # define IS_SWAPFILE(inode) (0)
...@@ -397,7 +402,6 @@ extern int nfs_readpages(struct file *, struct address_space *, ...@@ -397,7 +402,6 @@ extern int nfs_readpages(struct file *, struct address_space *,
struct list_head *, unsigned); struct list_head *, unsigned);
extern int nfs_pagein_list(struct list_head *, int); extern int nfs_pagein_list(struct list_head *, int);
extern void nfs_readpage_result(struct rpc_task *); extern void nfs_readpage_result(struct rpc_task *);
extern void nfs_readdata_release(struct rpc_task *);
/* /*
* linux/fs/mount_clnt.c * linux/fs/mount_clnt.c
......
...@@ -38,10 +38,19 @@ struct nfs_server { ...@@ -38,10 +38,19 @@ struct nfs_server {
struct list_head nfs4_siblings; /* List of other nfs_server structs struct list_head nfs4_siblings; /* List of other nfs_server structs
* that share the same clientid * that share the same clientid
*/ */
u32 attr_bitmask[2];/* V4 bitmask representing the set
of attributes supported on this
filesystem */
u32 acl_bitmask; /* V4 bitmask representing the ACEs
that are supported on this
filesystem */
#endif #endif
}; };
/* Server capabilities */ /* Server capabilities */
#define NFS_CAP_READDIRPLUS (1) #define NFS_CAP_READDIRPLUS (1U << 0)
#define NFS_CAP_HARDLINKS (1U << 1)
#define NFS_CAP_SYMLINKS (1U << 2)
#define NFS_CAP_ACLS (1U << 3)
#endif #endif
...@@ -17,10 +17,14 @@ ...@@ -17,10 +17,14 @@
#include <linux/sunrpc/auth.h> #include <linux/sunrpc/auth.h>
#include <linux/nfs_xdr.h> #include <linux/nfs_xdr.h>
#include <asm/atomic.h>
/* /*
* Valid flags for a dirty buffer * Valid flags for a dirty buffer
*/ */
#define PG_BUSY 0 #define PG_BUSY 0
#define PG_NEED_COMMIT 1
#define PG_NEED_RESCHED 2
struct nfs_page { struct nfs_page {
struct list_head wb_list, /* Defines state of page: */ struct list_head wb_list, /* Defines state of page: */
...@@ -31,6 +35,7 @@ struct nfs_page { ...@@ -31,6 +35,7 @@ struct nfs_page {
struct rpc_cred *wb_cred; struct rpc_cred *wb_cred;
struct nfs4_state *wb_state; struct nfs4_state *wb_state;
struct page *wb_page; /* page to read in/write out */ struct page *wb_page; /* page to read in/write out */
atomic_t wb_complete; /* i/os we're waiting for */
wait_queue_head_t wb_wait; /* wait queue */ wait_queue_head_t wb_wait; /* wait queue */
unsigned long wb_index; /* Offset >> PAGE_CACHE_SHIFT */ unsigned long wb_index; /* Offset >> PAGE_CACHE_SHIFT */
unsigned int wb_offset, /* Offset & ~PAGE_CACHE_MASK */ unsigned int wb_offset, /* Offset & ~PAGE_CACHE_MASK */
...@@ -42,6 +47,8 @@ struct nfs_page { ...@@ -42,6 +47,8 @@ struct nfs_page {
}; };
#define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags)) #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags))
#define NFS_NEED_COMMIT(req) (test_bit(PG_NEED_COMMIT,&(req)->wb_flags))
#define NFS_NEED_RESCHED(req) (test_bit(PG_NEED_RESCHED,&(req)->wb_flags))
extern struct nfs_page *nfs_create_request(struct file *, struct inode *, extern struct nfs_page *nfs_create_request(struct file *, struct inode *,
struct page *, struct page *,
...@@ -93,7 +100,6 @@ nfs_unlock_request(struct nfs_page *req) ...@@ -93,7 +100,6 @@ nfs_unlock_request(struct nfs_page *req)
smp_mb__before_clear_bit(); smp_mb__before_clear_bit();
clear_bit(PG_BUSY, &req->wb_flags); clear_bit(PG_BUSY, &req->wb_flags);
smp_mb__after_clear_bit(); smp_mb__after_clear_bit();
if (waitqueue_active(&req->wb_wait))
wake_up_all(&req->wb_wait); wake_up_all(&req->wb_wait);
nfs_release_request(req); nfs_release_request(req);
} }
...@@ -115,6 +121,38 @@ nfs_list_remove_request(struct nfs_page *req) ...@@ -115,6 +121,38 @@ nfs_list_remove_request(struct nfs_page *req)
req->wb_list_head = NULL; req->wb_list_head = NULL;
} }
static inline int
nfs_defer_commit(struct nfs_page *req)
{
if (test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags))
return 0;
return 1;
}
static inline void
nfs_clear_commit(struct nfs_page *req)
{
smp_mb__before_clear_bit();
clear_bit(PG_NEED_COMMIT, &req->wb_flags);
smp_mb__after_clear_bit();
}
static inline int
nfs_defer_reschedule(struct nfs_page *req)
{
if (test_and_set_bit(PG_NEED_RESCHED, &req->wb_flags))
return 0;
return 1;
}
static inline void
nfs_clear_reschedule(struct nfs_page *req)
{
smp_mb__before_clear_bit();
clear_bit(PG_NEED_RESCHED, &req->wb_flags);
smp_mb__after_clear_bit();
}
static inline struct nfs_page * static inline struct nfs_page *
nfs_list_entry(struct list_head *head) nfs_list_entry(struct list_head *head)
{ {
......
This diff is collapsed.
...@@ -49,6 +49,8 @@ struct rpc_task { ...@@ -49,6 +49,8 @@ struct rpc_task {
tk_cred_retry, tk_cred_retry,
tk_suid_retry; tk_suid_retry;
unsigned long tk_cookie; /* Cookie for batching tasks */
/* /*
* timeout_fn to be executed by timer bottom half * timeout_fn to be executed by timer bottom half
* callback to be executed after waking up * callback to be executed after waking up
...@@ -72,7 +74,9 @@ struct rpc_task { ...@@ -72,7 +74,9 @@ struct rpc_task {
unsigned long tk_timeout; /* timeout for rpc_sleep() */ unsigned long tk_timeout; /* timeout for rpc_sleep() */
unsigned short tk_flags; /* misc flags */ unsigned short tk_flags; /* misc flags */
unsigned char tk_active : 1;/* Task has been activated */ unsigned char tk_active : 1;/* Task has been activated */
unsigned char tk_priority : 2;/* Task priority */
unsigned long tk_runstate; /* Task run status */ unsigned long tk_runstate; /* Task run status */
struct list_head tk_links; /* links to related tasks */
#ifdef RPC_DEBUG #ifdef RPC_DEBUG
unsigned short tk_pid; /* debugging aid */ unsigned short tk_pid; /* debugging aid */
#endif #endif
...@@ -137,29 +141,59 @@ typedef void (*rpc_action)(struct rpc_task *); ...@@ -137,29 +141,59 @@ typedef void (*rpc_action)(struct rpc_task *);
smp_mb__after_clear_bit(); \ smp_mb__after_clear_bit(); \
} while(0) } while(0)
/*
* Task priorities.
* Note: if you change these, you must also change
* the task initialization definitions below.
*/
#define RPC_PRIORITY_LOW 0
#define RPC_PRIORITY_NORMAL 1
#define RPC_PRIORITY_HIGH 2
#define RPC_NR_PRIORITY (RPC_PRIORITY_HIGH+1)
/* /*
* RPC synchronization objects * RPC synchronization objects
*/ */
struct rpc_wait_queue { struct rpc_wait_queue {
struct list_head tasks; struct list_head tasks[RPC_NR_PRIORITY]; /* task queue for each priority level */
unsigned long cookie; /* cookie of last task serviced */
unsigned char maxpriority; /* maximum priority (0 if queue is not a priority queue) */
unsigned char priority; /* current priority */
unsigned char count; /* # task groups remaining serviced so far */
unsigned char nr; /* # tasks remaining for cookie */
#ifdef RPC_DEBUG #ifdef RPC_DEBUG
char * name; const char * name;
#endif #endif
}; };
/*
* This is the # requests to send consecutively
* from a single cookie. The aim is to improve
* performance of NFS operations such as read/write.
*/
#define RPC_BATCH_COUNT 16
#ifndef RPC_DEBUG #ifndef RPC_DEBUG
# define RPC_WAITQ_INIT(var,qname) ((struct rpc_wait_queue) {LIST_HEAD_INIT(var)}) # define RPC_WAITQ_INIT(var,qname) { \
# define RPC_WAITQ(var,qname) struct rpc_wait_queue var = RPC_WAITQ_INIT(var.tasks,qname) .tasks = { \
# define INIT_RPC_WAITQ(ptr,qname) do { \ [0] = LIST_HEAD_INIT(var.tasks[0]), \
INIT_LIST_HEAD(&(ptr)->tasks); \ [1] = LIST_HEAD_INIT(var.tasks[1]), \
} while(0) [2] = LIST_HEAD_INIT(var.tasks[2]), \
}, \
}
#else #else
# define RPC_WAITQ_INIT(var,qname) ((struct rpc_wait_queue) {LIST_HEAD_INIT(var.tasks), qname}) # define RPC_WAITQ_INIT(var,qname) { \
# define RPC_WAITQ(var,qname) struct rpc_wait_queue var = RPC_WAITQ_INIT(var,qname) .tasks = { \
# define INIT_RPC_WAITQ(ptr,qname) do { \ [0] = LIST_HEAD_INIT(var.tasks[0]), \
INIT_LIST_HEAD(&(ptr)->tasks); (ptr)->name = qname; \ [1] = LIST_HEAD_INIT(var.tasks[1]), \
} while(0) [2] = LIST_HEAD_INIT(var.tasks[2]), \
}, \
.name = qname, \
}
#endif #endif
# define RPC_WAITQ(var,qname) struct rpc_wait_queue var = RPC_WAITQ_INIT(var,qname)
#define RPC_IS_PRIORITY(q) ((q)->maxpriority > 0)
/* /*
* Function prototypes * Function prototypes
...@@ -175,6 +209,8 @@ void rpc_run_child(struct rpc_task *parent, struct rpc_task *child, ...@@ -175,6 +209,8 @@ void rpc_run_child(struct rpc_task *parent, struct rpc_task *child,
rpc_action action); rpc_action action);
int rpc_add_wait_queue(struct rpc_wait_queue *, struct rpc_task *); int rpc_add_wait_queue(struct rpc_wait_queue *, struct rpc_task *);
void rpc_remove_wait_queue(struct rpc_task *); void rpc_remove_wait_queue(struct rpc_task *);
void rpc_init_priority_wait_queue(struct rpc_wait_queue *, const char *);
void rpc_init_wait_queue(struct rpc_wait_queue *, const char *);
void rpc_sleep_on(struct rpc_wait_queue *, struct rpc_task *, void rpc_sleep_on(struct rpc_wait_queue *, struct rpc_task *,
rpc_action action, rpc_action timer); rpc_action action, rpc_action timer);
void rpc_add_timer(struct rpc_task *, rpc_action); void rpc_add_timer(struct rpc_task *, rpc_action);
...@@ -194,16 +230,14 @@ void rpc_show_tasks(void); ...@@ -194,16 +230,14 @@ void rpc_show_tasks(void);
int rpc_init_mempool(void); int rpc_init_mempool(void);
void rpc_destroy_mempool(void); void rpc_destroy_mempool(void);
static __inline__ void static inline void rpc_exit(struct rpc_task *task, int status)
rpc_exit(struct rpc_task *task, int status)
{ {
task->tk_status = status; task->tk_status = status;
task->tk_action = NULL; task->tk_action = NULL;
} }
#ifdef RPC_DEBUG #ifdef RPC_DEBUG
static __inline__ char * static inline const char * rpc_qname(struct rpc_wait_queue *q)
rpc_qname(struct rpc_wait_queue *q)
{ {
return ((q && q->name) ? q->name : "unknown"); return ((q && q->name) ? q->name : "unknown");
} }
......
...@@ -55,7 +55,8 @@ struct xdr_buf { ...@@ -55,7 +55,8 @@ struct xdr_buf {
unsigned int page_base, /* Start of page data */ unsigned int page_base, /* Start of page data */
page_len; /* Length of page data */ page_len; /* Length of page data */
unsigned int len; /* Total length of data */ unsigned int buflen, /* Total length of storage buffer */
len; /* Length of XDR encoded message */
}; };
...@@ -87,7 +88,8 @@ struct xdr_buf { ...@@ -87,7 +88,8 @@ struct xdr_buf {
/* /*
* Miscellaneous XDR helper functions * Miscellaneous XDR helper functions
*/ */
u32 * xdr_encode_array(u32 *p, const void *s, unsigned int len); u32 * xdr_encode_opaque_fixed(u32 *p, const void *ptr, unsigned int len);
u32 * xdr_encode_opaque(u32 *p, const void *ptr, unsigned int len);
u32 * xdr_encode_string(u32 *p, const char *s); u32 * xdr_encode_string(u32 *p, const char *s);
u32 * xdr_decode_string(u32 *p, char **sp, int *lenp, int maxlen); u32 * xdr_decode_string(u32 *p, char **sp, int *lenp, int maxlen);
u32 * xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen); u32 * xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen);
...@@ -100,6 +102,11 @@ void xdr_encode_pages(struct xdr_buf *, struct page **, unsigned int, ...@@ -100,6 +102,11 @@ void xdr_encode_pages(struct xdr_buf *, struct page **, unsigned int,
void xdr_inline_pages(struct xdr_buf *, unsigned int, void xdr_inline_pages(struct xdr_buf *, unsigned int,
struct page **, unsigned int, unsigned int); struct page **, unsigned int, unsigned int);
static inline u32 *xdr_encode_array(u32 *p, const void *s, unsigned int len)
{
return xdr_encode_opaque(p, s, len);
}
/* /*
* Decode 64bit quantities (NFSv3 support) * Decode 64bit quantities (NFSv3 support)
*/ */
...@@ -178,86 +185,14 @@ struct xdr_stream { ...@@ -178,86 +185,14 @@ struct xdr_stream {
struct iovec *iov; /* pointer to the current iovec */ struct iovec *iov; /* pointer to the current iovec */
}; };
/* extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
* Initialize an xdr_stream for encoding data. extern uint32_t *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
*
* Note: at the moment the RPC client only passes the length of our
* scratch buffer in the xdr_buf's header iovec. Previously this
* meant we needed to call xdr_adjust_iovec() after encoding the
* data. With the new scheme, the xdr_stream manages the details
* of the buffer length, and takes care of adjusting the iovec
* length for us.
*/
static inline void
xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
{
struct iovec *iov = buf->head;
xdr->buf = buf;
xdr->iov = iov;
xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
buf->len = iov->iov_len = (char *)p - (char *)iov->iov_base;
xdr->p = p;
}
/*
* Check that we have enough buffer space to encode 'nbytes' more
* bytes of data. If so, update the total xdr_buf length, and
* adjust the length of the current iovec.
*/
static inline uint32_t *
xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes)
{
uint32_t *p = xdr->p;
uint32_t *q;
/* align nbytes on the next 32-bit boundary */
nbytes += 3;
nbytes &= ~3;
q = p + (nbytes >> 2);
if (unlikely(q > xdr->end || q < p))
return NULL;
xdr->p = q;
xdr->iov->iov_len += nbytes;
xdr->buf->len += nbytes;
return p;
}
extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
unsigned int base, unsigned int len); unsigned int base, unsigned int len);
extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
extern uint32_t *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len); extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len);
/*
* Initialize an xdr_stream for decoding data.
*/
static inline void
xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p)
{
struct iovec *iov = buf->head;
xdr->buf = buf;
xdr->iov = iov;
xdr->p = p;
xdr->end = (uint32_t *)((char *)iov->iov_base + iov->iov_len);
}
/*
* Check if the input buffer is long enough to enable us to decode
* 'nbytes' more bytes of data starting at the current position.
* If so return the current pointer, then update the current
* position.
*/
static inline uint32_t *
xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes)
{
uint32_t *p = xdr->p;
uint32_t *q = p + XDR_QUADLEN(nbytes);
if (unlikely(q > xdr->end || q < p))
return NULL;
xdr->p = q;
return p;
}
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _SUNRPC_XDR_H_ */ #endif /* _SUNRPC_XDR_H_ */
...@@ -120,8 +120,6 @@ struct rpc_rqst { ...@@ -120,8 +120,6 @@ struct rpc_rqst {
}; };
#define rq_svec rq_snd_buf.head #define rq_svec rq_snd_buf.head
#define rq_slen rq_snd_buf.len #define rq_slen rq_snd_buf.len
#define rq_rvec rq_rcv_buf.head
#define rq_rlen rq_rcv_buf.len
#define XPRT_LAST_FRAG (1 << 0) #define XPRT_LAST_FRAG (1 << 0)
#define XPRT_COPY_RECM (1 << 1) #define XPRT_COPY_RECM (1 << 1)
...@@ -218,12 +216,15 @@ void xprt_connect(struct rpc_task *); ...@@ -218,12 +216,15 @@ void xprt_connect(struct rpc_task *);
int xprt_clear_backlog(struct rpc_xprt *); int xprt_clear_backlog(struct rpc_xprt *);
void xprt_sock_setbufsize(struct rpc_xprt *); void xprt_sock_setbufsize(struct rpc_xprt *);
#define XPRT_CONNECT 0 #define XPRT_LOCKED 0
#define XPRT_LOCKED 1 #define XPRT_CONNECT 1
#define XPRT_CONNECTING 2
#define xprt_connected(xp) (test_bit(XPRT_CONNECT, &(xp)->sockstate)) #define xprt_connected(xp) (test_bit(XPRT_CONNECT, &(xp)->sockstate))
#define xprt_set_connected(xp) (set_bit(XPRT_CONNECT, &(xp)->sockstate)) #define xprt_set_connected(xp) (set_bit(XPRT_CONNECT, &(xp)->sockstate))
#define xprt_test_and_set_connected(xp) (test_and_set_bit(XPRT_CONNECT, &(xp)->sockstate)) #define xprt_test_and_set_connected(xp) (test_and_set_bit(XPRT_CONNECT, &(xp)->sockstate))
#define xprt_test_and_clear_connected(xp) \
(test_and_clear_bit(XPRT_CONNECT, &(xp)->sockstate))
#define xprt_clear_connected(xp) (clear_bit(XPRT_CONNECT, &(xp)->sockstate)) #define xprt_clear_connected(xp) (clear_bit(XPRT_CONNECT, &(xp)->sockstate))
#endif /* __KERNEL__*/ #endif /* __KERNEL__*/
......
...@@ -365,7 +365,7 @@ gss_upcall(struct rpc_clnt *clnt, struct rpc_task *task, struct rpc_cred *cred) ...@@ -365,7 +365,7 @@ gss_upcall(struct rpc_clnt *clnt, struct rpc_task *task, struct rpc_cred *cred)
gss_msg = gss_new; gss_msg = gss_new;
memset(gss_new, 0, sizeof(*gss_new)); memset(gss_new, 0, sizeof(*gss_new));
INIT_LIST_HEAD(&gss_new->list); INIT_LIST_HEAD(&gss_new->list);
INIT_RPC_WAITQ(&gss_new->waitq, "RPCSEC_GSS upcall waitq"); rpc_init_wait_queue(&gss_new->waitq, "RPCSEC_GSS upcall waitq");
atomic_set(&gss_new->count, 2); atomic_set(&gss_new->count, 2);
msg = &gss_new->msg; msg = &gss_new->msg;
msg->data = &gss_new->uid; msg->data = &gss_new->uid;
...@@ -721,8 +721,7 @@ gss_marshal(struct rpc_task *task, u32 *p, int ruid) ...@@ -721,8 +721,7 @@ gss_marshal(struct rpc_task *task, u32 *p, int ruid)
printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat); printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat);
goto out_put_ctx; goto out_put_ctx;
} }
*p++ = htonl(mic.len); p = xdr_encode_opaque(p, NULL, mic.len);
p += XDR_QUADLEN(mic.len);
gss_put_ctx(ctx); gss_put_ctx(ctx);
return p; return p;
out_put_ctx: out_put_ctx:
...@@ -857,9 +856,7 @@ gss_wrap_req(struct rpc_task *task, ...@@ -857,9 +856,7 @@ gss_wrap_req(struct rpc_task *task,
status = -EIO; /* XXX? */ status = -EIO; /* XXX? */
if (maj_stat) if (maj_stat)
goto out; goto out;
q = p; q = xdr_encode_opaque(p, NULL, mic.len);
*q++ = htonl(mic.len);
q += XDR_QUADLEN(mic.len);
offset = (u8 *)q - (u8 *)p; offset = (u8 *)q - (u8 *)p;
iov->iov_len += offset; iov->iov_len += offset;
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <asm/scatterlist.h> #include <asm/scatterlist.h>
#include <linux/crypto.h> #include <linux/crypto.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/sunrpc/gss_krb5.h> #include <linux/sunrpc/gss_krb5.h>
#ifdef RPC_DEBUG #ifdef RPC_DEBUG
...@@ -171,22 +172,24 @@ krb5_make_checksum(s32 cksumtype, char *header, struct xdr_buf *body, ...@@ -171,22 +172,24 @@ krb5_make_checksum(s32 cksumtype, char *header, struct xdr_buf *body,
} }
len = body->page_len; len = body->page_len;
offset = body->page_base; if (len != 0) {
i = 0; offset = body->page_base & (PAGE_CACHE_SIZE - 1);
while (len) { i = body->page_base >> PAGE_CACHE_SHIFT;
thislen = PAGE_CACHE_SIZE - offset;
do {
if (thislen > len)
thislen = len;
sg->page = body->pages[i]; sg->page = body->pages[i];
sg->offset = offset; sg->offset = offset;
offset = 0;
if (PAGE_SIZE > len)
thislen = len;
else
thislen = PAGE_SIZE;
sg->length = thislen; sg->length = thislen;
kmap(sg->page); /* XXX kmap_atomic? */ kmap(sg->page); /* XXX kmap_atomic? */
crypto_digest_update(tfm, sg, 1); crypto_digest_update(tfm, sg, 1);
kunmap(sg->page); kunmap(sg->page);
len -= thislen; len -= thislen;
i++; i++;
offset = 0;
thislen = PAGE_CACHE_SIZE;
} while(len != 0);
} }
if (body->tail[0].iov_len) { if (body->tail[0].iov_len) {
buf_to_sg(sg, body->tail[0].iov_base, body->tail[0].iov_len); buf_to_sg(sg, body->tail[0].iov_base, body->tail[0].iov_len);
......
...@@ -144,7 +144,7 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname, ...@@ -144,7 +144,7 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname,
clnt->cl_vers = version->number; clnt->cl_vers = version->number;
clnt->cl_prot = xprt->prot; clnt->cl_prot = xprt->prot;
clnt->cl_stats = program->stats; clnt->cl_stats = program->stats;
INIT_RPC_WAITQ(&clnt->cl_pmap_default.pm_bindwait, "bindwait"); rpc_init_wait_queue(&clnt->cl_pmap_default.pm_bindwait, "bindwait");
if (!clnt->cl_port) if (!clnt->cl_port)
clnt->cl_autobind = 1; clnt->cl_autobind = 1;
...@@ -605,11 +605,13 @@ call_encode(struct rpc_task *task) ...@@ -605,11 +605,13 @@ call_encode(struct rpc_task *task)
sndbuf->tail[0].iov_len = 0; sndbuf->tail[0].iov_len = 0;
sndbuf->page_len = 0; sndbuf->page_len = 0;
sndbuf->len = 0; sndbuf->len = 0;
sndbuf->buflen = bufsiz;
rcvbuf->head[0].iov_base = (void *)((char *)task->tk_buffer + bufsiz); rcvbuf->head[0].iov_base = (void *)((char *)task->tk_buffer + bufsiz);
rcvbuf->head[0].iov_len = bufsiz; rcvbuf->head[0].iov_len = bufsiz;
rcvbuf->tail[0].iov_len = 0; rcvbuf->tail[0].iov_len = 0;
rcvbuf->page_len = 0; rcvbuf->page_len = 0;
rcvbuf->len = bufsiz; rcvbuf->len = 0;
rcvbuf->buflen = bufsiz;
/* Encode header and provided arguments */ /* Encode header and provided arguments */
encode = task->tk_msg.rpc_proc->p_encode; encode = task->tk_msg.rpc_proc->p_encode;
...@@ -849,6 +851,8 @@ call_decode(struct rpc_task *task) ...@@ -849,6 +851,8 @@ call_decode(struct rpc_task *task)
return; return;
} }
req->rq_rcv_buf.len = req->rq_private_buf.len;
/* Check that the softirq receive buffer is valid */ /* Check that the softirq receive buffer is valid */
WARN_ON(memcmp(&req->rq_rcv_buf, &req->rq_private_buf, WARN_ON(memcmp(&req->rq_rcv_buf, &req->rq_private_buf,
sizeof(req->rq_rcv_buf)) != 0); sizeof(req->rq_rcv_buf)) != 0);
...@@ -884,7 +888,7 @@ call_decode(struct rpc_task *task) ...@@ -884,7 +888,7 @@ call_decode(struct rpc_task *task)
task->tk_status); task->tk_status);
return; return;
out_retry: out_retry:
req->rq_received = 0; req->rq_received = req->rq_private_buf.len = 0;
task->tk_status = 0; task->tk_status = 0;
} }
...@@ -956,7 +960,7 @@ call_header(struct rpc_task *task) ...@@ -956,7 +960,7 @@ call_header(struct rpc_task *task)
static u32 * static u32 *
call_verify(struct rpc_task *task) call_verify(struct rpc_task *task)
{ {
u32 *p = task->tk_rqstp->rq_rvec[0].iov_base, n; u32 *p = task->tk_rqstp->rq_rcv_buf.head[0].iov_base, n;
p += 1; /* skip XID */ p += 1; /* skip XID */
......
This diff is collapsed.
...@@ -120,7 +120,6 @@ EXPORT_SYMBOL(svcauth_unix_purge); ...@@ -120,7 +120,6 @@ EXPORT_SYMBOL(svcauth_unix_purge);
EXPORT_SYMBOL(unix_domain_find); EXPORT_SYMBOL(unix_domain_find);
/* Generic XDR */ /* Generic XDR */
EXPORT_SYMBOL(xdr_encode_array);
EXPORT_SYMBOL(xdr_encode_string); EXPORT_SYMBOL(xdr_encode_string);
EXPORT_SYMBOL(xdr_decode_string); EXPORT_SYMBOL(xdr_decode_string);
EXPORT_SYMBOL(xdr_decode_string_inplace); EXPORT_SYMBOL(xdr_decode_string_inplace);
...@@ -129,8 +128,6 @@ EXPORT_SYMBOL(xdr_encode_netobj); ...@@ -129,8 +128,6 @@ EXPORT_SYMBOL(xdr_encode_netobj);
EXPORT_SYMBOL(xdr_encode_pages); EXPORT_SYMBOL(xdr_encode_pages);
EXPORT_SYMBOL(xdr_inline_pages); EXPORT_SYMBOL(xdr_inline_pages);
EXPORT_SYMBOL(xdr_shift_buf); EXPORT_SYMBOL(xdr_shift_buf);
EXPORT_SYMBOL(xdr_write_pages);
EXPORT_SYMBOL(xdr_read_pages);
EXPORT_SYMBOL(xdr_buf_from_iov); EXPORT_SYMBOL(xdr_buf_from_iov);
EXPORT_SYMBOL(xdr_buf_subsegment); EXPORT_SYMBOL(xdr_buf_subsegment);
EXPORT_SYMBOL(xdr_buf_read_netobj); EXPORT_SYMBOL(xdr_buf_read_netobj);
......
This diff is collapsed.
This diff is collapsed.
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