summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/fs/nfs/nfs_var.h1
-rw-r--r--sys/fs/nfsclient/nfs_clport.c25
-rw-r--r--sys/fs/nfsclient/nfs_clvfsops.c102
-rw-r--r--sys/nfs/nfs_nfssvc.c4
-rw-r--r--sys/nfs/nfssvc.h8
5 files changed, 138 insertions, 2 deletions
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index e5bacb2..8e68d42 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -313,6 +313,7 @@ void nfsd_init(void);
int nfsd_checkrootexp(struct nfsrv_descript *);
/* nfs_clvfsops.c */
+void nfscl_retopts(struct nfsmount *, char *, size_t);
/* nfs_commonport.c */
int nfsrv_checksockseqnum(struct socket *, tcp_seq);
diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c
index 1cbf325..fe28975 100644
--- a/sys/fs/nfsclient/nfs_clport.c
+++ b/sys/fs/nfsclient/nfs_clport.c
@@ -1201,6 +1201,9 @@ nfssvc_nfscl(struct thread *td, struct nfssvc_args *uap)
struct nfscbd_args nfscbdarg;
struct nfsd_nfscbd_args nfscbdarg2;
int error;
+ struct nameidata nd;
+ struct nfscl_dumpmntopts dumpmntopts;
+ char *buf;
if (uap->flag & NFSSVC_CBADDSOCK) {
error = copyin(uap->argp, (caddr_t)&nfscbdarg, sizeof(nfscbdarg));
@@ -1233,6 +1236,28 @@ nfssvc_nfscl(struct thread *td, struct nfssvc_args *uap)
if (error)
return (error);
error = nfscbd_nfsd(td, &nfscbdarg2);
+ } else if (uap->flag & NFSSVC_DUMPMNTOPTS) {
+ error = copyin(uap->argp, &dumpmntopts, sizeof(dumpmntopts));
+ if (error == 0 && (dumpmntopts.ndmnt_blen < 256 ||
+ dumpmntopts.ndmnt_blen > 1024))
+ error = EINVAL;
+ if (error == 0)
+ error = nfsrv_lookupfilename(&nd,
+ dumpmntopts.ndmnt_fname, td);
+ if (error == 0 && strcmp(nd.ni_vp->v_mount->mnt_vfc->vfc_name,
+ "nfs") != 0) {
+ vput(nd.ni_vp);
+ error = EINVAL;
+ }
+ if (error == 0) {
+ buf = malloc(dumpmntopts.ndmnt_blen, M_TEMP, M_WAITOK);
+ nfscl_retopts(VFSTONFS(nd.ni_vp->v_mount), buf,
+ dumpmntopts.ndmnt_blen);
+ vput(nd.ni_vp);
+ error = copyout(buf, dumpmntopts.ndmnt_buf,
+ dumpmntopts.ndmnt_blen);
+ free(buf, M_TEMP);
+ }
} else {
error = EINVAL;
}
diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c
index 71791fa..41a6b78 100644
--- a/sys/fs/nfsclient/nfs_clvfsops.c
+++ b/sys/fs/nfsclient/nfs_clvfsops.c
@@ -1627,3 +1627,105 @@ nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
}
}
+/*
+ * This function prints out an option name, based on the conditional
+ * argument.
+ */
+static __inline void nfscl_printopt(struct nfsmount *nmp, int testval,
+ char *opt, char **buf, size_t *blen)
+{
+ int len;
+
+ if (testval != 0 && *blen > strlen(opt)) {
+ len = snprintf(*buf, *blen, "%s", opt);
+ if (len != strlen(opt))
+ printf("EEK!!\n");
+ *buf += len;
+ *blen -= len;
+ }
+}
+
+/*
+ * This function printf out an options integer value.
+ */
+static __inline void nfscl_printoptval(struct nfsmount *nmp, int optval,
+ char *opt, char **buf, size_t *blen)
+{
+ int len;
+
+ if (*blen > strlen(opt) + 1) {
+ /* Could result in truncated output string. */
+ len = snprintf(*buf, *blen, "%s=%d", opt, optval);
+ if (len < *blen) {
+ *buf += len;
+ *blen -= len;
+ }
+ }
+}
+
+/*
+ * Load the option flags and values into the buffer.
+ */
+void nfscl_retopts(struct nfsmount *nmp, char *buffer, size_t buflen)
+{
+ char *buf;
+ size_t blen;
+
+ buf = buffer;
+ blen = buflen;
+ nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV4) != 0, "nfsv4", &buf,
+ &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NFSV3) != 0, "nfsv3", &buf,
+ &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) == 0,
+ "nfsv2", &buf, &blen);
+ nfscl_printopt(nmp, nmp->nm_sotype == SOCK_STREAM, ",tcp", &buf, &blen);
+ nfscl_printopt(nmp, nmp->nm_sotype != SOCK_STREAM, ",udp", &buf, &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RESVPORT) != 0, ",resvport",
+ &buf, &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCONN) != 0, ",noconn",
+ &buf, &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) == 0, ",hard", &buf,
+ &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_SOFT) != 0, ",soft", &buf,
+ &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_INT) != 0, ",intr", &buf,
+ &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) == 0, ",cto", &buf,
+ &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_NOCTO) != 0, ",nocto", &buf,
+ &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
+ 0, ",lockd", &buf, &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_NOLOCKD | NFSMNT_NFSV4)) ==
+ NFSMNT_NOLOCKD, ",nolockd", &buf, &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_RDIRPLUS) != 0, ",rdirplus",
+ &buf, &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & NFSMNT_KERB) == 0, ",sec=sys",
+ &buf, &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
+ NFSMNT_PRIVACY)) == NFSMNT_KERB, ",sec=krb5", &buf, &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
+ NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_INTEGRITY), ",sec=krb5i",
+ &buf, &blen);
+ nfscl_printopt(nmp, (nmp->nm_flag & (NFSMNT_KERB | NFSMNT_INTEGRITY |
+ NFSMNT_PRIVACY)) == (NFSMNT_KERB | NFSMNT_PRIVACY), ",sec=krb5p",
+ &buf, &blen);
+ nfscl_printoptval(nmp, nmp->nm_acdirmin, ",acdirmin", &buf, &blen);
+ nfscl_printoptval(nmp, nmp->nm_acdirmax, ",acdirmax", &buf, &blen);
+ nfscl_printoptval(nmp, nmp->nm_acregmin, ",acregmin", &buf, &blen);
+ nfscl_printoptval(nmp, nmp->nm_acregmax, ",acregmax", &buf, &blen);
+ nfscl_printoptval(nmp, nmp->nm_nametimeo, ",nametimeo", &buf, &blen);
+ nfscl_printoptval(nmp, nmp->nm_negnametimeo, ",negnametimeo", &buf,
+ &blen);
+ nfscl_printoptval(nmp, nmp->nm_rsize, ",rsize", &buf, &blen);
+ nfscl_printoptval(nmp, nmp->nm_wsize, ",wsize", &buf, &blen);
+ nfscl_printoptval(nmp, nmp->nm_readdirsize, ",readdirsize", &buf,
+ &blen);
+ nfscl_printoptval(nmp, nmp->nm_readahead, ",readahead", &buf, &blen);
+ nfscl_printoptval(nmp, nmp->nm_wcommitsize, ",wcommitsize", &buf,
+ &blen);
+ nfscl_printoptval(nmp, nmp->nm_timeo, ",timeout", &buf, &blen);
+ nfscl_printoptval(nmp, nmp->nm_retry, ",retrans", &buf, &blen);
+}
+
diff --git a/sys/nfs/nfs_nfssvc.c b/sys/nfs/nfs_nfssvc.c
index 25dfee8..3f925a1 100644
--- a/sys/nfs/nfs_nfssvc.c
+++ b/sys/nfs/nfs_nfssvc.c
@@ -91,8 +91,8 @@ sys_nfssvc(struct thread *td, struct nfssvc_args *uap)
if ((uap->flag & (NFSSVC_ADDSOCK | NFSSVC_OLDNFSD | NFSSVC_NFSD)) &&
nfsd_call_nfsserver != NULL)
error = (*nfsd_call_nfsserver)(td, uap);
- else if ((uap->flag & (NFSSVC_CBADDSOCK | NFSSVC_NFSCBD)) &&
- nfsd_call_nfscl != NULL)
+ else if ((uap->flag & (NFSSVC_CBADDSOCK | NFSSVC_NFSCBD |
+ NFSSVC_DUMPMNTOPTS)) && nfsd_call_nfscl != NULL)
error = (*nfsd_call_nfscl)(td, uap);
else if ((uap->flag & (NFSSVC_IDNAME | NFSSVC_GETSTATS |
NFSSVC_GSSDADDPORT | NFSSVC_GSSDADDFIRST | NFSSVC_GSSDDELETEALL |
diff --git a/sys/nfs/nfssvc.h b/sys/nfs/nfssvc.h
index 6e636d5..65b1681 100644
--- a/sys/nfs/nfssvc.h
+++ b/sys/nfs/nfssvc.h
@@ -68,5 +68,13 @@
#define NFSSVC_ZEROSRVSTATS 0x02000000 /* modifier for GETSTATS */
#define NFSSVC_SUSPENDNFSD 0x04000000
#define NFSSVC_RESUMENFSD 0x08000000
+#define NFSSVC_DUMPMNTOPTS 0x10000000
+
+/* Argument structure for NFSSVC_DUMPMNTOPTS. */
+struct nfscl_dumpmntopts {
+ char *ndmnt_fname; /* File Name */
+ size_t ndmnt_blen; /* Size of buffer */
+ void *ndmnt_buf; /* and the buffer */
+};
#endif /* _NFS_NFSSVC_H */
OpenPOWER on IntegriCloud