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

Merge NFS conflicts

parents f2d816ef 78a21ca0
......@@ -228,7 +228,6 @@ reclaimer(void *ptr)
}
host->h_reclaiming = 0;
wake_up(&host->h_gracewait);
/* Now, wake up all processes that sleep on a blocked lock */
for (block = nlm_blocked; block; block = block->b_next) {
......
......@@ -217,6 +217,21 @@ nlmclnt_alloc_call(void)
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
*/
......@@ -241,10 +256,8 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc)
msg.rpc_cred = nfs_file_cred(filp);
do {
if (host->h_reclaiming && !argp->reclaim) {
interruptible_sleep_on(&host->h_gracewait);
continue;
}
if (host->h_reclaiming && !argp->reclaim)
goto in_grace_period;
/* If we have no RPC client yet, create one. */
if ((clnt = nlm_bind_host(host)) == NULL)
......@@ -279,22 +292,23 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc)
return -ENOLCK;
}
} 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);
return 0; /* Okay, call complete */
}
/* Back off a little and try again */
interruptible_sleep_on_timeout(&host->h_gracewait, 15*HZ);
/* When the lock requested by F_SETLKW isn't available,
we will wait until the request can be satisfied. If
a signal is received during wait, we should return
-EINTR. */
if (signalled ()) {
status = -EINTR;
break;
}
} while (1);
in_grace_period:
/*
* The server has rebooted and appears to be in the grace
* period during which locks are only allowed to be
* reclaimed.
* We can only back off and try again later.
*/
status = nlm_wait_on_grace(&host->h_gracewait);
} while (status == 0);
return status;
}
......
......@@ -128,6 +128,7 @@ nfs_direct_read_seg(struct inode *inode, struct file *file,
.inode = inode,
.args = {
.fh = NFS_FH(inode),
.lockowner = current->files,
},
.res = {
.fattr = &rdata.fattr,
......@@ -258,6 +259,7 @@ nfs_direct_write_seg(struct inode *inode, struct file *file,
.inode = inode,
.args = {
.fh = NFS_FH(inode),
.lockowner = current->files,
},
.res = {
.fattr = &wdata.fattr,
......@@ -335,8 +337,7 @@ nfs_direct_write_seg(struct inode *inode, struct file *file,
VERF_SIZE) != 0)
goto sync_retry;
}
nfs_end_data_update(inode);
NFS_FLAGS(inode) |= NFS_INO_INVALID_DATA;
nfs_end_data_update_defer(inode);
return tot_bytes;
......@@ -395,10 +396,6 @@ nfs_direct_write(struct inode *inode, struct file *file,
if (result < size)
break;
}
/* Zap the page cache if we managed to write */
if (tot_bytes > 0)
invalidate_remote_inode(inode);
return tot_bytes;
}
......
......@@ -1012,6 +1012,8 @@ void nfs_begin_data_update(struct inode *inode)
* nfs_end_data_update
* @inode - pointer to inode
* 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)
{
......@@ -1026,6 +1028,27 @@ void nfs_end_data_update(struct inode *inode)
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
* @inode - pointer to inode
......
......@@ -231,7 +231,7 @@ nfs_xdr_readargs(struct rpc_rqst *req, u32 *p, struct nfs_readargs *args)
static int
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;
if ((status = ntohl(*p++)))
......@@ -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);
}
recvd = req->rq_received - hdrlen;
recvd = req->rq_rcv_buf.len - hdrlen;
if (count > recvd) {
printk(KERN_WARNING "NFS: server cheating in read reply: "
"count %d > recvd %d\n", count, recvd);
......@@ -396,7 +396,7 @@ nfs_xdr_readdirres(struct rpc_rqst *req, u32 *p, void *dummy)
}
pglen = rcvbuf->page_len;
recvd = req->rq_received - hdrlen;
recvd = rcvbuf->len - hdrlen;
if (pglen > recvd)
pglen = recvd;
page = rcvbuf->pages;
......
......@@ -729,11 +729,10 @@ nfs3_read_done(struct rpc_task *task)
}
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 inode *inode = data->inode;
struct nfs_page *req;
int flags;
struct rpc_message msg = {
.rpc_proc = &nfs3_procedures[NFS3PROC_READ],
......@@ -741,27 +740,13 @@ nfs3_proc_read_setup(struct nfs_read_data *data, unsigned int count)
.rpc_resp = &data->res,
.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 */
flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
/* Finalize the task. */
rpc_init_task(task, NFS_CLIENT(inode), nfs3_read_done, flags);
task->tk_calldata = data;
/* Release requests */
task->tk_release = nfs_readdata_release;
rpc_call_setup(&data->task, &msg, 0);
rpc_call_setup(task, &msg, 0);
}
static void
......@@ -778,11 +763,10 @@ nfs3_write_done(struct rpc_task *task)
}
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 inode *inode = data->inode;
struct nfs_page *req;
int stable;
int flags;
struct rpc_message msg = {
......@@ -799,28 +783,14 @@ nfs3_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how)
stable = NFS_DATA_SYNC;
} else
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.pages = data->pagevec;
data->res.fattr = &data->fattr;
data->res.count = count;
data->res.verf = &data->verf;
/* Set the initial flags for the task. */
flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
/* Finalize the task. */
rpc_init_task(task, NFS_CLIENT(inode), nfs3_write_done, flags);
task->tk_calldata = data;
/* Release requests */
task->tk_release = nfs_writedata_release;
rpc_call_setup(&data->task, &msg, 0);
rpc_call_setup(task, &msg, 0);
}
static void
......@@ -837,7 +807,7 @@ nfs3_commit_done(struct rpc_task *task)
}
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 inode *inode = data->inode;
......@@ -849,23 +819,12 @@ nfs3_proc_commit_setup(struct nfs_write_data *data, u64 start, u32 len, int how)
.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. */
flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
/* Finalize the task. */
rpc_init_task(task, NFS_CLIENT(inode), nfs3_commit_done, flags);
task->tk_calldata = data;
/* Release requests */
task->tk_release = nfs_commit_release;
rpc_call_setup(&data->task, &msg, 0);
rpc_call_setup(task, &msg, 0);
}
/*
......
......@@ -515,7 +515,7 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, u32 *p, struct nfs3_readdirres *res)
}
pglen = rcvbuf->page_len;
recvd = req->rq_received - hdrlen;
recvd = rcvbuf->len - hdrlen;
if (pglen > recvd)
pglen = recvd;
page = rcvbuf->pages;
......@@ -758,7 +758,7 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, u32 *p, struct nfs_fattr *fattr)
static int
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;
status = ntohl(*p++);
......@@ -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);
}
recvd = req->rq_received - hdrlen;
recvd = req->rq_rcv_buf.len - hdrlen;
if (count > recvd) {
printk(KERN_WARNING "NFS: server cheating in read reply: "
"count %d > recvd %d\n", count, recvd);
......
This diff is collapsed.
......@@ -105,7 +105,7 @@ nfs4_alloc_client(struct in_addr *addr)
INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp);
INIT_LIST_HEAD(&clp->cl_superblocks);
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;
}
return clp;
......
This diff is collapsed.
......@@ -66,7 +66,8 @@
* is NOT for the length of the hostname.
* Hua Qin : Support for mounting root file system via
* NFS over TCP.
*/
* Fabian Frederick: Option parser rebuilt (using parser lib)
*/
#include <linux/config.h>
#include <linux/types.h>
......@@ -85,6 +86,7 @@
#include <linux/inet.h>
#include <linux/root_dev.h>
#include <net/ipconfig.h>
#include <linux/parser.h>
/* Define this to allow debugging output */
#undef NFSROOT_DEBUG
......@@ -114,92 +116,158 @@ static int mount_port __initdata = 0; /* Mount daemon port number */
***************************************************************************/
/*
* The following integer options are recognized
*/
static struct nfs_int_opts {
char *name;
int *val;
} 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 }
enum {
Opt_port, Opt_rsize, Opt_wsize, Opt_timeo, Opt_retrans, Opt_acregmin,
Opt_acregmax, Opt_acdirmin, Opt_acdirmax, Opt_soft, Opt_hard, Opt_intr,
Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac,
Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp,
Opt_broken_suid, Opt_err,
};
/*
* 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 }
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}
};
/*
* 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, ','))) {
*options++ = 0;
while ((cp = strsep(&options, ",")) != NULL) {
if (!*cp)
continue;
if ((val = strchr(cp, '='))) {
struct nfs_int_opts *opts = root_int_opts;
*val++ = '\0';
while (opts->name && strcmp(opts->name, cp))
opts++;
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;
}
}
char *p;
substring_t args[MAX_OPT_ARGS];
int option;
if (!name)
return 1;
if (name[0] && strcmp(name, "default")){
strlcpy(buf, name, NFS_MAXPATHLEN);
return 1;
}
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"))
strlcpy(buf, name, NFS_MAXPATHLEN);
return 1;
}
/*
* Prepare the NFS data structure and parse all options.
*/
......
......@@ -32,7 +32,7 @@ static inline struct nfs_page *
nfs_page_alloc(void)
{
struct nfs_page *p;
p = kmem_cache_alloc(nfs_page_cachep, SLAB_NOFS);
p = kmem_cache_alloc(nfs_page_cachep, SLAB_KERNEL);
if (p) {
memset(p, 0, sizeof(*p));
INIT_LIST_HEAD(&p->wb_list);
......@@ -88,6 +88,7 @@ nfs_create_request(struct file *file, struct inode *inode,
* long write-back delay. This will be adjusted in
* update_nfs_request below if the region is not locked. */
req->wb_page = page;
atomic_set(&req->wb_complete, 0);
req->wb_index = page->index;
page_cache_get(page);
req->wb_offset = offset;
......
......@@ -559,11 +559,10 @@ nfs_read_done(struct rpc_task *task)
}
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 inode *inode = data->inode;
struct nfs_page *req;
int flags;
struct rpc_message msg = {
.rpc_proc = &nfs_procedures[NFSPROC_READ],
......@@ -571,27 +570,13 @@ nfs_proc_read_setup(struct nfs_read_data *data, unsigned int count)
.rpc_resp = &data->res,
.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 */
flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
/* Finalize the task. */
rpc_init_task(task, NFS_CLIENT(inode), nfs_read_done, flags);
task->tk_calldata = data;
/* Release requests */
task->tk_release = nfs_readdata_release;
rpc_call_setup(&data->task, &msg, 0);
rpc_call_setup(task, &msg, 0);
}
static void
......@@ -605,11 +590,10 @@ nfs_write_done(struct rpc_task *task)
}
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 inode *inode = data->inode;
struct nfs_page *req;
int flags;
struct rpc_message msg = {
.rpc_proc = &nfs_procedures[NFSPROC_WRITE],
......@@ -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 */
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.pages = data->pagevec;
data->res.fattr = &data->fattr;
data->res.count = count;
data->res.verf = &data->verf;
/* Set the initial flags for the task. */
flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
/* Finalize the task. */
rpc_init_task(task, NFS_CLIENT(inode), nfs_write_done, flags);
task->tk_calldata = data;
/* Release requests */
task->tk_release = nfs_writedata_release;
rpc_call_setup(&data->task, &msg, 0);
rpc_call_setup(task, &msg, 0);
}
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();
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -47,6 +47,11 @@
#define NFS4_ACE_SYSTEM_AUDIT_ACE_TYPE 2
#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[16]; } nfs4_stateid;
......@@ -217,64 +222,64 @@ enum lock_type4 {
/* Mandatory Attributes */
#define FATTR4_WORD0_SUPPORTED_ATTRS (1)
#define FATTR4_WORD0_TYPE (1 << 1)
#define FATTR4_WORD0_FH_EXPIRE_TYPE (1 << 2)
#define FATTR4_WORD0_CHANGE (1 << 3)
#define FATTR4_WORD0_SIZE (1 << 4)
#define FATTR4_WORD0_LINK_SUPPORT (1 << 5)
#define FATTR4_WORD0_SYMLINK_SUPPORT (1 << 6)
#define FATTR4_WORD0_NAMED_ATTR (1 << 7)
#define FATTR4_WORD0_FSID (1 << 8)
#define FATTR4_WORD0_UNIQUE_HANDLES (1 << 9)
#define FATTR4_WORD0_LEASE_TIME (1 << 10)
#define FATTR4_WORD0_RDATTR_ERROR (1 << 11)
#define FATTR4_WORD0_SUPPORTED_ATTRS (1UL << 0)
#define FATTR4_WORD0_TYPE (1UL << 1)
#define FATTR4_WORD0_FH_EXPIRE_TYPE (1UL << 2)
#define FATTR4_WORD0_CHANGE (1UL << 3)
#define FATTR4_WORD0_SIZE (1UL << 4)
#define FATTR4_WORD0_LINK_SUPPORT (1UL << 5)
#define FATTR4_WORD0_SYMLINK_SUPPORT (1UL << 6)
#define FATTR4_WORD0_NAMED_ATTR (1UL << 7)
#define FATTR4_WORD0_FSID (1UL << 8)
#define FATTR4_WORD0_UNIQUE_HANDLES (1UL << 9)
#define FATTR4_WORD0_LEASE_TIME (1UL << 10)
#define FATTR4_WORD0_RDATTR_ERROR (1UL << 11)
/* Recommended Attributes */
#define FATTR4_WORD0_ACL (1 << 12)
#define FATTR4_WORD0_ACLSUPPORT (1 << 13)
#define FATTR4_WORD0_ARCHIVE (1 << 14)
#define FATTR4_WORD0_CANSETTIME (1 << 15)
#define FATTR4_WORD0_CASE_INSENSITIVE (1 << 16)
#define FATTR4_WORD0_CASE_PRESERVING (1 << 17)
#define FATTR4_WORD0_CHOWN_RESTRICTED (1 << 18)
#define FATTR4_WORD0_FILEHANDLE (1 << 19)
#define FATTR4_WORD0_FILEID (1 << 20)
#define FATTR4_WORD0_FILES_AVAIL (1 << 21)
#define FATTR4_WORD0_FILES_FREE (1 << 22)
#define FATTR4_WORD0_FILES_TOTAL (1 << 23)
#define FATTR4_WORD0_FS_LOCATIONS (1 << 24)
#define FATTR4_WORD0_HIDDEN (1 << 25)
#define FATTR4_WORD0_HOMOGENEOUS (1 << 26)
#define FATTR4_WORD0_MAXFILESIZE (1 << 27)
#define FATTR4_WORD0_MAXLINK (1 << 28)
#define FATTR4_WORD0_MAXNAME (1 << 29)
#define FATTR4_WORD0_MAXREAD (1 << 30)
#define FATTR4_WORD0_MAXWRITE (1 << 31)
#define FATTR4_WORD1_MIMETYPE (1)
#define FATTR4_WORD1_MODE (1 << 1)
#define FATTR4_WORD1_NO_TRUNC (1 << 2)
#define FATTR4_WORD1_NUMLINKS (1 << 3)
#define FATTR4_WORD1_OWNER (1 << 4)
#define FATTR4_WORD1_OWNER_GROUP (1 << 5)
#define FATTR4_WORD1_QUOTA_HARD (1 << 6)
#define FATTR4_WORD1_QUOTA_SOFT (1 << 7)
#define FATTR4_WORD1_QUOTA_USED (1 << 8)
#define FATTR4_WORD1_RAWDEV (1 << 9)
#define FATTR4_WORD1_SPACE_AVAIL (1 << 10)
#define FATTR4_WORD1_SPACE_FREE (1 << 11)
#define FATTR4_WORD1_SPACE_TOTAL (1 << 12)
#define FATTR4_WORD1_SPACE_USED (1 << 13)
#define FATTR4_WORD1_SYSTEM (1 << 14)
#define FATTR4_WORD1_TIME_ACCESS (1 << 15)
#define FATTR4_WORD1_TIME_ACCESS_SET (1 << 16)
#define FATTR4_WORD1_TIME_BACKUP (1 << 17)
#define FATTR4_WORD1_TIME_CREATE (1 << 18)
#define FATTR4_WORD1_TIME_DELTA (1 << 19)
#define FATTR4_WORD1_TIME_METADATA (1 << 20)
#define FATTR4_WORD1_TIME_MODIFY (1 << 21)
#define FATTR4_WORD1_TIME_MODIFY_SET (1 << 22)
#define FATTR4_WORD1_MOUNTED_ON_FILEID (1 << 23)
#define FATTR4_WORD0_ACL (1UL << 12)
#define FATTR4_WORD0_ACLSUPPORT (1UL << 13)
#define FATTR4_WORD0_ARCHIVE (1UL << 14)
#define FATTR4_WORD0_CANSETTIME (1UL << 15)
#define FATTR4_WORD0_CASE_INSENSITIVE (1UL << 16)
#define FATTR4_WORD0_CASE_PRESERVING (1UL << 17)
#define FATTR4_WORD0_CHOWN_RESTRICTED (1UL << 18)
#define FATTR4_WORD0_FILEHANDLE (1UL << 19)
#define FATTR4_WORD0_FILEID (1UL << 20)
#define FATTR4_WORD0_FILES_AVAIL (1UL << 21)
#define FATTR4_WORD0_FILES_FREE (1UL << 22)
#define FATTR4_WORD0_FILES_TOTAL (1UL << 23)
#define FATTR4_WORD0_FS_LOCATIONS (1UL << 24)
#define FATTR4_WORD0_HIDDEN (1UL << 25)
#define FATTR4_WORD0_HOMOGENEOUS (1UL << 26)
#define FATTR4_WORD0_MAXFILESIZE (1UL << 27)
#define FATTR4_WORD0_MAXLINK (1UL << 28)
#define FATTR4_WORD0_MAXNAME (1UL << 29)
#define FATTR4_WORD0_MAXREAD (1UL << 30)
#define FATTR4_WORD0_MAXWRITE (1UL << 31)
#define FATTR4_WORD1_MIMETYPE (1UL << 0)
#define FATTR4_WORD1_MODE (1UL << 1)
#define FATTR4_WORD1_NO_TRUNC (1UL << 2)
#define FATTR4_WORD1_NUMLINKS (1UL << 3)
#define FATTR4_WORD1_OWNER (1UL << 4)
#define FATTR4_WORD1_OWNER_GROUP (1UL << 5)
#define FATTR4_WORD1_QUOTA_HARD (1UL << 6)
#define FATTR4_WORD1_QUOTA_SOFT (1UL << 7)
#define FATTR4_WORD1_QUOTA_USED (1UL << 8)
#define FATTR4_WORD1_RAWDEV (1UL << 9)
#define FATTR4_WORD1_SPACE_AVAIL (1UL << 10)
#define FATTR4_WORD1_SPACE_FREE (1UL << 11)
#define FATTR4_WORD1_SPACE_TOTAL (1UL << 12)
#define FATTR4_WORD1_SPACE_USED (1UL << 13)
#define FATTR4_WORD1_SYSTEM (1UL << 14)
#define FATTR4_WORD1_TIME_ACCESS (1UL << 15)
#define FATTR4_WORD1_TIME_ACCESS_SET (1UL << 16)
#define FATTR4_WORD1_TIME_BACKUP (1UL << 17)
#define FATTR4_WORD1_TIME_CREATE (1UL << 18)
#define FATTR4_WORD1_TIME_DELTA (1UL << 19)
#define FATTR4_WORD1_TIME_METADATA (1UL << 20)
#define FATTR4_WORD1_TIME_MODIFY (1UL << 21)
#define FATTR4_WORD1_TIME_MODIFY_SET (1UL << 22)
#define FATTR4_WORD1_MOUNTED_ON_FILEID (1UL << 23)
#define NFSPROC4_NULL 0
#define NFSPROC4_COMPOUND 1
......@@ -287,7 +292,6 @@ enum lock_type4 {
enum {
NFSPROC4_CLNT_NULL = 0, /* Unused */
NFSPROC4_CLNT_COMPOUND, /* Soon to be unused */
NFSPROC4_CLNT_READ,
NFSPROC4_CLNT_WRITE,
NFSPROC4_CLNT_COMMIT,
......@@ -304,6 +308,19 @@ enum {
NFSPROC4_CLNT_LOCK,
NFSPROC4_CLNT_LOCKT,
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
......
......@@ -69,6 +69,8 @@
#define FLUSH_SYNC 1 /* file being synced, or contention */
#define FLUSH_WAIT 2 /* wait for completion */
#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__
......@@ -275,6 +277,7 @@ extern void nfs_begin_attr_update(struct inode *);
extern void nfs_end_attr_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_defer(struct inode *);
/* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
extern u32 root_nfs_parse_addr(char *name); /*__init*/
......@@ -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_updatepage(struct file *, struct page *, unsigned int, unsigned int);
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)
extern void nfs_commit_release(struct rpc_task *task);
extern void nfs_commit_done(struct rpc_task *);
#endif
......@@ -376,14 +377,18 @@ nfs_wb_all(struct inode *inode)
/*
* Write back all requests on one page - we do this before reading it.
*/
static inline int
nfs_wb_page(struct inode *inode, struct page* page)
static inline int nfs_wb_page_priority(struct inode *inode, struct page* page, int how)
{
int error = nfs_sync_inode(inode, page->index, 1,
FLUSH_WAIT | FLUSH_STABLE);
how | FLUSH_WAIT | FLUSH_STABLE);
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 */
#ifndef IS_SWAPFILE
# define IS_SWAPFILE(inode) (0)
......@@ -397,7 +402,6 @@ extern int nfs_readpages(struct file *, struct address_space *,
struct list_head *, unsigned);
extern int nfs_pagein_list(struct list_head *, int);
extern void nfs_readpage_result(struct rpc_task *);
extern void nfs_readdata_release(struct rpc_task *);
/*
* linux/fs/mount_clnt.c
......
......@@ -38,10 +38,19 @@ struct nfs_server {
struct list_head nfs4_siblings; /* List of other nfs_server structs
* 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
};
/* 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
......@@ -17,10 +17,14 @@
#include <linux/sunrpc/auth.h>
#include <linux/nfs_xdr.h>
#include <asm/atomic.h>
/*
* Valid flags for a dirty buffer
*/
#define PG_BUSY 0
#define PG_NEED_COMMIT 1
#define PG_NEED_RESCHED 2
struct nfs_page {
struct list_head wb_list, /* Defines state of page: */
......@@ -31,6 +35,7 @@ struct nfs_page {
struct rpc_cred *wb_cred;
struct nfs4_state *wb_state;
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 */
unsigned long wb_index; /* Offset >> PAGE_CACHE_SHIFT */
unsigned int wb_offset, /* Offset & ~PAGE_CACHE_MASK */
......@@ -42,6 +47,8 @@ struct nfs_page {
};
#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 *,
struct page *,
......@@ -93,8 +100,7 @@ nfs_unlock_request(struct nfs_page *req)
smp_mb__before_clear_bit();
clear_bit(PG_BUSY, &req->wb_flags);
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);
}
......@@ -115,6 +121,38 @@ nfs_list_remove_request(struct nfs_page *req)
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 *
nfs_list_entry(struct list_head *head)
{
......
This diff is collapsed.
......@@ -49,6 +49,8 @@ struct rpc_task {
tk_cred_retry,
tk_suid_retry;
unsigned long tk_cookie; /* Cookie for batching tasks */
/*
* timeout_fn to be executed by timer bottom half
* callback to be executed after waking up
......@@ -72,7 +74,9 @@ struct rpc_task {
unsigned long tk_timeout; /* timeout for rpc_sleep() */
unsigned short tk_flags; /* misc flags */
unsigned char tk_active : 1;/* Task has been activated */
unsigned char tk_priority : 2;/* Task priority */
unsigned long tk_runstate; /* Task run status */
struct list_head tk_links; /* links to related tasks */
#ifdef RPC_DEBUG
unsigned short tk_pid; /* debugging aid */
#endif
......@@ -137,29 +141,59 @@ typedef void (*rpc_action)(struct rpc_task *);
smp_mb__after_clear_bit(); \
} 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
*/
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
char * name;
const char * name;
#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
# define RPC_WAITQ_INIT(var,qname) ((struct rpc_wait_queue) {LIST_HEAD_INIT(var)})
# define RPC_WAITQ(var,qname) struct rpc_wait_queue var = RPC_WAITQ_INIT(var.tasks,qname)
# define INIT_RPC_WAITQ(ptr,qname) do { \
INIT_LIST_HEAD(&(ptr)->tasks); \
} while(0)
# define RPC_WAITQ_INIT(var,qname) { \
.tasks = { \
[0] = LIST_HEAD_INIT(var.tasks[0]), \
[1] = LIST_HEAD_INIT(var.tasks[1]), \
[2] = LIST_HEAD_INIT(var.tasks[2]), \
}, \
}
#else
# define RPC_WAITQ_INIT(var,qname) ((struct rpc_wait_queue) {LIST_HEAD_INIT(var.tasks), qname})
# define RPC_WAITQ(var,qname) struct rpc_wait_queue var = RPC_WAITQ_INIT(var,qname)
# define INIT_RPC_WAITQ(ptr,qname) do { \
INIT_LIST_HEAD(&(ptr)->tasks); (ptr)->name = qname; \
} while(0)
# define RPC_WAITQ_INIT(var,qname) { \
.tasks = { \
[0] = LIST_HEAD_INIT(var.tasks[0]), \
[1] = LIST_HEAD_INIT(var.tasks[1]), \
[2] = LIST_HEAD_INIT(var.tasks[2]), \
}, \
.name = qname, \
}
#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
......@@ -175,6 +209,8 @@ void rpc_run_child(struct rpc_task *parent, struct rpc_task *child,
rpc_action action);
int rpc_add_wait_queue(struct rpc_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 *,
rpc_action action, rpc_action timer);
void rpc_add_timer(struct rpc_task *, rpc_action);
......@@ -194,16 +230,14 @@ void rpc_show_tasks(void);
int rpc_init_mempool(void);
void rpc_destroy_mempool(void);
static __inline__ void
rpc_exit(struct rpc_task *task, int status)
static inline void rpc_exit(struct rpc_task *task, int status)
{
task->tk_status = status;
task->tk_action = NULL;
}
#ifdef RPC_DEBUG
static __inline__ char *
rpc_qname(struct rpc_wait_queue *q)
static inline const char * rpc_qname(struct rpc_wait_queue *q)
{
return ((q && q->name) ? q->name : "unknown");
}
......
......@@ -55,7 +55,8 @@ struct xdr_buf {
unsigned int page_base, /* Start 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 {
/*
* 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_decode_string(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,
void xdr_inline_pages(struct xdr_buf *, 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)
*/
......@@ -178,86 +185,14 @@ struct xdr_stream {
struct iovec *iov; /* pointer to the current iovec */
};
/*
* Initialize an xdr_stream for encoding data.
*
* 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_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
extern uint32_t *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
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);
/*
* 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 /* _SUNRPC_XDR_H_ */
......@@ -120,8 +120,6 @@ struct rpc_rqst {
};
#define rq_svec rq_snd_buf.head
#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_COPY_RECM (1 << 1)
......@@ -218,12 +216,15 @@ void xprt_connect(struct rpc_task *);
int xprt_clear_backlog(struct rpc_xprt *);
void xprt_sock_setbufsize(struct rpc_xprt *);
#define XPRT_CONNECT 0
#define XPRT_LOCKED 1
#define XPRT_LOCKED 0
#define XPRT_CONNECT 1
#define XPRT_CONNECTING 2
#define xprt_connected(xp) (test_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_clear_connected(xp) \
(test_and_clear_bit(XPRT_CONNECT, &(xp)->sockstate))
#define xprt_clear_connected(xp) (clear_bit(XPRT_CONNECT, &(xp)->sockstate))
#endif /* __KERNEL__*/
......
......@@ -365,7 +365,7 @@ gss_upcall(struct rpc_clnt *clnt, struct rpc_task *task, struct rpc_cred *cred)
gss_msg = gss_new;
memset(gss_new, 0, sizeof(*gss_new));
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);
msg = &gss_new->msg;
msg->data = &gss_new->uid;
......@@ -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);
goto out_put_ctx;
}
*p++ = htonl(mic.len);
p += XDR_QUADLEN(mic.len);
p = xdr_encode_opaque(p, NULL, mic.len);
gss_put_ctx(ctx);
return p;
out_put_ctx:
......@@ -857,9 +856,7 @@ gss_wrap_req(struct rpc_task *task,
status = -EIO; /* XXX? */
if (maj_stat)
goto out;
q = p;
*q++ = htonl(mic.len);
q += XDR_QUADLEN(mic.len);
q = xdr_encode_opaque(p, NULL, mic.len);
offset = (u8 *)q - (u8 *)p;
iov->iov_len += offset;
......
......@@ -40,6 +40,7 @@
#include <asm/scatterlist.h>
#include <linux/crypto.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/sunrpc/gss_krb5.h>
#ifdef RPC_DEBUG
......@@ -171,22 +172,24 @@ krb5_make_checksum(s32 cksumtype, char *header, struct xdr_buf *body,
}
len = body->page_len;
offset = body->page_base;
i = 0;
while (len) {
sg->page = body->pages[i];
sg->offset = offset;
offset = 0;
if (PAGE_SIZE > len)
thislen = len;
else
thislen = PAGE_SIZE;
sg->length = thislen;
kmap(sg->page); /* XXX kmap_atomic? */
crypto_digest_update(tfm, sg, 1);
kunmap(sg->page);
len -= thislen;
i++;
if (len != 0) {
offset = body->page_base & (PAGE_CACHE_SIZE - 1);
i = body->page_base >> PAGE_CACHE_SHIFT;
thislen = PAGE_CACHE_SIZE - offset;
do {
if (thislen > len)
thislen = len;
sg->page = body->pages[i];
sg->offset = offset;
sg->length = thislen;
kmap(sg->page); /* XXX kmap_atomic? */
crypto_digest_update(tfm, sg, 1);
kunmap(sg->page);
len -= thislen;
i++;
offset = 0;
thislen = PAGE_CACHE_SIZE;
} while(len != 0);
}
if (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,
clnt->cl_vers = version->number;
clnt->cl_prot = xprt->prot;
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)
clnt->cl_autobind = 1;
......@@ -605,11 +605,13 @@ call_encode(struct rpc_task *task)
sndbuf->tail[0].iov_len = 0;
sndbuf->page_len = 0;
sndbuf->len = 0;
sndbuf->buflen = bufsiz;
rcvbuf->head[0].iov_base = (void *)((char *)task->tk_buffer + bufsiz);
rcvbuf->head[0].iov_len = bufsiz;
rcvbuf->tail[0].iov_len = 0;
rcvbuf->page_len = 0;
rcvbuf->len = bufsiz;
rcvbuf->len = 0;
rcvbuf->buflen = bufsiz;
/* Encode header and provided arguments */
encode = task->tk_msg.rpc_proc->p_encode;
......@@ -849,6 +851,8 @@ call_decode(struct rpc_task *task)
return;
}
req->rq_rcv_buf.len = req->rq_private_buf.len;
/* Check that the softirq receive buffer is valid */
WARN_ON(memcmp(&req->rq_rcv_buf, &req->rq_private_buf,
sizeof(req->rq_rcv_buf)) != 0);
......@@ -884,7 +888,7 @@ call_decode(struct rpc_task *task)
task->tk_status);
return;
out_retry:
req->rq_received = 0;
req->rq_received = req->rq_private_buf.len = 0;
task->tk_status = 0;
}
......@@ -956,7 +960,7 @@ call_header(struct rpc_task *task)
static u32 *
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 */
......
This diff is collapsed.
......@@ -120,7 +120,6 @@ EXPORT_SYMBOL(svcauth_unix_purge);
EXPORT_SYMBOL(unix_domain_find);
/* Generic XDR */
EXPORT_SYMBOL(xdr_encode_array);
EXPORT_SYMBOL(xdr_encode_string);
EXPORT_SYMBOL(xdr_decode_string);
EXPORT_SYMBOL(xdr_decode_string_inplace);
......@@ -129,8 +128,6 @@ EXPORT_SYMBOL(xdr_encode_netobj);
EXPORT_SYMBOL(xdr_encode_pages);
EXPORT_SYMBOL(xdr_inline_pages);
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_subsegment);
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