Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7d2ed9ac authored by Weston Andros Adamson's avatar Weston Andros Adamson Committed by Trond Myklebust
Browse files

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: default avatarWeston Andros Adamson <dros@netapp.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 9edbd953
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -304,6 +304,7 @@ static void nfs_free_client(struct nfs_client *clp)
	put_net(clp->net);
	kfree(clp->cl_hostname);
	kfree(clp->server_scope);
	kfree(clp->impl_id);
	kfree(clp);

	dprintk("<-- nfs_free_client()\n");
+21 −0
Original line number Diff line number Diff line
@@ -4950,10 +4950,23 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
		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);
	if (!status)
		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 (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;
		}
	}

out_server_scope:
	kfree(res.server_scope);
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);
	return status;
}
+37 −5
Original line number Diff line number Diff line
@@ -291,7 +291,11 @@ static int nfs4_stat_to_errno(int);
				/* eir_server_scope<> */ \
				XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \
				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 decode_channel_attrs_maxsz  (6 + \
				     1 /* ca_rdma_ird.len */ + \
@@ -5256,6 +5260,7 @@ static int decode_exchange_id(struct xdr_stream *xdr,
	char *dummy_str;
	int status;
	struct nfs_client *clp = res->client;
	uint32_t impl_id_count;

	status = decode_op_hdr(xdr, OP_EXCHANGE_ID);
	if (status)
@@ -5297,11 +5302,38 @@ static int decode_exchange_id(struct xdr_stream *xdr,
	memcpy(res->server_scope->server_scope, dummy_str, dummy);
	res->server_scope->server_scope_sz = dummy;

	/* Throw away Implementation id array */
	/* Implementation Id */
	p = xdr_inline_decode(xdr, 4);
	if (unlikely(!p))
		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;
out_overflow:
	print_overflow_msg(__func__, xdr);
+8 −0
Original line number Diff line number Diff line
@@ -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);

	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, "caps=0x%x", nfss->caps);
	seq_printf(m, ",wtmult=%u", nfss->wtmult);
+2 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ struct nfs4_sequence_res;
struct nfs_server;
struct nfs4_minor_version_ops;
struct server_scope;
struct nfs41_impl_id;

/*
 * The nfs_client identifies our client state to the server.
@@ -86,6 +87,7 @@ struct nfs_client {
#endif

	struct server_scope	*server_scope;	/* from exchange_id */
	struct nfs41_impl_id	*impl_id;	/* from exchange_id */
	struct net		*net;
};

Loading