aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorWeston Andros Adamson <dros@netapp.com>2012-02-17 15:20:24 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-03-01 17:10:21 -0500
commitdb8ac8ba871ae7b97118cfb2913b4986867f09a7 (patch)
treecae7a2bfb92ea435f356f767cb0f36a819cceace /fs/nfs
parent57e62324e469e092ecc6c94a7a86fe4bd6ac5172 (diff)
NFSv4: Send implementation id with exchange_id
Send the nfs implementation id in EXCHANGE_ID requests unless the module parameter nfs.send_implementation_id is 0. This adds a CONFIG variable for the nii_domain that defaults to "kernel.org". Signed-off-by: Weston Andros Adamson <dros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/Kconfig12
-rw-r--r--fs/nfs/nfs4xdr.c41
2 files changed, 51 insertions, 2 deletions
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index ee86cfcd6c33..7bce64c7060e 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -99,6 +99,18 @@ config PNFS_OBJLAYOUT
99 depends on NFS_FS && NFS_V4_1 && SCSI_OSD_ULD 99 depends on NFS_FS && NFS_V4_1 && SCSI_OSD_ULD
100 default m 100 default m
101 101
102config NFS_V4_1_IMPLEMENTATION_ID_DOMAIN
103 string "NFSv4.1 Implementation ID Domain"
104 depends on NFS_V4_1
105 default "kernel.org"
106 help
107 This option defines the domain portion of the implementation ID that
108 may be sent in the NFS exchange_id operation. The value must be in
109 the format of a DNS domain name and should be set to the DNS domain
110 name of the distribution.
111 If the NFS client is unchanged from the upstream kernel, this
112 option should be set to the default "kernel.org".
113
102config ROOT_NFS 114config ROOT_NFS
103 bool "Root file system on NFS" 115 bool "Root file system on NFS"
104 depends on NFS_FS=y && IP_PNP 116 depends on NFS_FS=y && IP_PNP
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index ae7834366712..d824aedb1237 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -44,6 +44,8 @@
44#include <linux/pagemap.h> 44#include <linux/pagemap.h>
45#include <linux/proc_fs.h> 45#include <linux/proc_fs.h>
46#include <linux/kdev_t.h> 46#include <linux/kdev_t.h>
47#include <linux/module.h>
48#include <linux/utsname.h>
47#include <linux/sunrpc/clnt.h> 49#include <linux/sunrpc/clnt.h>
48#include <linux/sunrpc/msg_prot.h> 50#include <linux/sunrpc/msg_prot.h>
49#include <linux/sunrpc/gss_api.h> 51#include <linux/sunrpc/gss_api.h>
@@ -271,7 +273,12 @@ static int nfs4_stat_to_errno(int);
271 1 /* flags */ + \ 273 1 /* flags */ + \
272 1 /* spa_how */ + \ 274 1 /* spa_how */ + \
273 0 /* SP4_NONE (for now) */ + \ 275 0 /* SP4_NONE (for now) */ + \
274 1 /* zero implemetation id array */) 276 1 /* implementation id array of size 1 */ + \
277 1 /* nii_domain */ + \
278 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
279 1 /* nii_name */ + \
280 XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + \
281 3 /* nii_date */)
275#define decode_exchange_id_maxsz (op_decode_hdr_maxsz + \ 282#define decode_exchange_id_maxsz (op_decode_hdr_maxsz + \
276 2 /* eir_clientid */ + \ 283 2 /* eir_clientid */ + \
277 1 /* eir_sequenceid */ + \ 284 1 /* eir_sequenceid */ + \
@@ -838,6 +845,12 @@ const u32 nfs41_maxread_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
838 XDR_UNIT); 845 XDR_UNIT);
839#endif /* CONFIG_NFS_V4_1 */ 846#endif /* CONFIG_NFS_V4_1 */
840 847
848static unsigned short send_implementation_id = 1;
849
850module_param(send_implementation_id, ushort, 0644);
851MODULE_PARM_DESC(send_implementation_id,
852 "Send implementation ID with NFSv4.1 exchange_id");
853
841static const umode_t nfs_type2fmt[] = { 854static const umode_t nfs_type2fmt[] = {
842 [NF4BAD] = 0, 855 [NF4BAD] = 0,
843 [NF4REG] = S_IFREG, 856 [NF4REG] = S_IFREG,
@@ -1766,6 +1779,8 @@ static void encode_exchange_id(struct xdr_stream *xdr,
1766 struct compound_hdr *hdr) 1779 struct compound_hdr *hdr)
1767{ 1780{
1768 __be32 *p; 1781 __be32 *p;
1782 char impl_name[NFS4_OPAQUE_LIMIT];
1783 int len = 0;
1769 1784
1770 p = reserve_space(xdr, 4 + sizeof(args->verifier->data)); 1785 p = reserve_space(xdr, 4 + sizeof(args->verifier->data));
1771 *p++ = cpu_to_be32(OP_EXCHANGE_ID); 1786 *p++ = cpu_to_be32(OP_EXCHANGE_ID);
@@ -1776,7 +1791,29 @@ static void encode_exchange_id(struct xdr_stream *xdr,
1776 p = reserve_space(xdr, 12); 1791 p = reserve_space(xdr, 12);
1777 *p++ = cpu_to_be32(args->flags); 1792 *p++ = cpu_to_be32(args->flags);
1778 *p++ = cpu_to_be32(0); /* zero length state_protect4_a */ 1793 *p++ = cpu_to_be32(0); /* zero length state_protect4_a */
1779 *p = cpu_to_be32(0); /* zero length implementation id array */ 1794
1795 if (send_implementation_id &&
1796 sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) > 1 &&
1797 sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN)
1798 <= NFS4_OPAQUE_LIMIT + 1)
1799 len = snprintf(impl_name, sizeof(impl_name), "%s %s %s %s",
1800 utsname()->sysname, utsname()->release,
1801 utsname()->version, utsname()->machine);
1802
1803 if (len > 0) {
1804 *p = cpu_to_be32(1); /* implementation id array length=1 */
1805
1806 encode_string(xdr,
1807 sizeof(CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN) - 1,
1808 CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN);
1809 encode_string(xdr, len, impl_name);
1810 /* just send zeros for nii_date - the date is in nii_name */
1811 p = reserve_space(xdr, 12);
1812 p = xdr_encode_hyper(p, 0);
1813 *p = cpu_to_be32(0);
1814 } else
1815 *p = cpu_to_be32(0); /* implementation id array length=0 */
1816
1780 hdr->nops++; 1817 hdr->nops++;
1781 hdr->replen += decode_exchange_id_maxsz; 1818 hdr->replen += decode_exchange_id_maxsz;
1782} 1819}