2009-11-23 21:59:24

by Alexandros Batsakis

[permalink] [raw]
Subject: [PATCH 01/10] nfs41: adjust max_rqst_sz, max_resp_sz w.r.t to rsize, wsize

The v4.1 client should take into account the desired rsize, wsize when
negotiating the max size in CREATE_SESSION. Accordingly, it should use
rsize, wsize that are smaller than the session negotiated values.

Signed-off-by: Alexandros Batsakis <[email protected]>
---
fs/nfs/client.c | 14 ++++++++++----
fs/nfs/internal.h | 4 ++++
fs/nfs/nfs4proc.c | 7 +++++--
fs/nfs/nfs4xdr.c | 14 ++++++++++++++
4 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 99ea196..f360739 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -911,8 +911,10 @@ static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *

server->maxfilesize = fsinfo->maxfilesize;

- /* We're airborne Set socket buffersize */
- rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
+ /* We're airborne Set socket buffersize. */
+ if (!nfs4_has_session(server->nfs_client))
+ rpc_setbufsize(server->client, server->wsize + 100,
+ server->rsize + 100);
}

/*
@@ -1260,10 +1262,14 @@ error:
static void nfs4_session_set_rwsize(struct nfs_server *server)
{
#ifdef CONFIG_NFS_V4_1
+ struct nfs4_session *sess;
if (!nfs4_has_session(server->nfs_client))
return;
- server->rsize = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
- server->wsize = server->nfs_client->cl_session->fc_attrs.max_rqst_sz;
+ sess = server->nfs_client->cl_session;
+ server->rsize = sess->fc_attrs.max_resp_sz - nfs41_maxread_overhead;
+ server->wsize = sess->fc_attrs.max_rqst_sz - nfs41_maxwrite_overhead;
+ rpc_setbufsize(server->client, sess->fc_attrs.max_rqst_sz,
+ sess->fc_attrs.max_resp_sz);
#endif /* CONFIG_NFS_V4_1 */
}

diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index e21b1bb..d946936 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -195,6 +195,10 @@ static inline void nfs4_restart_rpc(struct rpc_task *task,
#ifdef CONFIG_NFS_V4
extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus);
#endif
+#ifdef CONFIG_NFS_V4_1
+extern const u32 nfs41_maxread_overhead;
+extern const u32 nfs41_maxwrite_overhead;
+#endif

/* nfs4proc.c */
#ifdef CONFIG_NFS_V4
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index ff37454..ef77d40 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -4827,13 +4827,16 @@ int nfs4_proc_destroy_session(struct nfs4_session *session)
int nfs4_init_session(struct nfs_server *server)
{
struct nfs_client *clp = server->nfs_client;
+ struct nfs4_session *session;
int ret;

if (!nfs4_has_session(clp))
return 0;

- clp->cl_session->fc_attrs.max_rqst_sz = server->wsize;
- clp->cl_session->fc_attrs.max_resp_sz = server->rsize;
+ session = clp->cl_session;
+ session->fc_attrs.max_rqst_sz = server->wsize + nfs41_maxwrite_overhead;
+ session->fc_attrs.max_resp_sz = server->rsize + nfs41_maxread_overhead;
+
ret = nfs4_recover_expired_lease(server);
if (!ret)
ret = nfs4_check_client_ready(clp);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 20b4e30..fc36af4 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -46,6 +46,7 @@
#include <linux/proc_fs.h>
#include <linux/kdev_t.h>
#include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/msg_prot.h>
#include <linux/nfs.h>
#include <linux/nfs4.h>
#include <linux/nfs_fs.h>
@@ -676,6 +677,19 @@ static int nfs4_stat_to_errno(int);
decode_sequence_maxsz + \
decode_putrootfh_maxsz + \
decode_fsinfo_maxsz)
+
+const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
+ compound_encode_hdr_maxsz +
+ encode_sequence_maxsz +
+ encode_putfh_maxsz +
+ encode_getattr_maxsz) *
+ XDR_UNIT);
+
+const u32 nfs41_maxread_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
+ compound_decode_hdr_maxsz +
+ decode_sequence_maxsz +
+ decode_putfh_maxsz) *
+ XDR_UNIT);
#endif /* CONFIG_NFS_V4_1 */

static const umode_t nfs_type2fmt[] = {
--
1.6.2.5



2009-11-23 21:59:25

by Alexandros Batsakis

[permalink] [raw]
Subject: [PATCH 05/10] nfs4: return/expire delegations depending on their type

Signed-off-by: Alexandros Batsakis <[email protected]>
---
fs/nfs/delegation.c | 20 ++++++++++++++++----
1 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 71d5094..a14df44 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -371,29 +371,41 @@ void nfs_super_return_all_delegations(struct super_block *sb)
nfs_client_return_marked_delegations(clp);
}

-static void nfs_client_mark_return_all_delegations(struct nfs_client *clp)
+static
+void nfs_client_mark_return_all_delegation_types(struct nfs_client *clp, fmode_t flags)
{
struct nfs_delegation *delegation;

rcu_read_lock();
list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
- nfs_mark_return_delegation(clp, delegation);
+ if (delegation->type & flags)
+ nfs_mark_return_delegation(clp, delegation);
}
rcu_read_unlock();
}

+static void nfs_client_mark_return_all_delegations(struct nfs_client *clp)
+{
+ nfs_client_mark_return_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
+}
+
static void nfs_delegation_run_state_manager(struct nfs_client *clp)
{
if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state))
nfs4_schedule_state_manager(clp);
}

-void nfs_expire_all_delegations(struct nfs_client *clp)
+void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags)
{
- nfs_client_mark_return_all_delegations(clp);
+ nfs_client_mark_return_all_delegation_types(clp, flags);
nfs_delegation_run_state_manager(clp);
}

+void nfs_expire_all_delegations(struct nfs_client *clp)
+{
+ nfs_expire_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
+}
+
/*
* Return all delegations following an NFS4ERR_CB_PATH_DOWN error.
*/
--
1.6.2.5


2009-11-23 21:59:25

by Alexandros Batsakis

[permalink] [raw]
Subject: [PATCH 04/10] nfs4: minor delegation cleaning

Signed-off-by: Alexandros Batsakis <[email protected]>
---
fs/nfs/delegation.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 4096dcf..71d5094 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -377,8 +377,7 @@ static void nfs_client_mark_return_all_delegations(struct nfs_client *clp)

rcu_read_lock();
list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
- set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
- set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
+ nfs_mark_return_delegation(clp, delegation);
}
rcu_read_unlock();
}
@@ -413,8 +412,7 @@ static void nfs_client_mark_return_unreferenced_delegations(struct nfs_client *c
list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
continue;
- set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
- set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
+ nfs_mark_return_delegation(clp, delegation);
}
rcu_read_unlock();
}
--
1.6.2.5


2009-11-23 21:59:24

by Alexandros Batsakis

[permalink] [raw]
Subject: [PATCH 02/10] nfs41: add support for callback with RPC version number 4

The NFSv4.1 spec-29 (18.36.3) says that the server MUST use an ONC RPC
(program) version number equal to 4 in callbacks sent to the client.
For now we allow both versions 1 and 4.

Signed-off-by: Alexandros Batsakis <[email protected]>
---
fs/nfs/callback.c | 1 +
fs/nfs/callback_xdr.c | 7 +++++++
fs/nfs/internal.h | 1 +
fs/nfs/nfs4_fs.h | 1 +
4 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 293fa05..71d9766 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -397,6 +397,7 @@ static int nfs_callback_authenticate(struct svc_rqst *rqstp)
*/
static struct svc_version *nfs4_callback_version[] = {
[1] = &nfs4_callback_version1,
+ [4] = &nfs4_callback_version4,
};

static struct svc_stat nfs4_callback_stats;
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 76b0aa0..0fda5e6 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -718,3 +718,10 @@ struct svc_version nfs4_callback_version1 = {
.vs_dispatch = NULL,
};

+struct svc_version nfs4_callback_version4 = {
+ .vs_vers = 4,
+ .vs_nproc = ARRAY_SIZE(nfs4_callback_procedures1),
+ .vs_proc = nfs4_callback_procedures1,
+ .vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
+ .vs_dispatch = NULL,
+};
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index d946936..4664dc5 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -156,6 +156,7 @@ struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentr

/* callback_xdr.c */
extern struct svc_version nfs4_callback_version1;
+extern struct svc_version nfs4_callback_version4;

/* pagelist.c */
extern int __init nfs_init_nfspagecache(void);
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 6ea07a3..df1299e 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -287,6 +287,7 @@ struct nfs4_mount_data;

/* callback_xdr.c */
extern struct svc_version nfs4_callback_version1;
+extern struct svc_version nfs4_callback_version4;

#else

--
1.6.2.5


2009-11-23 21:59:25

by Alexandros Batsakis

[permalink] [raw]
Subject: [PATCH 09/10] nfs41: remove server-only EXCHGID4_FLAG_CONFIRMED_R flag from exchange_id

Signed-off-by: Alexandros Batsakis <[email protected]>
---
fs/nfs/nfs4proc.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 2de209c..6a0f9ea 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -4324,6 +4324,9 @@ static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
dprintk("--> %s\n", __func__);
BUG_ON(clp == NULL);

+ if (args.flags & EXCHGID4_FLAG_CONFIRMED_R)
+ args.flags ^= EXCHGID4_FLAG_CONFIRMED_R;
+
p = (u32 *)verifier.data;
*p++ = htonl((u32)clp->cl_boot_time.tv_sec);
*p = htonl((u32)clp->cl_boot_time.tv_nsec);
--
1.6.2.5


2009-11-23 21:59:25

by Alexandros Batsakis

[permalink] [raw]
Subject: [PATCH 08/10] nfs41: add support for the exclusive create flags

In v4.1 the client MUST/SHOULD use the EXCLUSIVE4_1 flag instead of
EXCLUSIVE4, and GUARDED when the server supports persistent sessions.
For now (and until we support suppattr_exclcreat), we don't send any
attributes with EXCLUSIVE4_1 relying in the subsequent SETATTR as in v4.0

Signed-off-by: Alexandros Batsakis <[email protected]>
---
fs/nfs/nfs4proc.c | 12 +++++++++---
fs/nfs/nfs4xdr.c | 23 ++++++++++++++++++++---
2 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index ef77d40..2de209c 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -720,9 +720,15 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
p->o_arg.bitmask = server->attr_bitmask;
p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
if (flags & O_EXCL) {
- u32 *s = (u32 *) p->o_arg.u.verifier.data;
- s[0] = jiffies;
- s[1] = current->pid;
+ if (nfs4_has_persistent_session(server->nfs_client)) {
+ /* GUARDED */
+ p->o_arg.u.attrs = &p->attrs;
+ memcpy(&p->attrs, attrs, sizeof(p->attrs));
+ } else { /* EXCLUSIVE4_1 */
+ u32 *s = (u32 *) p->o_arg.u.verifier.data;
+ s[0] = jiffies;
+ s[1] = current->pid;
+ }
} else if (flags & O_CREAT) {
p->o_arg.u.attrs = &p->attrs;
memcpy(&p->attrs, attrs, sizeof(p->attrs));
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index fc36af4..3875759 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -52,6 +52,7 @@
#include <linux/nfs_fs.h>
#include <linux/nfs_idmap.h>
#include "nfs4_fs.h"
+#include "internal.h"

#define NFSDBG_FACILITY NFSDBG_XDR

@@ -135,7 +136,7 @@ static int nfs4_stat_to_errno(int);
#define decode_lookup_maxsz (op_decode_hdr_maxsz)
#define encode_share_access_maxsz \
(2)
-#define encode_createmode_maxsz (1 + encode_attrs_maxsz)
+#define encode_createmode_maxsz (1 + encode_attrs_maxsz + encode_verifier_maxsz)
#define encode_opentype_maxsz (1 + encode_createmode_maxsz)
#define encode_claim_null_maxsz (1 + nfs4_name_maxsz)
#define encode_open_maxsz (op_encode_hdr_maxsz + \
@@ -1154,6 +1155,7 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
{
__be32 *p;
+ struct nfs_client *clp;

p = reserve_space(xdr, 4);
switch(arg->open_flags & O_EXCL) {
@@ -1162,8 +1164,23 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op
encode_attrs(xdr, arg->u.attrs, arg->server);
break;
default:
- *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
- encode_nfs4_verifier(xdr, &arg->u.verifier);
+ clp = arg->server->nfs_client;
+ if (clp->cl_minorversion > 0) {
+ if (nfs4_has_persistent_session(clp)) {
+ *p = cpu_to_be32(NFS4_CREATE_GUARDED);
+ encode_attrs(xdr, arg->u.attrs, arg->server);
+ } else {
+ struct iattr dummy;
+
+ *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1);
+ encode_nfs4_verifier(xdr, &arg->u.verifier);
+ dummy.ia_valid = 0;
+ encode_attrs(xdr, &dummy, arg->server);
+ }
+ } else {
+ *p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
+ encode_nfs4_verifier(xdr, &arg->u.verifier);
+ }
}
}

--
1.6.2.5


2009-11-23 21:59:24

by Alexandros Batsakis

[permalink] [raw]
Subject: [PATCH 03/10] nfs41: fix cb_recall bug

in NFSv4.1 the seqid part of a stateid in CB_RECALL must be 0

Signed-off-by: Alexandros Batsakis <[email protected]>
---
fs/nfs/delegation.c | 21 +++++++++++++++++----
1 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 6dd48a4..4096dcf 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -432,18 +432,31 @@ int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *s
{
struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
struct nfs_delegation *delegation;
+ u32 seqid_len = 0;

rcu_read_lock();
delegation = rcu_dereference(NFS_I(inode)->delegation);
- if (delegation == NULL || memcmp(delegation->stateid.data, stateid->data,
- sizeof(delegation->stateid.data)) != 0) {
- rcu_read_unlock();
- return -ENOENT;
+ if (delegation == NULL)
+ goto enoent;
+
+ if (clp->cl_minorversion > 0) {
+ if (((u32 *) &stateid->data)[0] != 0)
+ goto enoent;
+ seqid_len = 4;
}
+
+ if (memcmp(&delegation->stateid.data[seqid_len],
+ &stateid->data[seqid_len],
+ sizeof(stateid->data)-seqid_len))
+ goto enoent;
+
nfs_mark_return_delegation(clp, delegation);
rcu_read_unlock();
nfs_delegation_run_state_manager(clp);
return 0;
+enoent:
+ rcu_read_unlock();
+ return -ENOENT;
}

/*
--
1.6.2.5


2009-11-23 21:59:25

by Alexandros Batsakis

[permalink] [raw]
Subject: [PATCH 06/10] nfs41: initial support for CB_RECALL_ANY

For now the clients returns _all_ the delegations of the specificed type
it holds

Signed-off-by: Alexandros Batsakis <[email protected]>
---
fs/nfs/callback.h | 10 ++++++++++
fs/nfs/callback_proc.c | 30 ++++++++++++++++++++++++++++++
fs/nfs/callback_xdr.c | 27 ++++++++++++++++++++++++++-
fs/nfs/delegation.h | 1 +
4 files changed, 67 insertions(+), 1 deletions(-)

diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index 07baa82..b4cd63c 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -103,8 +103,18 @@ struct cb_sequenceres {
uint32_t csr_target_highestslotid;
};

+#define RCA4_TYPE_MASK_RDATA_DLG 0
+#define RCA4_TYPE_MASK_WDATA_DLG 1
+
+struct cb_recallanyargs {
+ struct sockaddr *craa_addr;
+ uint32_t craa_objs_to_keep;
+ uint32_t craa_type_mask;
+};
+
extern unsigned nfs4_callback_sequence(struct cb_sequenceargs *args,
struct cb_sequenceres *res);
+extern unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy);

#endif /* CONFIG_NFS_V4_1 */

diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index b7da1f5..d37e8c9 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -227,4 +227,34 @@ out:
return res->csr_status;
}

+unsigned nfs4_callback_recallany(struct cb_recallanyargs *args,
+ void *dummy)
+{
+ struct nfs_client *clp;
+ int status;
+ fmode_t flags = 0;
+
+ status = htonl(NFS4ERR_OP_NOT_IN_SESSION);
+ clp = nfs_find_client(args->craa_addr, 4);
+ if (clp == NULL)
+ goto out;
+
+ dprintk("NFS: RECALL_ANY callback request from %s\n",
+ rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR));
+
+ if (test_bit(RCA4_TYPE_MASK_RDATA_DLG, (const unsigned long *)
+ &args->craa_type_mask))
+ flags = FMODE_READ;
+ if (test_bit(RCA4_TYPE_MASK_WDATA_DLG, (const unsigned long *)
+ &args->craa_type_mask))
+ flags |= FMODE_WRITE;
+
+ if (flags)
+ nfs_expire_all_delegation_types(clp, flags);
+ status = htonl(NFS4_OK);
+ out:
+ dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
+ return status;
+}
+
#endif /* CONFIG_NFS_V4_1 */
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 0fda5e6..8e1a251 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -23,6 +23,7 @@
#if defined(CONFIG_NFS_V4_1)
#define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \
4 + 1 + 3)
+#define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ)
#endif /* CONFIG_NFS_V4_1 */

#define NFSDBG_FACILITY NFSDBG_CALLBACK
@@ -326,6 +327,25 @@ out_free:
goto out;
}

+static unsigned decode_recallany_args(struct svc_rqst *rqstp,
+ struct xdr_stream *xdr,
+ struct cb_recallanyargs *args)
+{
+ uint32_t *p;
+
+ args->craa_addr = svc_addr(rqstp);
+ p = read_buf(xdr, 4);
+ if (unlikely(p == NULL))
+ return htonl(NFS4ERR_BADXDR);
+ args->craa_objs_to_keep = ntohl(*p++);
+ p = read_buf(xdr, 4);
+ if (unlikely(p == NULL))
+ return htonl(NFS4ERR_BADXDR);
+ args->craa_type_mask = ntohl(*p);
+
+ return 0;
+}
+
#endif /* CONFIG_NFS_V4_1 */

static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
@@ -533,6 +553,7 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
case OP_CB_GETATTR:
case OP_CB_RECALL:
case OP_CB_SEQUENCE:
+ case OP_CB_RECALL_ANY:
*op = &callback_ops[op_nr];
break;

@@ -540,7 +561,6 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
case OP_CB_NOTIFY_DEVICEID:
case OP_CB_NOTIFY:
case OP_CB_PUSH_DELEG:
- case OP_CB_RECALL_ANY:
case OP_CB_RECALLABLE_OBJ_AVAIL:
case OP_CB_RECALL_SLOT:
case OP_CB_WANTS_CANCELLED:
@@ -688,6 +708,11 @@ static struct callback_op callback_ops[] = {
.encode_res = (callback_encode_res_t)encode_cb_sequence_res,
.res_maxsize = CB_OP_SEQUENCE_RES_MAXSZ,
},
+ [OP_CB_RECALL_ANY] = {
+ .process_op = (callback_process_op_t)nfs4_callback_recallany,
+ .decode_args = (callback_decode_arg_t)decode_recallany_args,
+ .res_maxsize = CB_OP_RECALLANY_RES_MAXSZ,
+ },
#endif /* CONFIG_NFS_V4_1 */
};

diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 09f3837..ad8b18d 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -40,6 +40,7 @@ void nfs_inode_return_delegation_noreclaim(struct inode *inode);
struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle);
void nfs_super_return_all_delegations(struct super_block *sb);
void nfs_expire_all_delegations(struct nfs_client *clp);
+void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags);
void nfs_expire_unreferenced_delegations(struct nfs_client *clp);
void nfs_handle_cb_pathdown(struct nfs_client *clp);
void nfs_client_return_marked_delegations(struct nfs_client *clp);
--
1.6.2.5


2009-11-23 21:59:26

by Alexandros Batsakis

[permalink] [raw]
Subject: [PATCH 10/10] nfs41: check SEQUENCE status flag

the server can indicate a number of error conditions by setting the
appropriate bits in the SEQUENCE operation. The client re-establishes
state with the server when it receives one of those, with the action
depending on the specific case.

Signed-off-by: Alexandros Batsakis <[email protected]>
---
fs/nfs/nfs4_fs.h | 1 +
fs/nfs/nfs4proc.c | 2 ++
fs/nfs/nfs4state.c | 22 ++++++++++++++++++++++
fs/nfs/nfs4xdr.c | 4 ++--
include/linux/nfs4.h | 2 ++
include/linux/nfs_xdr.h | 1 +
6 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index df1299e..d792b7d 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -267,6 +267,7 @@ extern void nfs4_state_set_mode_locked(struct nfs4_state *, fmode_t);
extern void nfs4_schedule_state_recovery(struct nfs_client *);
extern void nfs4_schedule_state_manager(struct nfs_client *);
extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state);
+extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags);
extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 6a0f9ea..4b1938b 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -388,6 +388,8 @@ static void nfs41_sequence_done(struct nfs_client *clp,
if (time_before(clp->cl_last_renewal, timestamp))
clp->cl_last_renewal = timestamp;
spin_unlock(&clp->cl_lock);
+ /* Check sequence flags */
+ nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags);
return;
}
out:
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 2ef4fec..340cdee 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1151,6 +1151,28 @@ static int nfs4_reclaim_lease(struct nfs_client *clp)
}

#ifdef CONFIG_NFS_V4_1
+void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags)
+{
+ if (!flags)
+ return;
+ else if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED) {
+ set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
+ nfs4_state_start_reclaim_reboot(clp);
+ nfs4_schedule_state_recovery(clp);
+ } else if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED |
+ SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED |
+ SEQ4_STATUS_ADMIN_STATE_REVOKED |
+ SEQ4_STATUS_RECALLABLE_STATE_REVOKED |
+ SEQ4_STATUS_LEASE_MOVED)) {
+ set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
+ nfs4_state_start_reclaim_nograce(clp);
+ nfs4_schedule_state_recovery(clp);
+ } else if (flags & (SEQ4_STATUS_CB_PATH_DOWN |
+ SEQ4_STATUS_BACKCHANNEL_FAULT |
+ SEQ4_STATUS_CB_PATH_DOWN_SESSION))
+ nfs_expire_all_delegations(clp);
+}
+
static void nfs4_session_recovery_handle_error(struct nfs_client *clp, int err)
{
switch (err) {
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 3875759..ec5aec1 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4614,8 +4614,8 @@ static int decode_sequence(struct xdr_stream *xdr,
dummy = be32_to_cpup(p++);
/* target highest slot id - currently not processed */
dummy = be32_to_cpup(p++);
- /* result flags - currently not processed */
- dummy = be32_to_cpup(p);
+ /* result flags */
+ res->sr_status_flags = be32_to_cpup(p);
status = 0;
out_err:
res->sr_status = status;
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index c4c0602..89404bf 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -128,6 +128,8 @@
#define SEQ4_STATUS_RECALLABLE_STATE_REVOKED 0x00000040
#define SEQ4_STATUS_LEASE_MOVED 0x00000080
#define SEQ4_STATUS_RESTART_RECLAIM_NEEDED 0x00000100
+#define SEQ4_STATUS_CB_PATH_DOWN_SESSION 0x00000200
+#define SEQ4_STATUS_BACKCHANNEL_FAULT 0x00000400

#define NFS4_MAX_UINT64 (~(u64)0)

diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 62f63fb..b0c65e4 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -172,6 +172,7 @@ struct nfs4_sequence_res {
u8 sr_slotid; /* slot used to send request */
unsigned long sr_renewal_time;
int sr_status; /* sequence operation status */
+ u32 sr_status_flags;
};

struct nfs4_get_lease_time_args {
--
1.6.2.5


2009-11-23 21:59:25

by Alexandros Batsakis

[permalink] [raw]
Subject: [PATCH 07/10] nfs41: check if session exists and if it is persistent

Signed-off-by: Alexandros Batsakis <[email protected]>
---
fs/nfs/internal.h | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 4664dc5..7c44804 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -30,6 +30,15 @@ static inline int nfs4_has_session(const struct nfs_client *clp)
return 0;
}

+static inline int nfs4_has_persistent_session(const struct nfs_client *clp)
+{
+#ifdef CONFIG_NFS_V4_1
+ if (nfs4_has_session(clp))
+ return (clp->cl_session->flags & SESSION4_PERSIST);
+#endif /* CONFIG_NFS_V4_1 */
+ return 0;
+}
+
struct nfs_clone_mount {
const struct super_block *sb;
const struct dentry *dentry;
--
1.6.2.5


2009-11-23 22:06:07

by Peter Staubach

[permalink] [raw]
Subject: Re: [PATCH 01/10] nfs41: adjust max_rqst_sz, max_resp_sz w.r.t to rsize, wsize

Alexandros Batsakis wrote:
> The v4.1 client should take into account the desired rsize, wsize when
> negotiating the max size in CREATE_SESSION. Accordingly, it should use
> rsize, wsize that are smaller than the session negotiated values.
>
> Signed-off-by: Alexandros Batsakis <[email protected]>
> ---
> fs/nfs/client.c | 14 ++++++++++----
> fs/nfs/internal.h | 4 ++++
> fs/nfs/nfs4proc.c | 7 +++++--
> fs/nfs/nfs4xdr.c | 14 ++++++++++++++
> 4 files changed, 33 insertions(+), 6 deletions(-)
>
> diff --git a/fs/nfs/client.c b/fs/nfs/client.c
> index 99ea196..f360739 100644
> --- a/fs/nfs/client.c
> +++ b/fs/nfs/client.c
> @@ -911,8 +911,10 @@ static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *
>
> server->maxfilesize = fsinfo->maxfilesize;
>
> - /* We're airborne Set socket buffersize */
> - rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
> + /* We're airborne Set socket buffersize. */
> + if (!nfs4_has_session(server->nfs_client))
> + rpc_setbufsize(server->client, server->wsize + 100,
> + server->rsize + 100);

Just out of curiosity, 100? Why 100 and not some other number?
(I do realize that this wasn't changed, but huh? Magic numbers
like this are a bad thing...)

Thanx...

ps

> }
>
> /*
> @@ -1260,10 +1262,14 @@ error:
> static void nfs4_session_set_rwsize(struct nfs_server *server)
> {
> #ifdef CONFIG_NFS_V4_1
> + struct nfs4_session *sess;
> if (!nfs4_has_session(server->nfs_client))
> return;
> - server->rsize = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
> - server->wsize = server->nfs_client->cl_session->fc_attrs.max_rqst_sz;
> + sess = server->nfs_client->cl_session;
> + server->rsize = sess->fc_attrs.max_resp_sz - nfs41_maxread_overhead;
> + server->wsize = sess->fc_attrs.max_rqst_sz - nfs41_maxwrite_overhead;
> + rpc_setbufsize(server->client, sess->fc_attrs.max_rqst_sz,
> + sess->fc_attrs.max_resp_sz);
> #endif /* CONFIG_NFS_V4_1 */
> }
>
> diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
> index e21b1bb..d946936 100644
> --- a/fs/nfs/internal.h
> +++ b/fs/nfs/internal.h
> @@ -195,6 +195,10 @@ static inline void nfs4_restart_rpc(struct rpc_task *task,
> #ifdef CONFIG_NFS_V4
> extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus);
> #endif
> +#ifdef CONFIG_NFS_V4_1
> +extern const u32 nfs41_maxread_overhead;
> +extern const u32 nfs41_maxwrite_overhead;
> +#endif
>
> /* nfs4proc.c */
> #ifdef CONFIG_NFS_V4
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index ff37454..ef77d40 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -4827,13 +4827,16 @@ int nfs4_proc_destroy_session(struct nfs4_session *session)
> int nfs4_init_session(struct nfs_server *server)
> {
> struct nfs_client *clp = server->nfs_client;
> + struct nfs4_session *session;
> int ret;
>
> if (!nfs4_has_session(clp))
> return 0;
>
> - clp->cl_session->fc_attrs.max_rqst_sz = server->wsize;
> - clp->cl_session->fc_attrs.max_resp_sz = server->rsize;
> + session = clp->cl_session;
> + session->fc_attrs.max_rqst_sz = server->wsize + nfs41_maxwrite_overhead;
> + session->fc_attrs.max_resp_sz = server->rsize + nfs41_maxread_overhead;
> +
> ret = nfs4_recover_expired_lease(server);
> if (!ret)
> ret = nfs4_check_client_ready(clp);
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index 20b4e30..fc36af4 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -46,6 +46,7 @@
> #include <linux/proc_fs.h>
> #include <linux/kdev_t.h>
> #include <linux/sunrpc/clnt.h>
> +#include <linux/sunrpc/msg_prot.h>
> #include <linux/nfs.h>
> #include <linux/nfs4.h>
> #include <linux/nfs_fs.h>
> @@ -676,6 +677,19 @@ static int nfs4_stat_to_errno(int);
> decode_sequence_maxsz + \
> decode_putrootfh_maxsz + \
> decode_fsinfo_maxsz)
> +
> +const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
> + compound_encode_hdr_maxsz +
> + encode_sequence_maxsz +
> + encode_putfh_maxsz +
> + encode_getattr_maxsz) *
> + XDR_UNIT);
> +
> +const u32 nfs41_maxread_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
> + compound_decode_hdr_maxsz +
> + decode_sequence_maxsz +
> + decode_putfh_maxsz) *
> + XDR_UNIT);
> #endif /* CONFIG_NFS_V4_1 */
>
> static const umode_t nfs_type2fmt[] = {


2009-11-23 22:57:19

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH 01/10] nfs41: adjust max_rqst_sz, max_resp_sz w.r.t to rsize, wsize

On Mon, 2009-11-23 at 13:54 -0800, Alexandros Batsakis wrote:
> The v4.1 client should take into account the desired rsize, wsize when
> negotiating the max size in CREATE_SESSION. Accordingly, it should use
> rsize, wsize that are smaller than the session negotiated values.
>
> Signed-off-by: Alexandros Batsakis <[email protected]>
> ---
> fs/nfs/client.c | 14 ++++++++++----
> fs/nfs/internal.h | 4 ++++
> fs/nfs/nfs4proc.c | 7 +++++--
> fs/nfs/nfs4xdr.c | 14 ++++++++++++++
> 4 files changed, 33 insertions(+), 6 deletions(-)
>
> diff --git a/fs/nfs/client.c b/fs/nfs/client.c
> index 99ea196..f360739 100644
> --- a/fs/nfs/client.c
> +++ b/fs/nfs/client.c
> @@ -911,8 +911,10 @@ static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *
>
> server->maxfilesize = fsinfo->maxfilesize;
>
> - /* We're airborne Set socket buffersize */
> - rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
> + /* We're airborne Set socket buffersize. */
> + if (!nfs4_has_session(server->nfs_client))
> + rpc_setbufsize(server->client, server->wsize + 100,
> + server->rsize + 100);
> }

Please move this out of generic NFS code.

I really don't like this ugly proliferation of 'if (nfs4_has_session())'
that appears to be creeping into every single function in the NFS client
code.

> /*
> @@ -1260,10 +1262,14 @@ error:
> static void nfs4_session_set_rwsize(struct nfs_server *server)
> {
> #ifdef CONFIG_NFS_V4_1
> + struct nfs4_session *sess;
> if (!nfs4_has_session(server->nfs_client))
> return;
> - server->rsize = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
> - server->wsize = server->nfs_client->cl_session->fc_attrs.max_rqst_sz;
> + sess = server->nfs_client->cl_session;
> + server->rsize = sess->fc_attrs.max_resp_sz - nfs41_maxread_overhead;
> + server->wsize = sess->fc_attrs.max_rqst_sz - nfs41_maxwrite_overhead;


For one thing, the r/wsize is conventionally set to be a power of 2,
since most disks have block sizes of that form.

Secondly, what if the server has given you a max_resp_sz/max_rqst_sz
that is larger than what you asked for?

> + rpc_setbufsize(server->client, sess->fc_attrs.max_rqst_sz,
> + sess->fc_attrs.max_resp_sz);

Is anyone ever going to use NFSv4.1 over UDP?

> #endif /* CONFIG_NFS_V4_1 */
> }
>
> diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
> index e21b1bb..d946936 100644
> --- a/fs/nfs/internal.h
> +++ b/fs/nfs/internal.h
> @@ -195,6 +195,10 @@ static inline void nfs4_restart_rpc(struct rpc_task *task,
> #ifdef CONFIG_NFS_V4
> extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus);
> #endif
> +#ifdef CONFIG_NFS_V4_1
> +extern const u32 nfs41_maxread_overhead;
> +extern const u32 nfs41_maxwrite_overhead;
> +#endif
>
> /* nfs4proc.c */
> #ifdef CONFIG_NFS_V4
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index ff37454..ef77d40 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -4827,13 +4827,16 @@ int nfs4_proc_destroy_session(struct nfs4_session *session)
> int nfs4_init_session(struct nfs_server *server)
> {
> struct nfs_client *clp = server->nfs_client;
> + struct nfs4_session *session;
> int ret;
>
> if (!nfs4_has_session(clp))
> return 0;
>
> - clp->cl_session->fc_attrs.max_rqst_sz = server->wsize;
> - clp->cl_session->fc_attrs.max_resp_sz = server->rsize;
> + session = clp->cl_session;
> + session->fc_attrs.max_rqst_sz = server->wsize + nfs41_maxwrite_overhead;
> + session->fc_attrs.max_resp_sz = server->rsize + nfs41_maxread_overhead;
> +
> ret = nfs4_recover_expired_lease(server);
> if (!ret)
> ret = nfs4_check_client_ready(clp);
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index 20b4e30..fc36af4 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -46,6 +46,7 @@
> #include <linux/proc_fs.h>
> #include <linux/kdev_t.h>
> #include <linux/sunrpc/clnt.h>
> +#include <linux/sunrpc/msg_prot.h>
> #include <linux/nfs.h>
> #include <linux/nfs4.h>
> #include <linux/nfs_fs.h>
> @@ -676,6 +677,19 @@ static int nfs4_stat_to_errno(int);
> decode_sequence_maxsz + \
> decode_putrootfh_maxsz + \
> decode_fsinfo_maxsz)
> +
> +const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
> + compound_encode_hdr_maxsz +
> + encode_sequence_maxsz +
> + encode_putfh_maxsz +
> + encode_getattr_maxsz) *
> + XDR_UNIT);
> +
> +const u32 nfs41_maxread_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
> + compound_decode_hdr_maxsz +
> + decode_sequence_maxsz +
> + decode_putfh_maxsz) *
> + XDR_UNIT);
> #endif /* CONFIG_NFS_V4_1 */
>
> static const umode_t nfs_type2fmt[] = {
> --
> 1.6.2.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html




2009-11-23 23:06:59

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH 05/10] nfs4: return/expire delegations depending on their type

On Mon, 2009-11-23 at 13:54 -0800, Alexandros Batsakis wrote:
> Signed-off-by: Alexandros Batsakis <[email protected]>
> ---
> fs/nfs/delegation.c | 20 ++++++++++++++++----
> 1 files changed, 16 insertions(+), 4 deletions(-)
>
> diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
> index 71d5094..a14df44 100644
> --- a/fs/nfs/delegation.c
> +++ b/fs/nfs/delegation.c
> @@ -371,29 +371,41 @@ void nfs_super_return_all_delegations(struct super_block *sb)
> nfs_client_return_marked_delegations(clp);
> }
>
> -static void nfs_client_mark_return_all_delegations(struct nfs_client *clp)
> +static
> +void nfs_client_mark_return_all_delegation_types(struct nfs_client *clp, fmode_t flags)
> {
> struct nfs_delegation *delegation;
>
> rcu_read_lock();
> list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
> - nfs_mark_return_delegation(clp, delegation);
> + if (delegation->type & flags)
> + nfs_mark_return_delegation(clp, delegation);

This will be confusing. In all other parts of the code, we label write
delegations as FMODE_READ|FMODE_WRITE, since a write delegation implies
a read delegation too.

> }
> rcu_read_unlock();
> }
>
> +static void nfs_client_mark_return_all_delegations(struct nfs_client *clp)
> +{
> + nfs_client_mark_return_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
> +}
> +
> static void nfs_delegation_run_state_manager(struct nfs_client *clp)
> {
> if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state))
> nfs4_schedule_state_manager(clp);
> }
>
> -void nfs_expire_all_delegations(struct nfs_client *clp)
> +void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags)

Should be static void since there is no declaration of
nfs_expire_all_delegation types in any header files (that only appears
in patch 07/10).

> {
> - nfs_client_mark_return_all_delegations(clp);
> + nfs_client_mark_return_all_delegation_types(clp, flags);
> nfs_delegation_run_state_manager(clp);
> }
>
> +void nfs_expire_all_delegations(struct nfs_client *clp)
> +{
> + nfs_expire_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
> +}
> +
> /*
> * Return all delegations following an NFS4ERR_CB_PATH_DOWN error.
> */




2009-11-23 23:15:04

by Batsakis, Alexandros

[permalink] [raw]
Subject: RE: [PATCH 01/10] nfs41: adjust max_rqst_sz, max_resp_sz w.r.t to rsize, wsize

DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogVHJvbmQgTXlrbGVidXN0
IFttYWlsdG86dHJvbmQubXlrbGVidXN0QGZ5cy51aW8ubm9dDQo+IFNlbnQ6IE1vbmRheSwgTm92
ZW1iZXIgMjMsIDIwMDkgMjo1NyBQTQ0KPiBUbzogQmF0c2FraXMsIEFsZXhhbmRyb3MNCj4gQ2M6
IGxpbnV4LW5mc0B2Z2VyLmtlcm5lbC5vcmcNCj4gU3ViamVjdDogUmU6IFtQQVRDSCAwMS8xMF0g
bmZzNDE6IGFkanVzdCBtYXhfcnFzdF9zeiwgbWF4X3Jlc3Bfc3ogdy5yLnQNCj4gdG8gcnNpemUs
IHdzaXplDQo+IA0KPiBPbiBNb24sIDIwMDktMTEtMjMgYXQgMTM6NTQgLTA4MDAsIEFsZXhhbmRy
b3MgQmF0c2FraXMgd3JvdGU6DQo+ID4gVGhlIHY0LjEgY2xpZW50IHNob3VsZCB0YWtlIGludG8g
YWNjb3VudCB0aGUgZGVzaXJlZCByc2l6ZSwgd3NpemUNCj4gd2hlbg0KPiA+IG5lZ290aWF0aW5n
IHRoZSBtYXggc2l6ZSBpbiBDUkVBVEVfU0VTU0lPTi4gQWNjb3JkaW5nbHksIGl0IHNob3VsZA0K
PiB1c2UNCj4gPiByc2l6ZSwgd3NpemUgdGhhdCBhcmUgc21hbGxlciB0aGFuIHRoZSBzZXNzaW9u
IG5lZ290aWF0ZWQgdmFsdWVzLg0KPiA+DQo+ID4gU2lnbmVkLW9mZi1ieTogQWxleGFuZHJvcyBC
YXRzYWtpcyA8YmF0c2FraXNAbmV0YXBwLmNvbT4NCj4gPiAtLS0NCj4gPiAgZnMvbmZzL2NsaWVu
dC5jICAgfCAgIDE0ICsrKysrKysrKystLS0tDQo+ID4gIGZzL25mcy9pbnRlcm5hbC5oIHwgICAg
NCArKysrDQo+ID4gIGZzL25mcy9uZnM0cHJvYy5jIHwgICAgNyArKysrKy0tDQo+ID4gIGZzL25m
cy9uZnM0eGRyLmMgIHwgICAxNCArKysrKysrKysrKysrKw0KPiA+ICA0IGZpbGVzIGNoYW5nZWQs
IDMzIGluc2VydGlvbnMoKyksIDYgZGVsZXRpb25zKC0pDQo+ID4NCj4gPiBkaWZmIC0tZ2l0IGEv
ZnMvbmZzL2NsaWVudC5jIGIvZnMvbmZzL2NsaWVudC5jDQo+ID4gaW5kZXggOTllYTE5Ni4uZjM2
MDczOSAxMDA2NDQNCj4gPiAtLS0gYS9mcy9uZnMvY2xpZW50LmMNCj4gPiArKysgYi9mcy9uZnMv
Y2xpZW50LmMNCj4gPiBAQCAtOTExLDggKzkxMSwxMCBAQCBzdGF0aWMgdm9pZCBuZnNfc2VydmVy
X3NldF9mc2luZm8oc3RydWN0DQo+IG5mc19zZXJ2ZXIgKnNlcnZlciwgc3RydWN0IG5mc19mc2lu
Zm8gKg0KPiA+DQo+ID4gIAlzZXJ2ZXItPm1heGZpbGVzaXplID0gZnNpbmZvLT5tYXhmaWxlc2l6
ZTsNCj4gPg0KPiA+IC0JLyogV2UncmUgYWlyYm9ybmUgU2V0IHNvY2tldCBidWZmZXJzaXplICov
DQo+ID4gLQlycGNfc2V0YnVmc2l6ZShzZXJ2ZXItPmNsaWVudCwgc2VydmVyLT53c2l6ZSArIDEw
MCwgc2VydmVyLT5yc2l6ZQ0KPiArIDEwMCk7DQo+ID4gKwkvKiBXZSdyZSBhaXJib3JuZSBTZXQg
c29ja2V0IGJ1ZmZlcnNpemUuICovDQo+ID4gKwlpZiAoIW5mczRfaGFzX3Nlc3Npb24oc2VydmVy
LT5uZnNfY2xpZW50KSkNCj4gPiArCQlycGNfc2V0YnVmc2l6ZShzZXJ2ZXItPmNsaWVudCwgc2Vy
dmVyLT53c2l6ZSArIDEwMCwNCj4gPiArCQkJICAgICAgIHNlcnZlci0+cnNpemUgKyAxMDApOw0K
PiA+ICB9DQo+IA0KPiBQbGVhc2UgbW92ZSB0aGlzIG91dCBvZiBnZW5lcmljIE5GUyBjb2RlLg0K
PiANCj4gSSByZWFsbHkgZG9uJ3QgbGlrZSB0aGlzIHVnbHkgcHJvbGlmZXJhdGlvbiBvZiAnaWYN
Cj4gKG5mczRfaGFzX3Nlc3Npb24oKSknDQo+IHRoYXQgYXBwZWFycyB0byBiZSBjcmVlcGluZyBp
bnRvIGV2ZXJ5IHNpbmdsZSBmdW5jdGlvbiBpbiB0aGUgTkZTDQo+IGNsaWVudA0KPiBjb2RlLg0K
PiANCg0KT0sNCg0KPiA+IC8qDQo+ID4gQEAgLTEyNjAsMTAgKzEyNjIsMTQgQEAgZXJyb3I6DQo+
ID4gIHN0YXRpYyB2b2lkIG5mczRfc2Vzc2lvbl9zZXRfcndzaXplKHN0cnVjdCBuZnNfc2VydmVy
ICpzZXJ2ZXIpDQo+ID4gIHsNCj4gPiAgI2lmZGVmIENPTkZJR19ORlNfVjRfMQ0KPiA+ICsJc3Ry
dWN0IG5mczRfc2Vzc2lvbiAqc2VzczsNCj4gPiAgCWlmICghbmZzNF9oYXNfc2Vzc2lvbihzZXJ2
ZXItPm5mc19jbGllbnQpKQ0KPiA+ICAJCXJldHVybjsNCj4gPiAtCXNlcnZlci0+cnNpemUgPSBz
ZXJ2ZXItPm5mc19jbGllbnQtPmNsX3Nlc3Npb24tDQo+ID5mY19hdHRycy5tYXhfcmVzcF9zejsN
Cj4gPiAtCXNlcnZlci0+d3NpemUgPSBzZXJ2ZXItPm5mc19jbGllbnQtPmNsX3Nlc3Npb24tDQo+
ID5mY19hdHRycy5tYXhfcnFzdF9zejsNCj4gPiArCXNlc3MgPSBzZXJ2ZXItPm5mc19jbGllbnQt
PmNsX3Nlc3Npb247DQo+ID4gKwlzZXJ2ZXItPnJzaXplID0gc2Vzcy0+ZmNfYXR0cnMubWF4X3Jl
c3Bfc3ogLQ0KPiBuZnM0MV9tYXhyZWFkX292ZXJoZWFkOw0KPiA+ICsJc2VydmVyLT53c2l6ZSA9
IHNlc3MtPmZjX2F0dHJzLm1heF9ycXN0X3N6IC0NCj4gbmZzNDFfbWF4d3JpdGVfb3ZlcmhlYWQ7
DQo+IA0KPiANCj4gRm9yIG9uZSB0aGluZywgdGhlIHIvd3NpemUgaXMgY29udmVudGlvbmFsbHkg
c2V0IHRvIGJlIGEgcG93ZXIgb2YgMiwNCj4gc2luY2UgbW9zdCBkaXNrcyBoYXZlIGJsb2NrIHNp
emVzIG9mIHRoYXQgZm9ybS4NCj4gDQoNClRoaXMgaXMgc3RpbGwgdHJ1ZS4gSXQgaGFzIGhhcHBl
bmVkIGJlZm9yZSBkdXJpbmcgdGhlIHByb2Nlc3Npbmcgb2YgdGhlIG1vdW50IG9wdGlvbnMuDQpM
ZXQgbWUga25vdyBpZiB5b3UgdGhpbmsgSSBzaG91bGQgcmUtZW5mb3JjZSBpdCBoZXJlLg0KDQo+
IFNlY29uZGx5LCB3aGF0IGlmIHRoZSBzZXJ2ZXIgaGFzIGdpdmVuIHlvdSBhIG1heF9yZXNwX3N6
L21heF9ycXN0X3N6DQo+IHRoYXQgaXMgbGFyZ2VyIHRoYW4gd2hhdCB5b3UgYXNrZWQgZm9yPw0K
DQpJbiB0aGVvcnkgdGhlIHNlcnZlciBNVVNUL1NIT1VMRCBub3QgdG8gZG8gdGhhdCwgYnV0IHlv
dSBhcmUgcmlnaHQgSSBzaG91bGQgbWFrZSBzdXJlIGl0IGRvZXNuJ3QgbWVzcyB1cCB0aGUgdXNl
ciBwcmVmZXJlbmNlcw0KDQo+IA0KPiA+ICsJcnBjX3NldGJ1ZnNpemUoc2VydmVyLT5jbGllbnQs
IHNlc3MtPmZjX2F0dHJzLm1heF9ycXN0X3N6LA0KPiA+ICsJCSAgICAgICBzZXNzLT5mY19hdHRy
cy5tYXhfcmVzcF9zeik7DQo+IA0KPiBJcyBhbnlvbmUgZXZlciBnb2luZyB0byB1c2UgTkZTdjQu
MSBvdmVyIFVEUD8NCj4gDQoNCllvdSBhcmUgcmlnaHQuIFRoZW4gSSBjYW4ganVzdCByZW1vdmUg
dGhlIHNlc3Npb24gY2hlY2tpbmcgZnJvbSBhYm92ZS4NCkkgbGwgc2VuZCB2MiBzaG9ydGx5DQoN
Ci1hbGV4YW5kcm9zDQoNCj4gPiAjZW5kaWYgLyogQ09ORklHX05GU19WNF8xICovDQo+ID4gIH0N
Cj4gPg0KPiA+IGRpZmYgLS1naXQgYS9mcy9uZnMvaW50ZXJuYWwuaCBiL2ZzL25mcy9pbnRlcm5h
bC5oDQo+ID4gaW5kZXggZTIxYjFiYi4uZDk0NjkzNiAxMDA2NDQNCj4gPiAtLS0gYS9mcy9uZnMv
aW50ZXJuYWwuaA0KPiA+ICsrKyBiL2ZzL25mcy9pbnRlcm5hbC5oDQo+ID4gQEAgLTE5NSw2ICsx
OTUsMTAgQEAgc3RhdGljIGlubGluZSB2b2lkIG5mczRfcmVzdGFydF9ycGMoc3RydWN0DQo+IHJw
Y190YXNrICp0YXNrLA0KPiA+ICAjaWZkZWYgQ09ORklHX05GU19WNA0KPiA+ICBleHRlcm4gX19i
ZTMyICpuZnM0X2RlY29kZV9kaXJlbnQoX19iZTMyICpwLCBzdHJ1Y3QgbmZzX2VudHJ5DQo+ICpl
bnRyeSwgaW50IHBsdXMpOw0KPiA+ICAjZW5kaWYNCj4gPiArI2lmZGVmIENPTkZJR19ORlNfVjRf
MQ0KPiA+ICtleHRlcm4gY29uc3QgdTMyIG5mczQxX21heHJlYWRfb3ZlcmhlYWQ7DQo+ID4gK2V4
dGVybiBjb25zdCB1MzIgbmZzNDFfbWF4d3JpdGVfb3ZlcmhlYWQ7DQo+ID4gKyNlbmRpZg0KPiA+
DQo+ID4gIC8qIG5mczRwcm9jLmMgKi8NCj4gPiAgI2lmZGVmIENPTkZJR19ORlNfVjQNCj4gPiBk
aWZmIC0tZ2l0IGEvZnMvbmZzL25mczRwcm9jLmMgYi9mcy9uZnMvbmZzNHByb2MuYw0KPiA+IGlu
ZGV4IGZmMzc0NTQuLmVmNzdkNDAgMTAwNjQ0DQo+ID4gLS0tIGEvZnMvbmZzL25mczRwcm9jLmMN
Cj4gPiArKysgYi9mcy9uZnMvbmZzNHByb2MuYw0KPiA+IEBAIC00ODI3LDEzICs0ODI3LDE2IEBA
IGludCBuZnM0X3Byb2NfZGVzdHJveV9zZXNzaW9uKHN0cnVjdA0KPiBuZnM0X3Nlc3Npb24gKnNl
c3Npb24pDQo+ID4gIGludCBuZnM0X2luaXRfc2Vzc2lvbihzdHJ1Y3QgbmZzX3NlcnZlciAqc2Vy
dmVyKQ0KPiA+ICB7DQo+ID4gIAlzdHJ1Y3QgbmZzX2NsaWVudCAqY2xwID0gc2VydmVyLT5uZnNf
Y2xpZW50Ow0KPiA+ICsJc3RydWN0IG5mczRfc2Vzc2lvbiAqc2Vzc2lvbjsNCj4gPiAgCWludCBy
ZXQ7DQo+ID4NCj4gPiAgCWlmICghbmZzNF9oYXNfc2Vzc2lvbihjbHApKQ0KPiA+ICAJCXJldHVy
biAwOw0KPiA+DQo+ID4gLQljbHAtPmNsX3Nlc3Npb24tPmZjX2F0dHJzLm1heF9ycXN0X3N6ID0g
c2VydmVyLT53c2l6ZTsNCj4gPiAtCWNscC0+Y2xfc2Vzc2lvbi0+ZmNfYXR0cnMubWF4X3Jlc3Bf
c3ogPSBzZXJ2ZXItPnJzaXplOw0KPiA+ICsJc2Vzc2lvbiA9IGNscC0+Y2xfc2Vzc2lvbjsNCj4g
PiArCXNlc3Npb24tPmZjX2F0dHJzLm1heF9ycXN0X3N6ID0gc2VydmVyLT53c2l6ZSArDQo+IG5m
czQxX21heHdyaXRlX292ZXJoZWFkOw0KPiA+ICsJc2Vzc2lvbi0+ZmNfYXR0cnMubWF4X3Jlc3Bf
c3ogPSBzZXJ2ZXItPnJzaXplICsNCj4gbmZzNDFfbWF4cmVhZF9vdmVyaGVhZDsNCj4gPiArDQo+
ID4gIAlyZXQgPSBuZnM0X3JlY292ZXJfZXhwaXJlZF9sZWFzZShzZXJ2ZXIpOw0KPiA+ICAJaWYg
KCFyZXQpDQo+ID4gIAkJcmV0ID0gbmZzNF9jaGVja19jbGllbnRfcmVhZHkoY2xwKTsNCj4gPiBk
aWZmIC0tZ2l0IGEvZnMvbmZzL25mczR4ZHIuYyBiL2ZzL25mcy9uZnM0eGRyLmMNCj4gPiBpbmRl
eCAyMGI0ZTMwLi5mYzM2YWY0IDEwMDY0NA0KPiA+IC0tLSBhL2ZzL25mcy9uZnM0eGRyLmMNCj4g
PiArKysgYi9mcy9uZnMvbmZzNHhkci5jDQo+ID4gQEAgLTQ2LDYgKzQ2LDcgQEANCj4gPiAgI2lu
Y2x1ZGUgPGxpbnV4L3Byb2NfZnMuaD4NCj4gPiAgI2luY2x1ZGUgPGxpbnV4L2tkZXZfdC5oPg0K
PiA+ICAjaW5jbHVkZSA8bGludXgvc3VucnBjL2NsbnQuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4
L3N1bnJwYy9tc2dfcHJvdC5oPg0KPiA+ICAjaW5jbHVkZSA8bGludXgvbmZzLmg+DQo+ID4gICNp
bmNsdWRlIDxsaW51eC9uZnM0Lmg+DQo+ID4gICNpbmNsdWRlIDxsaW51eC9uZnNfZnMuaD4NCj4g
PiBAQCAtNjc2LDYgKzY3NywxOSBAQCBzdGF0aWMgaW50IG5mczRfc3RhdF90b19lcnJubyhpbnQp
Ow0KPiA+ICAJCQkJCSBkZWNvZGVfc2VxdWVuY2VfbWF4c3ogKyBcDQo+ID4gIAkJCQkJIGRlY29k
ZV9wdXRyb290ZmhfbWF4c3ogKyBcDQo+ID4gIAkJCQkJIGRlY29kZV9mc2luZm9fbWF4c3opDQo+
ID4gKw0KPiA+ICtjb25zdCB1MzIgbmZzNDFfbWF4d3JpdGVfb3ZlcmhlYWQgPSAoKFJQQ19NQVhf
SEVBREVSX1dJVEhfQVVUSCArDQo+ID4gKwkJCQkgICAgICBjb21wb3VuZF9lbmNvZGVfaGRyX21h
eHN6ICsNCj4gPiArCQkJCSAgICAgIGVuY29kZV9zZXF1ZW5jZV9tYXhzeiArDQo+ID4gKwkJCQkg
ICAgICBlbmNvZGVfcHV0ZmhfbWF4c3ogKw0KPiA+ICsJCQkJICAgICAgZW5jb2RlX2dldGF0dHJf
bWF4c3opICoNCj4gPiArCQkJCSAgICAgWERSX1VOSVQpOw0KPiA+ICsNCj4gPiArY29uc3QgdTMy
IG5mczQxX21heHJlYWRfb3ZlcmhlYWQgPSAoKFJQQ19NQVhfSEVBREVSX1dJVEhfQVVUSCArDQo+
ID4gKwkJCQkgICAgIGNvbXBvdW5kX2RlY29kZV9oZHJfbWF4c3ogKw0KPiA+ICsJCQkJICAgICBk
ZWNvZGVfc2VxdWVuY2VfbWF4c3ogKw0KPiA+ICsJCQkJICAgICBkZWNvZGVfcHV0ZmhfbWF4c3op
ICoNCj4gPiArCQkJCSAgICBYRFJfVU5JVCk7DQo+ID4gICNlbmRpZiAvKiBDT05GSUdfTkZTX1Y0
XzEgKi8NCj4gPg0KPiA+ICBzdGF0aWMgY29uc3QgdW1vZGVfdCBuZnNfdHlwZTJmbXRbXSA9IHsN
Cj4gPiAtLQ0KPiA+IDEuNi4yLjUNCj4gPg0KPiA+IC0tDQo+ID4gVG8gdW5zdWJzY3JpYmUgZnJv
bSB0aGlzIGxpc3Q6IHNlbmQgdGhlIGxpbmUgInVuc3Vic2NyaWJlIGxpbnV4LW5mcyINCj4gaW4N
Cj4gPiB0aGUgYm9keSBvZiBhIG1lc3NhZ2UgdG8gbWFqb3Jkb21vQHZnZXIua2VybmVsLm9yZw0K
PiA+IE1vcmUgbWFqb3Jkb21vIGluZm8gYXQgIGh0dHA6Ly92Z2VyLmtlcm5lbC5vcmcvbWFqb3Jk
b21vLWluZm8uaHRtbA0KPiANCj4gDQo+IA0KPiAtLQ0KPiBUbyB1bnN1YnNjcmliZSBmcm9tIHRo
aXMgbGlzdDogc2VuZCB0aGUgbGluZSAidW5zdWJzY3JpYmUgbGludXgtbmZzIiBpbg0KPiB0aGUg
Ym9keSBvZiBhIG1lc3NhZ2UgdG8gbWFqb3Jkb21vQHZnZXIua2VybmVsLm9yZw0KPiBNb3JlIG1h
am9yZG9tbyBpbmZvIGF0ICBodHRwOi8vdmdlci5rZXJuZWwub3JnL21ham9yZG9tby1pbmZvLmh0
bWwNCg==

2009-11-23 23:16:45

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH 03/10] nfs41: fix cb_recall bug

On Mon, 2009-11-23 at 13:54 -0800, Alexandros Batsakis wrote:
> in NFSv4.1 the seqid part of a stateid in CB_RECALL must be 0
>
> Signed-off-by: Alexandros Batsakis <[email protected]>
> ---
> fs/nfs/delegation.c | 21 +++++++++++++++++----
> 1 files changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
> index 6dd48a4..4096dcf 100644
> --- a/fs/nfs/delegation.c
> +++ b/fs/nfs/delegation.c
> @@ -432,18 +432,31 @@ int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *s
> {
> struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
> struct nfs_delegation *delegation;
> + u32 seqid_len = 0;
>
> rcu_read_lock();
> delegation = rcu_dereference(NFS_I(inode)->delegation);
> - if (delegation == NULL || memcmp(delegation->stateid.data, stateid->data,
> - sizeof(delegation->stateid.data)) != 0) {
> - rcu_read_unlock();
> - return -ENOENT;
> + if (delegation == NULL)
> + goto enoent;
> +
> + if (clp->cl_minorversion > 0) {
> + if (((u32 *) &stateid->data)[0] != 0)
> + goto enoent;
> + seqid_len = 4;
> }
> +
> + if (memcmp(&delegation->stateid.data[seqid_len],
> + &stateid->data[seqid_len],
> + sizeof(stateid->data)-seqid_len))
> + goto enoent;

cl_minorversion has nothing to do with generic delegation code. Please
just let the comparison be a pointer-to-function argument to
nfs_async_inode_return_delegation.

> +
> nfs_mark_return_delegation(clp, delegation);
> rcu_read_unlock();
> nfs_delegation_run_state_manager(clp);
> return 0;
> +enoent:
> + rcu_read_unlock();
> + return -ENOENT;
> }
>
> /*




2009-11-24 19:10:26

by Peter Staubach

[permalink] [raw]
Subject: Re: [PATCH 01/10] nfs41: adjust max_rqst_sz, max_resp_sz w.r.t to rsize, wsize

Trond Myklebust wrote:
> On Mon, 2009-11-23 at 13:54 -0800, Alexandros Batsakis wrote:
>> The v4.1 client should take into account the desired rsize, wsize when
>> negotiating the max size in CREATE_SESSION. Accordingly, it should use
>> rsize, wsize that are smaller than the session negotiated values.
>>
>> Signed-off-by: Alexandros Batsakis <[email protected]>
>> ---
>> fs/nfs/client.c | 14 ++++++++++----
>> fs/nfs/internal.h | 4 ++++
>> fs/nfs/nfs4proc.c | 7 +++++--
>> fs/nfs/nfs4xdr.c | 14 ++++++++++++++
>> 4 files changed, 33 insertions(+), 6 deletions(-)
>>
>> diff --git a/fs/nfs/client.c b/fs/nfs/client.c
>> index 99ea196..f360739 100644
>> --- a/fs/nfs/client.c
>> +++ b/fs/nfs/client.c
>> @@ -911,8 +911,10 @@ static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *
>>
>> server->maxfilesize = fsinfo->maxfilesize;
>>
>> - /* We're airborne Set socket buffersize */
>> - rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
>> + /* We're airborne Set socket buffersize. */
>> + if (!nfs4_has_session(server->nfs_client))
>> + rpc_setbufsize(server->client, server->wsize + 100,
>> + server->rsize + 100);
>> }
>
> Please move this out of generic NFS code.
>
> I really don't like this ugly proliferation of 'if (nfs4_has_session())'
> that appears to be creeping into every single function in the NFS client
> code.
>
>> /*
>> @@ -1260,10 +1262,14 @@ error:
>> static void nfs4_session_set_rwsize(struct nfs_server *server)
>> {
>> #ifdef CONFIG_NFS_V4_1
>> + struct nfs4_session *sess;
>> if (!nfs4_has_session(server->nfs_client))
>> return;
>> - server->rsize = server->nfs_client->cl_session->fc_attrs.max_resp_sz;
>> - server->wsize = server->nfs_client->cl_session->fc_attrs.max_rqst_sz;
>> + sess = server->nfs_client->cl_session;
>> + server->rsize = sess->fc_attrs.max_resp_sz - nfs41_maxread_overhead;
>> + server->wsize = sess->fc_attrs.max_rqst_sz - nfs41_maxwrite_overhead;
>
>
> For one thing, the r/wsize is conventionally set to be a power of 2,
> since most disks have block sizes of that form.
>
> Secondly, what if the server has given you a max_resp_sz/max_rqst_sz
> that is larger than what you asked for?
>
>> + rpc_setbufsize(server->client, sess->fc_attrs.max_rqst_sz,
>> + sess->fc_attrs.max_resp_sz);
>
> Is anyone ever going to use NFSv4.1 over UDP?
>

I thought that NFSv4 over UDP was outlawed because UDP, as
a transport, did not offer the correct set of semantics
required. I know that the Linux NFSv4 server registers
NFSv4 over UDP, but I don't know of any other servers which
do.

I was going to file a bug and a patch to stop NFSv4 from
being transported over UDP. :-)

Thanx...

ps

>> #endif /* CONFIG_NFS_V4_1 */
>> }
>>
>> diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
>> index e21b1bb..d946936 100644
>> --- a/fs/nfs/internal.h
>> +++ b/fs/nfs/internal.h
>> @@ -195,6 +195,10 @@ static inline void nfs4_restart_rpc(struct rpc_task *task,
>> #ifdef CONFIG_NFS_V4
>> extern __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus);
>> #endif
>> +#ifdef CONFIG_NFS_V4_1
>> +extern const u32 nfs41_maxread_overhead;
>> +extern const u32 nfs41_maxwrite_overhead;
>> +#endif
>>
>> /* nfs4proc.c */
>> #ifdef CONFIG_NFS_V4
>> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
>> index ff37454..ef77d40 100644
>> --- a/fs/nfs/nfs4proc.c
>> +++ b/fs/nfs/nfs4proc.c
>> @@ -4827,13 +4827,16 @@ int nfs4_proc_destroy_session(struct nfs4_session *session)
>> int nfs4_init_session(struct nfs_server *server)
>> {
>> struct nfs_client *clp = server->nfs_client;
>> + struct nfs4_session *session;
>> int ret;
>>
>> if (!nfs4_has_session(clp))
>> return 0;
>>
>> - clp->cl_session->fc_attrs.max_rqst_sz = server->wsize;
>> - clp->cl_session->fc_attrs.max_resp_sz = server->rsize;
>> + session = clp->cl_session;
>> + session->fc_attrs.max_rqst_sz = server->wsize + nfs41_maxwrite_overhead;
>> + session->fc_attrs.max_resp_sz = server->rsize + nfs41_maxread_overhead;
>> +
>> ret = nfs4_recover_expired_lease(server);
>> if (!ret)
>> ret = nfs4_check_client_ready(clp);
>> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
>> index 20b4e30..fc36af4 100644
>> --- a/fs/nfs/nfs4xdr.c
>> +++ b/fs/nfs/nfs4xdr.c
>> @@ -46,6 +46,7 @@
>> #include <linux/proc_fs.h>
>> #include <linux/kdev_t.h>
>> #include <linux/sunrpc/clnt.h>
>> +#include <linux/sunrpc/msg_prot.h>
>> #include <linux/nfs.h>
>> #include <linux/nfs4.h>
>> #include <linux/nfs_fs.h>
>> @@ -676,6 +677,19 @@ static int nfs4_stat_to_errno(int);
>> decode_sequence_maxsz + \
>> decode_putrootfh_maxsz + \
>> decode_fsinfo_maxsz)
>> +
>> +const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
>> + compound_encode_hdr_maxsz +
>> + encode_sequence_maxsz +
>> + encode_putfh_maxsz +
>> + encode_getattr_maxsz) *
>> + XDR_UNIT);
>> +
>> +const u32 nfs41_maxread_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
>> + compound_decode_hdr_maxsz +
>> + decode_sequence_maxsz +
>> + decode_putfh_maxsz) *
>> + XDR_UNIT);
>> #endif /* CONFIG_NFS_V4_1 */
>>
>> static const umode_t nfs_type2fmt[] = {
>> --
>> 1.6.2.5
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html


2009-11-24 20:38:44

by J. Bruce Fields

[permalink] [raw]
Subject: Re: [PATCH 01/10] nfs41: adjust max_rqst_sz, max_resp_sz w.r.t to rsize, wsize

On Tue, Nov 24, 2009 at 02:10:26PM -0500, Peter Staubach wrote:
> Trond Myklebust wrote:
> >
> > Is anyone ever going to use NFSv4.1 over UDP?
> >
>
> I thought that NFSv4 over UDP was outlawed because UDP, as
> a transport, did not offer the correct set of semantics
> required. I know that the Linux NFSv4 server registers
> NFSv4 over UDP, but I don't know of any other servers which
> do.
>
> I was going to file a bug and a patch to stop NFSv4 from
> being transported over UDP. :-)

OK by me.--b.