NFSv4: parse and display server implementation ids
Shows the implementation ids in /proc/self/mountstats. This doesn't break the nfs-utils mountstats tool. Signed-off-by: Weston Andros Adamson <dros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
Родитель
9edbd953f8
Коммит
7d2ed9ac22
|
@ -304,6 +304,7 @@ static void nfs_free_client(struct nfs_client *clp)
|
||||||
put_net(clp->net);
|
put_net(clp->net);
|
||||||
kfree(clp->cl_hostname);
|
kfree(clp->cl_hostname);
|
||||||
kfree(clp->server_scope);
|
kfree(clp->server_scope);
|
||||||
|
kfree(clp->impl_id);
|
||||||
kfree(clp);
|
kfree(clp);
|
||||||
|
|
||||||
dprintk("<-- nfs_free_client()\n");
|
dprintk("<-- nfs_free_client()\n");
|
||||||
|
|
|
@ -4950,10 +4950,23 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res.impl_id = kzalloc(sizeof(struct nfs41_impl_id), GFP_KERNEL);
|
||||||
|
if (unlikely(!res.impl_id)) {
|
||||||
|
status = -ENOMEM;
|
||||||
|
goto out_server_scope;
|
||||||
|
}
|
||||||
|
|
||||||
status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
|
status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
|
||||||
if (!status)
|
if (!status)
|
||||||
status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags);
|
status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags);
|
||||||
|
|
||||||
|
if (!status) {
|
||||||
|
/* use the most recent implementation id */
|
||||||
|
kfree(clp->impl_id);
|
||||||
|
clp->impl_id = res.impl_id;
|
||||||
|
} else
|
||||||
|
kfree(res.impl_id);
|
||||||
|
|
||||||
if (!status) {
|
if (!status) {
|
||||||
if (clp->server_scope &&
|
if (clp->server_scope &&
|
||||||
!nfs41_same_server_scope(clp->server_scope,
|
!nfs41_same_server_scope(clp->server_scope,
|
||||||
|
@ -4970,8 +4983,16 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out_server_scope:
|
||||||
kfree(res.server_scope);
|
kfree(res.server_scope);
|
||||||
out:
|
out:
|
||||||
|
if (clp->impl_id)
|
||||||
|
dprintk("%s: Server Implementation ID: "
|
||||||
|
"domain: %s, name: %s, date: %llu,%u\n",
|
||||||
|
__func__, clp->impl_id->domain, clp->impl_id->name,
|
||||||
|
clp->impl_id->date.seconds,
|
||||||
|
clp->impl_id->date.nseconds);
|
||||||
dprintk("<-- %s status= %d\n", __func__, status);
|
dprintk("<-- %s status= %d\n", __func__, status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -291,7 +291,11 @@ static int nfs4_stat_to_errno(int);
|
||||||
/* eir_server_scope<> */ \
|
/* eir_server_scope<> */ \
|
||||||
XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \
|
XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \
|
||||||
1 /* eir_server_impl_id array length */ + \
|
1 /* eir_server_impl_id array length */ + \
|
||||||
0 /* ignored eir_server_impl_id contents */)
|
1 /* nii_domain */ + \
|
||||||
|
XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
|
||||||
|
1 /* nii_name */ + \
|
||||||
|
XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
|
||||||
|
3 /* nii_date */)
|
||||||
#define encode_channel_attrs_maxsz (6 + 1 /* ca_rdma_ird.len (0) */)
|
#define encode_channel_attrs_maxsz (6 + 1 /* ca_rdma_ird.len (0) */)
|
||||||
#define decode_channel_attrs_maxsz (6 + \
|
#define decode_channel_attrs_maxsz (6 + \
|
||||||
1 /* ca_rdma_ird.len */ + \
|
1 /* ca_rdma_ird.len */ + \
|
||||||
|
@ -5256,6 +5260,7 @@ static int decode_exchange_id(struct xdr_stream *xdr,
|
||||||
char *dummy_str;
|
char *dummy_str;
|
||||||
int status;
|
int status;
|
||||||
struct nfs_client *clp = res->client;
|
struct nfs_client *clp = res->client;
|
||||||
|
uint32_t impl_id_count;
|
||||||
|
|
||||||
status = decode_op_hdr(xdr, OP_EXCHANGE_ID);
|
status = decode_op_hdr(xdr, OP_EXCHANGE_ID);
|
||||||
if (status)
|
if (status)
|
||||||
|
@ -5297,11 +5302,38 @@ static int decode_exchange_id(struct xdr_stream *xdr,
|
||||||
memcpy(res->server_scope->server_scope, dummy_str, dummy);
|
memcpy(res->server_scope->server_scope, dummy_str, dummy);
|
||||||
res->server_scope->server_scope_sz = dummy;
|
res->server_scope->server_scope_sz = dummy;
|
||||||
|
|
||||||
/* Throw away Implementation id array */
|
/* Implementation Id */
|
||||||
status = decode_opaque_inline(xdr, &dummy, &dummy_str);
|
p = xdr_inline_decode(xdr, 4);
|
||||||
if (unlikely(status))
|
if (unlikely(!p))
|
||||||
return status;
|
goto out_overflow;
|
||||||
|
impl_id_count = be32_to_cpup(p++);
|
||||||
|
|
||||||
|
if (impl_id_count) {
|
||||||
|
/* nii_domain */
|
||||||
|
status = decode_opaque_inline(xdr, &dummy, &dummy_str);
|
||||||
|
if (unlikely(status))
|
||||||
|
return status;
|
||||||
|
if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
|
||||||
|
return -EIO;
|
||||||
|
memcpy(res->impl_id->domain, dummy_str, dummy);
|
||||||
|
|
||||||
|
/* nii_name */
|
||||||
|
status = decode_opaque_inline(xdr, &dummy, &dummy_str);
|
||||||
|
if (unlikely(status))
|
||||||
|
return status;
|
||||||
|
if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
|
||||||
|
return -EIO;
|
||||||
|
memcpy(res->impl_id->name, dummy_str, dummy);
|
||||||
|
|
||||||
|
/* nii_date */
|
||||||
|
p = xdr_inline_decode(xdr, 12);
|
||||||
|
if (unlikely(!p))
|
||||||
|
goto out_overflow;
|
||||||
|
p = xdr_decode_hyper(p, &res->impl_id->date.seconds);
|
||||||
|
res->impl_id->date.nseconds = be32_to_cpup(p);
|
||||||
|
|
||||||
|
/* if there's more than one entry, ignore the rest */
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
out_overflow:
|
out_overflow:
|
||||||
print_overflow_msg(__func__, xdr);
|
print_overflow_msg(__func__, xdr);
|
||||||
|
|
|
@ -809,6 +809,14 @@ static int nfs_show_stats(struct seq_file *m, struct dentry *root)
|
||||||
|
|
||||||
seq_printf(m, "\n\tage:\t%lu", (jiffies - nfss->mount_time) / HZ);
|
seq_printf(m, "\n\tage:\t%lu", (jiffies - nfss->mount_time) / HZ);
|
||||||
|
|
||||||
|
if (nfss->nfs_client && nfss->nfs_client->impl_id) {
|
||||||
|
struct nfs41_impl_id *impl_id = nfss->nfs_client->impl_id;
|
||||||
|
seq_printf(m, "\n\timpl_id:\tname='%s',domain='%s',"
|
||||||
|
"date='%llu,%u'",
|
||||||
|
impl_id->name, impl_id->domain,
|
||||||
|
impl_id->date.seconds, impl_id->date.nseconds);
|
||||||
|
}
|
||||||
|
|
||||||
seq_printf(m, "\n\tcaps:\t");
|
seq_printf(m, "\n\tcaps:\t");
|
||||||
seq_printf(m, "caps=0x%x", nfss->caps);
|
seq_printf(m, "caps=0x%x", nfss->caps);
|
||||||
seq_printf(m, ",wtmult=%u", nfss->wtmult);
|
seq_printf(m, ",wtmult=%u", nfss->wtmult);
|
||||||
|
|
|
@ -18,6 +18,7 @@ struct nfs4_sequence_res;
|
||||||
struct nfs_server;
|
struct nfs_server;
|
||||||
struct nfs4_minor_version_ops;
|
struct nfs4_minor_version_ops;
|
||||||
struct server_scope;
|
struct server_scope;
|
||||||
|
struct nfs41_impl_id;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The nfs_client identifies our client state to the server.
|
* The nfs_client identifies our client state to the server.
|
||||||
|
@ -86,6 +87,7 @@ struct nfs_client {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct server_scope *server_scope; /* from exchange_id */
|
struct server_scope *server_scope; /* from exchange_id */
|
||||||
|
struct nfs41_impl_id *impl_id; /* from exchange_id */
|
||||||
struct net *net;
|
struct net *net;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1054,14 +1054,6 @@ struct nfstime4 {
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_NFS_V4_1
|
#ifdef CONFIG_NFS_V4_1
|
||||||
struct nfs_impl_id4 {
|
|
||||||
u32 domain_len;
|
|
||||||
char *domain;
|
|
||||||
u32 name_len;
|
|
||||||
char *name;
|
|
||||||
struct nfstime4 date;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NFS4_EXCHANGE_ID_LEN (48)
|
#define NFS4_EXCHANGE_ID_LEN (48)
|
||||||
struct nfs41_exchange_id_args {
|
struct nfs41_exchange_id_args {
|
||||||
struct nfs_client *client;
|
struct nfs_client *client;
|
||||||
|
@ -1082,10 +1074,17 @@ struct server_scope {
|
||||||
char server_scope[NFS4_OPAQUE_LIMIT];
|
char server_scope[NFS4_OPAQUE_LIMIT];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct nfs41_impl_id {
|
||||||
|
char domain[NFS4_OPAQUE_LIMIT + 1];
|
||||||
|
char name[NFS4_OPAQUE_LIMIT + 1];
|
||||||
|
struct nfstime4 date;
|
||||||
|
};
|
||||||
|
|
||||||
struct nfs41_exchange_id_res {
|
struct nfs41_exchange_id_res {
|
||||||
struct nfs_client *client;
|
struct nfs_client *client;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
struct server_scope *server_scope;
|
struct server_scope *server_scope;
|
||||||
|
struct nfs41_impl_id *impl_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nfs41_create_session_args {
|
struct nfs41_create_session_args {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче