* [PATCH 02/46] nfs41: Add Kconfig symbols for NFSv4.1
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
@ 2009-03-03 23:51 ` Benny Halevy
2009-03-03 23:52 ` [PATCH 03/46] nfs41: define NFS4_MAX_MINOR_VERSION based on CONFIG_NFS_V4_1 Benny Halevy
` (43 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:51 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Ricardo Labiaga <ricardo.labiaga@netapp.com>
Added CONFIG_NFS_V4_1 and made it depend upon CONFIG_NFS_V4 and EXPERIMENTAL.
Indicate that CONFIG_NFS_V4_1 is for NFS developers at the moment
At the moment we're expecting folks trying out nfs41 to
actively participate in the development process by helping us
debug issues and ideally send patches to fix problems.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/Kconfig | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 36fe20d..055a0aa 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -74,6 +74,15 @@ config NFS_V4
If unsure, say N.
+config NFS_V4_1
+ bool "NFS client support for NFSv4.1 (DEVELOPER ONLY)"
+ depends on NFS_V4 && EXPERIMENTAL
+ help
+ This option enables support for minor version 1 of the NFSv4 protocol
+ (draft-ietf-nfsv4-minorversion1) in the kernel's NFS client.
+
+ Unless you're an NFS developer, say N.
+
config ROOT_NFS
bool "Root file system on NFS"
depends on NFS_FS=y && IP_PNP
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 03/46] nfs41: define NFS4_MAX_MINOR_VERSION based on CONFIG_NFS_V4_1
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
2009-03-03 23:51 ` [PATCH 02/46] nfs41: Add Kconfig symbols for NFSv4.1 Benny Halevy
@ 2009-03-03 23:52 ` Benny Halevy
2009-03-03 23:52 ` [PATCH 04/46] nfs41: nfs_client.cl_minorversion Benny Halevy
` (42 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:52 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Mike Sager <sager@netapp.com>
If 4.1 isn't supported, NFS4_MAX_MINOR_VERSION will be 0.
Signed-off-by: Mike Sager <sager@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
include/linux/nfs4.h | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index a64b41c..696cbec 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -448,6 +448,13 @@ enum lock_type4 {
#define NFSPROC4_NULL 0
#define NFSPROC4_COMPOUND 1
#define NFS4_MINOR_VERSION 0
+
+#if defined(CONFIG_NFS_V4_1)
+#define NFS4_MAX_MINOR_VERSION 1
+#else
+#define NFS4_MAX_MINOR_VERSION 0
+#endif /* CONFIG_NFS_V4_1 */
+
#define NFS4_DEBUG 1
/* Index of predefined Linux client operations */
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 04/46] nfs41: nfs_client.cl_minorversion
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
2009-03-03 23:51 ` [PATCH 02/46] nfs41: Add Kconfig symbols for NFSv4.1 Benny Halevy
2009-03-03 23:52 ` [PATCH 03/46] nfs41: define NFS4_MAX_MINOR_VERSION based on CONFIG_NFS_V4_1 Benny Halevy
@ 2009-03-03 23:52 ` Benny Halevy
2009-03-29 16:02 ` Trond Myklebust
2009-03-03 23:52 ` [PATCH 05/46] nfs41: add mount command option minorversion Benny Halevy
` (41 subsequent siblings)
44 siblings, 1 reply; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:52 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
This field is set to the nfsv4 minor version for this mount.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Note: This patch sets the referral to the same minorversion as the
current mount. Revisit in future patch.
Signed-off-by: Andy Adamson <andros@netapp.com>
[removed cl_minorversion assignment in nfs_set_client]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/client.c | 9 ++++++---
include/linux/nfs_fs_sb.h | 3 ++-
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 9b728f3..2555e48 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -1036,7 +1036,8 @@ static int nfs4_set_client(struct nfs_server *server,
const size_t addrlen,
const char *ip_addr,
rpc_authflavor_t authflavour,
- int proto, const struct rpc_timeout *timeparms)
+ int proto, const struct rpc_timeout *timeparms,
+ u32 minorversion)
{
struct nfs_client_initdata cl_init = {
.hostname = hostname,
@@ -1098,7 +1099,8 @@ static int nfs4_init_server(struct nfs_server *server,
data->client_address,
data->auth_flavors[0],
data->nfs_server.protocol,
- &timeparms);
+ &timeparms,
+ data->minorversion);
if (error < 0)
goto error;
@@ -1216,7 +1218,8 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
parent_client->cl_ipaddr,
data->authflavor,
parent_server->client->cl_xprt->prot,
- parent_server->client->cl_timeout);
+ parent_server->client->cl_timeout,
+ parent_client->cl_minorversion);
if (error < 0)
goto error;
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 9bb81ae..63f8b00 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -63,7 +63,8 @@ struct nfs_client {
*/
char cl_ipaddr[48];
unsigned char cl_id_uniquifier;
-#endif
+ u32 cl_minorversion;
+#endif /* CONFIG_NFS_V4 */
};
/*
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* Re: [PATCH 04/46] nfs41: nfs_client.cl_minorversion
2009-03-03 23:52 ` [PATCH 04/46] nfs41: nfs_client.cl_minorversion Benny Halevy
@ 2009-03-29 16:02 ` Trond Myklebust
[not found] ` <1238342562.10999.0.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
0 siblings, 1 reply; 63+ messages in thread
From: Trond Myklebust @ 2009-03-29 16:02 UTC (permalink / raw)
To: Benny Halevy; +Cc: linux-nfs, pnfs
On Tue, 2009-03-03 at 16:52 -0700, Benny Halevy wrote:
> This field is set to the nfsv4 minor version for this mount.
>
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
>
> Note: This patch sets the referral to the same minorversion as the
> current mount. Revisit in future patch.
>
> Signed-off-by: Andy Adamson <andros@netapp.com>
> [removed cl_minorversion assignment in nfs_set_client]
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> ---
> fs/nfs/client.c | 9 ++++++---
> include/linux/nfs_fs_sb.h | 3 ++-
> 2 files changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/fs/nfs/client.c b/fs/nfs/client.c
> index 9b728f3..2555e48 100644
> --- a/fs/nfs/client.c
> +++ b/fs/nfs/client.c
> @@ -1036,7 +1036,8 @@ static int nfs4_set_client(struct nfs_server
> *server,
> const size_t addrlen,
> const char *ip_addr,
> rpc_authflavor_t authflavour,
> - int proto, const struct rpc_timeout *timeparms)
> + int proto, const struct rpc_timeout *timeparms,
> + u32 minorversion)
> {
> struct nfs_client_initdata cl_init = {
> .hostname = hostname,
> @@ -1098,7 +1099,8 @@ static int nfs4_init_server(struct nfs_server
> *server,
> data->client_address,
> data->auth_flavors[0],
> data->nfs_server.protocol,
> - &timeparms);
> + &timeparms,
> + data->minorversion);
This can't compile. There is no minor version field in the mount
structure yet.
> if (error < 0)
> goto error;
>
> @@ -1216,7 +1218,8 @@ struct nfs_server
> *nfs4_create_referral_server(struct nfs_clone_mount *data,
> parent_client->cl_ipaddr,
> data->authflavor,
> parent_server->client->cl_xprt->prot,
> - parent_server->client->cl_timeout);
> + parent_server->client->cl_timeout,
> + parent_client->cl_minorversion);
> if (error < 0)
> goto error;
>
> diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
> index 9bb81ae..63f8b00 100644
> --- a/include/linux/nfs_fs_sb.h
> +++ b/include/linux/nfs_fs_sb.h
> @@ -63,7 +63,8 @@ struct nfs_client {
> */
> char cl_ipaddr[48];
> unsigned char cl_id_uniquifier;
> -#endif
> + u32 cl_minorversion;
> +#endif /* CONFIG_NFS_V4 */
> };
>
> /*
> --
> 1.6.1.3
>
>
>
--
Trond Myklebust
Linux NFS client maintainer
NetApp
Trond.Myklebust@netapp.com
www.netapp.com
^ permalink raw reply [flat|nested] 63+ messages in thread
* [PATCH 05/46] nfs41: add mount command option minorversion
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (2 preceding siblings ...)
2009-03-03 23:52 ` [PATCH 04/46] nfs41: nfs_client.cl_minorversion Benny Halevy
@ 2009-03-03 23:52 ` Benny Halevy
2009-03-29 16:18 ` Trond Myklebust
2009-03-03 23:52 ` [PATCH 06/46] nfs41: Use mount minorversion option Benny Halevy
` (40 subsequent siblings)
44 siblings, 1 reply; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:52 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Mike Sager <sager@netapp.com>
mount -t nfs4 -o minorversion=[0|1] specifies whether to use 4.0 or 4.1.
By default, the minorversion is set to 0.
Signed-off-by: Mike Sager <sager@netapp.com>
[set default minorversion to 0 as per Trond and SteveD's request]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/internal.h | 1 +
fs/nfs/super.c | 10 ++++++++++
2 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 340ede8..73e4d9f 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -41,6 +41,7 @@ struct nfs_parsed_mount_data {
unsigned int auth_flavor_len;
rpc_authflavor_t auth_flavors[1];
char *client_address;
+ unsigned int minorversion;
struct {
struct sockaddr_storage address;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index d6686f4..5db4e3b 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -88,6 +88,7 @@ enum {
Opt_mountport,
Opt_mountvers,
Opt_nfsvers,
+ Opt_minorversion,
/* Mount options that take string arguments */
Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,
@@ -149,6 +150,7 @@ static const match_table_t nfs_mount_option_tokens = {
{ Opt_mountvers, "mountvers=%u" },
{ Opt_nfsvers, "nfsvers=%u" },
{ Opt_nfsvers, "vers=%u" },
+ { Opt_minorversion, "minorversion=%u" },
{ Opt_sec, "sec=%s" },
{ Opt_proto, "proto=%s" },
@@ -1168,6 +1170,13 @@ static int nfs_parse_mount_options(char *raw,
nfs_parse_invalid_value("nfsvers");
}
break;
+ case Opt_minorversion:
+ if (match_int(args, &option))
+ return 0;
+ if (option < 0 || option > NFS4_MAX_MINOR_VERSION)
+ return 0;
+ mnt->minorversion = option;
+ break;
/*
* options that take text values
@@ -2218,6 +2227,7 @@ static int nfs4_validate_mount_data(void *options,
args->nfs_server.port = NFS_PORT; /* 2049 unless user set port= */
args->auth_flavors[0] = RPC_AUTH_UNIX;
args->auth_flavor_len = 0;
+ args->minorversion = 0;
switch (data->version) {
case 1:
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* Re: [PATCH 05/46] nfs41: add mount command option minorversion
2009-03-03 23:52 ` [PATCH 05/46] nfs41: add mount command option minorversion Benny Halevy
@ 2009-03-29 16:18 ` Trond Myklebust
[not found] ` <1238343501.10999.6.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
0 siblings, 1 reply; 63+ messages in thread
From: Trond Myklebust @ 2009-03-29 16:18 UTC (permalink / raw)
To: Benny Halevy; +Cc: linux-nfs, pnfs
On Tue, 2009-03-03 at 16:52 -0700, Benny Halevy wrote:
> From: Mike Sager <sager@netapp.com>
>
> mount -t nfs4 -o minorversion=[0|1] specifies whether to use 4.0 or
> 4.1.
> By default, the minorversion is set to 0.
>
> Signed-off-by: Mike Sager <sager@netapp.com>
> [set default minorversion to 0 as per Trond and SteveD's request]
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> ---
> fs/nfs/internal.h | 1 +
> fs/nfs/super.c | 10 ++++++++++
> 2 files changed, 11 insertions(+), 0 deletions(-)
>
> diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
> index 340ede8..73e4d9f 100644
> --- a/fs/nfs/internal.h
> +++ b/fs/nfs/internal.h
> @@ -41,6 +41,7 @@ struct nfs_parsed_mount_data {
> unsigned int auth_flavor_len;
> rpc_authflavor_t auth_flavors[1];
> char *client_address;
> + unsigned int minorversion;
>
> struct {
> struct sockaddr_storage address;
> diff --git a/fs/nfs/super.c b/fs/nfs/super.c
> index d6686f4..5db4e3b 100644
> --- a/fs/nfs/super.c
> +++ b/fs/nfs/super.c
> @@ -88,6 +88,7 @@ enum {
> Opt_mountport,
> Opt_mountvers,
> Opt_nfsvers,
> + Opt_minorversion,
>
> /* Mount options that take string arguments */
> Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,
> @@ -149,6 +150,7 @@ static const match_table_t nfs_mount_option_tokens
> = {
> { Opt_mountvers, "mountvers=%u" },
> { Opt_nfsvers, "nfsvers=%u" },
> { Opt_nfsvers, "vers=%u" },
> + { Opt_minorversion, "minorversion=%u" },
>
> { Opt_sec, "sec=%s" },
> { Opt_proto, "proto=%s" },
> @@ -1168,6 +1170,13 @@ static int nfs_parse_mount_options(char *raw,
> nfs_parse_invalid_value("nfsvers");
> }
> break;
> + case Opt_minorversion:
> + if (match_int(args, &option))
> + return 0;
> + if (option < 0 || option >
> NFS4_MAX_MINOR_VERSION)
> + return 0;
> + mnt->minorversion = option;
There is nothing preventing the user from setting this on NFSv2 or
NFSv3. That will cause nfs_match_client() to get confused.
> + break;
>
> /*
> * options that take text values
> @@ -2218,6 +2227,7 @@ static int nfs4_validate_mount_data(void
> *options,
> args->nfs_server.port = NFS_PORT; /* 2049 unless user set
> port= */
> args->auth_flavors[0] = RPC_AUTH_UNIX;
> args->auth_flavor_len = 0;
> + args->minorversion = 0;
>
> switch (data->version) {
> case 1:
> --
> 1.6.1.3
>
>
>
--
Trond Myklebust
Linux NFS client maintainer
NetApp
Trond.Myklebust@netapp.com
www.netapp.com
^ permalink raw reply [flat|nested] 63+ messages in thread
* [PATCH 06/46] nfs41: Use mount minorversion option
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (3 preceding siblings ...)
2009-03-03 23:52 ` [PATCH 05/46] nfs41: add mount command option minorversion Benny Halevy
@ 2009-03-03 23:52 ` Benny Halevy
2009-03-29 16:16 ` Trond Myklebust
2009-03-03 23:52 ` [PATCH 07/46] nfs41: translate NFS4ERR_MINOR_VERS_MISMATCH to EPROTONOSUPPORT Benny Halevy
` (39 subsequent siblings)
44 siblings, 1 reply; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:52 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
Use the mount minorversion option to initialize the nfs_client cl_minorversion
and match it in nfs_match_client() when looking up a nfs_client.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/client.c | 11 ++++++++++-
1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 2555e48..e9f002f 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -101,6 +101,9 @@ struct nfs_client_initdata {
size_t addrlen;
const struct nfs_rpc_ops *rpc_ops;
int proto;
+#ifdef CONFIG_NFS_V4
+ u32 minorversion;
+#endif
};
/*
@@ -149,6 +152,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
clp->cl_boot_time = CURRENT_TIME;
clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
+ clp->cl_minorversion = cl_init->minorversion;
#endif
cred = rpc_lookup_machine_cred();
if (!IS_ERR(cred))
@@ -356,7 +360,11 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
if (clp->cl_proto != data->proto)
continue;
-
+#ifdef CONFIG_NFS_V4
+ /* Match minorversion */
+ if (clp->cl_minorversion != data->minorversion)
+ continue;
+#endif
/* Match the full socket address */
if (memcmp(&clp->cl_addr, data->addr, sizeof(clp->cl_addr)) != 0)
continue;
@@ -1045,6 +1053,7 @@ static int nfs4_set_client(struct nfs_server *server,
.addrlen = addrlen,
.rpc_ops = &nfs_v4_clientops,
.proto = proto,
+ .minorversion = minorversion,
};
struct nfs_client *clp;
int error;
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* Re: [PATCH 06/46] nfs41: Use mount minorversion option
2009-03-03 23:52 ` [PATCH 06/46] nfs41: Use mount minorversion option Benny Halevy
@ 2009-03-29 16:16 ` Trond Myklebust
0 siblings, 0 replies; 63+ messages in thread
From: Trond Myklebust @ 2009-03-29 16:16 UTC (permalink / raw)
To: Benny Halevy; +Cc: linux-nfs, pnfs
On Tue, 2009-03-03 at 16:52 -0700, Benny Halevy wrote:
> Use the mount minorversion option to initialize the nfs_client
> cl_minorversion
> and match it in nfs_match_client() when looking up a nfs_client.
>
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> ---
> fs/nfs/client.c | 11 ++++++++++-
> 1 files changed, 10 insertions(+), 1 deletions(-)
>
> diff --git a/fs/nfs/client.c b/fs/nfs/client.c
> index 2555e48..e9f002f 100644
> --- a/fs/nfs/client.c
> +++ b/fs/nfs/client.c
> @@ -101,6 +101,9 @@ struct nfs_client_initdata {
> size_t addrlen;
> const struct nfs_rpc_ops *rpc_ops;
> int proto;
> +#ifdef CONFIG_NFS_V4
> + u32 minorversion;
> +#endif
> };
>
> /*
> @@ -149,6 +152,7 @@ static struct nfs_client *nfs_alloc_client(const
> struct nfs_client_initdata *cl_
> rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
> clp->cl_boot_time = CURRENT_TIME;
> clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
> + clp->cl_minorversion = cl_init->minorversion;
> #endif
> cred = rpc_lookup_machine_cred();
> if (!IS_ERR(cred))
> @@ -356,7 +360,11 @@ static struct nfs_client *nfs_match_client(const
> struct nfs_client_initdata *dat
>
> if (clp->cl_proto != data->proto)
> continue;
> -
> +#ifdef CONFIG_NFS_V4
> + /* Match minorversion */
> + if (clp->cl_minorversion != data->minorversion)
> + continue;
> +#endif
This is really ugly and unnecessary. Please just remove those ifdefs,
and have clp->cl_minorversion data->minorversion always defined, and set
to 0.
> /* Match the full socket address */
> if (memcmp(&clp->cl_addr, data->addr,
> sizeof(clp->cl_addr)) != 0)
> continue;
> @@ -1045,6 +1053,7 @@ static int nfs4_set_client(struct nfs_server
> *server,
> .addrlen = addrlen,
> .rpc_ops = &nfs_v4_clientops,
> .proto = proto,
> + .minorversion = minorversion,
> };
> struct nfs_client *clp;
> int error;
> --
> 1.6.1.3
>
>
>
--
Trond Myklebust
Linux NFS client maintainer
NetApp
Trond.Myklebust@netapp.com
www.netapp.com
^ permalink raw reply [flat|nested] 63+ messages in thread
* [PATCH 07/46] nfs41: translate NFS4ERR_MINOR_VERS_MISMATCH to EPROTONOSUPPORT
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (4 preceding siblings ...)
2009-03-03 23:52 ` [PATCH 06/46] nfs41: Use mount minorversion option Benny Halevy
@ 2009-03-03 23:52 ` Benny Halevy
2009-03-03 23:53 ` [PATCH 08/46] nfs41: client xdr definitions Benny Halevy
` (38 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:52 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
To be returned to the mount command when trying to mount a v4 server
using minorversion 1.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4state.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 2022fe4..42e60b6 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1101,6 +1101,8 @@ static int nfs4_reclaim_lease(struct nfs_client *clp)
nfs4_clear_machine_cred(clp);
status = -EAGAIN;
}
+ if (status == -NFS4ERR_MINOR_VERS_MISMATCH)
+ status = -EPROTONOSUPPORT;
}
return status;
}
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 08/46] nfs41: client xdr definitions
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (5 preceding siblings ...)
2009-03-03 23:52 ` [PATCH 07/46] nfs41: translate NFS4ERR_MINOR_VERS_MISMATCH to EPROTONOSUPPORT Benny Halevy
@ 2009-03-03 23:53 ` Benny Halevy
2009-03-03 23:53 ` [PATCH 09/46] nfs41: sessions client infrastructure Benny Halevy
` (37 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:53 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
Define stubs for sequence args and res data structures and embed
them in all other nfs4 and nfs41 xdr types. They are needed for
sending any op in a nfs41 compound rpc.
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
include/linux/nfs_xdr.h | 99 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 99 insertions(+), 0 deletions(-)
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index a550b52..c137ca0 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -113,6 +113,24 @@ struct nfs4_change_info {
};
struct nfs_seqid;
+
+struct nfs4_sequence_args {
+ /* stub */
+};
+
+struct nfs4_sequence_res {
+ /* stub */
+};
+
+struct nfs4_get_lease_time_args {
+ struct nfs4_sequence_args la_seq_args;
+};
+
+struct nfs4_get_lease_time_res {
+ struct nfs_fsinfo *lr_fsinfo;
+ struct nfs4_sequence_res lr_seq_res;
+};
+
/*
* Arguments to the open call.
*/
@@ -133,6 +151,7 @@ struct nfs_openargs {
const struct nfs_server *server; /* Needed for ID mapping */
const u32 * bitmask;
__u32 claim;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_openres {
@@ -149,6 +168,7 @@ struct nfs_openres {
__u32 do_recall;
__u64 maxsize;
__u32 attrset[NFS4_BITMAP_SIZE];
+ struct nfs4_sequence_res seq_res;
};
/*
@@ -174,6 +194,7 @@ struct nfs_closeargs {
struct nfs_seqid * seqid;
fmode_t fmode;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_closeres {
@@ -181,6 +202,7 @@ struct nfs_closeres {
struct nfs_fattr * fattr;
struct nfs_seqid * seqid;
const struct nfs_server *server;
+ struct nfs4_sequence_res seq_res;
};
/*
* * Arguments to the lock,lockt, and locku call.
@@ -201,12 +223,14 @@ struct nfs_lock_args {
unsigned char block : 1;
unsigned char reclaim : 1;
unsigned char new_lock_owner : 1;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_lock_res {
nfs4_stateid stateid;
struct nfs_seqid * lock_seqid;
struct nfs_seqid * open_seqid;
+ struct nfs4_sequence_res seq_res;
};
struct nfs_locku_args {
@@ -214,32 +238,38 @@ struct nfs_locku_args {
struct file_lock * fl;
struct nfs_seqid * seqid;
nfs4_stateid * stateid;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_locku_res {
nfs4_stateid stateid;
struct nfs_seqid * seqid;
+ struct nfs4_sequence_res seq_res;
};
struct nfs_lockt_args {
struct nfs_fh * fh;
struct file_lock * fl;
struct nfs_lowner lock_owner;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_lockt_res {
struct file_lock * denied; /* LOCK, LOCKT failed */
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_delegreturnargs {
const struct nfs_fh *fhandle;
const nfs4_stateid *stateid;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_delegreturnres {
struct nfs_fattr * fattr;
const struct nfs_server *server;
+ struct nfs4_sequence_res seq_res;
};
/*
@@ -252,12 +282,14 @@ struct nfs_readargs {
__u32 count;
unsigned int pgbase;
struct page ** pages;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_readres {
struct nfs_fattr * fattr;
__u32 count;
int eof;
+ struct nfs4_sequence_res seq_res;
};
/*
@@ -272,6 +304,7 @@ struct nfs_writeargs {
unsigned int pgbase;
struct page ** pages;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_writeverf {
@@ -284,6 +317,7 @@ struct nfs_writeres {
struct nfs_writeverf * verf;
__u32 count;
const struct nfs_server *server;
+ struct nfs4_sequence_res seq_res;
};
/*
@@ -293,12 +327,14 @@ struct nfs_removeargs {
const struct nfs_fh *fh;
struct qstr name;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_removeres {
const struct nfs_server *server;
struct nfs4_change_info cinfo;
struct nfs_fattr dir_attr;
+ struct nfs4_sequence_res seq_res;
};
/*
@@ -351,6 +387,7 @@ struct nfs_setattrargs {
struct iattr * iap;
const struct nfs_server * server; /* Needed for name mapping */
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs_setaclargs {
@@ -358,6 +395,11 @@ struct nfs_setaclargs {
size_t acl_len;
unsigned int acl_pgbase;
struct page ** acl_pages;
+ struct nfs4_sequence_args seq_args;
+};
+
+struct nfs_setaclres {
+ struct nfs4_sequence_res seq_res;
};
struct nfs_getaclargs {
@@ -365,11 +407,18 @@ struct nfs_getaclargs {
size_t acl_len;
unsigned int acl_pgbase;
struct page ** acl_pages;
+ struct nfs4_sequence_args seq_args;
+};
+
+struct nfs_getaclres {
+ size_t *acl_len;
+ struct nfs4_sequence_res seq_res;
};
struct nfs_setattrres {
struct nfs_fattr * fattr;
const struct nfs_server * server;
+ struct nfs4_sequence_res seq_res;
};
struct nfs_linkargs {
@@ -549,6 +598,7 @@ struct nfs4_accessargs {
const struct nfs_fh * fh;
const u32 * bitmask;
u32 access;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_accessres {
@@ -556,6 +606,7 @@ struct nfs4_accessres {
struct nfs_fattr * fattr;
u32 supported;
u32 access;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_create_arg {
@@ -575,6 +626,7 @@ struct nfs4_create_arg {
const struct iattr * attrs;
const struct nfs_fh * dir_fh;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_create_res {
@@ -583,21 +635,30 @@ struct nfs4_create_res {
struct nfs_fattr * fattr;
struct nfs4_change_info dir_cinfo;
struct nfs_fattr * dir_fattr;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_fsinfo_arg {
const struct nfs_fh * fh;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
+};
+
+struct nfs4_fsinfo_res {
+ struct nfs_fsinfo *fsinfo;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_getattr_arg {
const struct nfs_fh * fh;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_getattr_res {
const struct nfs_server * server;
struct nfs_fattr * fattr;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_link_arg {
@@ -605,6 +666,7 @@ struct nfs4_link_arg {
const struct nfs_fh * dir_fh;
const struct qstr * name;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_link_res {
@@ -612,6 +674,7 @@ struct nfs4_link_res {
struct nfs_fattr * fattr;
struct nfs4_change_info cinfo;
struct nfs_fattr * dir_attr;
+ struct nfs4_sequence_res seq_res;
};
@@ -619,21 +682,30 @@ struct nfs4_lookup_arg {
const struct nfs_fh * dir_fh;
const struct qstr * name;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_lookup_res {
const struct nfs_server * server;
struct nfs_fattr * fattr;
struct nfs_fh * fh;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_lookup_root_arg {
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_pathconf_arg {
const struct nfs_fh * fh;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
+};
+
+struct nfs4_pathconf_res {
+ struct nfs_pathconf *pathconf;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_readdir_arg {
@@ -644,11 +716,13 @@ struct nfs4_readdir_arg {
struct page ** pages; /* zero-copy data */
unsigned int pgbase; /* zero-copy data */
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_readdir_res {
nfs4_verifier verifier;
unsigned int pgbase;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_readlink {
@@ -656,6 +730,11 @@ struct nfs4_readlink {
unsigned int pgbase;
unsigned int pglen; /* zero-copy data */
struct page ** pages; /* zero-copy data */
+ struct nfs4_sequence_args seq_args;
+};
+
+struct nfs4_readlink_res {
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_rename_arg {
@@ -664,6 +743,7 @@ struct nfs4_rename_arg {
const struct qstr * old_name;
const struct qstr * new_name;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_rename_res {
@@ -672,6 +752,7 @@ struct nfs4_rename_res {
struct nfs_fattr * old_fattr;
struct nfs4_change_info new_cinfo;
struct nfs_fattr * new_fattr;
+ struct nfs4_sequence_res seq_res;
};
#define NFS4_SETCLIENTID_NAMELEN (127)
@@ -690,6 +771,17 @@ struct nfs4_setclientid {
struct nfs4_statfs_arg {
const struct nfs_fh * fh;
const u32 * bitmask;
+ struct nfs4_sequence_args seq_args;
+};
+
+struct nfs4_statfs_res {
+ struct nfs_fsstat *fsstat;
+ struct nfs4_sequence_res seq_res;
+};
+
+struct nfs4_server_caps_arg {
+ struct nfs_fh *fhandle;
+ struct nfs4_sequence_args seq_args;
};
struct nfs4_server_caps_res {
@@ -697,6 +789,7 @@ struct nfs4_server_caps_res {
u32 acl_bitmask;
u32 has_links;
u32 has_symlinks;
+ struct nfs4_sequence_res seq_res;
};
struct nfs4_string {
@@ -731,6 +824,12 @@ struct nfs4_fs_locations_arg {
const struct qstr *name;
struct page *page;
const u32 *bitmask;
+ struct nfs4_sequence_args seq_args;
+};
+
+struct nfs4_fs_locations_res {
+ struct nfs4_fs_locations *fs_locations;
+ struct nfs4_sequence_res seq_res;
};
#endif /* CONFIG_NFS_V4 */
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 09/46] nfs41: sessions client infrastructure
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (6 preceding siblings ...)
2009-03-03 23:53 ` [PATCH 08/46] nfs41: client xdr definitions Benny Halevy
@ 2009-03-03 23:53 ` Benny Halevy
2009-03-29 16:31 ` Trond Myklebust
2009-03-03 23:53 ` [PATCH 10/46] nfs41: find slot Benny Halevy
` (36 subsequent siblings)
44 siblings, 1 reply; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:53 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
NFSv4.1 Sessions basic data types, initialization, and destruction.
The session is always associated with a struct nfs_client that holds
the exchange_id results.
Signed-off-by: Rahul Iyer <iyer@netapp.com>
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[remove extraneous rpc_clnt pointer, use the struct nfs_client cl_rpcclient.
remove the rpc_clnt parameter from nfs4 nfs4_init_session]
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[Use the presence of a session to determine behaviour instead of the
minorversion number.]
Signed-off-by: Andy Adamson <andros@netapp.com>
[constified nfs4_has_session's struct nfs_client parameter]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[Rename nfs4_put_session() to nfs4_destroy_session() and call it from nfs4_free_client() not nfs4_free_server().
Also get rid of nfs4_get_session() and the ref_count in nfs4_session struct as keeping track of nfs_client should be sufficient]
Signed-off-by: Alexandros Batsakis <Alexandros.Batsakis@netapp.com>
[nfs41: pass rsize and wsize into nfs4_init_session]
In preparation to use r/wsize for session channel initialization.
Note: The filelayout data server calls nfs4_init_session without a struct
nfs_server, so we can't reduce the parameters to just an nfs_server pointer.
Signed-off-by: Andy Adamson <andros@netapp.com>
[separated out removal of rpc_clnt parameter from nfs4_init_session ot a
patch of its own]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[Pass the nfs_client pointer into nfs4_alloc_session]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: don't assign to session->clp->cl_session in nfs4_destroy_session]
[nfs41: fixup nfs4_clear_client_minor_version]
[introduce nfs4_clear_client_minor_version() in this patch]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Refactor nfs4_init_session:
Moved session allocation into nfs4_init_client_minor_version, called from
nfs4_init_client.
Leave rwise and wsize initialization in nfs4_init_session, called from
nfs4_init_server.
Reverted moving of nfs_fsid definition to nfs_fs_sb.h
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: Move NFS4_MAX_SLOT_TABLE define from under CONFIG_NFS_V4_1]
Fix comile error when CONFIG_NFS_V4_1 is not set.
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/client.c | 60 +++++++++++++++++++++++++++++++++++
fs/nfs/internal.h | 12 +++++++
fs/nfs/nfs4_fs.h | 4 ++
fs/nfs/nfs4proc.c | 77 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/nfs_fs_sb.h | 49 ++++++++++++++++++++++++++++
include/linux/nfs_xdr.h | 15 +++++++++
6 files changed, 217 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index e9f002f..c1536d9 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -183,12 +183,27 @@ static void nfs4_shutdown_client(struct nfs_client *clp)
}
/*
+ * Clears/puts all minor version specific parts from an nfs_client struct
+ * reverting it to minorversion 0.
+ */
+static void nfs4_clear_client_minor_version(struct nfs_client *clp)
+{
+#ifdef CONFIG_NFS_V4_1
+ if (nfs4_has_session(clp)) {
+ nfs4_destroy_session(clp->cl_session);
+ clp->cl_session = NULL;
+ }
+#endif /* CONFIG_NFS_V4_1 */
+}
+
+/*
* Destroy a shared client record
*/
static void nfs_free_client(struct nfs_client *clp)
{
dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version);
+ nfs4_clear_client_minor_version(clp);
nfs4_shutdown_client(clp);
/* -EIO all pending I/O */
@@ -993,6 +1008,30 @@ error:
#ifdef CONFIG_NFS_V4
/*
+ * Initialize the minor version specific parts of an NFS4 client record
+ */
+static int nfs4_init_client_minor_version(struct nfs_client *clp)
+{
+#if defined(CONFIG_NFS_V4_1)
+ if (clp->cl_minorversion) {
+ struct nfs4_session *session = NULL;
+ /*
+ * Create the session and mark it expired.
+ * When a SEQUENCE operation encounters the expired session
+ * it will do session recovery to initialize it.
+ */
+ session = nfs4_alloc_session(clp);
+ if (!session)
+ return -ENOMEM;
+
+ clp->cl_session = session;
+ }
+#endif /* CONFIG_NFS_V4_1 */
+
+ return 0;
+}
+
+/*
* Initialise an NFS4 client record
*/
static int nfs4_init_client(struct nfs_client *clp,
@@ -1026,6 +1065,10 @@ static int nfs4_init_client(struct nfs_client *clp,
}
__set_bit(NFS_CS_IDMAP, &clp->cl_res_state);
+ error = nfs4_init_client_minor_version(clp);
+ if (error < 0)
+ goto error;
+
nfs_mark_client_ready(clp, NFS_CS_READY);
return 0;
@@ -1083,6 +1126,21 @@ error:
}
/*
+ * Initialize a session.
+ * Note: save the mount rsize and wsize for create_server negotiation.
+ */
+static void nfs4_init_session(struct nfs_client *clp,
+ unsigned int wsize, unsigned int rsize)
+{
+#if defined(CONFIG_NFS_V4_1)
+ if (nfs4_has_session(clp)) {
+ clp->cl_session->fc_attrs.max_rqst_sz = wsize;
+ clp->cl_session->fc_attrs.max_resp_sz = rsize;
+ }
+#endif /* CONFIG_NFS_V4_1 */
+}
+
+/*
* Create a version 4 volume record
*/
static int nfs4_init_server(struct nfs_server *server,
@@ -1159,6 +1217,8 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
BUG_ON(!server->nfs_client->rpc_ops);
BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
+ nfs4_init_session(server->nfs_client, server->wsize, server->rsize);
+
/* Probe the root fh to retrieve its FSID */
error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path);
if (error < 0)
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 73e4d9f..b7fc8d4 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -199,6 +199,18 @@ extern int nfs4_path_walk(struct nfs_server *server,
#endif
/*
+ * Determine if sessions are in use.
+ */
+static inline int nfs4_has_session(const struct nfs_client *clp)
+{
+#ifdef CONFIG_NFS_V4_1
+ if (clp->cl_session)
+ return 1;
+#endif /* CONFIG_NFS_V4_1 */
+ return 0;
+}
+
+/*
* Determine the device name as a string
*/
static inline char *nfs_devname(const struct vfsmount *mnt_parent,
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 4e4d332..5d7b036 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -202,6 +202,10 @@ extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
extern struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops;
+#if defined(CONFIG_NFS_V4_1)
+extern void nfs4_destroy_session(struct nfs4_session *session);
+extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp);
+#endif /* CONFIG_NFS_V4_1 */
extern const u32 nfs4_fattr_bitmap[2];
extern const u32 nfs4_statfs_bitmap[2];
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 8dde84b..c12cf91 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3708,6 +3708,83 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
return status;
}
+#ifdef CONFIG_NFS_V4_1
+/*
+ * Initialize slot table
+ */
+static int nfs4_init_slot_table(struct nfs4_session *session)
+{
+ struct nfs4_slot_table *tbl = &session->fc_slot_table;
+ int i, max_slots = session->fc_attrs.max_reqs;
+ struct nfs4_slot *slot;
+ int ret = -ENOMEM;
+
+ BUG_ON(max_slots > NFS4_MAX_SLOT_TABLE);
+
+ dprintk("--> %s: max_reqs=%u\n", __func__,
+ session->fc_attrs.max_reqs);
+
+ slot = kzalloc(max_slots * sizeof(struct nfs4_slot), GFP_ATOMIC);
+ if (!slot)
+ goto out;
+ for (i = 0; i < max_slots; ++i)
+ slot[i].seq_nr = 1;
+ ret = 0;
+
+ spin_lock(&tbl->slot_tbl_lock);
+ if (tbl->slots != NULL) {
+ spin_unlock(&tbl->slot_tbl_lock);
+ dprintk("%s: slot table already initialized. tbl=%p slots=%p\n",
+ __func__, tbl, tbl->slots);
+ WARN_ON(1);
+ goto out_free;
+ }
+ tbl->max_slots = max_slots;
+ tbl->slots = slot;
+ tbl->highest_used_slotid = -1; /* no slot is currently used */
+ spin_unlock(&tbl->slot_tbl_lock);
+ dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
+ tbl, tbl->slots, tbl->max_slots);
+out:
+ dprintk("<-- %s: return %d\n", __func__, ret);
+ return ret;
+out_free:
+ kfree(slot);
+ goto out;
+}
+/* Destroy the slot table */
+static void nfs4_destroy_slot_table(struct nfs4_session *session)
+{
+ if (session->fc_slot_table.slots == NULL)
+ return;
+ kfree(session->fc_slot_table.slots);
+ session->fc_slot_table.slots = NULL;
+ return;
+}
+
+struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
+{
+ struct nfs4_session *session;
+ struct nfs4_slot_table *tbl;
+
+ session = kzalloc(sizeof(struct nfs4_session), GFP_ATOMIC);
+ if (!session)
+ return NULL;
+ tbl = &session->fc_slot_table;
+ spin_lock_init(&tbl->slot_tbl_lock);
+ rpc_init_wait_queue(&tbl->slot_tbl_waitq, "Slot table");
+ session->clp = clp;
+ return session;
+}
+
+void nfs4_destroy_session(struct nfs4_session *session)
+{
+ nfs4_destroy_slot_table(session);
+ kfree(session);
+}
+
+#endif /* CONFIG_NFS_V4_1 */
+
struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = {
.owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT,
.state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 63f8b00..5673eac 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -4,9 +4,12 @@
#include <linux/list.h>
#include <linux/backing-dev.h>
#include <linux/wait.h>
+#include <linux/nfs_xdr.h>
+#include <linux/sunrpc/xprt.h>
#include <asm/atomic.h>
+struct nfs4_session;
struct nfs_iostats;
struct nlm_host;
@@ -65,6 +68,10 @@ struct nfs_client {
unsigned char cl_id_uniquifier;
u32 cl_minorversion;
#endif /* CONFIG_NFS_V4 */
+
+#ifdef CONFIG_NFS_V4_1
+ struct nfs4_session *cl_session; /* sharred session */
+#endif /* CONFIG_NFS_V4_1 */
};
/*
@@ -130,4 +137,46 @@ struct nfs_server {
#define NFS_CAP_ACLS (1U << 3)
#define NFS_CAP_ATOMIC_OPEN (1U << 4)
+
+/* maximum number of slots to use */
+#define NFS4_MAX_SLOT_TABLE RPC_MAX_SLOT_TABLE
+
+#if defined(CONFIG_NFS_V4_1)
+
+/* Sessions */
+#define SLOT_TABLE_SZ (NFS4_MAX_SLOT_TABLE/(8*sizeof(long)))
+struct nfs4_slot_table {
+ struct nfs4_slot *slots; /* seqid per slot */
+ unsigned long used_slots[SLOT_TABLE_SZ]; /* used/unused bitmap */
+ spinlock_t slot_tbl_lock;
+ struct rpc_wait_queue slot_tbl_waitq; /* allocators may wait here */
+ int max_slots; /* # slots in table */
+ int highest_used_slotid; /* sent to server on each SEQ.
+ * op for dynamic resizing */
+};
+
+static inline int slot_idx(struct nfs4_slot_table *tbl, struct nfs4_slot *sp)
+{
+ return sp - tbl->slots;
+}
+
+/*
+ * Session related parameters
+ */
+struct nfs4_session {
+ struct nfs4_sessionid sess_id;
+ u32 flags;
+ unsigned long session_state;
+ u32 hash_alg;
+ u32 ssv_len;
+
+ /* The fore and back channel */
+ struct nfs4_channel_attrs fc_attrs;
+ struct nfs4_slot_table fc_slot_table;
+ struct nfs4_channel_attrs bc_attrs;
+ /* back channel has one slot */
+ struct nfs_client *clp;
+};
+
+#endif /* CONFIG_NFS_V4_1 */
#endif
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index c137ca0..16bef5d 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -114,6 +114,21 @@ struct nfs4_change_info {
struct nfs_seqid;
+/* nfs41 sessions channel attributes */
+struct nfs4_channel_attrs {
+ u32 headerpadsz;
+ u32 max_rqst_sz;
+ u32 max_resp_sz;
+ u32 max_resp_sz_cached;
+ u32 max_ops;
+ u32 max_reqs;
+};
+
+/* nfs41 sessions slot seqid */
+struct nfs4_slot {
+ u32 seq_nr;
+};
+
struct nfs4_sequence_args {
/* stub */
};
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* Re: [PATCH 09/46] nfs41: sessions client infrastructure
2009-03-03 23:53 ` [PATCH 09/46] nfs41: sessions client infrastructure Benny Halevy
@ 2009-03-29 16:31 ` Trond Myklebust
[not found] ` <1238344265.10999.14.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
0 siblings, 1 reply; 63+ messages in thread
From: Trond Myklebust @ 2009-03-29 16:31 UTC (permalink / raw)
To: Benny Halevy; +Cc: linux-nfs, pnfs
On Tue, 2009-03-03 at 16:53 -0700, Benny Halevy wrote:
> From: Andy Adamson <andros@netapp.com>
>
> NFSv4.1 Sessions basic data types, initialization, and destruction.
>
> The session is always associated with a struct nfs_client that holds
> the exchange_id results.
>
> Signed-off-by: Rahul Iyer <iyer@netapp.com>
> Signed-off-by: Andy Adamson<andros@netapp.com>
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> [remove extraneous rpc_clnt pointer, use the struct nfs_client
> cl_rpcclient.
> remove the rpc_clnt parameter from nfs4 nfs4_init_session]
> Signed-off-by: Andy Adamson<andros@netapp.com>
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> [Use the presence of a session to determine behaviour instead of the
> minorversion number.]
> Signed-off-by: Andy Adamson <andros@netapp.com>
> [constified nfs4_has_session's struct nfs_client parameter]
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> [Rename nfs4_put_session() to nfs4_destroy_session() and call it from
> nfs4_free_client() not nfs4_free_server().
> Also get rid of nfs4_get_session() and the ref_count in nfs4_session
> struct as keeping track of nfs_client should be sufficient]
> Signed-off-by: Alexandros Batsakis <Alexandros.Batsakis@netapp.com>
> [nfs41: pass rsize and wsize into nfs4_init_session]
> In preparation to use r/wsize for session channel initialization.
>
> Note: The filelayout data server calls nfs4_init_session without a
> struct
> nfs_server, so we can't reduce the parameters to just an
> nfs_server pointer.
> Signed-off-by: Andy Adamson <andros@netapp.com>
> [separated out removal of rpc_clnt parameter from nfs4_init_session ot
> a
> patch of its own]
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> [Pass the nfs_client pointer into nfs4_alloc_session]
> Signed-off-by: Andy Adamson <andros@netapp.com>
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> [nfs41: don't assign to session->clp->cl_session in
> nfs4_destroy_session]
> [nfs41: fixup nfs4_clear_client_minor_version]
> [introduce nfs4_clear_client_minor_version() in this patch]
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> Refactor nfs4_init_session:
> Moved session allocation into nfs4_init_client_minor_version,
> called from
> nfs4_init_client.
> Leave rwise and wsize initialization in nfs4_init_session, called
> from
> nfs4_init_server.
> Reverted moving of nfs_fsid definition to nfs_fs_sb.h
> Signed-off-by: Andy Adamson <andros@netapp.com>
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> [nfs41: Move NFS4_MAX_SLOT_TABLE define from under CONFIG_NFS_V4_1]
> Fix comile error when CONFIG_NFS_V4_1 is not set.
> Signed-off-by: Andy Adamson <andros@netapp.com>
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> ---
> fs/nfs/client.c | 60 +++++++++++++++++++++++++++++++++++
> fs/nfs/internal.h | 12 +++++++
> fs/nfs/nfs4_fs.h | 4 ++
> fs/nfs/nfs4proc.c | 77
> +++++++++++++++++++++++++++++++++++++++++++++
> include/linux/nfs_fs_sb.h | 49 ++++++++++++++++++++++++++++
> include/linux/nfs_xdr.h | 15 +++++++++
> 6 files changed, 217 insertions(+), 0 deletions(-)
>
> diff --git a/fs/nfs/client.c b/fs/nfs/client.c
> index e9f002f..c1536d9 100644
> --- a/fs/nfs/client.c
> +++ b/fs/nfs/client.c
> @@ -183,12 +183,27 @@ static void nfs4_shutdown_client(struct
> nfs_client *clp)
> }
>
> /*
> + * Clears/puts all minor version specific parts from an nfs_client
> struct
> + * reverting it to minorversion 0.
> + */
> +static void nfs4_clear_client_minor_version(struct nfs_client *clp)
> +{
> +#ifdef CONFIG_NFS_V4_1
> + if (nfs4_has_session(clp)) {
> + nfs4_destroy_session(clp->cl_session);
> + clp->cl_session = NULL;
> + }
> +#endif /* CONFIG_NFS_V4_1 */
> +}
> +
> +/*
> * Destroy a shared client record
> */
> static void nfs_free_client(struct nfs_client *clp)
> {
> dprintk("--> nfs_free_client(%u)\n", clp->rpc_ops->version);
>
> + nfs4_clear_client_minor_version(clp);
> nfs4_shutdown_client(clp);
>
> /* -EIO all pending I/O */
> @@ -993,6 +1008,30 @@ error:
>
> #ifdef CONFIG_NFS_V4
> /*
> + * Initialize the minor version specific parts of an NFS4 client
> record
> + */
> +static int nfs4_init_client_minor_version(struct nfs_client *clp)
> +{
> +#if defined(CONFIG_NFS_V4_1)
> + if (clp->cl_minorversion) {
> + struct nfs4_session *session = NULL;
> + /*
> + * Create the session and mark it expired.
> + * When a SEQUENCE operation encounters the expired
> session
> + * it will do session recovery to initialize it.
> + */
> + session = nfs4_alloc_session(clp);
> + if (!session)
> + return -ENOMEM;
> +
> + clp->cl_session = session;
> + }
> +#endif /* CONFIG_NFS_V4_1 */
> +
> + return 0;
> +}
> +
> +/*
> * Initialise an NFS4 client record
> */
> static int nfs4_init_client(struct nfs_client *clp,
> @@ -1026,6 +1065,10 @@ static int nfs4_init_client(struct nfs_client
> *clp,
> }
> __set_bit(NFS_CS_IDMAP, &clp->cl_res_state);
>
> + error = nfs4_init_client_minor_version(clp);
> + if (error < 0)
> + goto error;
> +
> nfs_mark_client_ready(clp, NFS_CS_READY);
> return 0;
>
> @@ -1083,6 +1126,21 @@ error:
> }
>
> /*
> + * Initialize a session.
> + * Note: save the mount rsize and wsize for create_server
> negotiation.
> + */
> +static void nfs4_init_session(struct nfs_client *clp,
> + unsigned int wsize, unsigned int rsize)
> +{
> +#if defined(CONFIG_NFS_V4_1)
> + if (nfs4_has_session(clp)) {
> + clp->cl_session->fc_attrs.max_rqst_sz = wsize;
> + clp->cl_session->fc_attrs.max_resp_sz = rsize;
> + }
> +#endif /* CONFIG_NFS_V4_1 */
> +}
> +
> +/*
> * Create a version 4 volume record
> */
> static int nfs4_init_server(struct nfs_server *server,
> @@ -1159,6 +1217,8 @@ struct nfs_server *nfs4_create_server(const
> struct nfs_parsed_mount_data *data,
> BUG_ON(!server->nfs_client->rpc_ops);
> BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
>
> + nfs4_init_session(server->nfs_client, server->wsize,
> server->rsize);
> +
> /* Probe the root fh to retrieve its FSID */
> error = nfs4_path_walk(server, mntfh,
> data->nfs_server.export_path);
> if (error < 0)
> diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
> index 73e4d9f..b7fc8d4 100644
> --- a/fs/nfs/internal.h
> +++ b/fs/nfs/internal.h
> @@ -199,6 +199,18 @@ extern int nfs4_path_walk(struct nfs_server
> *server,
> #endif
>
> /*
> + * Determine if sessions are in use.
> + */
> +static inline int nfs4_has_session(const struct nfs_client *clp)
> +{
> +#ifdef CONFIG_NFS_V4_1
> + if (clp->cl_session)
> + return 1;
> +#endif /* CONFIG_NFS_V4_1 */
> + return 0;
> +}
> +
> +/*
> * Determine the device name as a string
> */
> static inline char *nfs_devname(const struct vfsmount *mnt_parent,
> diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
> index 4e4d332..5d7b036 100644
> --- a/fs/nfs/nfs4_fs.h
> +++ b/fs/nfs/nfs4_fs.h
> @@ -202,6 +202,10 @@ extern int nfs4_proc_fs_locations(struct inode
> *dir, const struct qstr *name,
>
> extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
> extern struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops;
> +#if defined(CONFIG_NFS_V4_1)
> +extern void nfs4_destroy_session(struct nfs4_session *session);
> +extern struct nfs4_session *nfs4_alloc_session(struct nfs_client
> *clp);
> +#endif /* CONFIG_NFS_V4_1 */
>
> extern const u32 nfs4_fattr_bitmap[2];
> extern const u32 nfs4_statfs_bitmap[2];
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index 8dde84b..c12cf91 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -3708,6 +3708,83 @@ int nfs4_proc_fs_locations(struct inode *dir,
> const struct qstr *name,
> return status;
> }
>
> +#ifdef CONFIG_NFS_V4_1
> +/*
> + * Initialize slot table
> + */
> +static int nfs4_init_slot_table(struct nfs4_session *session)
This function isn't used anywhere. Why is it being defined in this
patch?
> +{
> + struct nfs4_slot_table *tbl = &session->fc_slot_table;
> + int i, max_slots = session->fc_attrs.max_reqs;
> + struct nfs4_slot *slot;
> + int ret = -ENOMEM;
> +
> + BUG_ON(max_slots > NFS4_MAX_SLOT_TABLE);
> +
> + dprintk("--> %s: max_reqs=%u\n", __func__,
> + session->fc_attrs.max_reqs);
> +
> + slot = kzalloc(max_slots * sizeof(struct nfs4_slot),
> GFP_ATOMIC);
Please use kcalloc() when allocating an array. Also, you need a strong
justification for why this has to be a GFP_ATOMIC allocation.
> + if (!slot)
> + goto out;
> + for (i = 0; i < max_slots; ++i)
> + slot[i].seq_nr = 1;
> + ret = 0;
> +
> + spin_lock(&tbl->slot_tbl_lock);
> + if (tbl->slots != NULL) {
> + spin_unlock(&tbl->slot_tbl_lock);
> + dprintk("%s: slot table already initialized. tbl=%p
> slots=%p\n",
> + __func__, tbl, tbl->slots);
> + WARN_ON(1);
> + goto out_free;
> + }
> + tbl->max_slots = max_slots;
> + tbl->slots = slot;
> + tbl->highest_used_slotid = -1; /* no slot is currently used
> */
> + spin_unlock(&tbl->slot_tbl_lock);
> + dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
> + tbl, tbl->slots, tbl->max_slots);
> +out:
> + dprintk("<-- %s: return %d\n", __func__, ret);
> + return ret;
> +out_free:
> + kfree(slot);
> + goto out;
> +}
> +/* Destroy the slot table */
> +static void nfs4_destroy_slot_table(struct nfs4_session *session)
> +{
> + if (session->fc_slot_table.slots == NULL)
> + return;
> + kfree(session->fc_slot_table.slots);
> + session->fc_slot_table.slots = NULL;
> + return;
> +}
> +
> +struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
> +{
> + struct nfs4_session *session;
> + struct nfs4_slot_table *tbl;
> +
> + session = kzalloc(sizeof(struct nfs4_session), GFP_ATOMIC);
I can see no reason why this needs to be a GFP_ATOMIC allocation.
> + if (!session)
> + return NULL;
> + tbl = &session->fc_slot_table;
> + spin_lock_init(&tbl->slot_tbl_lock);
> + rpc_init_wait_queue(&tbl->slot_tbl_waitq, "Slot table");
> + session->clp = clp;
> + return session;
> +}
> +
> +void nfs4_destroy_session(struct nfs4_session *session)
> +{
> + nfs4_destroy_slot_table(session);
> + kfree(session);
> +}
> +
> +#endif /* CONFIG_NFS_V4_1 */
> +
> struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = {
> .owner_flag_bit = NFS_OWNER_RECLAIM_REBOOT,
> .state_flag_bit = NFS_STATE_RECLAIM_REBOOT,
> diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
> index 63f8b00..5673eac 100644
> --- a/include/linux/nfs_fs_sb.h
> +++ b/include/linux/nfs_fs_sb.h
> @@ -4,9 +4,12 @@
> #include <linux/list.h>
> #include <linux/backing-dev.h>
> #include <linux/wait.h>
> +#include <linux/nfs_xdr.h>
> +#include <linux/sunrpc/xprt.h>
>
> #include <asm/atomic.h>
>
> +struct nfs4_session;
> struct nfs_iostats;
> struct nlm_host;
>
> @@ -65,6 +68,10 @@ struct nfs_client {
> unsigned char cl_id_uniquifier;
> u32 cl_minorversion;
> #endif /* CONFIG_NFS_V4 */
> +
> +#ifdef CONFIG_NFS_V4_1
> + struct nfs4_session *cl_session; /* sharred session */
> +#endif /* CONFIG_NFS_V4_1 */
> };
>
> /*
> @@ -130,4 +137,46 @@ struct nfs_server {
> #define NFS_CAP_ACLS (1U << 3)
> #define NFS_CAP_ATOMIC_OPEN (1U << 4)
>
> +
> +/* maximum number of slots to use */
> +#define NFS4_MAX_SLOT_TABLE RPC_MAX_SLOT_TABLE
> +
> +#if defined(CONFIG_NFS_V4_1)
> +
> +/* Sessions */
> +#define SLOT_TABLE_SZ (NFS4_MAX_SLOT_TABLE/(8*sizeof(long)))
> +struct nfs4_slot_table {
> + struct nfs4_slot *slots; /* seqid per slot */
> + unsigned long used_slots[SLOT_TABLE_SZ]; /* used/unused
> bitmap */
> + spinlock_t slot_tbl_lock;
> + struct rpc_wait_queue slot_tbl_waitq; /* allocators may wait
> here */
> + int max_slots; /* # slots in table */
> + int highest_used_slotid; /* sent to server on
> each SEQ.
> + * op for dynamic
> resizing */
> +};
> +
> +static inline int slot_idx(struct nfs4_slot_table *tbl, struct
> nfs4_slot *sp)
> +{
> + return sp - tbl->slots;
> +}
> +
> +/*
> + * Session related parameters
> + */
> +struct nfs4_session {
> + struct nfs4_sessionid sess_id;
> + u32 flags;
> + unsigned long session_state;
> + u32 hash_alg;
> + u32 ssv_len;
> +
> + /* The fore and back channel */
> + struct nfs4_channel_attrs fc_attrs;
> + struct nfs4_slot_table fc_slot_table;
> + struct nfs4_channel_attrs bc_attrs;
> + /* back channel has one slot
> */
> + struct nfs_client *clp;
> +};
> +
> +#endif /* CONFIG_NFS_V4_1 */
> #endif
> diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
> index c137ca0..16bef5d 100644
> --- a/include/linux/nfs_xdr.h
> +++ b/include/linux/nfs_xdr.h
> @@ -114,6 +114,21 @@ struct nfs4_change_info {
>
> struct nfs_seqid;
>
> +/* nfs41 sessions channel attributes */
> +struct nfs4_channel_attrs {
> + u32 headerpadsz;
> + u32 max_rqst_sz;
> + u32 max_resp_sz;
> + u32 max_resp_sz_cached;
> + u32 max_ops;
> + u32 max_reqs;
> +};
> +
> +/* nfs41 sessions slot seqid */
> +struct nfs4_slot {
> + u32 seq_nr;
> +};
> +
> struct nfs4_sequence_args {
> /* stub */
> };
> --
> 1.6.1.3
>
>
>
--
Trond Myklebust
Linux NFS client maintainer
NetApp
Trond.Myklebust@netapp.com
www.netapp.com
^ permalink raw reply [flat|nested] 63+ messages in thread
* [PATCH 10/46] nfs41: find slot
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (7 preceding siblings ...)
2009-03-03 23:53 ` [PATCH 09/46] nfs41: sessions client infrastructure Benny Halevy
@ 2009-03-03 23:53 ` Benny Halevy
2009-03-03 23:53 ` [PATCH 11/46] nfs41: free slot Benny Halevy
` (35 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:53 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
Find a free slot using bitmap-based allocation.
Use the optimized ffz function to find a zero bit
in the bitmap that indicates a free slot, starting
the search from the 'lowest_free_slotid' position.
If found, mark the slot as used in the bitmap, get
the slot's slotid and seqid, and update max_slotid
to be used by the SEQUENCE operation.
Also, update lowest_free_slotid for next search.
If no free slot was found the caller has to wait
for a free slot (outside the scope of this function)
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: find slot return slotid]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[use find_first_zero_bit for nfs4_find_slot as per review comment 21/85.]
[use NFS4_MAX_SLOT_TABLE rather than NFS4_NO_SLOT]
[nfs41: rpc_sleep_on slot_tbl_waitq must be called under slot_tbl_lock]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 37 +++++++++++++++++++++++++++++++++++++
1 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index c12cf91..9bc6bb7 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -279,6 +279,43 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
spin_unlock(&clp->cl_lock);
}
+#if defined(CONFIG_NFS_V4_1)
+
+/*
+ * nfs4_find_slot - efficiently look for a free slot
+ *
+ * nfs4_find_slot looks for an unset bit in the used_slots bitmap.
+ * If found, we mark the slot as used, update the highest_used_slotid,
+ * and respectively set up the sequence operation args.
+ * The slot number is returned if found, or NFS4_MAX_SLOT_TABLE otherwise.
+ */
+static u8
+nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task)
+{
+ int slotid;
+ u8 ret_id = NFS4_MAX_SLOT_TABLE;
+ BUILD_BUG_ON((u8)NFS4_MAX_SLOT_TABLE != (int)NFS4_MAX_SLOT_TABLE);
+
+ spin_lock(&tbl->slot_tbl_lock);
+ dprintk("--> %s used_slots=%04lx highest_used=%d max_slots=%d\n",
+ __func__, tbl->used_slots[0], tbl->highest_used_slotid,
+ tbl->max_slots);
+ slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slots);
+ if (slotid >= tbl->max_slots)
+ goto out;
+ __set_bit(slotid, tbl->used_slots);
+ if (slotid > tbl->highest_used_slotid)
+ tbl->highest_used_slotid = slotid;
+ ret_id = slotid;
+out:
+ dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n",
+ __func__, tbl->used_slots[0], tbl->highest_used_slotid, ret_id);
+ spin_unlock(&tbl->slot_tbl_lock);
+ return ret_id;
+}
+
+#endif /* CONFIG_NFS_V4_1 */
+
static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
{
struct nfs_inode *nfsi = NFS_I(dir);
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 11/46] nfs41: free slot
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (8 preceding siblings ...)
2009-03-03 23:53 ` [PATCH 10/46] nfs41: find slot Benny Halevy
@ 2009-03-03 23:53 ` Benny Halevy
2009-03-03 23:53 ` [PATCH 12/46] nfs41: use nfs4_server_caps_arg Benny Halevy
` (34 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:53 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Free a slot in the slot table.
Mark the slot as free in the bitmap-based allocation table
by clearing a bit corresponding to the slotid.
Update lowest_free_slotid if freed slotid is lower than that.
Update highest_used_slotid. In the case the freed slotid
equals the highest_used_slotid, scan downwards for the next
highest used slotid using the optimized fls* functions.
Finally, wake up thread waiting on slot_tbl_waitq for a free slot
to become available.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: free slot use slotid]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: use find_first_zero_bit for nfs4_find_slot]
While at it, obliterate lowest_free_slotid and fix-up related comments.
As per review comment 21/85.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: use __clear_bit for nfs4_free_slot]
While at it, fix-up function comment.
Part of review comment 22/85.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: use find_last_bit in nfs4_free_slot to determine highest used slot.]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: rpc_sleep_on slot_tbl_waitq must be called under slot_tbl_lock]
Otherwise there's a race (we've hit) with nfs4_free_slot where
nfs41_setup_sequence sees a full slot table, unlocks slot_tbl_lock,
nfs4_free_slots happen concurrently and call rpc_wake_up_next
where there's nobody to wake up yet, context goes back to
nfs41_setup_sequence which goes to sleep when the slot table
is actually empty now and there's no-one to wake it up anymore.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 36 ++++++++++++++++++++++++++++++++++++
1 files changed, 36 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 9bc6bb7..fed6cfb 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -282,6 +282,42 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
#if defined(CONFIG_NFS_V4_1)
/*
+ * nfs4_free_slot - free a slot and efficiently update slot table.
+ *
+ * freeing a slot is trivially done by clearing its respective bit
+ * in the bitmap.
+ * If the freed slotid equals highest_used_slotid we want to update it
+ * so that the server would be able to size down the slot table if needed,
+ * otherwise we know that the highest_used_slotid is still in use.
+ * When updating highest_used_slotid there may be "holes" in the bitmap
+ * so we need to scan down from highest_used_slotid to 0 looking for the now
+ * highest slotid in use.
+ * If none found, highest_used_slotid is set to -1.
+ */
+static void
+nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
+{
+ int slotid = free_slotid;
+
+ spin_lock(&tbl->slot_tbl_lock);
+ /* clear used bit in bitmap */
+ __clear_bit(slotid, tbl->used_slots);
+
+ /* update highest_used_slotid when it is freed */
+ if (slotid == tbl->highest_used_slotid) {
+ slotid = find_last_bit(tbl->used_slots, tbl->max_slots);
+ if (slotid >= 0 && slotid < tbl->max_slots)
+ tbl->highest_used_slotid = slotid;
+ else
+ tbl->highest_used_slotid = -1;
+ }
+ rpc_wake_up_next(&tbl->slot_tbl_waitq);
+ spin_unlock(&tbl->slot_tbl_lock);
+ dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__,
+ free_slotid, tbl->highest_used_slotid);
+}
+
+/*
* nfs4_find_slot - efficiently look for a free slot
*
* nfs4_find_slot looks for an unset bit in the used_slots bitmap.
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 12/46] nfs41: use nfs4_server_caps_arg
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (9 preceding siblings ...)
2009-03-03 23:53 ` [PATCH 11/46] nfs41: free slot Benny Halevy
@ 2009-03-03 23:53 ` Benny Halevy
2009-03-03 23:54 ` [PATCH 13/46] nfs41: use nfs4_readlink_res Benny Halevy
` (33 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:53 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
In preparation for nfs41 sequence processing.
Signed-off-by: Andy Admason <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 5 ++++-
fs/nfs/nfs4xdr.c | 5 +++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index fed6cfb..0c60965 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1656,10 +1656,13 @@ out_drop:
static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
{
+ struct nfs4_server_caps_arg args = {
+ .fhandle = fhandle,
+ };
struct nfs4_server_caps_res res = {};
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SERVER_CAPS],
- .rpc_argp = fhandle,
+ .rpc_argp = &args,
.rpc_resp = &res,
};
int status;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index d1e4c8f..4b356ac 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1903,7 +1903,8 @@ static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs
/*
* GETATTR_BITMAP request
*/
-static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p, const struct nfs_fh *fhandle)
+static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p,
+ struct nfs4_server_caps_arg *args)
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
@@ -1912,7 +1913,7 @@ static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p, const struc
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, &hdr);
- encode_putfh(&xdr, fhandle, &hdr);
+ encode_putfh(&xdr, args->fhandle, &hdr);
encode_getattr_one(&xdr, FATTR4_WORD0_SUPPORTED_ATTRS|
FATTR4_WORD0_LINK_SUPPORT|
FATTR4_WORD0_SYMLINK_SUPPORT|
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 13/46] nfs41: use nfs4_readlink_res
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (10 preceding siblings ...)
2009-03-03 23:53 ` [PATCH 12/46] nfs41: use nfs4_server_caps_arg Benny Halevy
@ 2009-03-03 23:54 ` Benny Halevy
2009-03-03 23:54 ` [PATCH 14/46] nfs41: use nfs4_statfs_res Benny Halevy
` (32 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:54 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
In preparation for nfs41 sequence processing.
Signed-off-by: Andy Admason <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 3 ++-
fs/nfs/nfs4xdr.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 0c60965..13a22c6 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2029,10 +2029,11 @@ static int _nfs4_proc_readlink(struct inode *inode, struct page *page,
.pglen = pglen,
.pages = &page,
};
+ struct nfs4_readlink_res res;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READLINK],
.rpc_argp = &args,
- .rpc_resp = NULL,
+ .rpc_resp = &res,
};
return rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 4b356ac..17de1d4 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4152,7 +4152,8 @@ out:
/*
* Decode READLINK response
*/
-static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p, void *res)
+static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p,
+ struct nfs4_readlink_res *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 14/46] nfs41: use nfs4_statfs_res
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (11 preceding siblings ...)
2009-03-03 23:54 ` [PATCH 13/46] nfs41: use nfs4_readlink_res Benny Halevy
@ 2009-03-03 23:54 ` Benny Halevy
2009-03-03 23:54 ` [PATCH 15/46] nfs41: use nfs4_fsinfo_res Benny Halevy
` (31 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:54 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
In preparation for nfs41 sequence processing.
Signed-off-by: Andy Admason <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 5 ++++-
fs/nfs/nfs4xdr.c | 5 +++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 13a22c6..20c5e0d 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2495,10 +2495,13 @@ static int _nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
.fh = fhandle,
.bitmask = server->attr_bitmask,
};
+ struct nfs4_statfs_res res = {
+ .fsstat = fsstat,
+ };
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_STATFS],
.rpc_argp = &args,
- .rpc_resp = fsstat,
+ .rpc_resp = &res,
};
nfs_fattr_init(fsstat->fattr);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 17de1d4..1b37faa 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4304,7 +4304,8 @@ static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, struct nfs_pat
/*
* STATFS request
*/
-static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *fsstat)
+static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p,
+ struct nfs4_statfs_res *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -4315,7 +4316,7 @@ static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p, struct nfs_fssta
if (!status)
status = decode_putfh(&xdr);
if (!status)
- status = decode_statfs(&xdr, fsstat);
+ status = decode_statfs(&xdr, res->fsstat);
return status;
}
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 15/46] nfs41: use nfs4_fsinfo_res
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (12 preceding siblings ...)
2009-03-03 23:54 ` [PATCH 14/46] nfs41: use nfs4_statfs_res Benny Halevy
@ 2009-03-03 23:54 ` Benny Halevy
2009-03-03 23:54 ` [PATCH 16/46] nfs41: use nfs4_pathconf_res Benny Halevy
` (30 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:54 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
In preparation for nfs41 sequence processing.
Signed-off-by: Andy Admason <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 5 ++++-
fs/nfs/nfs4xdr.c | 5 +++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 20c5e0d..7a01a3f 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2527,10 +2527,13 @@ static int _nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
.fh = fhandle,
.bitmask = server->attr_bitmask,
};
+ struct nfs4_fsinfo_res res = {
+ .fsinfo = fsinfo,
+ };
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FSINFO],
.rpc_argp = &args,
- .rpc_resp = fsinfo,
+ .rpc_resp = &res,
};
return rpc_call_sync(server->client, &msg, 0);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 1b37faa..6647f10 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4268,7 +4268,8 @@ out:
/*
* FSINFO request
*/
-static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *fsinfo)
+static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p,
+ struct nfs4_fsinfo_res *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -4279,7 +4280,7 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinf
if (!status)
status = decode_putfh(&xdr);
if (!status)
- status = decode_fsinfo(&xdr, fsinfo);
+ status = decode_fsinfo(&xdr, res->fsinfo);
return status;
}
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 16/46] nfs41: use nfs4_pathconf_res
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (13 preceding siblings ...)
2009-03-03 23:54 ` [PATCH 15/46] nfs41: use nfs4_fsinfo_res Benny Halevy
@ 2009-03-03 23:54 ` Benny Halevy
2009-03-03 23:54 ` [PATCH 17/46] nfs41: use nfs4_getaclres Benny Halevy
` (29 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:54 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
In preparation for nfs41 sequence processing.
Signed-off-by: Andy Admason <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 5 ++++-
fs/nfs/nfs4xdr.c | 5 +++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 7a01a3f..4db965c 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2565,10 +2565,13 @@ static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle
.fh = fhandle,
.bitmask = server->attr_bitmask,
};
+ struct nfs4_pathconf_res res = {
+ .pathconf = pathconf,
+ };
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_PATHCONF],
.rpc_argp = &args,
- .rpc_resp = pathconf,
+ .rpc_resp = &res,
};
/* None of the pathconf attributes are mandatory to implement */
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 6647f10..3f84ab7 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4287,7 +4287,8 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p,
/*
* PATHCONF request
*/
-static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *pathconf)
+static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p,
+ struct nfs4_pathconf_res *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -4298,7 +4299,7 @@ static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, struct nfs_pat
if (!status)
status = decode_putfh(&xdr);
if (!status)
- status = decode_pathconf(&xdr, pathconf);
+ status = decode_pathconf(&xdr, res->pathconf);
return status;
}
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 17/46] nfs41: use nfs4_getaclres
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (14 preceding siblings ...)
2009-03-03 23:54 ` [PATCH 16/46] nfs41: use nfs4_pathconf_res Benny Halevy
@ 2009-03-03 23:54 ` Benny Halevy
2009-03-29 17:28 ` Trond Myklebust
2009-03-03 23:55 ` [PATCH 18/46] NFS: get rid of unused xdr decode_setattr(, res) argument Benny Halevy
` (28 subsequent siblings)
44 siblings, 1 reply; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:54 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
In preparation for nfs41 sequence processing.
Signed-off-by: Andy Admason <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 7 +++++--
fs/nfs/nfs4xdr.c | 5 +++--
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 4db965c..1a5fa1d 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2822,17 +2822,20 @@ out:
static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
{
struct page *pages[NFS4ACL_MAXPAGES];
+ size_t resp_len = buflen;
struct nfs_getaclargs args = {
.fh = NFS_FH(inode),
.acl_pages = pages,
.acl_len = buflen,
};
- size_t resp_len = buflen;
+ struct nfs_getaclres res = {
+ .acl_len = &resp_len,
+ };
void *resp_buf;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL],
.rpc_argp = &args,
- .rpc_resp = &resp_len,
+ .rpc_resp = &res,
};
struct page *localpage = NULL;
int ret;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 3f84ab7..62fc817 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -3933,7 +3933,8 @@ out:
* Decode GETACL response
*/
static int
-nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p, size_t *acl_len)
+nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p,
+ struct nfs_getaclres *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -3946,7 +3947,7 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p, size_t *acl_len)
status = decode_putfh(&xdr);
if (status)
goto out;
- status = decode_getacl(&xdr, rqstp, acl_len);
+ status = decode_getacl(&xdr, rqstp, res->acl_len);
out:
return status;
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* Re: [PATCH 17/46] nfs41: use nfs4_getaclres
2009-03-03 23:54 ` [PATCH 17/46] nfs41: use nfs4_getaclres Benny Halevy
@ 2009-03-29 17:28 ` Trond Myklebust
[not found] ` <1238347692.10999.16.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
0 siblings, 1 reply; 63+ messages in thread
From: Trond Myklebust @ 2009-03-29 17:28 UTC (permalink / raw)
To: Benny Halevy; +Cc: linux-nfs, pnfs
On Tue, 2009-03-03 at 16:54 -0700, Benny Halevy wrote:
> In preparation for nfs41 sequence processing.
>
> Signed-off-by: Andy Admason <andros@netapp.com>
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> ---
> fs/nfs/nfs4proc.c | 7 +++++--
> fs/nfs/nfs4xdr.c | 5 +++--
> 2 files changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index 4db965c..1a5fa1d 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -2822,17 +2822,20 @@ out:
> static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void
> *buf, size_t buflen)
> {
> struct page *pages[NFS4ACL_MAXPAGES];
> + size_t resp_len = buflen;
> struct nfs_getaclargs args = {
> .fh = NFS_FH(inode),
> .acl_pages = pages,
> .acl_len = buflen,
> };
> - size_t resp_len = buflen;
> + struct nfs_getaclres res = {
> + .acl_len = &resp_len,
> + };
Please embed resp_len in nfs_getaclres. There is no need for a double
indirection here...
> void *resp_buf;
> struct rpc_message msg = {
> .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL],
> .rpc_argp = &args,
> - .rpc_resp = &resp_len,
> + .rpc_resp = &res,
> };
> struct page *localpage = NULL;
> int ret;
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index 3f84ab7..62fc817 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -3933,7 +3933,8 @@ out:
> * Decode GETACL response
> */
> static int
> -nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p, size_t
> *acl_len)
> +nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p,
> + struct nfs_getaclres *res)
> {
> struct xdr_stream xdr;
> struct compound_hdr hdr;
> @@ -3946,7 +3947,7 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp,
> __be32 *p, size_t *acl_len)
> status = decode_putfh(&xdr);
> if (status)
> goto out;
> - status = decode_getacl(&xdr, rqstp, acl_len);
> + status = decode_getacl(&xdr, rqstp, res->acl_len);
>
> out:
> return status;
> --
> 1.6.1.3
>
>
>
--
Trond Myklebust
Linux NFS client maintainer
NetApp
Trond.Myklebust@netapp.com
www.netapp.com
^ permalink raw reply [flat|nested] 63+ messages in thread
* [PATCH 18/46] NFS: get rid of unused xdr decode_setattr(, res) argument
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (15 preceding siblings ...)
2009-03-03 23:54 ` [PATCH 17/46] nfs41: use nfs4_getaclres Benny Halevy
@ 2009-03-03 23:55 ` Benny Halevy
2009-03-03 23:55 ` [PATCH 19/46] nfs41: use nfs4_setaclres Benny Halevy
` (27 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:55 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4xdr.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 62fc817..13320af 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -3573,7 +3573,7 @@ decode_savefh(struct xdr_stream *xdr)
return decode_op_hdr(xdr, OP_SAVEFH);
}
-static int decode_setattr(struct xdr_stream *xdr, struct nfs_setattrres *res)
+static int decode_setattr(struct xdr_stream *xdr)
{
__be32 *p;
uint32_t bmlen;
@@ -3924,7 +3924,7 @@ nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p, void *res)
status = decode_putfh(&xdr);
if (status)
goto out;
- status = decode_setattr(&xdr, res);
+ status = decode_setattr(&xdr);
out:
return status;
}
@@ -4077,7 +4077,7 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_se
status = decode_putfh(&xdr);
if (status)
goto out;
- status = decode_setattr(&xdr, res);
+ status = decode_setattr(&xdr);
if (status)
goto out;
status = decode_getfattr(&xdr, res->fattr, res->server);
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 19/46] nfs41: use nfs4_setaclres
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (16 preceding siblings ...)
2009-03-03 23:55 ` [PATCH 18/46] NFS: get rid of unused xdr decode_setattr(, res) argument Benny Halevy
@ 2009-03-03 23:55 ` Benny Halevy
2009-03-29 17:30 ` Trond Myklebust
2009-03-03 23:55 ` [PATCH 20/46] nfs41: use nfs4_fs_locations_res Benny Halevy
` (26 subsequent siblings)
44 siblings, 1 reply; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:55 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
In preparation for nfs41 sequence processing.
Signed-off-by: Andy Admason <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 3 ++-
fs/nfs/nfs4xdr.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 1a5fa1d..98b2e89 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2915,10 +2915,11 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
.acl_pages = pages,
.acl_len = buflen,
};
+ struct nfs_setaclres res;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETACL],
.rpc_argp = &arg,
- .rpc_resp = NULL,
+ .rpc_resp = &res,
};
int ret;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 13320af..5fb452c 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -3911,7 +3911,8 @@ nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args
* Decode SETACL response
*/
static int
-nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p, void *res)
+nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p,
+ struct nfs_setaclres *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* Re: [PATCH 19/46] nfs41: use nfs4_setaclres
2009-03-03 23:55 ` [PATCH 19/46] nfs41: use nfs4_setaclres Benny Halevy
@ 2009-03-29 17:30 ` Trond Myklebust
[not found] ` <1238347823.10999.17.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
0 siblings, 1 reply; 63+ messages in thread
From: Trond Myklebust @ 2009-03-29 17:30 UTC (permalink / raw)
To: Benny Halevy; +Cc: linux-nfs, pnfs
On Tue, 2009-03-03 at 16:55 -0700, Benny Halevy wrote:
> In preparation for nfs41 sequence processing.
>
> Signed-off-by: Andy Admason <andros@netapp.com>
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> ---
> fs/nfs/nfs4proc.c | 3 ++-
> fs/nfs/nfs4xdr.c | 3 ++-
> 2 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index 1a5fa1d..98b2e89 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -2915,10 +2915,11 @@ static int __nfs4_proc_set_acl(struct inode
> *inode, const void *buf, size_t bufl
> .acl_pages = pages,
> .acl_len = buflen,
> };
> + struct nfs_setaclres res;
Where is the definition?
> struct rpc_message msg = {
> .rpc_proc =
> &nfs4_procedures[NFSPROC4_CLNT_SETACL],
> .rpc_argp = &arg,
> - .rpc_resp = NULL,
> + .rpc_resp = &res,
> };
> int ret;
>
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index 13320af..5fb452c 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -3911,7 +3911,8 @@ nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32
> *p, struct nfs_setaclargs *args
> * Decode SETACL response
> */
> static int
> -nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p, void *res)
> +nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p,
> + struct nfs_setaclres *res)
> {
> struct xdr_stream xdr;
> struct compound_hdr hdr;
> --
> 1.6.1.3
>
>
>
--
Trond Myklebust
Linux NFS client maintainer
NetApp
Trond.Myklebust@netapp.com
www.netapp.com
^ permalink raw reply [flat|nested] 63+ messages in thread
* [PATCH 20/46] nfs41: use nfs4_fs_locations_res
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (17 preceding siblings ...)
2009-03-03 23:55 ` [PATCH 19/46] nfs41: use nfs4_setaclres Benny Halevy
@ 2009-03-03 23:55 ` Benny Halevy
2009-03-03 23:55 ` [PATCH 21/46] sunrpc: add cl_private field to struct rpc_clnt Benny Halevy
` (25 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:55 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
In preparation for nfs41 sequence processing.
Signed-off-by: Andy Admason <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 5 ++++-
fs/nfs/nfs4xdr.c | 6 ++++--
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 98b2e89..7b69f00 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3782,10 +3782,13 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
.page = page,
.bitmask = bitmask,
};
+ struct nfs4_fs_locations_res res = {
+ .fs_locations = fs_locations,
+ };
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_FS_LOCATIONS],
.rpc_argp = &args,
- .rpc_resp = fs_locations,
+ .rpc_resp = &res,
};
int status;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 5fb452c..55b9091 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -4421,7 +4421,8 @@ out:
/*
* FS_LOCATIONS request
*/
-static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs4_fs_locations *res)
+static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p,
+ struct nfs4_fs_locations_res *res)
{
struct xdr_stream xdr;
struct compound_hdr hdr;
@@ -4436,7 +4437,8 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
if ((status = decode_lookup(&xdr)) != 0)
goto out;
xdr_enter_page(&xdr, PAGE_SIZE);
- status = decode_getfattr(&xdr, &res->fattr, res->server);
+ status = decode_getfattr(&xdr, &res->fs_locations->fattr,
+ res->fs_locations->server);
out:
return status;
}
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 21/46] sunrpc: add cl_private field to struct rpc_clnt
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (18 preceding siblings ...)
2009-03-03 23:55 ` [PATCH 20/46] nfs41: use nfs4_fs_locations_res Benny Halevy
@ 2009-03-03 23:55 ` Benny Halevy
2009-03-03 23:55 ` [PATCH 22/46] nfs41: sunrpc: use private void pointer in rpc_clnt Benny Halevy
` (24 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:55 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Note: the NFSv4.1 client also uses (and declares) this pointer.
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
include/linux/sunrpc/clnt.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index c39a210..928c547 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -53,6 +53,7 @@ struct rpc_clnt {
char cl_pathname[30];/* Path in rpc_pipe_fs */
struct vfsmount * cl_vfsmnt;
struct dentry * cl_dentry; /* inode */
+ void *cl_private; /* private data */
struct rpc_clnt * cl_parent; /* Points to parent of clones */
struct rpc_rtt cl_rtt_default;
struct rpc_timeout cl_timeout_default;
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 22/46] nfs41: sunrpc: use private void pointer in rpc_clnt
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (19 preceding siblings ...)
2009-03-03 23:55 ` [PATCH 21/46] sunrpc: add cl_private field to struct rpc_clnt Benny Halevy
@ 2009-03-03 23:55 ` Benny Halevy
2009-03-03 23:57 ` [PATCH 23/46] nfs41: encode minorversion in compound header Benny Halevy
` (23 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:55 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Set the rpc_clnt->cl_private to back point to the struct nfs_client
and use the nfs_client->cl_minorveraion to perform NFSv4.0 vrs NFSv4.1
encoding.
[was nfs41: sunrpc: add private void pointer to rpc_clnt]
During the review, we thought this could be a struct nfs_server pointer. But
that makes no sense given that all struct nfs_server's share a struct
nfs_client->cl_rpcclient.
NFS uses this as a backpointer to struct nfs_client, and will use the
cl_minorversion.
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/client.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index c1536d9..ace6e91 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -541,6 +541,7 @@ static int nfs_create_rpc_client(struct nfs_client *clp,
}
clp->cl_rpcclient = clnt;
+ clnt->cl_private = clp;
return 0;
}
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 23/46] nfs41: encode minorversion in compound header
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (20 preceding siblings ...)
2009-03-03 23:55 ` [PATCH 22/46] nfs41: sunrpc: use private void pointer in rpc_clnt Benny Halevy
@ 2009-03-03 23:57 ` Benny Halevy
2009-03-03 23:57 ` [PATCH 24/46] NFS: fix decode_fs_locations_maxsz Benny Halevy
` (22 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:57 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
Signed-off-by: Andy Adamdon <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4xdr.c | 119 ++++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 89 insertions(+), 30 deletions(-)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 55b9091..b60dc56 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -544,6 +544,7 @@ struct compound_hdr {
__be32 * nops_p;
uint32_t taglen;
char * tag;
+ u32 minorversion;
};
/*
@@ -588,7 +589,7 @@ static void encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr
RESERVE_SPACE(12+(XDR_QUADLEN(hdr->taglen)<<2));
WRITE32(hdr->taglen);
WRITEMEM(hdr->tag, hdr->taglen);
- WRITE32(NFS4_MINOR_VERSION);
+ WRITE32(hdr->minorversion);
hdr->nops_p = p;
WRITE32(hdr->nops);
}
@@ -1353,8 +1354,10 @@ static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *state
static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs4_accessargs *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1372,8 +1375,10 @@ static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs
static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs4_lookup_arg *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1392,8 +1397,10 @@ static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs
static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struct nfs4_lookup_root_arg *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1411,8 +1418,10 @@ static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struc
static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1430,8 +1439,10 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs
static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs4_rename_arg *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1453,8 +1464,10 @@ static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs
static int nfs4_xdr_enc_link(struct rpc_rqst *req, __be32 *p, const struct nfs4_link_arg *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1476,8 +1489,10 @@ static int nfs4_xdr_enc_link(struct rpc_rqst *req, __be32 *p, const struct nfs4_
static int nfs4_xdr_enc_create(struct rpc_rqst *req, __be32 *p, const struct nfs4_create_arg *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1507,8 +1522,10 @@ static int nfs4_xdr_enc_symlink(struct rpc_rqst *req, __be32 *p, const struct nf
static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nfs4_getattr_arg *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1525,8 +1542,10 @@ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nf
static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closeargs *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1544,8 +1563,10 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closea
static int nfs4_xdr_enc_open(struct rpc_rqst *req, __be32 *p, struct nfs_openargs *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1585,8 +1606,10 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, __be32 *p, struct nfs
static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, __be32 *p, struct nfs_openargs *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1604,8 +1627,10 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, __be32 *p, struct nfs_
static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, __be32 *p, struct nfs_closeargs *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1623,8 +1648,10 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, __be32 *p, struct n
static int nfs4_xdr_enc_lock(struct rpc_rqst *req, __be32 *p, struct nfs_lock_args *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1641,8 +1668,10 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, __be32 *p, struct nfs_lock_ar
static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, __be32 *p, struct nfs_lockt_args *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1659,8 +1688,10 @@ static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, __be32 *p, struct nfs_lockt_
static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_args *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1677,8 +1708,10 @@ static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_
static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct nfs4_readlink *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
unsigned int replen;
@@ -1705,8 +1738,10 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n
static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nfs4_readdir_arg *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
int replen;
@@ -1737,8 +1772,10 @@ static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readarg
{
struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
int replen;
@@ -1765,8 +1802,10 @@ static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readarg
static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, __be32 *p, struct nfs_setattrargs *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1787,8 +1826,10 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
{
struct xdr_stream xdr;
struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
int replen;
@@ -1811,8 +1852,10 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1831,8 +1874,10 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writea
static int nfs4_xdr_enc_commit(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1850,8 +1895,10 @@ static int nfs4_xdr_enc_commit(struct rpc_rqst *req, __be32 *p, struct nfs_write
static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsinfo_arg *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1868,8 +1915,10 @@ static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsin
static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct nfs4_pathconf_arg *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1887,8 +1936,10 @@ static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct n
static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs4_statfs_arg *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1907,8 +1958,10 @@ static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p,
struct nfs4_server_caps_arg *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -1982,8 +2035,10 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str
static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, __be32 *p, const struct nfs4_delegreturnargs *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -2001,8 +2056,10 @@ static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, __be32 *p, const struc
static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs4_fs_locations_arg *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
int replen;
@@ -3894,8 +3951,10 @@ static int
nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args)
{
struct xdr_stream xdr;
+ struct nfs_client *clp =
+ (struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
- .nops = 0,
+ .minorversion = clp->cl_minorversion,
};
int status;
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 24/46] NFS: fix decode_fs_locations_maxsz
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (21 preceding siblings ...)
2009-03-03 23:57 ` [PATCH 23/46] nfs41: encode minorversion in compound header Benny Halevy
@ 2009-03-03 23:57 ` Benny Halevy
2009-03-29 17:40 ` Trond Myklebust
2009-03-03 23:58 ` [PATCH 25/46] NFS: use decode_change_info_maxsz for xdr maxsz calculations Benny Halevy
` (21 subsequent siblings)
44 siblings, 1 reply; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:57 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
need to take into account the getattr reply.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4xdr.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index b60dc56..0e01660 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -239,7 +239,7 @@ static int nfs4_stat_to_errno(int);
#define encode_fs_locations_maxsz \
(encode_getattr_maxsz)
#define decode_fs_locations_maxsz \
- (0)
+ (decode_getattr_maxsz)
#define NFS4_enc_compound_sz (1024) /* XXX: large enough? */
#define NFS4_dec_compound_sz (1024) /* XXX: large enough? */
#define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* Re: [PATCH 24/46] NFS: fix decode_fs_locations_maxsz
2009-03-03 23:57 ` [PATCH 24/46] NFS: fix decode_fs_locations_maxsz Benny Halevy
@ 2009-03-29 17:40 ` Trond Myklebust
[not found] ` <1238348417.23986.1.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
0 siblings, 1 reply; 63+ messages in thread
From: Trond Myklebust @ 2009-03-29 17:40 UTC (permalink / raw)
To: Benny Halevy; +Cc: linux-nfs, pnfs
On Tue, 2009-03-03 at 16:57 -0700, Benny Halevy wrote:
> need to take into account the getattr reply.
>
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> ---
> fs/nfs/nfs4xdr.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index b60dc56..0e01660 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -239,7 +239,7 @@ static int nfs4_stat_to_errno(int);
> #define encode_fs_locations_maxsz \
> (encode_getattr_maxsz)
> #define decode_fs_locations_maxsz \
> - (0)
> + (decode_getattr_maxsz)
This is a bit excessive. If you look at xdr_enc_fs_locations, you'll see
that this just needs to decode the OP_GETATTR + status. All the data
goes into the page.
> #define NFS4_enc_compound_sz (1024) /* XXX: large enough? */
> #define NFS4_dec_compound_sz (1024) /* XXX: large enough? */
> #define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \
> --
> 1.6.1.3
>
>
>
--
Trond Myklebust
Linux NFS client maintainer
NetApp
Trond.Myklebust@netapp.com
www.netapp.com
^ permalink raw reply [flat|nested] 63+ messages in thread
* [PATCH 25/46] NFS: use decode_change_info_maxsz for xdr maxsz calculations
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (22 preceding siblings ...)
2009-03-03 23:57 ` [PATCH 24/46] NFS: fix decode_fs_locations_maxsz Benny Halevy
@ 2009-03-03 23:58 ` Benny Halevy
2009-03-03 23:58 ` [PATCH 26/46] NFS: define and initialize compound_hdr.replen Benny Halevy
` (20 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:58 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4xdr.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 0e01660..75ceb42 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -192,12 +192,16 @@ static int nfs4_stat_to_errno(int);
decode_verifier_maxsz)
#define encode_remove_maxsz (op_encode_hdr_maxsz + \
nfs4_name_maxsz)
+#define decode_remove_maxsz (op_decode_hdr_maxsz + \
+ decode_change_info_maxsz)
#define encode_rename_maxsz (op_encode_hdr_maxsz + \
2 * nfs4_name_maxsz)
-#define decode_rename_maxsz (op_decode_hdr_maxsz + 5 + 5)
+#define decode_rename_maxsz (op_decode_hdr_maxsz + \
+ decode_change_info_maxsz + \
+ decode_change_info_maxsz)
#define encode_link_maxsz (op_encode_hdr_maxsz + \
nfs4_name_maxsz)
-#define decode_link_maxsz (op_decode_hdr_maxsz + 5)
+#define decode_link_maxsz (op_decode_hdr_maxsz + decode_change_info_maxsz)
#define encode_lock_maxsz (op_encode_hdr_maxsz + \
7 + \
1 + encode_stateid_maxsz + 8)
@@ -414,7 +418,7 @@ static int nfs4_stat_to_errno(int);
encode_getattr_maxsz)
#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \
decode_putfh_maxsz + \
- op_decode_hdr_maxsz + 5 + \
+ decode_remove_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \
encode_putfh_maxsz + \
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 26/46] NFS: define and initialize compound_hdr.replen
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (23 preceding siblings ...)
2009-03-03 23:58 ` [PATCH 25/46] NFS: use decode_change_info_maxsz for xdr maxsz calculations Benny Halevy
@ 2009-03-03 23:58 ` Benny Halevy
2009-03-03 23:58 ` [PATCH 27/46] NFS: update hdr->replen for every encode op Benny Halevy
` (19 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:58 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
replen holds the running count of expected reply bytes.
repl will then be used by encoding routines for xdr_inline_pages offset
after which data bytes are to be received directly into the xdr
buffer pages.
NOTE: According to the nfsv4 and v4.1 RFCs, the replied tag SHOULD be the same
is the one sent, but this is not required as a MUST for the server to do so.
The server may screw us if it replies a tag of a different length in the
compound result.
[NFS: cb_compoundhdr.replen is in words not bytes]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4xdr.c | 77 ++++++++++++++++++++++++++++++------------------------
1 files changed, 43 insertions(+), 34 deletions(-)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 75ceb42..5d665a1 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -548,6 +548,7 @@ struct compound_hdr {
__be32 * nops_p;
uint32_t taglen;
char * tag;
+ uint32_t replen; /* expected reply words */
u32 minorversion;
};
@@ -584,9 +585,17 @@ static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *
xdr_encode_opaque(p, str, len);
}
-static void encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
+static void encode_compound_hdr(struct xdr_stream *xdr,
+ struct rpc_rqst *req,
+ struct compound_hdr *hdr)
{
__be32 *p;
+ struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
+
+ /* initialize running count of expected bytes in reply.
+ * NOTE: the replied tag SHOULD be the same is the one sent,
+ * but this is not required as a MUST for the server to do so. */
+ hdr->replen = RPC_REPHDRSIZE + auth->au_rslack + 3 + hdr->taglen;
dprintk("encode_compound: tag=%.*s\n", (int)hdr->taglen, hdr->tag);
BUG_ON(hdr->taglen > NFS4_MAXTAGLEN);
@@ -1365,7 +1374,7 @@ static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_access(&xdr, args->access, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1386,7 +1395,7 @@ static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->dir_fh, &hdr);
encode_lookup(&xdr, args->name, &hdr);
encode_getfh(&xdr, &hdr);
@@ -1408,7 +1417,7 @@ static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struc
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putrootfh(&xdr, &hdr);
encode_getfh(&xdr, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1429,7 +1438,7 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_remove(&xdr, &args->name, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1450,7 +1459,7 @@ static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->old_dir, &hdr);
encode_savefh(&xdr, &hdr);
encode_putfh(&xdr, args->new_dir, &hdr);
@@ -1475,7 +1484,7 @@ static int nfs4_xdr_enc_link(struct rpc_rqst *req, __be32 *p, const struct nfs4_
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_savefh(&xdr, &hdr);
encode_putfh(&xdr, args->dir_fh, &hdr);
@@ -1500,7 +1509,7 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, __be32 *p, const struct nfs
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->dir_fh, &hdr);
encode_savefh(&xdr, &hdr);
encode_create(&xdr, args, &hdr);
@@ -1533,7 +1542,7 @@ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nf
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
encode_nops(&hdr);
@@ -1553,7 +1562,7 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closea
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_close(&xdr, args, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1574,7 +1583,7 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, __be32 *p, struct nfs_openarg
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_savefh(&xdr, &hdr);
encode_open(&xdr, args, &hdr);
@@ -1597,7 +1606,7 @@ static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, __be32 *p, struct nfs
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_open_confirm(&xdr, args, &hdr);
encode_nops(&hdr);
@@ -1617,7 +1626,7 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, __be32 *p, struct nfs_
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_open(&xdr, args, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1638,7 +1647,7 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, __be32 *p, struct n
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_open_downgrade(&xdr, args, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1659,7 +1668,7 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, __be32 *p, struct nfs_lock_ar
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_lock(&xdr, args, &hdr);
encode_nops(&hdr);
@@ -1679,7 +1688,7 @@ static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, __be32 *p, struct nfs_lockt_
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_lockt(&xdr, args, &hdr);
encode_nops(&hdr);
@@ -1699,7 +1708,7 @@ static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_locku(&xdr, args, &hdr);
encode_nops(&hdr);
@@ -1721,7 +1730,7 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n
unsigned int replen;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_readlink(&xdr, args, req, &hdr);
@@ -1751,7 +1760,7 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf
int replen;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_readdir(&xdr, args, req, &hdr);
@@ -1784,7 +1793,7 @@ static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readarg
int replen;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_read(&xdr, args, &hdr);
@@ -1813,7 +1822,7 @@ static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, __be32 *p, struct nfs_seta
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_setattr(&xdr, args, args->server, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1838,7 +1847,7 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
int replen;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0, &hdr);
@@ -1863,7 +1872,7 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writea
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_write(&xdr, args, &hdr);
req->rq_snd_buf.flags |= XDRBUF_WRITE;
@@ -1885,7 +1894,7 @@ static int nfs4_xdr_enc_commit(struct rpc_rqst *req, __be32 *p, struct nfs_write
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_commit(&xdr, args, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1906,7 +1915,7 @@ static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsin
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_fsinfo(&xdr, args->bitmask, &hdr);
encode_nops(&hdr);
@@ -1926,7 +1935,7 @@ static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct n
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_getattr_one(&xdr, args->bitmask[0] & nfs4_pathconf_bitmap[0],
&hdr);
@@ -1947,7 +1956,7 @@ static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_getattr_two(&xdr, args->bitmask[0] & nfs4_statfs_bitmap[0],
args->bitmask[1] & nfs4_statfs_bitmap[1], &hdr);
@@ -1969,7 +1978,7 @@ static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fhandle, &hdr);
encode_getattr_one(&xdr, FATTR4_WORD0_SUPPORTED_ATTRS|
FATTR4_WORD0_LINK_SUPPORT|
@@ -1990,7 +1999,7 @@ static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_client
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_renew(&xdr, clp, &hdr);
encode_nops(&hdr);
return 0;
@@ -2007,7 +2016,7 @@ static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_setclientid(&xdr, sc, &hdr);
encode_nops(&hdr);
return 0;
@@ -2025,7 +2034,7 @@ static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, str
const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 };
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_setclientid_confirm(&xdr, clp, &hdr);
encode_putrootfh(&xdr, &hdr);
encode_fsinfo(&xdr, lease_bitmap, &hdr);
@@ -2046,7 +2055,7 @@ static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, __be32 *p, const struc
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fhandle, &hdr);
encode_delegreturn(&xdr, args->stateid, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -2069,7 +2078,7 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
int replen;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->dir_fh, &hdr);
encode_lookup(&xdr, args->name, &hdr);
encode_fs_locations(&xdr, args->bitmask, &hdr);
@@ -3963,7 +3972,7 @@ nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args
int status;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
- encode_compound_hdr(&xdr, &hdr);
+ encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
status = encode_setacl(&xdr, args, &hdr);
encode_nops(&hdr);
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 27/46] NFS: update hdr->replen for every encode op
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (24 preceding siblings ...)
2009-03-03 23:58 ` [PATCH 26/46] NFS: define and initialize compound_hdr.replen Benny Halevy
@ 2009-03-03 23:58 ` Benny Halevy
2009-03-29 17:46 ` Trond Myklebust
2009-03-03 23:58 ` [PATCH 28/46] NFS: use dynamically computed compound_hdr.replen for xdr_inline_pages offset Benny Halevy
` (18 subsequent siblings)
44 siblings, 1 reply; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:58 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4xdr.c | 31 +++++++++++++++++++++++++++++++
1 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 5d665a1..e6f2d84 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -753,6 +753,7 @@ static void encode_access(struct xdr_stream *xdr, u32 access, struct compound_hd
WRITE32(OP_ACCESS);
WRITE32(access);
hdr->nops++;
+ hdr->replen += decode_access_maxsz;
}
static void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr)
@@ -764,6 +765,7 @@ static void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg
WRITE32(arg->seqid->sequence->counter);
WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE);
hdr->nops++;
+ hdr->replen += decode_close_maxsz;
}
static void encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *args, struct compound_hdr *hdr)
@@ -775,6 +777,7 @@ static void encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *ar
WRITE64(args->offset);
WRITE32(args->count);
hdr->nops++;
+ hdr->replen += decode_commit_maxsz;
}
static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *create, struct compound_hdr *hdr)
@@ -806,6 +809,7 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *
WRITE32(create->name->len);
WRITEMEM(create->name->name, create->name->len);
hdr->nops++;
+ hdr->replen += decode_create_maxsz;
encode_attrs(xdr, create->attrs, create->server);
}
@@ -819,6 +823,7 @@ static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct c
WRITE32(1);
WRITE32(bitmap);
hdr->nops++;
+ hdr->replen += decode_getattr_maxsz;
}
static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1, struct compound_hdr *hdr)
@@ -831,6 +836,7 @@ static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm
WRITE32(bm0);
WRITE32(bm1);
hdr->nops++;
+ hdr->replen += decode_getattr_maxsz;
}
static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
@@ -858,6 +864,7 @@ static void encode_getfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
RESERVE_SPACE(4);
WRITE32(OP_GETFH);
hdr->nops++;
+ hdr->replen += decode_getfh_maxsz;
}
static void encode_link(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
@@ -869,6 +876,7 @@ static void encode_link(struct xdr_stream *xdr, const struct qstr *name, struct
WRITE32(name->len);
WRITEMEM(name->name, name->len);
hdr->nops++;
+ hdr->replen += decode_link_maxsz;
}
static inline int nfs4_lock_type(struct file_lock *fl, int block)
@@ -916,6 +924,7 @@ static void encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args
WRITE32(args->lock_seqid->sequence->counter);
}
hdr->nops++;
+ hdr->replen += decode_lock_maxsz;
}
static void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args, struct compound_hdr *hdr)
@@ -932,6 +941,7 @@ static void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *ar
WRITEMEM("lock id:", 8);
WRITE64(args->lock_owner.id);
hdr->nops++;
+ hdr->replen += decode_lockt_maxsz;
}
static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args, struct compound_hdr *hdr)
@@ -946,6 +956,7 @@ static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *ar
WRITE64(args->fl->fl_start);
WRITE64(nfs4_lock_length(args->fl));
hdr->nops++;
+ hdr->replen += decode_locku_maxsz;
}
static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
@@ -958,6 +969,7 @@ static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struc
WRITE32(len);
WRITEMEM(name->name, len);
hdr->nops++;
+ hdr->replen += decode_lookup_maxsz;
}
static void encode_share_access(struct xdr_stream *xdr, fmode_t fmode)
@@ -1097,6 +1109,7 @@ static void encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg,
BUG();
}
hdr->nops++;
+ hdr->replen += decode_open_maxsz;
}
static void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg, struct compound_hdr *hdr)
@@ -1108,6 +1121,7 @@ static void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_co
WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE);
WRITE32(arg->seqid->sequence->counter);
hdr->nops++;
+ hdr->replen += decode_open_confirm_maxsz;
}
static void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr)
@@ -1120,6 +1134,7 @@ static void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_close
WRITE32(arg->seqid->sequence->counter);
encode_share_access(xdr, arg->fmode);
hdr->nops++;
+ hdr->replen += decode_open_downgrade_maxsz;
}
static void
@@ -1133,6 +1148,7 @@ encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh, struct compound_hd
WRITE32(len);
WRITEMEM(fh->data, len);
hdr->nops++;
+ hdr->replen += decode_putfh_maxsz;
}
static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
@@ -1142,6 +1158,7 @@ static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
RESERVE_SPACE(4);
WRITE32(OP_PUTROOTFH);
hdr->nops++;
+ hdr->replen += decode_putrootfh_maxsz;
}
static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx)
@@ -1170,6 +1187,7 @@ static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args,
WRITE64(args->offset);
WRITE32(args->count);
hdr->nops++;
+ hdr->replen += decode_read_maxsz;
}
static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr)
@@ -1195,6 +1213,7 @@ static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg
WRITE32(attrs[0] & readdir->bitmask[0]);
WRITE32(attrs[1] & readdir->bitmask[1]);
hdr->nops++;
+ hdr->replen += decode_readdir_maxsz;
dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n",
__func__,
(unsigned long long)readdir->cookie,
@@ -1211,6 +1230,7 @@ static void encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *
RESERVE_SPACE(4);
WRITE32(OP_READLINK);
hdr->nops++;
+ hdr->replen += decode_readlink_maxsz;
}
static void encode_remove(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
@@ -1222,6 +1242,7 @@ static void encode_remove(struct xdr_stream *xdr, const struct qstr *name, struc
WRITE32(name->len);
WRITEMEM(name->name, name->len);
hdr->nops++;
+ hdr->replen += decode_remove_maxsz;
}
static void encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, const struct qstr *newname, struct compound_hdr *hdr)
@@ -1237,6 +1258,7 @@ static void encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, co
WRITE32(newname->len);
WRITEMEM(newname->name, newname->len);
hdr->nops++;
+ hdr->replen += decode_rename_maxsz;
}
static void encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_stateid, struct compound_hdr *hdr)
@@ -1247,6 +1269,7 @@ static void encode_renew(struct xdr_stream *xdr, const struct nfs_client *client
WRITE32(OP_RENEW);
WRITE64(client_stateid->cl_clientid);
hdr->nops++;
+ hdr->replen += decode_renew_maxsz;
}
static void
@@ -1257,6 +1280,7 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
RESERVE_SPACE(4);
WRITE32(OP_RESTOREFH);
hdr->nops++;
+ hdr->replen += decode_restorefh_maxsz;
}
static int
@@ -1276,6 +1300,7 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun
WRITE32(arg->acl_len);
xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
hdr->nops++;
+ hdr->replen += decode_setacl_maxsz;
return 0;
}
@@ -1287,6 +1312,7 @@ encode_savefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
RESERVE_SPACE(4);
WRITE32(OP_SAVEFH);
hdr->nops++;
+ hdr->replen += decode_savefh_maxsz;
}
static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *arg, const struct nfs_server *server, struct compound_hdr *hdr)
@@ -1297,6 +1323,7 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs
WRITE32(OP_SETATTR);
WRITEMEM(arg->stateid.data, NFS4_STATEID_SIZE);
hdr->nops++;
+ hdr->replen += decode_setattr_maxsz;
encode_attrs(xdr, arg->iap, server);
}
@@ -1316,6 +1343,7 @@ static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclie
RESERVE_SPACE(4);
WRITE32(setclientid->sc_cb_ident);
hdr->nops++;
+ hdr->replen += decode_setclientid_maxsz;
}
static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state, struct compound_hdr *hdr)
@@ -1327,6 +1355,7 @@ static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_
WRITE64(client_state->cl_clientid);
WRITEMEM(client_state->cl_confirm.data, NFS4_VERIFIER_SIZE);
hdr->nops++;
+ hdr->replen += decode_setclientid_confirm_maxsz;
}
static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args, struct compound_hdr *hdr)
@@ -1345,6 +1374,7 @@ static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *arg
xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
hdr->nops++;
+ hdr->replen += decode_write_maxsz;
}
static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid, struct compound_hdr *hdr)
@@ -1356,6 +1386,7 @@ static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *state
WRITE32(OP_DELEGRETURN);
WRITEMEM(stateid->data, NFS4_STATEID_SIZE);
hdr->nops++;
+ hdr->replen += decode_delegreturn_maxsz;
}
/*
* END OF "GENERIC" ENCODE ROUTINES.
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* Re: [PATCH 27/46] NFS: update hdr->replen for every encode op
2009-03-03 23:58 ` [PATCH 27/46] NFS: update hdr->replen for every encode op Benny Halevy
@ 2009-03-29 17:46 ` Trond Myklebust
[not found] ` <1238348809.23986.4.camel-rJ7iovZKK19ZJLDQqaL3InhyD016LWXt@public.gmane.org>
0 siblings, 1 reply; 63+ messages in thread
From: Trond Myklebust @ 2009-03-29 17:46 UTC (permalink / raw)
To: Benny Halevy; +Cc: linux-nfs, pnfs
On Tue, 2009-03-03 at 16:58 -0700, Benny Halevy wrote:
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> ---
> fs/nfs/nfs4xdr.c | 31 +++++++++++++++++++++++++++++++
> 1 files changed, 31 insertions(+), 0 deletions(-)
>
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index 5d665a1..e6f2d84 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -753,6 +753,7 @@ static void encode_access(struct xdr_stream *xdr,
> u32 access, struct compound_hd
> WRITE32(OP_ACCESS);
> WRITE32(access);
> hdr->nops++;
> + hdr->replen += decode_access_maxsz;
> }
>
> static void encode_close(struct xdr_stream *xdr, const struct
> nfs_closeargs *arg, struct compound_hdr *hdr)
> @@ -764,6 +765,7 @@ static void encode_close(struct xdr_stream *xdr,
> const struct nfs_closeargs *arg
> WRITE32(arg->seqid->sequence->counter);
> WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE);
> hdr->nops++;
> + hdr->replen += decode_close_maxsz;
> }
>
> static void encode_commit(struct xdr_stream *xdr, const struct
> nfs_writeargs *args, struct compound_hdr *hdr)
> @@ -775,6 +777,7 @@ static void encode_commit(struct xdr_stream *xdr,
> const struct nfs_writeargs *ar
> WRITE64(args->offset);
> WRITE32(args->count);
> hdr->nops++;
> + hdr->replen += decode_commit_maxsz;
> }
>
> static void encode_create(struct xdr_stream *xdr, const struct
> nfs4_create_arg *create, struct compound_hdr *hdr)
> @@ -806,6 +809,7 @@ static void encode_create(struct xdr_stream *xdr,
> const struct nfs4_create_arg *
> WRITE32(create->name->len);
> WRITEMEM(create->name->name, create->name->len);
> hdr->nops++;
> + hdr->replen += decode_create_maxsz;
>
> encode_attrs(xdr, create->attrs, create->server);
> }
> @@ -819,6 +823,7 @@ static void encode_getattr_one(struct xdr_stream
> *xdr, uint32_t bitmap, struct c
> WRITE32(1);
> WRITE32(bitmap);
> hdr->nops++;
> + hdr->replen += decode_getattr_maxsz;
> }
>
> static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0,
> uint32_t bm1, struct compound_hdr *hdr)
> @@ -831,6 +836,7 @@ static void encode_getattr_two(struct xdr_stream
> *xdr, uint32_t bm0, uint32_t bm
> WRITE32(bm0);
> WRITE32(bm1);
> hdr->nops++;
> + hdr->replen += decode_getattr_maxsz;
> }
Hmm... Not always true, as I pointed out w.r.t. fs_locations. Perhaps we
should add an encode_getfattr() for the generic case, and keep
fs_locations as special.
> static void encode_getfattr(struct xdr_stream *xdr, const u32*
> bitmask, struct compound_hdr *hdr)
> @@ -858,6 +864,7 @@ static void encode_getfh(struct xdr_stream *xdr,
> struct compound_hdr *hdr)
> RESERVE_SPACE(4);
> WRITE32(OP_GETFH);
> hdr->nops++;
> + hdr->replen += decode_getfh_maxsz;
> }
>
> static void encode_link(struct xdr_stream *xdr, const struct qstr
> *name, struct compound_hdr *hdr)
> @@ -869,6 +876,7 @@ static void encode_link(struct xdr_stream *xdr,
> const struct qstr *name, struct
> WRITE32(name->len);
> WRITEMEM(name->name, name->len);
> hdr->nops++;
> + hdr->replen += decode_link_maxsz;
> }
>
> static inline int nfs4_lock_type(struct file_lock *fl, int block)
> @@ -916,6 +924,7 @@ static void encode_lock(struct xdr_stream *xdr,
> const struct nfs_lock_args *args
> WRITE32(args->lock_seqid->sequence->counter);
> }
> hdr->nops++;
> + hdr->replen += decode_lock_maxsz;
> }
>
> static void encode_lockt(struct xdr_stream *xdr, const struct
> nfs_lockt_args *args, struct compound_hdr *hdr)
> @@ -932,6 +941,7 @@ static void encode_lockt(struct xdr_stream *xdr,
> const struct nfs_lockt_args *ar
> WRITEMEM("lock id:", 8);
> WRITE64(args->lock_owner.id);
> hdr->nops++;
> + hdr->replen += decode_lockt_maxsz;
> }
>
> static void encode_locku(struct xdr_stream *xdr, const struct
> nfs_locku_args *args, struct compound_hdr *hdr)
> @@ -946,6 +956,7 @@ static void encode_locku(struct xdr_stream *xdr,
> const struct nfs_locku_args *ar
> WRITE64(args->fl->fl_start);
> WRITE64(nfs4_lock_length(args->fl));
> hdr->nops++;
> + hdr->replen += decode_locku_maxsz;
> }
>
> static void encode_lookup(struct xdr_stream *xdr, const struct qstr
> *name, struct compound_hdr *hdr)
> @@ -958,6 +969,7 @@ static void encode_lookup(struct xdr_stream *xdr,
> const struct qstr *name, struc
> WRITE32(len);
> WRITEMEM(name->name, len);
> hdr->nops++;
> + hdr->replen += decode_lookup_maxsz;
> }
>
> static void encode_share_access(struct xdr_stream *xdr, fmode_t
> fmode)
> @@ -1097,6 +1109,7 @@ static void encode_open(struct xdr_stream *xdr,
> const struct nfs_openargs *arg,
> BUG();
> }
> hdr->nops++;
> + hdr->replen += decode_open_maxsz;
> }
>
> static void encode_open_confirm(struct xdr_stream *xdr, const struct
> nfs_open_confirmargs *arg, struct compound_hdr *hdr)
> @@ -1108,6 +1121,7 @@ static void encode_open_confirm(struct
> xdr_stream *xdr, const struct nfs_open_co
> WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE);
> WRITE32(arg->seqid->sequence->counter);
> hdr->nops++;
> + hdr->replen += decode_open_confirm_maxsz;
> }
>
> static void encode_open_downgrade(struct xdr_stream *xdr, const
> struct nfs_closeargs *arg, struct compound_hdr *hdr)
> @@ -1120,6 +1134,7 @@ static void encode_open_downgrade(struct
> xdr_stream *xdr, const struct nfs_close
> WRITE32(arg->seqid->sequence->counter);
> encode_share_access(xdr, arg->fmode);
> hdr->nops++;
> + hdr->replen += decode_open_downgrade_maxsz;
> }
>
> static void
> @@ -1133,6 +1148,7 @@ encode_putfh(struct xdr_stream *xdr, const
> struct nfs_fh *fh, struct compound_hd
> WRITE32(len);
> WRITEMEM(fh->data, len);
> hdr->nops++;
> + hdr->replen += decode_putfh_maxsz;
> }
>
> static void encode_putrootfh(struct xdr_stream *xdr, struct
> compound_hdr *hdr)
> @@ -1142,6 +1158,7 @@ static void encode_putrootfh(struct xdr_stream
> *xdr, struct compound_hdr *hdr)
> RESERVE_SPACE(4);
> WRITE32(OP_PUTROOTFH);
> hdr->nops++;
> + hdr->replen += decode_putrootfh_maxsz;
> }
>
> static void encode_stateid(struct xdr_stream *xdr, const struct
> nfs_open_context *ctx)
> @@ -1170,6 +1187,7 @@ static void encode_read(struct xdr_stream *xdr,
> const struct nfs_readargs *args,
> WRITE64(args->offset);
> WRITE32(args->count);
> hdr->nops++;
> + hdr->replen += decode_read_maxsz;
> }
>
> static void encode_readdir(struct xdr_stream *xdr, const struct
> nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr
> *hdr)
> @@ -1195,6 +1213,7 @@ static void encode_readdir(struct xdr_stream
> *xdr, const struct nfs4_readdir_arg
> WRITE32(attrs[0] & readdir->bitmask[0]);
> WRITE32(attrs[1] & readdir->bitmask[1]);
> hdr->nops++;
> + hdr->replen += decode_readdir_maxsz;
> dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %
> 08x:%08x\n",
> __func__,
> (unsigned long long)readdir->cookie,
> @@ -1211,6 +1230,7 @@ static void encode_readlink(struct xdr_stream
> *xdr, const struct nfs4_readlink *
> RESERVE_SPACE(4);
> WRITE32(OP_READLINK);
> hdr->nops++;
> + hdr->replen += decode_readlink_maxsz;
> }
>
> static void encode_remove(struct xdr_stream *xdr, const struct qstr
> *name, struct compound_hdr *hdr)
> @@ -1222,6 +1242,7 @@ static void encode_remove(struct xdr_stream
> *xdr, const struct qstr *name, struc
> WRITE32(name->len);
> WRITEMEM(name->name, name->len);
> hdr->nops++;
> + hdr->replen += decode_remove_maxsz;
> }
>
> static void encode_rename(struct xdr_stream *xdr, const struct qstr
> *oldname, const struct qstr *newname, struct compound_hdr *hdr)
> @@ -1237,6 +1258,7 @@ static void encode_rename(struct xdr_stream
> *xdr, const struct qstr *oldname, co
> WRITE32(newname->len);
> WRITEMEM(newname->name, newname->len);
> hdr->nops++;
> + hdr->replen += decode_rename_maxsz;
> }
>
> static void encode_renew(struct xdr_stream *xdr, const struct
> nfs_client *client_stateid, struct compound_hdr *hdr)
> @@ -1247,6 +1269,7 @@ static void encode_renew(struct xdr_stream *xdr,
> const struct nfs_client *client
> WRITE32(OP_RENEW);
> WRITE64(client_stateid->cl_clientid);
> hdr->nops++;
> + hdr->replen += decode_renew_maxsz;
> }
>
> static void
> @@ -1257,6 +1280,7 @@ encode_restorefh(struct xdr_stream *xdr, struct
> compound_hdr *hdr)
> RESERVE_SPACE(4);
> WRITE32(OP_RESTOREFH);
> hdr->nops++;
> + hdr->replen += decode_restorefh_maxsz;
> }
>
> static int
> @@ -1276,6 +1300,7 @@ encode_setacl(struct xdr_stream *xdr, struct
> nfs_setaclargs *arg, struct compoun
> WRITE32(arg->acl_len);
> xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase,
> arg->acl_len);
> hdr->nops++;
> + hdr->replen += decode_setacl_maxsz;
> return 0;
> }
>
> @@ -1287,6 +1312,7 @@ encode_savefh(struct xdr_stream *xdr, struct
> compound_hdr *hdr)
> RESERVE_SPACE(4);
> WRITE32(OP_SAVEFH);
> hdr->nops++;
> + hdr->replen += decode_savefh_maxsz;
> }
>
> static void encode_setattr(struct xdr_stream *xdr, const struct
> nfs_setattrargs *arg, const struct nfs_server *server, struct
> compound_hdr *hdr)
> @@ -1297,6 +1323,7 @@ static void encode_setattr(struct xdr_stream
> *xdr, const struct nfs_setattrargs
> WRITE32(OP_SETATTR);
> WRITEMEM(arg->stateid.data, NFS4_STATEID_SIZE);
> hdr->nops++;
> + hdr->replen += decode_setattr_maxsz;
> encode_attrs(xdr, arg->iap, server);
> }
>
> @@ -1316,6 +1343,7 @@ static void encode_setclientid(struct xdr_stream
> *xdr, const struct nfs4_setclie
> RESERVE_SPACE(4);
> WRITE32(setclientid->sc_cb_ident);
> hdr->nops++;
> + hdr->replen += decode_setclientid_maxsz;
> }
>
> static void encode_setclientid_confirm(struct xdr_stream *xdr, const
> struct nfs_client *client_state, struct compound_hdr *hdr)
> @@ -1327,6 +1355,7 @@ static void encode_setclientid_confirm(struct
> xdr_stream *xdr, const struct nfs_
> WRITE64(client_state->cl_clientid);
> WRITEMEM(client_state->cl_confirm.data, NFS4_VERIFIER_SIZE);
> hdr->nops++;
> + hdr->replen += decode_setclientid_confirm_maxsz;
> }
>
> static void encode_write(struct xdr_stream *xdr, const struct
> nfs_writeargs *args, struct compound_hdr *hdr)
> @@ -1345,6 +1374,7 @@ static void encode_write(struct xdr_stream *xdr,
> const struct nfs_writeargs *arg
>
> xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
> hdr->nops++;
> + hdr->replen += decode_write_maxsz;
> }
>
> static void encode_delegreturn(struct xdr_stream *xdr, const
> nfs4_stateid *stateid, struct compound_hdr *hdr)
> @@ -1356,6 +1386,7 @@ static void encode_delegreturn(struct xdr_stream
> *xdr, const nfs4_stateid *state
> WRITE32(OP_DELEGRETURN);
> WRITEMEM(stateid->data, NFS4_STATEID_SIZE);
> hdr->nops++;
> + hdr->replen += decode_delegreturn_maxsz;
> }
> /*
> * END OF "GENERIC" ENCODE ROUTINES.
> --
> 1.6.1.3
>
>
>
--
Trond Myklebust
Linux NFS client maintainer
NetApp
Trond.Myklebust@netapp.com
www.netapp.com
^ permalink raw reply [flat|nested] 63+ messages in thread
* [PATCH 28/46] NFS: use dynamically computed compound_hdr.replen for xdr_inline_pages offset
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (25 preceding siblings ...)
2009-03-03 23:58 ` [PATCH 27/46] NFS: update hdr->replen for every encode op Benny Halevy
@ 2009-03-03 23:58 ` Benny Halevy
2009-03-29 19:30 ` [pnfs] " Benny Halevy
2009-03-30 12:40 ` Benny Halevy
2009-03-03 23:58 ` [PATCH 29/46] nfs41: xdr {encode,decode}_sequence Benny Halevy
` (17 subsequent siblings)
44 siblings, 2 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:58 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
As Trond suggested, rather than passing a constant to xdr_inline_pages,
keep a running count of the expected reply bytes. In preparation for
nfs41, where additional op sequence are expteced when talking to nfs41
servers.
[NFS: cb_compoundhdr.replen is in words not bytes]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4xdr.c | 44 ++++++--------------------------------------
1 files changed, 6 insertions(+), 38 deletions(-)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index e6f2d84..9cec237 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1757,20 +1757,13 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n
struct compound_hdr hdr = {
.minorversion = clp->cl_minorversion,
};
- struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
- unsigned int replen;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_readlink(&xdr, args, req, &hdr);
- /* set up reply kvec
- * toplevel_status + taglen + rescount + OP_PUTFH + status
- * + OP_READLINK + status + string length = 8
- */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readlink_sz) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages,
+ xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
args->pgbase, args->pglen);
encode_nops(&hdr);
return 0;
@@ -1787,23 +1780,16 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf
struct compound_hdr hdr = {
.minorversion = clp->cl_minorversion,
};
- struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
- int replen;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_readdir(&xdr, args, req, &hdr);
- /* set up reply kvec
- * toplevel_status + taglen + rescount + OP_PUTFH + status
- * + OP_READDIR + status + verifer(2) = 9
- */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readdir_sz) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages,
+ xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
args->pgbase, args->count);
dprintk("%s: inlined page args = (%u, %p, %u, %u)\n",
- __func__, replen, args->pages,
+ __func__, hdr.replen << 2, args->pages,
args->pgbase, args->count);
encode_nops(&hdr);
return 0;
@@ -1814,26 +1800,19 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf
*/
static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
{
- struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
struct xdr_stream xdr;
struct nfs_client *clp =
(struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
.minorversion = clp->cl_minorversion,
};
- int replen;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_read(&xdr, args, &hdr);
- /* set up reply kvec
- * toplevel status + taglen=0 + rescount + OP_PUTFH + status
- * + OP_READ + status + eof + datalen = 9
- */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_read_sz) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen,
+ xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2,
args->pages, args->pgbase, args->count);
req->rq_rcv_buf.flags |= XDRBUF_READ;
encode_nops(&hdr);
@@ -1869,22 +1848,18 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
struct nfs_getaclargs *args)
{
struct xdr_stream xdr;
- struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
struct nfs_client *clp =
(struct nfs_client *)req->rq_task->tk_client->cl_private;
struct compound_hdr hdr = {
.minorversion = clp->cl_minorversion,
};
- int replen;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0, &hdr);
- /* set up reply buffer: */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_getacl_sz) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen,
+ xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2,
args->acl_pages, args->acl_pgbase, args->acl_len);
encode_nops(&hdr);
return 0;
@@ -2105,8 +2080,6 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
struct compound_hdr hdr = {
.minorversion = clp->cl_minorversion,
};
- struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
- int replen;
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
@@ -2114,12 +2087,7 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
encode_lookup(&xdr, args->name, &hdr);
encode_fs_locations(&xdr, args->bitmask, &hdr);
- /* set up reply
- * toplevel_status + OP_PUTFH + status
- * + OP_LOOKUP + status + OP_GETATTR + status = 7
- */
- replen = (RPC_REPHDRSIZE + auth->au_rslack + 7) << 2;
- xdr_inline_pages(&req->rq_rcv_buf, replen, &args->page,
+ xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, &args->page,
0, PAGE_SIZE);
encode_nops(&hdr);
return 0;
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* Re: [pnfs] [PATCH 28/46] NFS: use dynamically computed compound_hdr.replen for xdr_inline_pages offset
2009-03-03 23:58 ` [PATCH 28/46] NFS: use dynamically computed compound_hdr.replen for xdr_inline_pages offset Benny Halevy
@ 2009-03-29 19:30 ` Benny Halevy
2009-03-30 12:40 ` Benny Halevy
1 sibling, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-29 19:30 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
On Mar. 04, 2009, 1:58 +0200, Benny Halevy <bhalevy@panasas.com> wrote:
> As Trond suggested, rather than passing a constant to xdr_inline_pages,
> keep a running count of the expected reply bytes. In preparation for
> nfs41, where additional op sequence are expteced when talking to nfs41
> servers.
>
> [NFS: cb_compoundhdr.replen is in words not bytes]
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> ---
> fs/nfs/nfs4xdr.c | 44 ++++++--------------------------------------
> 1 files changed, 6 insertions(+), 38 deletions(-)
>
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index e6f2d84..9cec237 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -1757,20 +1757,13 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n
> struct compound_hdr hdr = {
> .minorversion = clp->cl_minorversion,
> };
> - struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
> - unsigned int replen;
>
> xdr_init_encode(&xdr, &req->rq_snd_buf, p);
> encode_compound_hdr(&xdr, req, &hdr);
> encode_putfh(&xdr, args->fh, &hdr);
> encode_readlink(&xdr, args, req, &hdr);
>
> - /* set up reply kvec
> - * toplevel_status + taglen + rescount + OP_PUTFH + status
> - * + OP_READLINK + status + string length = 8
> - */
> - replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readlink_sz) << 2;
> - xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages,
> + xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
> args->pgbase, args->pglen);
> encode_nops(&hdr);
> return 0;
> @@ -1787,23 +1780,16 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf
> struct compound_hdr hdr = {
> .minorversion = clp->cl_minorversion,
> };
> - struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
> - int replen;
>
> xdr_init_encode(&xdr, &req->rq_snd_buf, p);
> encode_compound_hdr(&xdr, req, &hdr);
> encode_putfh(&xdr, args->fh, &hdr);
> encode_readdir(&xdr, args, req, &hdr);
>
> - /* set up reply kvec
> - * toplevel_status + taglen + rescount + OP_PUTFH + status
> - * + OP_READDIR + status + verifer(2) = 9
> - */
> - replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readdir_sz) << 2;
> - xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages,
> + xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
> args->pgbase, args->count);
> dprintk("%s: inlined page args = (%u, %p, %u, %u)\n",
> - __func__, replen, args->pages,
> + __func__, hdr.replen << 2, args->pages,
> args->pgbase, args->count);
> encode_nops(&hdr);
> return 0;
> @@ -1814,26 +1800,19 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf
> */
> static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
> {
> - struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
> struct xdr_stream xdr;
> struct nfs_client *clp =
> (struct nfs_client *)req->rq_task->tk_client->cl_private;
> struct compound_hdr hdr = {
> .minorversion = clp->cl_minorversion,
> };
> - int replen;
>
> xdr_init_encode(&xdr, &req->rq_snd_buf, p);
> encode_compound_hdr(&xdr, req, &hdr);
> encode_putfh(&xdr, args->fh, &hdr);
> encode_read(&xdr, args, &hdr);
>
> - /* set up reply kvec
> - * toplevel status + taglen=0 + rescount + OP_PUTFH + status
> - * + OP_READ + status + eof + datalen = 9
> - */
> - replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_read_sz) << 2;
> - xdr_inline_pages(&req->rq_rcv_buf, replen,
> + xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2,
> args->pages, args->pgbase, args->count);
> req->rq_rcv_buf.flags |= XDRBUF_READ;
> encode_nops(&hdr);
> @@ -1869,22 +1848,18 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
> struct nfs_getaclargs *args)
> {
> struct xdr_stream xdr;
> - struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
> struct nfs_client *clp =
> (struct nfs_client *)req->rq_task->tk_client->cl_private;
> struct compound_hdr hdr = {
> .minorversion = clp->cl_minorversion,
> };
> - int replen;
>
> xdr_init_encode(&xdr, &req->rq_snd_buf, p);
> encode_compound_hdr(&xdr, req, &hdr);
> encode_putfh(&xdr, args->fh, &hdr);
> encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0, &hdr);
>
> - /* set up reply buffer: */
> - replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_getacl_sz) << 2;
> - xdr_inline_pages(&req->rq_rcv_buf, replen,
> + xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2,
> args->acl_pages, args->acl_pgbase, args->acl_len);
> encode_nops(&hdr);
> return 0;
> @@ -2105,8 +2080,6 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
> struct compound_hdr hdr = {
> .minorversion = clp->cl_minorversion,
> };
> - struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
> - int replen;
>
> xdr_init_encode(&xdr, &req->rq_snd_buf, p);
> encode_compound_hdr(&xdr, req, &hdr);
> @@ -2114,12 +2087,7 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
> encode_lookup(&xdr, args->name, &hdr);
To work around the fs_locations issue we can also get hdr.sample
replen here, right before calling encode_fs_locations.
Benny
> encode_fs_locations(&xdr, args->bitmask, &hdr);
>
> - /* set up reply
> - * toplevel_status + OP_PUTFH + status
> - * + OP_LOOKUP + status + OP_GETATTR + status = 7
> - */
> - replen = (RPC_REPHDRSIZE + auth->au_rslack + 7) << 2;
> - xdr_inline_pages(&req->rq_rcv_buf, replen, &args->page,
> + xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, &args->page,
> 0, PAGE_SIZE);
> encode_nops(&hdr);
> return 0;
^ permalink raw reply [flat|nested] 63+ messages in thread* Re: [pnfs] [PATCH 28/46] NFS: use dynamically computed compound_hdr.replen for xdr_inline_pages offset
2009-03-03 23:58 ` [PATCH 28/46] NFS: use dynamically computed compound_hdr.replen for xdr_inline_pages offset Benny Halevy
2009-03-29 19:30 ` [pnfs] " Benny Halevy
@ 2009-03-30 12:40 ` Benny Halevy
1 sibling, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-30 12:40 UTC (permalink / raw)
To: Trond Myklebust, J. Bruce Fields; +Cc: linux-nfs, pnfs
On Mar. 04, 2009, 1:58 +0200, Benny Halevy <bhalevy@panasas.com> wrote:
> As Trond suggested, rather than passing a constant to xdr_inline_pages,
> keep a running count of the expected reply bytes. In preparation for
> nfs41, where additional op sequence are expteced when talking to nfs41
> servers.
>
> [NFS: cb_compoundhdr.replen is in words not bytes]
> Signed-off-by: Benny Halevy <bhalevy@panasas.com>
> ---
> fs/nfs/nfs4xdr.c | 44 ++++++--------------------------------------
> 1 files changed, 6 insertions(+), 38 deletions(-)
>
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index e6f2d84..9cec237 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -1757,20 +1757,13 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n
> struct compound_hdr hdr = {
> .minorversion = clp->cl_minorversion,
> };
> - struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
> - unsigned int replen;
>
> xdr_init_encode(&xdr, &req->rq_snd_buf, p);
> encode_compound_hdr(&xdr, req, &hdr);
> encode_putfh(&xdr, args->fh, &hdr);
> encode_readlink(&xdr, args, req, &hdr);
>
> - /* set up reply kvec
> - * toplevel_status + taglen + rescount + OP_PUTFH + status
> - * + OP_READLINK + status + string length = 8
> - */
> - replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readlink_sz) << 2;
> - xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages,
> + xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
> args->pgbase, args->pglen);
> encode_nops(&hdr);
> return 0;
> @@ -1787,23 +1780,16 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf
> struct compound_hdr hdr = {
> .minorversion = clp->cl_minorversion,
> };
> - struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
> - int replen;
>
> xdr_init_encode(&xdr, &req->rq_snd_buf, p);
> encode_compound_hdr(&xdr, req, &hdr);
> encode_putfh(&xdr, args->fh, &hdr);
> encode_readdir(&xdr, args, req, &hdr);
>
> - /* set up reply kvec
> - * toplevel_status + taglen + rescount + OP_PUTFH + status
> - * + OP_READDIR + status + verifer(2) = 9
> - */
> - replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readdir_sz) << 2;
> - xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages,
> + xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
> args->pgbase, args->count);
> dprintk("%s: inlined page args = (%u, %p, %u, %u)\n",
> - __func__, replen, args->pages,
> + __func__, hdr.replen << 2, args->pages,
> args->pgbase, args->count);
> encode_nops(&hdr);
> return 0;
> @@ -1814,26 +1800,19 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf
> */
> static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
> {
> - struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
> struct xdr_stream xdr;
> struct nfs_client *clp =
> (struct nfs_client *)req->rq_task->tk_client->cl_private;
> struct compound_hdr hdr = {
> .minorversion = clp->cl_minorversion,
> };
> - int replen;
>
> xdr_init_encode(&xdr, &req->rq_snd_buf, p);
> encode_compound_hdr(&xdr, req, &hdr);
> encode_putfh(&xdr, args->fh, &hdr);
> encode_read(&xdr, args, &hdr);
>
> - /* set up reply kvec
> - * toplevel status + taglen=0 + rescount + OP_PUTFH + status
> - * + OP_READ + status + eof + datalen = 9
> - */
> - replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_read_sz) << 2;
> - xdr_inline_pages(&req->rq_rcv_buf, replen,
> + xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2,
> args->pages, args->pgbase, args->count);
> req->rq_rcv_buf.flags |= XDRBUF_READ;
> encode_nops(&hdr);
> @@ -1869,22 +1848,18 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
> struct nfs_getaclargs *args)
> {
> struct xdr_stream xdr;
> - struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
> struct nfs_client *clp =
> (struct nfs_client *)req->rq_task->tk_client->cl_private;
> struct compound_hdr hdr = {
> .minorversion = clp->cl_minorversion,
> };
> - int replen;
>
> xdr_init_encode(&xdr, &req->rq_snd_buf, p);
> encode_compound_hdr(&xdr, req, &hdr);
> encode_putfh(&xdr, args->fh, &hdr);
We need to get replen here too (similar to fs_locations)
and add to it nfs4_fattr_bitmap_maxsz + 1 (for attrlen).
That said, what if the server returns a bitmap of length 1
as FATTR4_WORD0_ACL uses only the first word in the bitmap?
In this case xdr_read_pages will need to shift a word into
the req pages, no?
We actually have a patch in the nfsd41 server series that
will do just that (42d7617 nfsd41: support for 3-word long attribute bitmask).
What other servers are expected to do?
Benny
> encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0, &hdr);
>
> - /* set up reply buffer: */
> - replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_getacl_sz) << 2;
> - xdr_inline_pages(&req->rq_rcv_buf, replen,
> + xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2,
> args->acl_pages, args->acl_pgbase, args->acl_len);
> encode_nops(&hdr);
> return 0;
> @@ -2105,8 +2080,6 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
> struct compound_hdr hdr = {
> .minorversion = clp->cl_minorversion,
> };
> - struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
> - int replen;
>
> xdr_init_encode(&xdr, &req->rq_snd_buf, p);
> encode_compound_hdr(&xdr, req, &hdr);
> @@ -2114,12 +2087,7 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
> encode_lookup(&xdr, args->name, &hdr);
> encode_fs_locations(&xdr, args->bitmask, &hdr);
>
> - /* set up reply
> - * toplevel_status + OP_PUTFH + status
> - * + OP_LOOKUP + status + OP_GETATTR + status = 7
> - */
> - replen = (RPC_REPHDRSIZE + auth->au_rslack + 7) << 2;
> - xdr_inline_pages(&req->rq_rcv_buf, replen, &args->page,
> + xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, &args->page,
> 0, PAGE_SIZE);
> encode_nops(&hdr);
> return 0;
^ permalink raw reply [flat|nested] 63+ messages in thread
* [PATCH 29/46] nfs41: xdr {encode,decode}_sequence
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (26 preceding siblings ...)
2009-03-03 23:58 ` [PATCH 28/46] NFS: use dynamically computed compound_hdr.replen for xdr_inline_pages offset Benny Halevy
@ 2009-03-03 23:58 ` Benny Halevy
2009-03-03 23:59 ` [PATCH 30/46] nfs41: stubs for nfs41 procedures Benny Halevy
` (16 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:58 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Implement stubs for encode and decode sequence, defined as no-ops when
CONFIG_NFS_V4_1 is not defined.
Add the nfsv41 encode and decode sizes. Add encode_sequence to all
nfs4_enc_* routines and decode_sequence to all nfs4_dec_* routines as required
by v41.
[was nfs41: minorversion support for xdr]
[added nfs_client argument to encode_sequence so not to use sequence_args to pass sa_session]
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4xdr.c | 244 +++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 234 insertions(+), 10 deletions(-)
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 9cec237..14af88a 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -244,43 +244,63 @@ static int nfs4_stat_to_errno(int);
(encode_getattr_maxsz)
#define decode_fs_locations_maxsz \
(decode_getattr_maxsz)
+
+#if defined(CONFIG_NFS_V4_1)
+#define encode_sequence_maxsz 0 /* stub */
+#define decode_sequence_maxsz 0 /* stub */
+#else /* CONFIG_NFS_V4_1 */
+#define encode_sequence_maxsz 0
+#define decode_sequence_maxsz 0
+#endif /* CONFIG_NFS_V4_1 */
+
#define NFS4_enc_compound_sz (1024) /* XXX: large enough? */
#define NFS4_dec_compound_sz (1024) /* XXX: large enough? */
#define NFS4_enc_read_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_read_maxsz)
#define NFS4_dec_read_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_read_maxsz)
#define NFS4_enc_readlink_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_readlink_maxsz)
#define NFS4_dec_readlink_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_readlink_maxsz)
#define NFS4_enc_readdir_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_readdir_maxsz)
#define NFS4_dec_readdir_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_readdir_maxsz)
#define NFS4_enc_write_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_write_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_write_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_write_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_commit_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_commit_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_savefh_maxsz + \
encode_open_maxsz + \
@@ -289,6 +309,7 @@ static int nfs4_stat_to_errno(int);
encode_restorefh_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_savefh_maxsz + \
decode_open_maxsz + \
@@ -305,43 +326,53 @@ static int nfs4_stat_to_errno(int);
decode_putfh_maxsz + \
decode_open_confirm_maxsz)
#define NFS4_enc_open_noattr_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_open_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_open_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_open_downgrade_sz \
(compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_open_downgrade_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_open_downgrade_sz \
(compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_open_downgrade_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_close_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_close_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_setattr_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_setattr_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_setattr_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_fsinfo_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_fsinfo_maxsz)
#define NFS4_dec_fsinfo_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_fsinfo_maxsz)
#define NFS4_enc_renew_sz (compound_encode_hdr_maxsz + \
@@ -363,64 +394,81 @@ static int nfs4_stat_to_errno(int);
decode_putrootfh_maxsz + \
decode_fsinfo_maxsz)
#define NFS4_enc_lock_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_lock_maxsz)
#define NFS4_dec_lock_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_lock_maxsz)
#define NFS4_enc_lockt_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_lockt_maxsz)
#define NFS4_dec_lockt_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_lockt_maxsz)
#define NFS4_enc_locku_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_locku_maxsz)
#define NFS4_dec_locku_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_locku_maxsz)
#define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_access_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_access_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_access_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_getattr_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_getattr_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_lookup_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_lookup_maxsz + \
encode_getattr_maxsz + \
encode_getfh_maxsz)
#define NFS4_dec_lookup_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_lookup_maxsz + \
decode_getattr_maxsz + \
decode_getfh_maxsz)
#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putrootfh_maxsz + \
encode_getattr_maxsz + \
encode_getfh_maxsz)
#define NFS4_dec_lookup_root_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putrootfh_maxsz + \
decode_getattr_maxsz + \
decode_getfh_maxsz)
#define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_remove_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_remove_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_savefh_maxsz + \
encode_putfh_maxsz + \
@@ -429,6 +477,7 @@ static int nfs4_stat_to_errno(int);
encode_restorefh_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_rename_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_savefh_maxsz + \
decode_putfh_maxsz + \
@@ -437,6 +486,7 @@ static int nfs4_stat_to_errno(int);
decode_restorefh_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_savefh_maxsz + \
encode_putfh_maxsz + \
@@ -445,6 +495,7 @@ static int nfs4_stat_to_errno(int);
encode_restorefh_maxsz + \
decode_getattr_maxsz)
#define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_savefh_maxsz + \
decode_putfh_maxsz + \
@@ -453,16 +504,19 @@ static int nfs4_stat_to_errno(int);
decode_restorefh_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_symlink_maxsz + \
encode_getattr_maxsz + \
encode_getfh_maxsz)
#define NFS4_dec_symlink_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_symlink_maxsz + \
decode_getattr_maxsz + \
decode_getfh_maxsz)
#define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_savefh_maxsz + \
encode_create_maxsz + \
@@ -471,6 +525,7 @@ static int nfs4_stat_to_errno(int);
encode_restorefh_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_savefh_maxsz + \
decode_create_maxsz + \
@@ -479,49 +534,63 @@ static int nfs4_stat_to_errno(int);
decode_restorefh_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_pathconf_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_statfs_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_statfs_maxsz)
#define NFS4_dec_statfs_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_statfs_maxsz)
#define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_server_caps_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_delegreturn_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_delegreturn_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_getacl_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_getacl_maxsz)
#define NFS4_dec_getacl_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_getacl_maxsz)
#define NFS4_enc_setacl_sz (compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_setacl_maxsz)
#define NFS4_dec_setacl_sz (compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_setacl_maxsz)
#define NFS4_enc_fs_locations_sz \
(compound_encode_hdr_maxsz + \
+ encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_lookup_maxsz + \
encode_fs_locations_maxsz)
#define NFS4_dec_fs_locations_sz \
(compound_decode_hdr_maxsz + \
+ decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_lookup_maxsz + \
decode_fs_locations_maxsz)
@@ -1388,6 +1457,23 @@ static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *state
hdr->nops++;
hdr->replen += decode_delegreturn_maxsz;
}
+
+/* NFSv4.1 operations */
+static void encode_sequence(struct xdr_stream *xdr,
+ const struct nfs_client *clp,
+ const struct nfs4_sequence_args *args,
+ struct compound_hdr *hdr)
+{
+#if defined(CONFIG_NFS_V4_1)
+ if (!clp->cl_minorversion)
+ return;
+
+ /* stub */
+ hdr->nops++;
+ hdr->replen += decode_sequence_maxsz;
+#endif /* CONFIG_NFS_V4_1 */
+}
+
/*
* END OF "GENERIC" ENCODE ROUTINES.
*/
@@ -1406,6 +1492,7 @@ static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_access(&xdr, args->access, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1427,6 +1514,7 @@ static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->dir_fh, &hdr);
encode_lookup(&xdr, args->name, &hdr);
encode_getfh(&xdr, &hdr);
@@ -1449,6 +1537,7 @@ static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struc
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putrootfh(&xdr, &hdr);
encode_getfh(&xdr, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1470,6 +1559,7 @@ static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_remove(&xdr, &args->name, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1491,6 +1581,7 @@ static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->old_dir, &hdr);
encode_savefh(&xdr, &hdr);
encode_putfh(&xdr, args->new_dir, &hdr);
@@ -1516,6 +1607,7 @@ static int nfs4_xdr_enc_link(struct rpc_rqst *req, __be32 *p, const struct nfs4_
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_savefh(&xdr, &hdr);
encode_putfh(&xdr, args->dir_fh, &hdr);
@@ -1541,6 +1633,7 @@ static int nfs4_xdr_enc_create(struct rpc_rqst *req, __be32 *p, const struct nfs
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->dir_fh, &hdr);
encode_savefh(&xdr, &hdr);
encode_create(&xdr, args, &hdr);
@@ -1574,6 +1667,7 @@ static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nf
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
encode_nops(&hdr);
@@ -1594,6 +1688,7 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closea
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_close(&xdr, args, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1615,6 +1710,7 @@ static int nfs4_xdr_enc_open(struct rpc_rqst *req, __be32 *p, struct nfs_openarg
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_savefh(&xdr, &hdr);
encode_open(&xdr, args, &hdr);
@@ -1658,6 +1754,7 @@ static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, __be32 *p, struct nfs_
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_open(&xdr, args, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1679,6 +1776,7 @@ static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, __be32 *p, struct n
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_open_downgrade(&xdr, args, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1700,6 +1798,7 @@ static int nfs4_xdr_enc_lock(struct rpc_rqst *req, __be32 *p, struct nfs_lock_ar
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_lock(&xdr, args, &hdr);
encode_nops(&hdr);
@@ -1720,6 +1819,7 @@ static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, __be32 *p, struct nfs_lockt_
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_lockt(&xdr, args, &hdr);
encode_nops(&hdr);
@@ -1740,6 +1840,7 @@ static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_locku(&xdr, args, &hdr);
encode_nops(&hdr);
@@ -1760,6 +1861,7 @@ static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct n
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_readlink(&xdr, args, req, &hdr);
@@ -1783,6 +1885,7 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_readdir(&xdr, args, req, &hdr);
@@ -1809,6 +1912,7 @@ static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readarg
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_read(&xdr, args, &hdr);
@@ -1833,6 +1937,7 @@ static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, __be32 *p, struct nfs_seta
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_setattr(&xdr, args, args->server, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1856,6 +1961,7 @@ nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0, &hdr);
@@ -1879,6 +1985,7 @@ static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writea
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_write(&xdr, args, &hdr);
req->rq_snd_buf.flags |= XDRBUF_WRITE;
@@ -1901,6 +2008,7 @@ static int nfs4_xdr_enc_commit(struct rpc_rqst *req, __be32 *p, struct nfs_write
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_commit(&xdr, args, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -1922,6 +2030,7 @@ static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsin
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_fsinfo(&xdr, args->bitmask, &hdr);
encode_nops(&hdr);
@@ -1942,6 +2051,7 @@ static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct n
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_getattr_one(&xdr, args->bitmask[0] & nfs4_pathconf_bitmap[0],
&hdr);
@@ -1963,6 +2073,7 @@ static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
encode_getattr_two(&xdr, args->bitmask[0] & nfs4_statfs_bitmap[0],
args->bitmask[1] & nfs4_statfs_bitmap[1], &hdr);
@@ -1985,6 +2096,7 @@ static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p,
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fhandle, &hdr);
encode_getattr_one(&xdr, FATTR4_WORD0_SUPPORTED_ATTRS|
FATTR4_WORD0_LINK_SUPPORT|
@@ -2062,6 +2174,7 @@ static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, __be32 *p, const struc
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fhandle, &hdr);
encode_delegreturn(&xdr, args->stateid, &hdr);
encode_getfattr(&xdr, args->bitmask, &hdr);
@@ -2083,6 +2196,7 @@ static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->dir_fh, &hdr);
encode_lookup(&xdr, args->name, &hdr);
encode_fs_locations(&xdr, args->bitmask, &hdr);
@@ -3720,6 +3834,23 @@ static int decode_delegreturn(struct xdr_stream *xdr)
return decode_op_hdr(xdr, OP_DELEGRETURN);
}
+static int decode_sequence(struct xdr_stream *xdr,
+ struct nfs4_sequence_res *res,
+ struct rpc_rqst *rqstp)
+{
+#if defined(CONFIG_NFS_V4_1)
+ struct nfs_client *clp =
+ (struct nfs_client *)rqstp->rq_task->tk_client->cl_private;
+
+ if (clp->cl_minorversion == 0)
+ return 0;
+
+ /* stub */
+#endif /* CONFIG_NFS_V4_1 */
+
+ return 0;
+}
+
/*
* END OF "GENERIC" DECODE ROUTINES.
*/
@@ -3737,6 +3868,9 @@ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, __be32 *p, struct
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -3758,7 +3892,11 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_ac
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
status = decode_putfh(&xdr);
if (status != 0)
@@ -3781,7 +3919,11 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lo
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
@@ -3804,7 +3946,11 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, __be32 *p, struct nf
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
if ((status = decode_putrootfh(&xdr)) != 0)
goto out;
@@ -3824,7 +3970,11 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_rem
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
@@ -3845,7 +3995,11 @@ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_re
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
@@ -3875,7 +4029,11 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_link
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
@@ -3908,7 +4066,11 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_cr
int status;
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
@@ -3948,6 +4110,9 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_g
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -3972,6 +4137,7 @@ nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
encode_compound_hdr(&xdr, req, &hdr);
+ encode_sequence(&xdr, clp, &args->seq_args, &hdr);
encode_putfh(&xdr, args->fh, &hdr);
status = encode_setacl(&xdr, args, &hdr);
encode_nops(&hdr);
@@ -3993,6 +4159,9 @@ nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p,
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4016,6 +4185,9 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p,
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4038,6 +4210,9 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_clos
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4068,6 +4243,9 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openr
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4122,6 +4300,9 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nf
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4146,6 +4327,9 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_se
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4172,6 +4356,9 @@ static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock_
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4193,6 +4380,9 @@ static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4214,6 +4404,9 @@ static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4236,6 +4429,9 @@ static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p,
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4257,6 +4453,9 @@ static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_r
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4278,6 +4477,9 @@ static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, __be32 *p, struct nfs_readr
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4301,6 +4503,9 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writ
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4327,6 +4532,9 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_wri
status = decode_compound_hdr(&xdr, &hdr);
if (status)
goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
+ goto out;
status = decode_putfh(&xdr);
if (status)
goto out;
@@ -4351,6 +4559,8 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p,
xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
status = decode_compound_hdr(&xdr, &hdr);
if (!status)
+ status = decode_sequence(&xdr, &res->seq_res, req);
+ if (!status)
status = decode_putfh(&xdr);
if (!status)
status = decode_fsinfo(&xdr, res->fsinfo);
@@ -4370,6 +4580,8 @@ static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p,
xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
status = decode_compound_hdr(&xdr, &hdr);
if (!status)
+ status = decode_sequence(&xdr, &res->seq_res, req);
+ if (!status)
status = decode_putfh(&xdr);
if (!status)
status = decode_pathconf(&xdr, res->pathconf);
@@ -4389,6 +4601,8 @@ static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p,
xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
status = decode_compound_hdr(&xdr, &hdr);
if (!status)
+ status = decode_sequence(&xdr, &res->seq_res, req);
+ if (!status)
status = decode_putfh(&xdr);
if (!status)
status = decode_statfs(&xdr, res->fsstat);
@@ -4405,7 +4619,11 @@ static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, __be32 *p, struct nfs4
int status;
xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
- if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, req);
+ if (status)
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
@@ -4478,7 +4696,10 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nf
xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
status = decode_compound_hdr(&xdr, &hdr);
- if (status != 0)
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, rqstp);
+ if (status)
goto out;
status = decode_putfh(&xdr);
if (status != 0)
@@ -4501,7 +4722,10 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p,
xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
status = decode_compound_hdr(&xdr, &hdr);
- if (status != 0)
+ if (status)
+ goto out;
+ status = decode_sequence(&xdr, &res->seq_res, req);
+ if (status)
goto out;
if ((status = decode_putfh(&xdr)) != 0)
goto out;
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 30/46] nfs41: stubs for nfs41 procedures
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (27 preceding siblings ...)
2009-03-03 23:58 ` [PATCH 29/46] nfs41: xdr {encode,decode}_sequence Benny Halevy
@ 2009-03-03 23:59 ` Benny Halevy
2009-03-03 23:59 ` [PATCH 31/46] nfs41: introduce nfs4_call_sync Benny Halevy
` (15 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:59 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4_fs.h | 2 ++
fs/nfs/nfs4proc.c | 26 ++++++++++++++++++++++++++
2 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 5d7b036..8e2eaa9 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -205,6 +205,8 @@ extern struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops;
#if defined(CONFIG_NFS_V4_1)
extern void nfs4_destroy_session(struct nfs4_session *session);
extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp);
+extern int nfs4_proc_create_session(struct nfs4_session *);
+extern int nfs4_proc_destroy_session(struct nfs4_session *);
#endif /* CONFIG_NFS_V4_1 */
extern const u32 nfs4_fattr_bitmap[2];
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 7b69f00..bd2b62c 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3802,6 +3802,11 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
}
#ifdef CONFIG_NFS_V4_1
+static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
+{
+ return -1; /* stub */
+}
+
/*
* Initialize slot table
*/
@@ -3876,6 +3881,27 @@ void nfs4_destroy_session(struct nfs4_session *session)
kfree(session);
}
+int nfs4_proc_create_session(struct nfs4_session *session)
+{
+ return -1; /* stub */
+}
+
+int nfs4_proc_destroy_session(struct nfs4_session *session)
+{
+ return -1; /* stub */
+}
+
+static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
+{
+ return -1; /* stub */
+}
+
+static int nfs41_proc_async_sequence(struct nfs_client *clp,
+ struct rpc_cred *cred)
+{
+ return -1; /* stub */
+}
+
#endif /* CONFIG_NFS_V4_1 */
struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = {
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 31/46] nfs41: introduce nfs4_call_sync
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (28 preceding siblings ...)
2009-03-03 23:59 ` [PATCH 30/46] nfs41: stubs for nfs41 procedures Benny Halevy
@ 2009-03-03 23:59 ` Benny Halevy
2009-03-03 23:59 ` [PATCH 32/46] nfs41: set up seq_res.sr_slotid Benny Halevy
` (14 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:59 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Use nfs4_call_sync rather than rpc_call_sync to provide
for a nfs41 sessions-enabled interface for sessions manipulation.
The nfs41 rpc logic uses the rpc_call_prepare method to
recover and create the session, as well as selecting a free slot id
and the rpc_call_done to free the slot and update slot table
related metadata.
In the coming patches we'll add rpc prepare and done routines
for setting up the sequence op and processing the sequence result.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: nfs4_call_sync]
As per 11-14-08 review.
Squash into "nfs41: introduce nfs4_call_sync" and "nfs41: nfs4_setup_sequence"
Define two functions one for v4 and one for v41
add a pointer to struct nfs4_client to the correct one.
Signed-off-by: Andy Adamson <andros@netapp.com>
[added BUG() in _nfs4_call_sync_session if !CONFIG_NFS_V4_1]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: check for session not minorversion]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[group minorversion specific stuff together]
Signed-off-by: Alexandros Batsakis <Alexandros.Batsakis@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: Andy Adamson <andros@netapp.com>
[nfs41: fixup nfs4_clear_client_minor_version]
[introduce nfs4_init_client_minor_version() in this patch]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[cleaned-up patch: got rid of nfs_call_sync_t, dprintks, cosmetics, extra server defs]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/client.c | 5 +++
fs/nfs/internal.h | 12 ++++++++
fs/nfs/nfs4proc.c | 63 +++++++++++++++++++++++++++++++-------------
include/linux/nfs_fs_sb.h | 8 +++++
4 files changed, 69 insertions(+), 19 deletions(-)
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index ace6e91..9f2d2bc 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -193,6 +193,8 @@ static void nfs4_clear_client_minor_version(struct nfs_client *clp)
nfs4_destroy_session(clp->cl_session);
clp->cl_session = NULL;
}
+
+ clp->cl_call_sync = _nfs4_call_sync;
#endif /* CONFIG_NFS_V4_1 */
}
@@ -1013,6 +1015,8 @@ error:
*/
static int nfs4_init_client_minor_version(struct nfs_client *clp)
{
+ clp->cl_call_sync = _nfs4_call_sync;
+
#if defined(CONFIG_NFS_V4_1)
if (clp->cl_minorversion) {
struct nfs4_session *session = NULL;
@@ -1026,6 +1030,7 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp)
return -ENOMEM;
clp->cl_session = session;
+ clp->cl_call_sync = _nfs4_call_sync_session;
}
#endif /* CONFIG_NFS_V4_1 */
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index b7fc8d4..427baef 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -198,6 +198,18 @@ extern int nfs4_path_walk(struct nfs_server *server,
const char *path);
#endif
+/* nfs4proc.c */
+extern int _nfs4_call_sync(struct nfs_server *server,
+ struct rpc_message *msg,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply);
+extern int _nfs4_call_sync_session(struct nfs_server *server,
+ struct rpc_message *msg,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply);
+
/*
* Determine if sessions are in use.
*/
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index bd2b62c..3760750 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -350,8 +350,31 @@ out:
return ret_id;
}
+int _nfs4_call_sync_session(struct nfs_server *server,
+ struct rpc_message *msg,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply)
+{
+ /* in preparation for setting up the sequence op */
+ return rpc_call_sync(server->client, msg, 0);
+}
+
#endif /* CONFIG_NFS_V4_1 */
+int _nfs4_call_sync(struct nfs_server *server,
+ struct rpc_message *msg,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply)
+{
+ return rpc_call_sync(server->client, msg, 0);
+}
+
+#define nfs4_call_sync(server, msg, args, res, cache_reply) \
+ (server)->nfs_client->cl_call_sync((server), (msg), &(args)->seq_args, \
+ &(res)->seq_res, (cache_reply))
+
static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
{
struct nfs_inode *nfsi = NFS_I(dir);
@@ -1350,7 +1373,7 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
} else
memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid));
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &arg, &res, 1);
if (status == 0 && state != NULL)
renew_lease(server, timestamp);
return status;
@@ -1667,7 +1690,7 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
};
int status;
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &args, &res, 0);
if (status == 0) {
memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask));
if (res.attr_bitmask[0] & FATTR4_WORD0_ACL)
@@ -1678,6 +1701,7 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
server->caps |= NFS_CAP_SYMLINKS;
server->acl_bitmask = res.acl_bitmask;
}
+
return status;
}
@@ -1710,7 +1734,7 @@ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
.rpc_resp = &res,
};
nfs_fattr_init(info->fattr);
- return rpc_call_sync(server->client, &msg, 0);
+ return nfs4_call_sync(server, &msg, &args, &res, 0);
}
static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -1800,7 +1824,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
};
nfs_fattr_init(fattr);
- return rpc_call_sync(server->client, &msg, 0);
+ return nfs4_call_sync(server, &msg, &args, &res, 0);
}
static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
@@ -1884,7 +1908,7 @@ static int _nfs4_proc_lookupfh(struct nfs_server *server, const struct nfs_fh *d
nfs_fattr_init(fattr);
dprintk("NFS call lookupfh %s\n", name->name);
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &args, &res, 0);
dprintk("NFS reply lookupfh: %d\n", status);
return status;
}
@@ -1970,7 +1994,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
args.access |= NFS4_ACCESS_EXECUTE;
}
nfs_fattr_init(&fattr);
- status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+ status = nfs4_call_sync(server, &msg, &args, &res, 0);
if (!status) {
entry->mask = 0;
if (res.access & NFS4_ACCESS_READ)
@@ -2036,7 +2060,7 @@ static int _nfs4_proc_readlink(struct inode *inode, struct page *page,
.rpc_resp = &res,
};
- return rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+ return nfs4_call_sync(NFS_SERVER(inode), &msg, &args, &res, 0);
}
static int nfs4_proc_readlink(struct inode *inode, struct page *page,
@@ -2130,7 +2154,7 @@ static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
int status;
nfs_fattr_init(&res.dir_attr);
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &args, &res, 1);
if (status == 0) {
update_changeattr(dir, &res.cinfo);
nfs_post_op_update_inode(dir, &res.dir_attr);
@@ -2198,7 +2222,7 @@ static int _nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
nfs_fattr_init(res.old_fattr);
nfs_fattr_init(res.new_fattr);
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &arg, &res, 1);
if (!status) {
update_changeattr(old_dir, &res.old_cinfo);
@@ -2247,7 +2271,7 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *
nfs_fattr_init(res.fattr);
nfs_fattr_init(res.dir_attr);
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &arg, &res, 1);
if (!status) {
update_changeattr(dir, &res.cinfo);
nfs_post_op_update_inode(dir, res.dir_attr);
@@ -2308,7 +2332,8 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir,
static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data)
{
- int status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0);
+ int status = nfs4_call_sync(NFS_SERVER(dir), &data->msg,
+ &data->arg, &data->res, 1);
if (status == 0) {
update_changeattr(dir, &data->res.dir_cinfo);
nfs_post_op_update_inode(dir, data->res.dir_fattr);
@@ -2417,7 +2442,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
(unsigned long long)cookie);
nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args);
res.pgbase = args.pgbase;
- status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+ status = nfs4_call_sync(NFS_SERVER(dir), &msg, &args, &res, 0);
if (status == 0)
memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE);
@@ -2505,7 +2530,7 @@ static int _nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
};
nfs_fattr_init(fsstat->fattr);
- return rpc_call_sync(server->client, &msg, 0);
+ return nfs4_call_sync(server, &msg, &args, &res, 0);
}
static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
@@ -2536,7 +2561,7 @@ static int _nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
.rpc_resp = &res,
};
- return rpc_call_sync(server->client, &msg, 0);
+ return nfs4_call_sync(server, &msg, &args, &res, 0);
}
static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
@@ -2581,7 +2606,7 @@ static int _nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle
}
nfs_fattr_init(pathconf->fattr);
- return rpc_call_sync(server->client, &msg, 0);
+ return nfs4_call_sync(server, &msg, &args, &res, 0);
}
static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -2854,7 +2879,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
resp_buf = buf;
buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase);
}
- ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+ ret = nfs4_call_sync(NFS_SERVER(inode), &msg, &args, &res, 0);
if (ret)
goto out_free;
if (resp_len > args.acl_len)
@@ -2927,7 +2952,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
return -EOPNOTSUPP;
nfs_inode_return_delegation(inode);
buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
- ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+ ret = nfs4_call_sync(server, &msg, &arg, &res, 1);
nfs_access_zap_cache(inode);
nfs_zap_acl_cache(inode);
return ret;
@@ -3216,7 +3241,7 @@ static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock
goto out;
lsp = request->fl_u.nfs4_fl.owner;
arg.lock_owner.id = lsp->ls_id.id;
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &arg, &res, 1);
switch (status) {
case 0:
request->fl_type = F_UNLCK;
@@ -3796,7 +3821,7 @@ int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
nfs_fattr_init(&fs_locations->fattr);
fs_locations->server = server;
fs_locations->nlocations = 0;
- status = rpc_call_sync(server->client, &msg, 0);
+ status = nfs4_call_sync(server, &msg, &args, &res, 0);
dprintk("%s: returned status = %d\n", __func__, status);
return status;
}
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 5673eac..e4cdc34 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -12,6 +12,9 @@
struct nfs4_session;
struct nfs_iostats;
struct nlm_host;
+struct nfs4_sequence_args;
+struct nfs4_sequence_res;
+struct nfs_server;
/*
* The nfs_client identifies our client state to the server.
@@ -67,6 +70,11 @@ struct nfs_client {
char cl_ipaddr[48];
unsigned char cl_id_uniquifier;
u32 cl_minorversion;
+ int (* cl_call_sync)(struct nfs_server *server,
+ struct rpc_message *msg,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply);
#endif /* CONFIG_NFS_V4 */
#ifdef CONFIG_NFS_V4_1
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 32/46] nfs41: set up seq_res.sr_slotid
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (29 preceding siblings ...)
2009-03-03 23:59 ` [PATCH 31/46] nfs41: introduce nfs4_call_sync Benny Halevy
@ 2009-03-03 23:59 ` Benny Halevy
2009-03-03 23:59 ` [PATCH 33/46] nfs41: nfs4_setup_sequence Benny Halevy
` (13 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:59 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Initialize nfs4_sequence_res sr_slotid to NFS4_MAX_SLOT_TABLE.
[was nfs41: sequence res use slotid]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 5 +++++
fs/nfs/read.c | 1 +
fs/nfs/unlink.c | 1 +
fs/nfs/write.c | 2 ++
4 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 3760750..f5e7c72 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -447,6 +447,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
p->o_arg.server = server;
p->o_arg.bitmask = server->attr_bitmask;
p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
+ p->o_res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
if (flags & O_EXCL) {
u32 *s = (u32 *) p->o_arg.u.verifier.data;
s[0] = jiffies;
@@ -1539,6 +1540,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
calldata->res.fattr = &calldata->fattr;
calldata->res.seqid = calldata->arg.seqid;
calldata->res.server = server;
+ calldata->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
calldata->path.mnt = mntget(path->mnt);
calldata->path.dentry = dget(path->dentry);
@@ -3156,6 +3158,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
memcpy(&data->stateid, stateid, sizeof(data->stateid));
data->res.fattr = &data->fattr;
data->res.server = server;
+ data->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
nfs_fattr_init(data->res.fattr);
data->timestamp = jiffies;
data->rpc_status = 0;
@@ -3308,6 +3311,7 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
p->arg.fl = &p->fl;
p->arg.seqid = seqid;
p->res.seqid = seqid;
+ p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
p->arg.stateid = &lsp->ls_stateid;
p->lsp = lsp;
atomic_inc(&lsp->ls_count);
@@ -3480,6 +3484,7 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
p->arg.lock_owner.clientid = server->nfs_client->cl_clientid;
p->arg.lock_owner.id = lsp->ls_id.id;
p->res.lock_seqid = p->arg.lock_seqid;
+ p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
p->lsp = lsp;
atomic_inc(&lsp->ls_count);
p->ctx = get_nfs_open_context(ctx);
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index f856004..9d72124 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -45,6 +45,7 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
memset(p, 0, sizeof(*p));
INIT_LIST_HEAD(&p->pages);
p->npages = pagecount;
+ p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
if (pagecount <= ARRAY_SIZE(p->page_array))
p->pagevec = p->page_array;
else {
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index ecc2953..83d0ce2 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -241,6 +241,7 @@ nfs_async_unlink(struct inode *dir, struct dentry *dentry)
status = PTR_ERR(data->cred);
goto out_free;
}
+ data->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
status = -EBUSY;
spin_lock(&dentry->d_lock);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 9f98458..a48afb4 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -52,6 +52,7 @@ struct nfs_write_data *nfs_commitdata_alloc(void)
if (p) {
memset(p, 0, sizeof(*p));
INIT_LIST_HEAD(&p->pages);
+ p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
}
return p;
}
@@ -71,6 +72,7 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount)
memset(p, 0, sizeof(*p));
INIT_LIST_HEAD(&p->pages);
p->npages = pagecount;
+ p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
if (pagecount <= ARRAY_SIZE(p->page_array))
p->pagevec = p->page_array;
else {
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 33/46] nfs41: nfs4_setup_sequence
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (30 preceding siblings ...)
2009-03-03 23:59 ` [PATCH 32/46] nfs41: set up seq_res.sr_slotid Benny Halevy
@ 2009-03-03 23:59 ` Benny Halevy
2009-03-04 0:00 ` [PATCH 34/46] nfs41: setup_sequence method Benny Halevy
` (12 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-03 23:59 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Perform the nfs4_setup_sequence in the rpc_call_prepare state.
If a session slot is not available, we will rpc_sleep_on the
slot wait queue leaving the tk_action as rpc_call_prepare.
Once we have a session slot, hang on to it even through rpc_restart_calls.
Ensure the nfs41_sequence_res sr_slot pointer is NULL before rpc_run_task is
called as nfs41_setup_sequence will only find a new slot if it is NULL.
A future patch will call free slot after any rpc_restart_calls, and handle the
rpc restart that result from a sequence operation error.
Signed-off-by: Rahul Iyer <iyer@netapp.com>
[nfs41: sequence res use slotid]
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: simplify nfs4_call_sync]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: nfs4_call_sync]
[nfs41: check for session not minorversion]
[nfs41: remove rpc_message from nfs41_call_sync_args]
[moved NFS4_MAX_SLOT_TABLE logic into nfs41_setup_sequence]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 89 +++++++++++++++++++++++++++++++++++++++++++++-
include/linux/nfs_xdr.h | 2 +-
2 files changed, 88 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f5e7c72..14d77f7 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -350,14 +350,99 @@ out:
return ret_id;
}
+static int nfs41_setup_sequence(struct nfs4_session *session,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply,
+ struct rpc_task *task)
+{
+ /* slot already allocated? */
+ if (res->sr_slotid != NFS4_MAX_SLOT_TABLE)
+ return 0;
+
+ memset(res, 0, sizeof(*res));
+ res->sr_slotid = NFS4_MAX_SLOT_TABLE;
+ return 0;
+}
+
+int nfs4_setup_sequence(struct nfs_client *clp,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply,
+ struct rpc_task *task)
+{
+ int ret = 0;
+
+ dprintk("--> %s clp %p session %p sr_slotid %d\n",
+ __func__, clp, clp->cl_session, res->sr_slotid);
+
+ if (!nfs4_has_session(clp))
+ goto out;
+ ret = nfs41_setup_sequence(clp->cl_session, args, res,
+ cache_reply, task);
+ if (ret != -EAGAIN) {
+ /* terminate rpc task */
+ task->tk_status = ret;
+ task->tk_action = NULL;
+ }
+out:
+ dprintk("<-- %s status=%d\n", __func__, ret);
+ return ret;
+}
+
+struct nfs41_call_sync_data {
+ struct nfs_server *server;
+ struct nfs4_sequence_args *seq_args;
+ struct nfs4_sequence_res *seq_res;
+ int cache_reply;
+};
+
+static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
+{
+ struct nfs41_call_sync_data *data = calldata;
+
+ dprintk("--> %s data->server->session %p\n", __func__,
+ data->server->nfs_client->cl_session);
+ if (nfs4_setup_sequence(data->server->nfs_client, data->seq_args,
+ data->seq_res, data->cache_reply, task))
+ return;
+ rpc_call_start(task);
+}
+
+struct rpc_call_ops nfs41_call_sync_ops = {
+ .rpc_call_prepare = nfs41_call_sync_prepare,
+};
+
int _nfs4_call_sync_session(struct nfs_server *server,
struct rpc_message *msg,
struct nfs4_sequence_args *args,
struct nfs4_sequence_res *res,
int cache_reply)
{
- /* in preparation for setting up the sequence op */
- return rpc_call_sync(server->client, msg, 0);
+ int ret;
+ struct rpc_task *task;
+ struct nfs41_call_sync_data data = {
+ .server = server,
+ .seq_args = args,
+ .seq_res = res,
+ .cache_reply = cache_reply,
+ };
+ struct rpc_task_setup task_setup = {
+ .rpc_client = server->client,
+ .rpc_message = msg,
+ .callback_ops = &nfs41_call_sync_ops,
+ .callback_data = &data
+ };
+
+ res->sr_slotid = NFS4_MAX_SLOT_TABLE;
+ task = rpc_run_task(&task_setup);
+ if (IS_ERR(task))
+ ret = PTR_ERR(task);
+ else {
+ ret = task->tk_status;
+ rpc_put_task(task);
+ }
+ return ret;
}
#endif /* CONFIG_NFS_V4_1 */
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 16bef5d..8dcf841 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -134,7 +134,7 @@ struct nfs4_sequence_args {
};
struct nfs4_sequence_res {
- /* stub */
+ u8 sr_slotid; /* slot used to send request */
};
struct nfs4_get_lease_time_args {
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 34/46] nfs41: setup_sequence method
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (31 preceding siblings ...)
2009-03-03 23:59 ` [PATCH 33/46] nfs41: nfs4_setup_sequence Benny Halevy
@ 2009-03-04 0:00 ` Benny Halevy
2009-03-04 0:00 ` [PATCH 35/46] nfs41: nfs41_sequence_free_slot Benny Halevy
` (11 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-04 0:00 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Allocate a slot in the session slot table and set the sequence op arguments.
Called at the rpc prepare stage.
Add a status to nfs41_sequence_res, initialize it to one so that we catch
rpc level failures which do not go through decode_sequence which sets
the new status field.
Note that upon an rpc level failure, we don't know if the server processed the
sequence operation or not. Proceed as if the server did process the sequence
operation.
Signed-off-by: Rahul Iyer <iyer@netapp.com>
[nfs41: sequence args use slotid]
[nfs41: find slot return slotid]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: remove SEQ4_STATUS_USE_TK_STATUS]
As per 11-14-08 review
[move extern declaration from nfs41: sequence setup/done support]
[removed sa_session definition, changed sa_cache_this into a u8 to reduce footprint]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: rpc_sleep_on slot_tbl_waitq must be called under slot_tbl_lock]
Otherwise there's a race (we've hit) with nfs4_free_slot where
nfs41_setup_sequence sees a full slot table, unlocks slot_tbl_lock,
nfs4_free_slots happen concurrently and call rpc_wake_up_next
where there's nobody to wake up yet, context goes back to
nfs41_setup_sequence which goes to sleep when the slot table
is actually empty now and there's no-one to wake it up anymore.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4_fs.h | 10 ++++++++++
fs/nfs/nfs4proc.c | 34 ++++++++++++++++++++++++++++++++--
include/linux/nfs_xdr.h | 5 ++++-
3 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 8e2eaa9..a3e57e1 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -203,10 +203,20 @@ extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
extern struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops;
extern struct nfs4_state_recovery_ops nfs4_nograce_recovery_ops;
#if defined(CONFIG_NFS_V4_1)
+extern int nfs4_setup_sequence(struct nfs_client *clp,
+ struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
+ int cache_reply, struct rpc_task *task);
extern void nfs4_destroy_session(struct nfs4_session *session);
extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp);
extern int nfs4_proc_create_session(struct nfs4_session *);
extern int nfs4_proc_destroy_session(struct nfs4_session *);
+#else /* CONFIG_NFS_v4_1 */
+static inline int nfs4_setup_sequence(struct nfs_client *clp,
+ struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
+ int cache_reply, struct rpc_task *task)
+{
+ return 0;
+}
#endif /* CONFIG_NFS_V4_1 */
extern const u32 nfs4_fattr_bitmap[2];
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 14d77f7..898d83b 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -324,6 +324,8 @@ nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
* If found, we mark the slot as used, update the highest_used_slotid,
* and respectively set up the sequence operation args.
* The slot number is returned if found, or NFS4_MAX_SLOT_TABLE otherwise.
+ *
+ * Note: must be called with under the slot_tbl_lock.
*/
static u8
nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task)
@@ -332,7 +334,6 @@ nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task)
u8 ret_id = NFS4_MAX_SLOT_TABLE;
BUILD_BUG_ON((u8)NFS4_MAX_SLOT_TABLE != (int)NFS4_MAX_SLOT_TABLE);
- spin_lock(&tbl->slot_tbl_lock);
dprintk("--> %s used_slots=%04lx highest_used=%d max_slots=%d\n",
__func__, tbl->used_slots[0], tbl->highest_used_slotid,
tbl->max_slots);
@@ -346,7 +347,6 @@ nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task)
out:
dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n",
__func__, tbl->used_slots[0], tbl->highest_used_slotid, ret_id);
- spin_unlock(&tbl->slot_tbl_lock);
return ret_id;
}
@@ -356,12 +356,42 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
int cache_reply,
struct rpc_task *task)
{
+ struct nfs4_slot *slot;
+ struct nfs4_slot_table *tbl;
+ u8 slotid;
+
+ dprintk("--> %s\n", __func__);
/* slot already allocated? */
if (res->sr_slotid != NFS4_MAX_SLOT_TABLE)
return 0;
memset(res, 0, sizeof(*res));
res->sr_slotid = NFS4_MAX_SLOT_TABLE;
+ tbl = &session->fc_slot_table;
+
+ spin_lock(&tbl->slot_tbl_lock);
+ slotid = nfs4_find_slot(tbl, task);
+ if (slotid == NFS4_MAX_SLOT_TABLE) {
+ rpc_sleep_on(&tbl->slot_tbl_waitq, task, NULL);
+ spin_unlock(&tbl->slot_tbl_lock);
+ dprintk("<-- %s: no free slots\n", __func__);
+ return -EAGAIN;
+ }
+ spin_unlock(&tbl->slot_tbl_lock);
+
+ slot = tbl->slots + slotid;
+ args->sa_slotid = slotid;
+ args->sa_cache_this = cache_reply;
+
+ dprintk("<-- %s slotid=%d seqid=%d\n", __func__, slotid, slot->seq_nr);
+
+ res->sr_slotid = slotid;
+ res->sr_renewal_time = jiffies;
+ /*
+ * sr_status is only set in decode_sequence, and so will remain
+ * set to 1 if an rpc level failure occurs.
+ */
+ res->sr_status = 1;
return 0;
}
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 8dcf841..9f7885f 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -130,11 +130,14 @@ struct nfs4_slot {
};
struct nfs4_sequence_args {
- /* stub */
+ u8 sa_slotid;
+ u8 sa_cache_this;
};
struct nfs4_sequence_res {
u8 sr_slotid; /* slot used to send request */
+ unsigned long sr_renewal_time;
+ int sr_status; /* sequence operation status */
};
struct nfs4_get_lease_time_args {
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 35/46] nfs41: nfs41_sequence_free_slot
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (32 preceding siblings ...)
2009-03-04 0:00 ` [PATCH 34/46] nfs41: setup_sequence method Benny Halevy
@ 2009-03-04 0:00 ` Benny Halevy
2009-03-04 0:00 ` [PATCH 36/46] nfs41: nfs41_sequence_done Benny Halevy
` (10 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-04 0:00 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
[from nfs41: separate free slot from sequence done]
Don't free the slot until after all rpc_restart_calls have completed.
Session reset will require more work.
As noted by Trond, since we're using rpc_wake_up_next rather than
rpc_wake_up() we must always wake up the next task in the queue
either by going through nfs4_free_slot, or just calling
rpc_wake_up_next if no slot is to be freed.
[nfs41: sequence res use slotid]
[nfs41: remove SEQ4_STATUS_USE_TK_STATUS]
[got rid of nfs4_sequence_res.sr_session, use nfs_client.cl_session instead]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: rpc_wake_up_next if sessions slot was not consumed.]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/internal.h | 14 ++++++++++++++
fs/nfs/nfs4proc.c | 21 +++++++++++++++++++++
2 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 427baef..f7d55a5 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -222,6 +222,20 @@ static inline int nfs4_has_session(const struct nfs_client *clp)
return 0;
}
+#ifdef CONFIG_NFS_V4_1
+extern void nfs41_sequence_free_slot(const struct nfs_client *,
+ struct nfs4_sequence_res *res);
+#endif /* CONFIG_NFS_V4_1 */
+
+static inline void nfs4_sequence_free_slot(const struct nfs_server *server,
+ struct nfs4_sequence_res *res)
+{
+#ifdef CONFIG_NFS_V4_1
+ if (nfs4_has_session(server->nfs_client))
+ nfs41_sequence_free_slot(server->nfs_client, res);
+#endif /* CONFIG_NFS_V4_1 */
+}
+
/*
* Determine the device name as a string
*/
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 898d83b..ca40377 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -317,6 +317,27 @@ nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
free_slotid, tbl->highest_used_slotid);
}
+void nfs41_sequence_free_slot(const struct nfs_client *clp,
+ struct nfs4_sequence_res *res)
+{
+ struct nfs4_slot_table *tbl;
+
+ if (!nfs4_has_session(clp)) {
+ dprintk("%s: No session\n", __func__);
+ return;
+ }
+ tbl = &clp->cl_session->fc_slot_table;
+ if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) {
+ dprintk("%s: No slot\n", __func__);
+ /* just wake up the next guy waiting since
+ * we may have not consumed a slot after all */
+ rpc_wake_up_next(&tbl->slot_tbl_waitq);
+ return;
+ }
+ nfs4_free_slot(tbl, res->sr_slotid);
+ res->sr_slotid = NFS4_MAX_SLOT_TABLE;
+}
+
/*
* nfs4_find_slot - efficiently look for a free slot
*
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 36/46] nfs41: nfs41_sequence_done
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (33 preceding siblings ...)
2009-03-04 0:00 ` [PATCH 35/46] nfs41: nfs41_sequence_free_slot Benny Halevy
@ 2009-03-04 0:00 ` Benny Halevy
2009-03-04 0:00 ` [PATCH 37/46] nfs41: nfs41_call_sync_done Benny Halevy
` (9 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-04 0:00 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Handle session level errors, update slot sequence id and
sessions bookeeping, free slot.
[nfs41: sequence res use slotid]
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: remove SEQ4_STATUS_USE_TK_STATUS]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: check for session not minorversion]
Signed-off-by: Andy Adamson <andros@netapp.com>
[nfs41: bail out early out of nfs41_sequence_done if !res->sr_session]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[move nfs4_sequence_done from nfs41: nfs41_call_sync_done]
Signed-off-by: Andy Adamson <andros@netapp.com>
[move nfs4_sequence_free_slot from nfs41: separate free slot from sequence done]
Don't free the slot until after all rpc_restart_calls have completed.
Session reset will require more work.
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[moved reset sr_slotid to nfs41_sequence_free_slot]
[free slot also on unexpectecd error]
[remove seq_res.sr_session member, use nfs_client's instead]
[ditch seq_res.sr_flags until used]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[look at sr_slotid for bailing out early from nfs41_sequence_done]
[nfs41: rpc_wake_up_next if sessions slot was not consumed.]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 93 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index ca40377..9179508 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -338,6 +338,81 @@ void nfs41_sequence_free_slot(const struct nfs_client *clp,
res->sr_slotid = NFS4_MAX_SLOT_TABLE;
}
+static void nfs41_sequence_done(struct nfs_client *clp,
+ struct nfs4_sequence_res *res,
+ int rpc_status)
+{
+ unsigned long timestamp;
+ struct nfs4_slot_table *tbl;
+ struct nfs4_slot *slot;
+
+ /*
+ * sr_status remains 1 if an RPC level error occurred. The server
+ * may or may not have processed the sequence operation..
+ * Proceed as if the server received and processed the sequence
+ * operation.
+ */
+ if (res->sr_status == 1)
+ res->sr_status = NFS_OK;
+
+ if (!nfs4_has_session(clp))
+ return;
+
+ /* -ERESTARTSYS can result in skipping nfs41_sequence_setup */
+ if (res->sr_slotid == NFS4_MAX_SLOT_TABLE)
+ goto out;
+
+ tbl = &clp->cl_session->fc_slot_table;
+ slot = tbl->slots + res->sr_slotid;
+
+ switch (res->sr_status) {
+ case NFS4_OK:
+ /*
+ * The sequence call was successful,
+ * Update the slot's sequence and client's lease renewal timers
+ */
+ ++slot->seq_nr;
+ if (clp) {
+ timestamp = res->sr_renewal_time;
+ spin_lock(&clp->cl_lock);
+ if (time_before(clp->cl_last_renewal, timestamp))
+ clp->cl_last_renewal = timestamp;
+ spin_unlock(&clp->cl_lock);
+ }
+ return;
+
+ case -NFS4ERR_BADSESSION:
+ case -NFS4ERR_BADSLOT:
+ case -NFS4ERR_BADXDR:
+ case -NFS4ERR_BAD_HIGH_SLOT:
+ case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
+ case -NFS4ERR_DEADSESSION:
+ case -NFS4ERR_DELAY:
+ case -NFS4ERR_REP_TOO_BIG:
+ case -NFS4ERR_REP_TOO_BIG_TO_CACHE:
+ case -NFS4ERR_REQ_TOO_BIG:
+ case -NFS4ERR_RETRY_UNCACHED_REP:
+ case -NFS4ERR_SEQUENCE_POS:
+ case -NFS4ERR_SEQ_FALSE_RETRY:
+ case -NFS4ERR_SEQ_MISORDERED:
+ case -NFS4ERR_TOO_MANY_OPS:
+ dprintk("%s: status %d\n", __func__, res->sr_status);
+ break;
+
+ default:
+ printk(KERN_WARNING "%s: Unexpected status %d\n", __func__,
+ res->sr_status);
+ }
+out:
+ /*
+ * The session will be reset by one of the error handlers,
+ * so free the slot and set the sr_slotid to NFS4_MAX_SLOT_TABLE
+ * so that nfs4_setup_sequence calls nfs41_find_slot
+ * to schedule session reset once all slots are drained.
+ */
+ nfs41_sequence_free_slot(clp, res);
+}
+
/*
* nfs4_find_slot - efficiently look for a free slot
*
@@ -511,6 +586,24 @@ int _nfs4_call_sync(struct nfs_server *server,
(server)->nfs_client->cl_call_sync((server), (msg), &(args)->seq_args, \
&(res)->seq_res, (cache_reply))
+static void nfs4_sequence_done(const struct nfs_server *server,
+ struct nfs4_sequence_res *res, int rpc_status)
+{
+#ifdef CONFIG_NFS_V4_1
+ if (nfs4_has_session(server->nfs_client))
+ nfs41_sequence_done(server->nfs_client, res, rpc_status);
+#endif /* CONFIG_NFS_V4_1 */
+}
+
+/* no restart, therefore free slot here */
+static void nfs4_sequence_done_free_slot(const struct nfs_server *server,
+ struct nfs4_sequence_res *res,
+ int rpc_status)
+{
+ nfs4_sequence_done(server, res, rpc_status);
+ nfs4_sequence_free_slot(server, res);
+}
+
static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
{
struct nfs_inode *nfsi = NFS_I(dir);
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 37/46] nfs41: nfs41_call_sync_done
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (34 preceding siblings ...)
2009-03-04 0:00 ` [PATCH 36/46] nfs41: nfs41_sequence_done Benny Halevy
@ 2009-03-04 0:00 ` Benny Halevy
2009-03-04 0:00 ` [PATCH 38/46] nfs41: close sequence setup/done support Benny Halevy
` (8 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-04 0:00 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Implement nfs4.1 synchronous rpc_call_done method
that essentially just calls nfs4_sequence_done, that turns
around and calls nfs41_sequence_done for minorversion1 rpcs.
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: check for session not minorversion]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
move adding nfs4_sequence_free_slot from nfs41-separate-free-slot-from-sequence-done
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 9179508..f2fc8fe 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -535,8 +535,18 @@ static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
rpc_call_start(task);
}
+static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)
+{
+ struct nfs41_call_sync_data *data = calldata;
+ struct nfs_server *server = data->server;
+
+ nfs41_sequence_done(server->nfs_client, data->seq_res, task->tk_status);
+ nfs41_sequence_free_slot(server->nfs_client, data->seq_res);
+}
+
struct rpc_call_ops nfs41_call_sync_ops = {
.rpc_call_prepare = nfs41_call_sync_prepare,
+ .rpc_call_done = nfs41_call_sync_done,
};
int _nfs4_call_sync_session(struct nfs_server *server,
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 38/46] nfs41: close sequence setup/done support
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (35 preceding siblings ...)
2009-03-04 0:00 ` [PATCH 37/46] nfs41: nfs41_call_sync_done Benny Halevy
@ 2009-03-04 0:00 ` Benny Halevy
2009-03-04 0:01 ` [PATCH 39/46] nfs41: open " Benny Halevy
` (7 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-04 0:00 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Separate nfs4_close calls from nfs41: sequence setup/done support
Call nfs4_sequence_done from respective rpc_call_done methods.
Note that we need to pass a pointer to the nfs_server in calls data
for passing on to nfs4_sequence_done.
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[pnfs: client data server write validate and release]
Signed-off-by: Andy Adamson<andros@umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
move nfs4_sequence_free_slot from nfs41: separate free slot from sequence done
[nfs41: sequence res use slotid]
[nfs41: remove SEQ4_STATUS_USE_TK_STATUS]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f2fc8fe..f11c38f 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1662,6 +1662,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
struct nfs4_state *state = calldata->state;
struct nfs_server *server = NFS_SERVER(calldata->inode);
+ nfs4_sequence_done(server, &calldata->res.seq_res, task->tk_status);
if (RPC_ASSASSINATED(task))
return;
/* hmm. we are done with the inode, and in the process of freeing
@@ -1684,6 +1685,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
return;
}
}
+ nfs4_sequence_free_slot(server, &calldata->res.seq_res);
nfs_refresh_inode(calldata->inode, calldata->res.fattr);
}
@@ -1724,6 +1726,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
calldata->arg.fmode = FMODE_WRITE;
}
calldata->timestamp = jiffies;
+ if (nfs4_setup_sequence((NFS_SERVER(calldata->inode))->nfs_client,
+ &calldata->arg.seq_args, &calldata->res.seq_res,
+ 1, task))
+ return;
rpc_call_start(task);
}
@@ -1763,7 +1769,7 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
};
int status = -ENOMEM;
- calldata = kmalloc(sizeof(*calldata), GFP_KERNEL);
+ calldata = kzalloc(sizeof(*calldata), GFP_KERNEL);
if (calldata == NULL)
goto out;
calldata->inode = state->inode;
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 39/46] nfs41: open sequence setup/done support
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (36 preceding siblings ...)
2009-03-04 0:00 ` [PATCH 38/46] nfs41: close sequence setup/done support Benny Halevy
@ 2009-03-04 0:01 ` Benny Halevy
2009-03-04 0:01 ` [PATCH 40/46] nfs41: lock " Benny Halevy
` (6 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-04 0:01 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Separate nfs4_open calls from nfs41: sequence setup/done support
Call nfs4_sequence_done from respective rpc_call_done methods.
Note that we need to pass a pointer to the nfs_server in calls data
for passing on to nfs4_sequence_done.
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[pnfs: client data server write validate and release]
[use nfs4_sequence_done_free_slot]
Signed-off-by: Andy Adamson<andros@umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f11c38f..56612d1 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1273,6 +1273,10 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
nfs_copy_fh(&data->o_res.fh, data->o_arg.fh);
}
data->timestamp = jiffies;
+ if (nfs4_setup_sequence(data->o_arg.server->nfs_client,
+ &data->o_arg.seq_args,
+ &data->o_res.seq_res, 1, task))
+ return;
rpc_call_start(task);
return;
out_no_action:
@@ -1285,6 +1289,10 @@ static void nfs4_open_done(struct rpc_task *task, void *calldata)
struct nfs4_opendata *data = calldata;
data->rpc_status = task->tk_status;
+
+ nfs4_sequence_done_free_slot(data->o_arg.server, &data->o_res.seq_res,
+ task->tk_status);
+
if (RPC_ASSASSINATED(task))
return;
if (task->tk_status == 0) {
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 40/46] nfs41: lock sequence setup/done support
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (37 preceding siblings ...)
2009-03-04 0:01 ` [PATCH 39/46] nfs41: open " Benny Halevy
@ 2009-03-04 0:01 ` Benny Halevy
2009-03-04 0:01 ` [PATCH 41/46] nfs41: locku " Benny Halevy
` (5 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-04 0:01 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Separate nfs4_lock calls from nfs41: sequence setup/done support
Call nfs4_sequence_done from respective rpc_call_done methods.
Note that we need to pass a pointer to the nfs_server in calls data
for passing on to nfs4_sequence_done.
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[pnfs: client data server write validate and release]
[use nfs4_sequence_done_free_slot]
Signed-off-by: Andy Adamson<andros@umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 56612d1..9c41d42 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3712,6 +3712,7 @@ struct nfs4_lockdata {
unsigned long timestamp;
int rpc_status;
int cancelled;
+ struct nfs_server *server;
};
static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
@@ -3739,6 +3740,7 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
p->res.lock_seqid = p->arg.lock_seqid;
p->res.seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
p->lsp = lsp;
+ p->server = server;
atomic_inc(&lsp->ls_count);
p->ctx = get_nfs_open_context(ctx);
memcpy(&p->fl, fl, sizeof(p->fl));
@@ -3768,6 +3770,9 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
} else
data->arg.new_lock_owner = 0;
data->timestamp = jiffies;
+ if (nfs4_setup_sequence(data->server->nfs_client, &data->arg.seq_args,
+ &data->res.seq_res, 1, task))
+ return;
rpc_call_start(task);
dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
}
@@ -3778,6 +3783,9 @@ static void nfs4_lock_done(struct rpc_task *task, void *calldata)
dprintk("%s: begin!\n", __func__);
+ nfs4_sequence_done_free_slot(data->server, &data->res.seq_res,
+ task->tk_status);
+
data->rpc_status = task->tk_status;
if (RPC_ASSASSINATED(task))
goto out;
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 41/46] nfs41: locku sequence setup/done support
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (38 preceding siblings ...)
2009-03-04 0:01 ` [PATCH 40/46] nfs41: lock " Benny Halevy
@ 2009-03-04 0:01 ` Benny Halevy
2009-03-04 0:01 ` [PATCH 42/46] nfs41: unlink " Benny Halevy
` (4 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-04 0:01 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Separate nfs4_locku calls from nfs41: sequence setup/done support
Call nfs4_sequence_done from respective rpc_call_done methods.
Note that we need to pass a pointer to the nfs_server in calls data
for passing on to nfs4_sequence_done.
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[pnfs: client data server write validate and release]
Signed-off-by: Andy Adamson<andros@umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 9c41d42..5d13918 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3557,7 +3557,7 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
struct nfs4_unlockdata *p;
struct inode *inode = lsp->ls_state->inode;
- p = kmalloc(sizeof(*p), GFP_KERNEL);
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
if (p == NULL)
return NULL;
p->arg.fh = NFS_FH(inode);
@@ -3588,6 +3588,8 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
{
struct nfs4_unlockdata *calldata = data;
+ nfs4_sequence_done(calldata->server, &calldata->res.seq_res,
+ task->tk_status);
if (RPC_ASSASSINATED(task))
return;
switch (task->tk_status) {
@@ -3606,6 +3608,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
rpc_restart_call(task);
}
+ nfs4_sequence_free_slot(calldata->server, &calldata->res.seq_res);
}
static void nfs4_locku_prepare(struct rpc_task *task, void *data)
@@ -3620,6 +3623,10 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
return;
}
calldata->timestamp = jiffies;
+ if (nfs4_setup_sequence(calldata->server->nfs_client,
+ &calldata->arg.seq_args,
+ &calldata->res.seq_res, 1, task))
+ return;
rpc_call_start(task);
}
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 42/46] nfs41: unlink sequence setup/done support
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (39 preceding siblings ...)
2009-03-04 0:01 ` [PATCH 41/46] nfs41: locku " Benny Halevy
@ 2009-03-04 0:01 ` Benny Halevy
2009-03-04 0:01 ` [PATCH 43/46] nfs41: read " Benny Halevy
` (3 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-04 0:01 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Implement the rpc_call_prepare methods for
asynchronuos nfs rpcs, call nfs41_setup_sequence from
respective rpc_call_validate_args methods.
Call nfs4_sequence_done from respective rpc_call_done methods.
Note that we need to pass a pointer to the nfs_server in calls data
for passing on to nfs4_sequence_done.
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[pnfs: client data server write validate and release]
Signed-off-by: Andy Adamson<andros@umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
move nfs4_sequence_free_slot from nfs41: separate free slot from sequence done
Don't free the slot until after all rpc_restart_calls have completed.
Session reset will require more work.
[nfs41: sequence res use slotid]
[nfs41: remove SEQ4_STATUS_USE_TK_STATUS]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 2 ++
fs/nfs/unlink.c | 17 +++++++++++++++++
2 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 5d13918..cb5d457 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2444,8 +2444,10 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
{
struct nfs_removeres *res = task->tk_msg.rpc_resp;
+ nfs4_sequence_done(res->server, &res->seq_res, task->tk_status);
if (nfs4_async_handle_error(task, res->server, NULL) == -EAGAIN)
return 0;
+ nfs4_sequence_free_slot(res->server, &res->seq_res);
update_changeattr(dir, &res->cinfo);
nfs_post_op_update_inode(dir, &res->dir_attr);
return 1;
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 83d0ce2..089a21b 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -15,6 +15,7 @@
#include <linux/wait.h>
#include "internal.h"
+#include "nfs4_fs.h"
struct nfs_unlinkdata {
struct hlist_node list;
@@ -102,9 +103,25 @@ static void nfs_async_unlink_release(void *calldata)
nfs_sb_deactive(sb);
}
+#if defined(CONFIG_NFS_V4_1)
+void nfs_unlink_prepare(struct rpc_task *task, void *calldata)
+{
+ struct nfs_unlinkdata *data = calldata;
+ struct nfs_server *server = NFS_SERVER(data->dir);
+
+ if (nfs4_setup_sequence(server->nfs_client, &data->args.seq_args,
+ &data->res.seq_res, 1, task))
+ return;
+ rpc_call_start(task);
+}
+#endif /* CONFIG_NFS_V4_1 */
+
static const struct rpc_call_ops nfs_unlink_ops = {
.rpc_call_done = nfs_async_unlink_done,
.rpc_release = nfs_async_unlink_release,
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_unlink_prepare,
+#endif /* CONFIG_NFS_V4_1 */
};
static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct nfs_unlinkdata *data)
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 43/46] nfs41: read sequence setup/done support
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (40 preceding siblings ...)
2009-03-04 0:01 ` [PATCH 42/46] nfs41: unlink " Benny Halevy
@ 2009-03-04 0:01 ` Benny Halevy
2009-03-04 0:01 ` [PATCH 44/46] nfs41 write sequence setup done support Benny Halevy
` (2 subsequent siblings)
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-04 0:01 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Implement the read rpc_call_prepare method for
asynchronuos nfs rpcs, call nfs41_setup_sequence from
respective rpc_call_validate_args methods.
Call nfs4_sequence_done from respective rpc_call_done methods.
Note that we need to pass a pointer to the nfs_server in calls data
for passing on to nfs4_sequence_done.
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[pnfs: client data server write validate and release]
Signed-off-by: Andy Adamson<andros@umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[move the nfs4_sequence_free_slot call in nfs_readpage_retry from]
[nfs41: separate free slot from sequence done]
[remove nfs_readargs.nfs_server, use calldata->inode instead]
Signed-off-by: Andy Adamson<andros@umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: Support sessions with O_DIRECT]
Signed-off-by: Dean Hildebrand <dhildeb@us.ibm.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/direct.c | 9 +++++++++
fs/nfs/internal.h | 6 ++++++
fs/nfs/nfs4proc.c | 5 +++++
fs/nfs/read.c | 30 +++++++++++++++++++++++++++---
4 files changed, 47 insertions(+), 3 deletions(-)
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 08f6b04..489fc01 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -259,6 +259,9 @@ static void nfs_direct_read_release(void *calldata)
}
static const struct rpc_call_ops nfs_read_direct_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_read_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_direct_read_result,
.rpc_release = nfs_direct_read_release,
};
@@ -535,6 +538,9 @@ static void nfs_direct_commit_release(void *calldata)
}
static const struct rpc_call_ops nfs_commit_direct_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_write_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_direct_commit_result,
.rpc_release = nfs_direct_commit_release,
};
@@ -673,6 +679,9 @@ out_unlock:
}
static const struct rpc_call_ops nfs_write_direct_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_write_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_direct_write_result,
.rpc_release = nfs_direct_write_release,
};
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index f7d55a5..0294a4a 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -198,6 +198,12 @@ extern int nfs4_path_walk(struct nfs_server *server,
const char *path);
#endif
+/* read.c */
+extern void nfs_read_prepare(struct rpc_task *task, void *calldata);
+
+/* write.c */
+extern void nfs_write_prepare(struct rpc_task *task, void *calldata);
+
/* nfs4proc.c */
extern int _nfs4_call_sync(struct nfs_server *server,
struct rpc_message *msg,
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index cb5d457..d7627c4 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2884,6 +2884,11 @@ static int nfs4_read_done(struct rpc_task *task, struct nfs_read_data *data)
{
struct nfs_server *server = NFS_SERVER(data->inode);
+ dprintk("--> %s\n", __func__);
+
+ /* nfs4_sequence_free_slot called in the read rpc_call_done */
+ nfs4_sequence_done(server, &data->res.seq_res, task->tk_status);
+
if (nfs4_async_handle_error(task, server, data->args.context->state) == -EAGAIN) {
rpc_restart_call(task);
return -EAGAIN;
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 9d72124..20104d5 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -22,6 +22,7 @@
#include <asm/system.h>
+#include "nfs4_fs.h"
#include "internal.h"
#include "iostat.h"
@@ -305,7 +306,6 @@ static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned
data = nfs_readdata_alloc(npages);
if (!data)
goto out_bad;
-
pages = data->pagevec;
while (!list_empty(head)) {
req = nfs_list_entry(head->next);
@@ -352,19 +352,24 @@ static void nfs_readpage_retry(struct rpc_task *task, struct nfs_read_data *data
struct nfs_readres *resp = &data->res;
if (resp->eof || resp->count == argp->count)
- return;
+ goto out;
/* This is a short read! */
nfs_inc_stats(data->inode, NFSIOS_SHORTREAD);
/* Has the server at least made some progress? */
if (resp->count == 0)
- return;
+ goto out;
/* Yes, so retry the read at the end of the data */
argp->offset += resp->count;
argp->pgbase += resp->count;
argp->count -= resp->count;
rpc_restart_call(task);
+ return;
+out:
+ nfs4_sequence_free_slot(NFS_SERVER(data->inode), &data->res.seq_res);
+ return;
+
}
/*
@@ -401,7 +406,23 @@ static void nfs_readpage_release_partial(void *calldata)
nfs_readdata_release(calldata);
}
+#if defined(CONFIG_NFS_V4_1)
+void nfs_read_prepare(struct rpc_task *task, void *calldata)
+{
+ struct nfs_read_data *data = calldata;
+
+ if (nfs4_setup_sequence(NFS_SERVER(data->inode)->nfs_client,
+ &data->args.seq_args, &data->res.seq_res,
+ 0, task))
+ return;
+ rpc_call_start(task);
+}
+#endif /* CONFIG_NFS_V4_1 */
+
static const struct rpc_call_ops nfs_read_partial_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_read_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_readpage_result_partial,
.rpc_release = nfs_readpage_release_partial,
};
@@ -465,6 +486,9 @@ static void nfs_readpage_release_full(void *calldata)
}
static const struct rpc_call_ops nfs_read_full_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_read_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_readpage_result_full,
.rpc_release = nfs_readpage_release_full,
};
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 44/46] nfs41 write sequence setup done support
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (41 preceding siblings ...)
2009-03-04 0:01 ` [PATCH 43/46] nfs41: read " Benny Halevy
@ 2009-03-04 0:01 ` Benny Halevy
2009-03-04 0:02 ` [PATCH 45/46] nfs41 commit " Benny Halevy
2009-03-04 0:02 ` [PATCH 46/46] nfs41 delegreturn " Benny Halevy
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-04 0:01 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Separate write calls from nfs41: sequence setup/done support
Implement the write rpc_call_prepare method for
asynchronuos nfs rpcs, call nfs41_setup_sequence from
respective rpc_call_validate_args methods.
Call nfs4_sequence_done from respective rpc_call_done methods.
Note that we need to pass a pointer to the nfs_server in calls data
for passing on to nfs4_sequence_done.
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[pnfs: client data server write validate and release]
Signed-off-by: Andy Adamson<andros@umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[move the nfs4_sequence_free_slot call in nfs_readpage_retry from]
[nfs41: separate free slot from sequence done
Signed-off-by: Andy Adamson<andros@umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: Support sessions with O_DIRECT.]
Signed-off-by: Dean Hildebrand <dhildeb@us.ibm.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 4 ++++
fs/nfs/write.c | 21 +++++++++++++++++++++
2 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index d7627c4..f37420c 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2910,6 +2910,10 @@ static int nfs4_write_done(struct rpc_task *task, struct nfs_write_data *data)
{
struct inode *inode = data->inode;
+ /* slot is freed in nfs_writeback_done */
+ nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
+ task->tk_status);
+
if (nfs4_async_handle_error(task, NFS_SERVER(inode), data->args.context->state) == -EAGAIN) {
rpc_restart_call(task);
return -EAGAIN;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index a48afb4..d01050b 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -25,6 +25,7 @@
#include "delegation.h"
#include "internal.h"
#include "iostat.h"
+#include "nfs4_fs.h"
#define NFSDBG_FACILITY NFSDBG_PAGECACHE
@@ -1028,7 +1029,23 @@ out:
nfs_writedata_release(calldata);
}
+#if defined(CONFIG_NFS_V4_1)
+void nfs_write_prepare(struct rpc_task *task, void *calldata)
+{
+ struct nfs_write_data *data = calldata;
+ struct nfs_client *clp = (NFS_SERVER(data->inode))->nfs_client;
+
+ if (nfs4_setup_sequence(clp, &data->args.seq_args,
+ &data->res.seq_res, 1, task))
+ return;
+ rpc_call_start(task);
+}
+#endif /* CONFIG_NFS_V4_1 */
+
static const struct rpc_call_ops nfs_write_partial_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_write_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_writeback_done_partial,
.rpc_release = nfs_writeback_release_partial,
};
@@ -1091,6 +1108,9 @@ remove_request:
}
static const struct rpc_call_ops nfs_write_full_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_write_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_writeback_done_full,
.rpc_release = nfs_writeback_release_full,
};
@@ -1173,6 +1193,7 @@ int nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
/* Can't do anything about it except throw an error. */
task->tk_status = -EIO;
}
+ nfs4_sequence_free_slot(NFS_SERVER(data->inode), &data->res.seq_res);
return 0;
}
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 45/46] nfs41 commit sequence setup done support
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (42 preceding siblings ...)
2009-03-04 0:01 ` [PATCH 44/46] nfs41 write sequence setup done support Benny Halevy
@ 2009-03-04 0:02 ` Benny Halevy
2009-03-04 0:02 ` [PATCH 46/46] nfs41 delegreturn " Benny Halevy
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-04 0:02 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Separate commit calls from nfs41: sequence setup/done support
Implement the commit rpc_call_prepare method for
asynchronuos nfs rpcs, call nfs41_setup_sequence from
respective rpc_call_validate_args methods.
Call nfs4_sequence_done from respective rpc_call_done methods.
Note that we need to pass a pointer to the nfs_server in calls data
for passing on to nfs4_sequence_done.
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[pnfs: client data server write validate and release]
Signed-off-by: Andy Adamson<andros@umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
move the nfs4_sequence_free_slot call in nfs_readpage_retry from
nfs41: separate free slot from sequence done
Signed-off-by: Andy Adamson<andros@umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 3 +++
fs/nfs/write.c | 3 +++
2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f37420c..6f92037 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2940,10 +2940,13 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_write_data *data)
{
struct inode *inode = data->inode;
+ nfs4_sequence_done(NFS_SERVER(inode), &data->res.seq_res,
+ task->tk_status);
if (nfs4_async_handle_error(task, NFS_SERVER(inode), NULL) == -EAGAIN) {
rpc_restart_call(task);
return -EAGAIN;
}
+ nfs4_sequence_free_slot(NFS_SERVER(inode), &data->res.seq_res);
nfs_refresh_inode(inode, data->res.fattr);
return 0;
}
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index d01050b..5c01551 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1350,6 +1350,9 @@ static void nfs_commit_release(void *calldata)
}
static const struct rpc_call_ops nfs_commit_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs_write_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs_commit_done,
.rpc_release = nfs_commit_release,
};
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread* [PATCH 46/46] nfs41 delegreturn sequence setup done support
2009-03-03 23:28 [PATCH 0/46] nfs41 sessions infrastructure Benny Halevy
` (43 preceding siblings ...)
2009-03-04 0:02 ` [PATCH 45/46] nfs41 commit " Benny Halevy
@ 2009-03-04 0:02 ` Benny Halevy
44 siblings, 0 replies; 63+ messages in thread
From: Benny Halevy @ 2009-03-04 0:02 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-nfs, pnfs
From: Andy Adamson <andros@netapp.com>
Separate delegreturn calls from nfs41: sequence setup/done support
Implement the delegreturn rpc_call_prepare method for
asynchronuos nfs rpcs, call nfs41_setup_sequence from
respective rpc_call_validate_args methods.
Call nfs4_sequence_done from respective rpc_call_done methods.
Note that we need to pass a pointer to the nfs_server in calls data
for passing on to nfs4_sequence_done.
Signed-off-by: Andy Adamson<andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[pnfs: client data server write validate and release]
Signed-off-by: Andy Adamson<andros@umich.edu>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
---
fs/nfs/nfs4proc.c | 24 +++++++++++++++++++++++-
1 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 6f92037..d85f15d 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3383,6 +3383,10 @@ struct nfs4_delegreturndata {
static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
{
struct nfs4_delegreturndata *data = calldata;
+
+ nfs4_sequence_done_free_slot(data->res.server, &data->res.seq_res,
+ task->tk_status);
+
data->rpc_status = task->tk_status;
if (data->rpc_status == 0)
renew_lease(data->res.server, data->timestamp);
@@ -3393,7 +3397,25 @@ static void nfs4_delegreturn_release(void *calldata)
kfree(calldata);
}
+#if defined(CONFIG_NFS_V4_1)
+static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
+{
+ struct nfs4_delegreturndata *d_data;
+
+ d_data = (struct nfs4_delegreturndata *)data;
+
+ if (nfs4_setup_sequence(d_data->res.server->nfs_client,
+ &d_data->args.seq_args,
+ &d_data->res.seq_res, 1, task))
+ return;
+ rpc_call_start(task);
+}
+#endif /* CONFIG_NFS_V4_1 */
+
static const struct rpc_call_ops nfs4_delegreturn_ops = {
+#if defined(CONFIG_NFS_V4_1)
+ .rpc_call_prepare = nfs4_delegreturn_prepare,
+#endif /* CONFIG_NFS_V4_1 */
.rpc_call_done = nfs4_delegreturn_done,
.rpc_release = nfs4_delegreturn_release,
};
@@ -3415,7 +3437,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
};
int status = 0;
- data = kmalloc(sizeof(*data), GFP_KERNEL);
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
data->args.fhandle = &data->fh;
--
1.6.1.3
^ permalink raw reply related [flat|nested] 63+ messages in thread