Re: [PATCH v3 04/11] Add utilities for resolving nfsd paths and stat()ing them

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, May 28, 2019 at 04:31:15PM -0400, Trond Myklebust wrote:
> +char *
> +nfsd_path_strip_root(char *pathname)
> +{
> +	const char *dir = nfsd_path_nfsd_rootdir();
> +	char *ret;
> +
> +	ret = strstr(pathname, dir);
> +	if (!ret || ret != pathname)
> +		return pathname;

Shouldn't we return NULL or an error or something here?  It seems a
little strange not to care if the path began with root or not.  I guess
I need to look at the caller....

--b.

> +	return pathname + strlen(dir);
> +}
> +
> +char *
> +nfsd_path_prepend_dir(const char *dir, const char *pathname)
> +{
> +	size_t len, dirlen;
> +	char *ret;
> +
> +	dirlen = strlen(dir);
> +	while (dirlen > 0 && dir[dirlen - 1] == '/')
> +		dirlen--;
> +	if (!dirlen)
> +		return NULL;
> +	len = dirlen + strlen(pathname) + 1;
> +	ret = xmalloc(len + 1);
> +	snprintf(ret, len, "%.*s/%s", (int)dirlen, dir, pathname);
> +	return ret;
> +}
> +
> +static void
> +nfsd_setup_workqueue(void)
> +{
> +	const char *rootdir = nfsd_path_nfsd_rootdir();
> +
> +	if (!rootdir)
> +		return;
> +	nfsd_wq = xthread_workqueue_alloc();
> +	if (!nfsd_wq)
> +		return;
> +	xthread_workqueue_chroot(nfsd_wq, rootdir);
> +}
> +
> +void
> +nfsd_path_init(void)
> +{
> +	nfsd_setup_workqueue();
> +}
> +
> +struct nfsd_stat_data {
> +	const char *pathname;
> +	struct stat *statbuf;
> +	int ret;
> +	int err;
> +};
> +
> +static void
> +nfsd_statfunc(void *data)
> +{
> +	struct nfsd_stat_data *d = data;
> +
> +	d->ret = xstat(d->pathname, d->statbuf);
> +	if (d->ret < 0)
> +		d->err = errno;
> +}
> +
> +static void
> +nfsd_lstatfunc(void *data)
> +{
> +	struct nfsd_stat_data *d = data;
> +
> +	d->ret = xlstat(d->pathname, d->statbuf);
> +	if (d->ret < 0)
> +		d->err = errno;
> +}
> +
> +static int
> +nfsd_run_stat(struct xthread_workqueue *wq,
> +		void (*func)(void *),
> +		const char *pathname,
> +		struct stat *statbuf)
> +{
> +	struct nfsd_stat_data data = {
> +		pathname,
> +		statbuf,
> +		0,
> +		0
> +	};
> +	xthread_work_run_sync(wq, func, &data);
> +	if (data.ret < 0)
> +		errno = data.err;
> +	return data.ret;
> +}
> +
> +int
> +nfsd_path_stat(const char *pathname, struct stat *statbuf)
> +{
> +	if (!nfsd_wq)
> +		return xstat(pathname, statbuf);
> +	return nfsd_run_stat(nfsd_wq, nfsd_statfunc, pathname, statbuf);
> +}
> +
> +int
> +nfsd_path_lstat(const char *pathname, struct stat *statbuf)
> +{
> +	if (!nfsd_wq)
> +		return xlstat(pathname, statbuf);
> +	return nfsd_run_stat(nfsd_wq, nfsd_lstatfunc, pathname, statbuf);
> +}
> diff --git a/support/misc/xstat.c b/support/misc/xstat.c
> new file mode 100644
> index 000000000000..d092f73dfd65
> --- /dev/null
> +++ b/support/misc/xstat.c
> @@ -0,0 +1,33 @@
> +#include <sys/types.h>
> +#include <fcntl.h>
> +#include <sys/stat.h>
> +#include <unistd.h>
> +
> +#include "config.h"
> +#include "xstat.h"
> +
> +#ifdef HAVE_FSTATAT
> +
> +int xlstat(const char *pathname, struct stat *statbuf)
> +{
> +	return fstatat(AT_FDCWD, pathname, statbuf, AT_NO_AUTOMOUNT |
> +			AT_SYMLINK_NOFOLLOW);
> +}
> +
> +int xstat(const char *pathname, struct stat *statbuf)
> +{
> +	return fstatat(AT_FDCWD, pathname, statbuf, AT_NO_AUTOMOUNT);
> +}
> +
> +#else
> +
> +int xlstat(const char *pathname, struct stat *statbuf)
> +{
> +	return lstat(pathname, statbuf);
> +}
> +
> +int xstat(const char *pathname, struct stat *statbuf)
> +{
> +	return stat(pathname, statbuf);
> +}
> +#endif
> -- 
> 2.21.0



[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux