NLM: Decode "priv" argument of NLMPROC_SM_NOTIFY as an opaque
authorChuck Lever <chuck.lever@oracle.com>
Sat, 6 Dec 2008 00:03:39 +0000 (19:03 -0500)
committerJ. Bruce Fields <bfields@citi.umich.edu>
Tue, 6 Jan 2009 16:53:54 +0000 (11:53 -0500)
The NLM XDR decoders for the NLMPROC_SM_NOTIFY procedure should treat
their "priv" argument truly as an opaque, as defined by the protocol,
and let the upper layers figure out what is in it.

This will make it easier to modify the contents and interpretation of
the "priv" argument, and keep knowledge about what's in "priv" local
to fs/lockd/mon.c.

For now, the NLM and NSM implementations should behave exactly as they
did before.

The formation of the address of the rebooted host in
nlm_host_rebooted() may look a little strange, but it is the inverse
of how nsm_init_private() forms the private cookie.  Plus, it's
going away soon anyway.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
fs/lockd/host.c
fs/lockd/xdr.c
fs/lockd/xdr4.c
include/linux/lockd/xdr.h

index ed103387964d648751833c277f0b00764b767c76..dc41e46ef74ccaa066047403069159150e0bdd69 100644 (file)
@@ -453,9 +453,10 @@ void nlm_release_host(struct nlm_host *host)
  */
 void nlm_host_rebooted(const struct nlm_reboot *info)
 {
+       __be32 *p = (__be32 *)&info->priv.data;
        const struct sockaddr_in sin = {
                .sin_family             = AF_INET,
-               .sin_addr.s_addr        = info->addr,
+               .sin_addr.s_addr        = *p,
        };
        struct hlist_head *chain;
        struct hlist_node *pos;
index 1f226290c67cf88a2707f08447d2e92f9a98bfbc..4cc7d01a1eb5300eeb5d8b2923228ed731dde15f 100644 (file)
@@ -349,8 +349,8 @@ nlmsvc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp)
        if (!(p = xdr_decode_string_inplace(p, &argp->mon, &argp->len, SM_MAXSTRLEN)))
                return 0;
        argp->state = ntohl(*p++);
-       /* Preserve the address in network byte order */
-       argp->addr = *p++;
+       memcpy(&argp->priv.data, p, sizeof(argp->priv.data));
+       p += XDR_QUADLEN(SM_PRIV_SIZE);
        return xdr_argsize_check(rqstp, p);
 }
 
index 50c493a8ad8e5e1f4fcd10eaa7d2311a35c5285b..61d1714a470e20027af2a7fd8483b3cfdb6f645a 100644 (file)
@@ -356,8 +356,8 @@ nlm4svc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp
        if (!(p = xdr_decode_string_inplace(p, &argp->mon, &argp->len, SM_MAXSTRLEN)))
                return 0;
        argp->state = ntohl(*p++);
-       /* Preserve the address in network byte order */
-       argp->addr  = *p++;
+       memcpy(&argp->priv.data, p, sizeof(argp->priv.data));
+       p += XDR_QUADLEN(SM_PRIV_SIZE);
        return xdr_argsize_check(rqstp, p);
 }
 
index 6b51992638585296b68748ced6b1d26632aaa293..6338866222a8fd1b4797058cf22251d718bedd34 100644 (file)
@@ -83,10 +83,10 @@ struct nlm_res {
  * statd callback when client has rebooted
  */
 struct nlm_reboot {
-       char *          mon;
-       unsigned int    len;
-       u32             state;
-       __be32          addr;
+       char                    *mon;
+       unsigned int            len;
+       u32                     state;
+       struct nsm_private      priv;
 };
 
 /*