Commit af0ccd94 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: Prime SETCLIENTID call for the delegation callback info.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@fys.uio.no>
parent ed373838
...@@ -1996,13 +1996,15 @@ nfs4_request_compatible(struct nfs_page *req, struct file *filp, struct page *pa ...@@ -1996,13 +1996,15 @@ nfs4_request_compatible(struct nfs_page *req, struct file *filp, struct page *pa
return 1; return 1;
} }
int int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short port)
nfs4_proc_setclientid(struct nfs4_client *clp,
u32 program, unsigned short port)
{ {
u32 *p; static nfs4_verifier sc_verifier;
struct nfs4_setclientid setclientid; static int initialized;
struct timespec tv;
struct nfs4_setclientid setclientid = {
.sc_verifier = &sc_verifier,
.sc_prog = program,
};
struct rpc_message msg = { struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID], .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID],
.rpc_argp = &setclientid, .rpc_argp = &setclientid,
...@@ -2010,15 +2012,24 @@ nfs4_proc_setclientid(struct nfs4_client *clp, ...@@ -2010,15 +2012,24 @@ nfs4_proc_setclientid(struct nfs4_client *clp,
.rpc_cred = clp->cl_cred, .rpc_cred = clp->cl_cred,
}; };
tv = CURRENT_TIME; if (!initialized) {
p = (u32*)setclientid.sc_verifier.data; struct timespec boot_time;
*p++ = (u32)tv.tv_sec; u32 *p;
*p = (u32)tv.tv_nsec;
setclientid.sc_name = clp->cl_ipaddr; initialized = 1;
sprintf(setclientid.sc_netid, "tcp"); boot_time = CURRENT_TIME;
sprintf(setclientid.sc_uaddr, "%s.%d.%d", clp->cl_ipaddr, port >> 8, port & 255); p = (u32*)sc_verifier.data;
setclientid.sc_prog = htonl(program); *p++ = htonl((u32)boot_time.tv_sec);
setclientid.sc_cb_ident = 0; *p = htonl((u32)boot_time.tv_nsec);
}
setclientid.sc_name_len = scnprintf(setclientid.sc_name,
sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u",
clp->cl_ipaddr, NIPQUAD(clp->cl_addr.s_addr));
setclientid.sc_netid_len = scnprintf(setclientid.sc_netid,
sizeof(setclientid.sc_netid), "tcp");
setclientid.sc_uaddr_len = scnprintf(setclientid.sc_uaddr,
sizeof(setclientid.sc_uaddr), "%s.%d.%d",
clp->cl_ipaddr, port >> 8, port & 255);
return rpc_call_sync(clp->cl_rpcclient, &msg, 0); return rpc_call_sync(clp->cl_rpcclient, &msg, 0);
} }
......
...@@ -404,6 +404,15 @@ struct compound_hdr { ...@@ -404,6 +404,15 @@ struct compound_hdr {
BUG_ON(!p); \ BUG_ON(!p); \
} while (0) } while (0)
static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
{
uint32_t *p;
p = xdr_reserve_space(xdr, 4 + len);
BUG_ON(p == NULL);
xdr_encode_opaque(p, str, len);
}
static int encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) static int encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
{ {
uint32_t *p; uint32_t *p;
...@@ -1047,26 +1056,18 @@ static int encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs * ...@@ -1047,26 +1056,18 @@ static int encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *
static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid) static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid)
{ {
uint32_t total_len;
uint32_t len1, len2, len3;
uint32_t *p; uint32_t *p;
len1 = strlen(setclientid->sc_name); RESERVE_SPACE(4 + sizeof(setclientid->sc_verifier->data));
len2 = strlen(setclientid->sc_netid);
len3 = strlen(setclientid->sc_uaddr);
total_len = XDR_QUADLEN(len1) + XDR_QUADLEN(len2) + XDR_QUADLEN(len3);
total_len = (total_len << 2) + 24 + sizeof(setclientid->sc_verifier.data);
RESERVE_SPACE(total_len);
WRITE32(OP_SETCLIENTID); WRITE32(OP_SETCLIENTID);
WRITEMEM(setclientid->sc_verifier.data, sizeof(setclientid->sc_verifier.data)); WRITEMEM(setclientid->sc_verifier->data, sizeof(setclientid->sc_verifier->data));
WRITE32(len1);
WRITEMEM(setclientid->sc_name, len1); encode_string(xdr, setclientid->sc_name_len, setclientid->sc_name);
RESERVE_SPACE(4);
WRITE32(setclientid->sc_prog); WRITE32(setclientid->sc_prog);
WRITE32(len2); encode_string(xdr, setclientid->sc_netid_len, setclientid->sc_netid);
WRITEMEM(setclientid->sc_netid, len2); encode_string(xdr, setclientid->sc_uaddr_len, setclientid->sc_uaddr);
WRITE32(len3); RESERVE_SPACE(4);
WRITEMEM(setclientid->sc_uaddr, len3);
WRITE32(setclientid->sc_cb_ident); WRITE32(setclientid->sc_cb_ident);
return 0; return 0;
......
...@@ -597,13 +597,15 @@ struct nfs4_rename_res { ...@@ -597,13 +597,15 @@ struct nfs4_rename_res {
}; };
struct nfs4_setclientid { struct nfs4_setclientid {
nfs4_verifier sc_verifier; /* request */ const nfs4_verifier * sc_verifier; /* request */
char * sc_name; /* request */ unsigned int sc_name_len;
char sc_name[32]; /* request */
u32 sc_prog; /* request */ u32 sc_prog; /* request */
unsigned int sc_netid_len;
char sc_netid[4]; /* request */ char sc_netid[4]; /* request */
unsigned int sc_uaddr_len;
char sc_uaddr[24]; /* request */ char sc_uaddr[24]; /* request */
u32 sc_cb_ident; /* request */ u32 sc_cb_ident; /* request */
struct nfs4_client * sc_state; /* response */
}; };
struct nfs4_statfs_arg { struct nfs4_statfs_arg {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment