Add a helper to resolve symlinked nfsd paths when the user has set the "[exports] rootdir" nfs.conf option. Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> --- support/include/nfsd_path.h | 2 ++ support/misc/nfsd_path.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/support/include/nfsd_path.h b/support/include/nfsd_path.h index f4a7f0a4337f..ca2570a92e68 100644 --- a/support/include/nfsd_path.h +++ b/support/include/nfsd_path.h @@ -13,6 +13,8 @@ char * nfsd_path_prepend_dir(const char *dir, const char *pathname); int nfsd_path_stat(const char *pathname, struct stat *statbuf); int nfsd_path_lstat(const char *pathname, struct stat *statbuf); +char * nfsd_realpath(const char *path, char *resolved_path); + ssize_t nfsd_path_read(int fd, char *buf, size_t len); ssize_t nfsd_path_write(int fd, const char *buf, size_t len); diff --git a/support/misc/nfsd_path.c b/support/misc/nfsd_path.c index 8ddafd65ab76..2f41a793c534 100644 --- a/support/misc/nfsd_path.c +++ b/support/misc/nfsd_path.c @@ -1,6 +1,7 @@ #include <errno.h> #include <sys/types.h> #include <sys/stat.h> +#include <stdlib.h> #include <unistd.h> #include "config.h" @@ -169,6 +170,40 @@ nfsd_path_lstat(const char *pathname, struct stat *statbuf) return nfsd_run_stat(nfsd_wq, nfsd_lstatfunc, pathname, statbuf); } +struct nfsd_realpath_data { + const char *pathname; + char *resolved; + int err; +}; + +static void +nfsd_realpathfunc(void *data) +{ + struct nfsd_realpath_data *d = data; + + d->resolved = realpath(d->pathname, d->resolved); + if (!d->resolved) + d->err = errno; +} + +char * +nfsd_realpath(const char *path, char *resolved_path) +{ + struct nfsd_realpath_data data = { + path, + resolved_path, + 0 + }; + + if (!nfsd_wq) + return realpath(path, resolved_path); + + xthread_work_run_sync(nfsd_wq, nfsd_realpathfunc, &data); + if (!data.resolved) + errno = data.err; + return data.resolved; +} + struct nfsd_read_data { int fd; char *buf; -- 2.21.0