@@ -60,6 +60,7 @@
# vers4.1=y
# vers4.2=y
# rdma=n
+# chroot=/export
#
[statd]
# debug=0
@@ -136,7 +136,8 @@ Recognized values:
.BR vers4.0 ,
.BR vers4.1 ,
.BR vers4.2 ,
-.BR rdma .
+.BR rdma ,
+.BR chroot .
Version and protocol values are Boolean values as described above,
and are also used by
@@ -33,11 +33,14 @@
#include "fsloc.h"
#include "pseudoflavors.h"
#include "xcommon.h"
+#include "conffile.h"
#ifdef USE_BLKID
#include "blkid/blkid.h"
#endif
+static struct xthread_workqueue *cache_workqueue;
+
/*
* Invoked by RPC service loop
*/
@@ -55,6 +58,32 @@ enum nfsd_fsid {
FSID_UUID16_INUM,
};
+static ssize_t cache_write(int fd, const char *buf, size_t len)
+{
+ if (cache_workqueue)
+ return xthread_write(cache_workqueue, fd, buf, len);
+ return write(fd, buf, len);
+}
+
+static void
+cache_setup_workqueue(void)
+{
+ const char *chroot;
+
+ chroot = conf_get_str("nfsd", "chroot");
+ if (!chroot || *chroot == '\0')
+ return;
+ /* Strip leading '/' */
+ while (chroot[0] == '/' && chroot[1] == '/')
+ chroot++;
+ if (chroot[0] == '/' && chroot[1] == '\0')
+ return;
+ cache_workqueue = xthread_workqueue_alloc();
+ if (!cache_workqueue)
+ return;
+ xthread_workqueue_chroot(cache_workqueue, chroot);
+}
+
/*
* Support routines for text-based upcalls.
* Fields are separated by spaces.
@@ -829,7 +858,7 @@ static void nfsd_fh(int f)
if (found)
qword_add(&bp, &blen, found_path);
qword_addeol(&bp, &blen);
- if (blen <= 0 || write(f, buf, bp - buf) != bp - buf)
+ if (blen <= 0 || cache_write(f, buf, bp - buf) != bp - buf)
xlog(L_ERROR, "nfsd_fh: error writing reply");
out:
if (found_path)
@@ -921,7 +950,7 @@ static int dump_to_cache(int f, char *buf, int buflen, char *domain,
qword_adduint(&bp, &blen, now + ttl);
qword_addeol(&bp, &blen);
if (blen <= 0) return -1;
- if (write(f, buf, bp - buf) != bp - buf) return -1;
+ if (cache_write(f, buf, bp - buf) != bp - buf) return -1;
return 0;
}
@@ -1381,6 +1410,8 @@ extern int manage_gids;
void cache_open(void)
{
int i;
+
+ cache_setup_workqueue();
for (i=0; cachelist[i].cache_name; i++ ) {
char path[100];
if (!manage_gids && cachelist[i].cache_handle == auth_unix_gid)
@@ -1508,7 +1539,7 @@ int cache_export(nfs_export *exp, char *path)
qword_adduint(&bp, &blen, time(0) + exp->m_export.e_ttl);
qword_add(&bp, &blen, exp->m_client->m_hostname);
qword_addeol(&bp, &blen);
- if (blen <= 0 || write(f, buf, bp - buf) != bp - buf) blen = -1;
+ if (blen <= 0 || cache_write(f, buf, bp - buf) != bp - buf) blen = -1;
close(f);
if (blen < 0) return -1;
@@ -1546,7 +1577,7 @@ cache_get_filehandle(nfs_export *exp, int len, char *p)
qword_add(&bp, &blen, p);
qword_addint(&bp, &blen, len);
qword_addeol(&bp, &blen);
- if (blen <= 0 || write(f, buf, bp - buf) != bp - buf) {
+ if (blen <= 0 || cache_write(f, buf, bp - buf) != bp - buf) {
close(f);
return NULL;
}
@@ -167,6 +167,10 @@ Setting these to "off" or similar will disable the selected minor
versions. Setting to "on" will enable them. The default values
are determined by the kernel, and usually minor versions default to
being enabled once the implementation is sufficiently complete.
+.B chroot
+Setting this to a valid path causes the nfs server to act as if the
+supplied path is being prefixed to all the exported entries.
+
.SH NOTES
If the program is built with TI-RPC support, it will enable any protocol and
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> --- nfs.conf | 1 + systemd/nfs.conf.man | 3 ++- utils/mountd/cache.c | 39 +++++++++++++++++++++++++++++++++++---- utils/nfsd/nfsd.man | 4 ++++ 4 files changed, 42 insertions(+), 5 deletions(-)