[PATCH] More VFS conversion to struct smb_filename *.

Jeremy Allison jra at samba.org
Fri Jun 2 02:32:26 UTC 2017


One small cleanup (remove now unused smb_vfs_call_llistxattr),
plus four more function conversions:

SMB_VFS_MKNOD
SMB_VFS_CHFLAGS
SMB_VFS_DISK_FREE
SMB_VFS_GET_QUOTA

Passes local make test. Please review
and push if happy !

Cheers,

	Jeremy.
-------------- next part --------------
>From 846ebd68a94f138f74352be627dd25d70c46e41f Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 1 Jun 2017 10:51:45 -0700
Subject: [PATCH 1/5] s3: VFS: Remove old traces of smb_vfs_call_llistxattr().

This call doesn't exist anymore.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/include/vfs.h      |  2 --
 source3/modules/vfs_ceph.c | 15 ---------------
 2 files changed, 17 deletions(-)

diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 30002bd..f7cfd33 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -1381,8 +1381,6 @@ ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
 				const struct smb_filename *smb_fname,
 				char *list,
 				size_t size);
-ssize_t smb_vfs_call_llistxattr(struct vfs_handle_struct *handle,
-				const char *path, char *list, size_t size);
 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
 				struct files_struct *fsp, char *list,
 				size_t size);
diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index 571d144..428aa97 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -1270,21 +1270,6 @@ static ssize_t cephwrap_listxattr(struct vfs_handle_struct *handle,
 	}
 }
 
-#if 0
-static ssize_t cephwrap_llistxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
-{
-	int ret;
-	DBG_DEBUG("[CEPH] llistxattr(%p, %s, %p, %llu)\n", handle, path, list, llu(size));
-	ret = ceph_llistxattr(handle->data, path, list, size);
-	DBG_DEBUG("[CEPH] listxattr(...) = %d\n", ret);
-	if (ret < 0) {
-		WRAP_RETURN(ret);
-	} else {
-		return (ssize_t)ret;
-	}
-}
-#endif
-
 static ssize_t cephwrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
 {
 	int ret;
-- 
2.7.4


>From 816475b3d780bc8f02aab4d787761d990a93550b Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 19 May 2017 15:01:52 -0700
Subject: [PATCH 2/5] s3: VFS: Change SMB_VFS_MKNOD to use const struct
 smb_filename * instead of const char *.

We need to migrate all pathname based VFS calls to use a struct
to finish modernising the VFS with extra timestamp and flags parameters.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 examples/VFS/skel_opaque.c          |  6 ++++--
 examples/VFS/skel_transparent.c     |  8 +++++---
 source3/include/vfs.h               | 12 +++++++++---
 source3/include/vfs_macros.h        |  8 ++++----
 source3/modules/vfs_cap.c           | 31 ++++++++++++++++++++++++++---
 source3/modules/vfs_ceph.c          |  9 ++++++---
 source3/modules/vfs_default.c       |  7 +++++--
 source3/modules/vfs_full_audit.c    |  9 ++++++---
 source3/modules/vfs_glusterfs.c     |  8 +++++---
 source3/modules/vfs_media_harmony.c | 21 +++++++++-----------
 source3/modules/vfs_shadow_copy2.c  | 21 ++++++++++++++------
 source3/modules/vfs_snapper.c       | 39 ++++++++++++++++++++++++-------------
 source3/modules/vfs_syncops.c       |  7 +++++--
 source3/modules/vfs_time_audit.c    |  7 ++++---
 source3/modules/vfs_unityed_media.c | 16 +++++++--------
 source3/smbd/trans2.c               |  2 +-
 source3/smbd/vfs.c                  |  8 +++++---
 source3/torture/cmd_vfs.c           |  9 ++++++++-
 18 files changed, 153 insertions(+), 75 deletions(-)

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index c5d4359..ae0d4dc 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -492,8 +492,10 @@ static int skel_link(vfs_handle_struct *handle, const char *oldpath,
 	return -1;
 }
 
-static int skel_mknod(vfs_handle_struct *handle, const char *path, mode_t mode,
-		      SMB_DEV_T dev)
+static int skel_mknod(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			mode_t mode,
+			SMB_DEV_T dev)
 {
 	errno = ENOSYS;
 	return -1;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index 91ea5c6..30f2b4e 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -583,10 +583,12 @@ static int skel_link(vfs_handle_struct *handle, const char *oldpath,
 	return SMB_VFS_NEXT_LINK(handle, oldpath, newpath);
 }
 
-static int skel_mknod(vfs_handle_struct *handle, const char *path, mode_t mode,
-		      SMB_DEV_T dev)
+static int skel_mknod(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			mode_t mode,
+			SMB_DEV_T dev)
 {
-	return SMB_VFS_NEXT_MKNOD(handle, path, mode, dev);
+	return SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev);
 }
 
 static char *skel_realpath(vfs_handle_struct *handle, const char *path)
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index f7cfd33..ec7f0d0 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -213,6 +213,7 @@
 		to const struct smb_filename * */
 /* Version 37 - Change getxattr from const char *
 		to const struct smb_filename * */
+/* Version 37 - Change mknod from const char * to const struct smb_filename * */
 
 #define SMB_VFS_INTERFACE_VERSION 37
 
@@ -728,7 +729,10 @@ struct vfs_fn_pointers {
 	int (*symlink_fn)(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath);
 	int (*readlink_fn)(struct vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz);
 	int (*link_fn)(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath);
-	int (*mknod_fn)(struct vfs_handle_struct *handle, const char *path, mode_t mode, SMB_DEV_T dev);
+	int (*mknod_fn)(struct vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				mode_t mode,
+				SMB_DEV_T dev);
 	char *(*realpath_fn)(struct vfs_handle_struct *handle, const char *path);
 	int (*chflags_fn)(struct vfs_handle_struct *handle, const char *path, unsigned int flags);
 	struct file_id (*file_id_create_fn)(struct vfs_handle_struct *handle,
@@ -1222,8 +1226,10 @@ int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
 			  const char *path, char *buf, size_t bufsiz);
 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
 		      const char *newpath);
-int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
-		       mode_t mode, SMB_DEV_T dev);
+int smb_vfs_call_mknod(struct vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			mode_t mode,
+			SMB_DEV_T dev);
 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path);
 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
 			 unsigned int flags);
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 0ebd469..30271a6 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -326,10 +326,10 @@
 #define SMB_VFS_NEXT_LINK(handle, oldpath, newpath) \
 	smb_vfs_call_link((handle)->next, (oldpath), (newpath))
 
-#define SMB_VFS_MKNOD(conn, path, mode, dev) \
-	smb_vfs_call_mknod((conn)->vfs_handles, (path), (mode), (dev))
-#define SMB_VFS_NEXT_MKNOD(handle, path, mode, dev) \
-	smb_vfs_call_mknod((handle)->next, (path), (mode), (dev))
+#define SMB_VFS_MKNOD(conn, smb_fname, mode, dev) \
+	smb_vfs_call_mknod((conn)->vfs_handles, (smb_fname), (mode), (dev))
+#define SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev) \
+	smb_vfs_call_mknod((handle)->next, (smb_fname), (mode), (dev))
 
 #define SMB_VFS_REALPATH(conn, path) \
 	smb_vfs_call_realpath((conn)->vfs_handles, (path))
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index c124592..eba5896 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -488,15 +488,40 @@ static int cap_link(vfs_handle_struct *handle, const char *oldpath, const char *
 	return SMB_VFS_NEXT_LINK(handle, capold, capnew);
 }
 
-static int cap_mknod(vfs_handle_struct *handle, const char *path, mode_t mode, SMB_DEV_T dev)
+static int cap_mknod(vfs_handle_struct *handle,
+		const struct smb_filename *smb_fname,
+		mode_t mode,
+		SMB_DEV_T dev)
 {
-	char *cappath = capencode(talloc_tos(), path);
+	struct smb_filename *cap_smb_fname = NULL;
+	char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+	int ret;
+	int saved_errno = 0;
 
 	if (!cappath) {
 		errno = ENOMEM;
 		return -1;
 	}
-	return SMB_VFS_NEXT_MKNOD(handle, cappath, mode, dev);
+	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+					cappath,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (cap_smb_fname == NULL) {
+		TALLOC_FREE(cappath);
+		errno = ENOMEM;
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_MKNOD(handle, cap_smb_fname, mode, dev);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(cappath);
+	TALLOC_FREE(cap_smb_fname);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
+	return ret;
 }
 
 static char *cap_realpath(vfs_handle_struct *handle, const char *path)
diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index 428aa97..d88ceac 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -1145,11 +1145,14 @@ static int cephwrap_link(struct vfs_handle_struct *handle,  const char *oldpath,
 	WRAP_RETURN(result);
 }
 
-static int cephwrap_mknod(struct vfs_handle_struct *handle,  const char *pathname, mode_t mode, SMB_DEV_T dev)
+static int cephwrap_mknod(struct vfs_handle_struct *handle,
+		const struct smb_filename *smb_fname,
+		mode_t mode,
+		SMB_DEV_T dev)
 {
 	int result = -1;
-	DBG_DEBUG("[CEPH] mknod(%p, %s)\n", handle, pathname);
-	result = ceph_mknod(handle->data, pathname, mode, dev);
+	DBG_DEBUG("[CEPH] mknod(%p, %s)\n", handle, smb_fname->base_name);
+	result = ceph_mknod(handle->data, smb_fname->base_name, mode, dev);
 	DBG_DEBUG("[CEPH] mknod(...) = %d\n", result);
 	WRAP_RETURN(result);
 }
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 5a4be7e..6de5d64 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -2442,12 +2442,15 @@ static int vfswrap_link(vfs_handle_struct *handle, const char *oldpath, const ch
 	return result;
 }
 
-static int vfswrap_mknod(vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev)
+static int vfswrap_mknod(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			mode_t mode,
+			SMB_DEV_T dev)
 {
 	int result;
 
 	START_PROFILE(syscall_mknod);
-	result = sys_mknod(pathname, mode, dev);
+	result = sys_mknod(smb_fname->base_name, mode, dev);
 	END_PROFILE(syscall_mknod);
 	return result;
 }
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index fd8c8c1..af165dd 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -1659,13 +1659,16 @@ static int smb_full_audit_link(vfs_handle_struct *handle,
 }
 
 static int smb_full_audit_mknod(vfs_handle_struct *handle,
-		       const char *pathname, mode_t mode, SMB_DEV_T dev)
+			const struct smb_filename *smb_fname,
+			mode_t mode,
+			SMB_DEV_T dev)
 {
 	int result;
 
-	result = SMB_VFS_NEXT_MKNOD(handle, pathname, mode, dev);
+	result = SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev);
 
-	do_log(SMB_VFS_OP_MKNOD, (result >= 0), handle, "%s", pathname);
+	do_log(SMB_VFS_OP_MKNOD, (result >= 0), handle, "%s",
+		smb_fname->base_name);
 
 	return result;
 }
diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index c648973..7c72777 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -1248,10 +1248,12 @@ static int vfs_gluster_link(struct vfs_handle_struct *handle,
 	return glfs_link(handle->data, oldpath, newpath);
 }
 
-static int vfs_gluster_mknod(struct vfs_handle_struct *handle, const char *path,
-			     mode_t mode, SMB_DEV_T dev)
+static int vfs_gluster_mknod(struct vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				mode_t mode,
+				SMB_DEV_T dev)
 {
-	return glfs_mknod(handle->data, path, mode, dev);
+	return glfs_mknod(handle->data, smb_fname->base_name, mode, dev);
 }
 
 static int vfs_gluster_chflags(struct vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c
index 422ca3d..99a5e9b 100644
--- a/source3/modules/vfs_media_harmony.c
+++ b/source3/modules/vfs_media_harmony.c
@@ -1853,34 +1853,31 @@ out:
  * Failure: set errno, return -1
  */
 static int mh_mknod(vfs_handle_struct *handle,
-		const char *pathname,
+		const struct smb_filename *smb_fname,
 		mode_t mode,
 		SMB_DEV_T dev)
 {
 	int status;
-	char *clientPath;
+	struct smb_filename *clientFname = NULL;
 	TALLOC_CTX *ctx;
 
 	DEBUG(MH_INFO_DEBUG, ("Entering mh_mknod\n"));
-	if (!is_in_media_files(pathname))
-	{
-		status = SMB_VFS_NEXT_MKNOD(handle, pathname, mode, dev);
+	if (!is_in_media_files(smb_fname->base_name)) {
+		status = SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev);
 		goto out;
 	}
 
-	clientPath = NULL;
 	ctx = talloc_tos();
 
-	if ((status = alloc_get_client_path(handle, ctx,
-				pathname,
-				&clientPath)))
-	{
+	if ((status = alloc_get_client_smb_fname(handle, ctx,
+				smb_fname,
+				&clientFname))) {
 		goto err;
 	}
 
-	status = SMB_VFS_NEXT_MKNOD(handle, clientPath, mode, dev);
+	status = SMB_VFS_NEXT_MKNOD(handle, clientFname, mode, dev);
 err:
-	TALLOC_FREE(clientPath);
+	TALLOC_FREE(clientFname);
 out:
 	return status;
 }
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index dba164e..1fb492b 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -1656,24 +1656,33 @@ static int shadow_copy2_readlink(vfs_handle_struct *handle,
 }
 
 static int shadow_copy2_mknod(vfs_handle_struct *handle,
-			      const char *fname, mode_t mode, SMB_DEV_T dev)
+				const struct smb_filename *smb_fname,
+				mode_t mode,
+				SMB_DEV_T dev)
 {
 	time_t timestamp = 0;
 	char *stripped = NULL;
 	int saved_errno = 0;
 	int ret;
-	char *conv;
+	struct smb_filename *conv = NULL;
 
-	if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
+	if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
+					 smb_fname->base_name,
 					 &timestamp, &stripped)) {
 		return -1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_MKNOD(handle, fname, mode, dev);
+		return SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev);
 	}
-	conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
-	TALLOC_FREE(stripped);
+	conv = cp_smb_filename(talloc_tos(), smb_fname);
 	if (conv == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+	conv->base_name = shadow_copy2_convert(
+		conv, handle, stripped, timestamp);
+	TALLOC_FREE(stripped);
+	if (conv->base_name == NULL) {
 		return -1;
 	}
 	ret = SMB_VFS_NEXT_MKNOD(handle, conv, mode, dev);
diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c
index 2274a56..43ea54f 100644
--- a/source3/modules/vfs_snapper.c
+++ b/source3/modules/vfs_snapper.c
@@ -2417,29 +2417,42 @@ static int snapper_gmt_readlink(vfs_handle_struct *handle,
 }
 
 static int snapper_gmt_mknod(vfs_handle_struct *handle,
-			     const char *fname, mode_t mode, SMB_DEV_T dev)
+			const struct smb_filename *smb_fname,
+			mode_t mode,
+			SMB_DEV_T dev)
 {
-	time_t timestamp;
-	char *stripped;
-	int ret, saved_errno;
-	char *conv;
+	time_t timestamp = (time_t)0;
+	char *stripped = NULL;
+	int ret, saved_errno = 0;
+	struct smb_filename *conv_smb_fname = NULL;
 
-	if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, fname,
+	if (!snapper_gmt_strip_snapshot(talloc_tos(), handle,
+					smb_fname->base_name,
 					&timestamp, &stripped)) {
 		return -1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_MKNOD(handle, fname, mode, dev);
+		return SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev);
 	}
-	conv = snapper_gmt_convert(talloc_tos(), handle, stripped, timestamp);
+	conv_smb_fname = cp_smb_filename(talloc_tos(), smb_fname);
+	if (conv_smb_fname == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+	conv_smb_fname->base_name = snapper_gmt_convert(conv, handle,
+					      stripped, timestamp);
 	TALLOC_FREE(stripped);
-	if (conv == NULL) {
+	if (conv_smb_fname->base_name == NULL) {
 		return -1;
 	}
-	ret = SMB_VFS_NEXT_MKNOD(handle, conv, mode, dev);
-	saved_errno = errno;
-	TALLOC_FREE(conv);
-	errno = saved_errno;
+	ret = SMB_VFS_NEXT_MKNOD(handle, conv_smb_fname, mode, dev);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(conv_smb_fname);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return ret;
 }
 
diff --git a/source3/modules/vfs_syncops.c b/source3/modules/vfs_syncops.c
index 381b80b..8c20af3 100644
--- a/source3/modules/vfs_syncops.c
+++ b/source3/modules/vfs_syncops.c
@@ -212,9 +212,12 @@ static int syncops_unlink(vfs_handle_struct *handle,
 }
 
 static int syncops_mknod(vfs_handle_struct *handle,
-			 const char *fname, mode_t mode, SMB_DEV_T dev)
+			const struct smb_filename *smb_fname,
+			mode_t mode,
+			SMB_DEV_T dev)
 {
-        SYNCOPS_NEXT(MKNOD, fname, (handle, fname, mode, dev));
+        SYNCOPS_NEXT_SMB_FNAME(MKNOD,
+			smb_fname, (handle, smb_fname, mode, dev));
 }
 
 static int syncops_mkdir(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index 761711b..3bbe2d9 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -1472,7 +1472,8 @@ static int smb_time_audit_link(vfs_handle_struct *handle,
 }
 
 static int smb_time_audit_mknod(vfs_handle_struct *handle,
-				const char *pathname, mode_t mode,
+				const struct smb_filename *smb_fname,
+				mode_t mode,
 				SMB_DEV_T dev)
 {
 	int result;
@@ -1480,12 +1481,12 @@ static int smb_time_audit_mknod(vfs_handle_struct *handle,
 	double timediff;
 
 	clock_gettime_mono(&ts1);
-	result = SMB_VFS_NEXT_MKNOD(handle, pathname, mode, dev);
+	result = SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev);
 	clock_gettime_mono(&ts2);
 	timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
 	if (timediff > audit_timeout) {
-		smb_time_audit_log_fname("mknod", timediff, pathname);
+		smb_time_audit_log_smb_fname("mknod", timediff, smb_fname);
 	}
 
 	return result;
diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c
index 7c8bee0..cda6ad6 100644
--- a/source3/modules/vfs_unityed_media.c
+++ b/source3/modules/vfs_unityed_media.c
@@ -1412,28 +1412,28 @@ err:
 }
 
 static int um_mknod(vfs_handle_struct *handle,
-		    const char *pathname,
+		    const struct smb_filename *smb_fname,
 		    mode_t mode,
 		    SMB_DEV_T dev)
 {
 	int status;
-	char *client_path = NULL;
+	struct smb_filename *client_fname = NULL;
 
 	DEBUG(10, ("Entering um_mknod\n"));
-	if (!is_in_media_files(pathname)) {
-		return SMB_VFS_NEXT_MKNOD(handle, pathname, mode, dev);
+	if (!is_in_media_files(smb_fname->base_name)) {
+		return SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev);
 	}
 
-	status = alloc_get_client_path(handle, talloc_tos(),
-				       pathname, &client_path);
+	status = alloc_get_client_smb_fname(handle, talloc_tos(),
+					    smb_fname, &client_fname);
 	if (status != 0) {
 		goto err;
 	}
 
-	status = SMB_VFS_NEXT_MKNOD(handle, client_path, mode, dev);
+	status = SMB_VFS_NEXT_MKNOD(handle, client_fname, mode, dev);
 
 err:
-	TALLOC_FREE(client_path);
+	TALLOC_FREE(client_fname);
 	return status;
 }
 
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index a35297c..758644b 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -7580,7 +7580,7 @@ static NTSTATUS smb_unix_mknod(connection_struct *conn,
 		  (unsigned int)unixmode, smb_fname_str_dbg(smb_fname)));
 
 	/* Ok - do the mknod. */
-	if (SMB_VFS_MKNOD(conn, smb_fname->base_name, unixmode, dev) != 0) {
+	if (SMB_VFS_MKNOD(conn, smb_fname, unixmode, dev) != 0) {
 		return map_nt_error_from_unix(errno);
 	}
 
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 9873f7f..b129bb1 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -2167,11 +2167,13 @@ int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
 	return handle->fns->link_fn(handle, oldpath, newpath);
 }
 
-int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
-		       mode_t mode, SMB_DEV_T dev)
+int smb_vfs_call_mknod(struct vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			mode_t mode,
+			SMB_DEV_T dev)
 {
 	VFS_FIND(mknod);
-	return handle->fns->mknod_fn(handle, path, mode, dev);
+	return handle->fns->mknod_fn(handle, smb_fname, mode, dev);
 }
 
 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
index 0e04a88..68def35 100644
--- a/source3/torture/cmd_vfs.c
+++ b/source3/torture/cmd_vfs.c
@@ -1260,6 +1260,7 @@ static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
 	mode_t mode;
 	unsigned int dev_val;
 	SMB_DEV_T dev;
+	struct smb_filename *smb_fname = NULL;
 
 	if (argc != 4) {
 		printf("Usage: mknod <path> <mode> <dev>\n");
@@ -1279,7 +1280,13 @@ static NTSTATUS cmd_mknod(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
 	}
 	dev = (SMB_DEV_T)dev_val;
 
-	if (SMB_VFS_MKNOD(vfs->conn, argv[1], mode, dev) == -1) {
+	smb_fname = synthetic_smb_fname_split(mem_ctx,
+					argv[1],
+					lp_posix_pathnames());
+	if (smb_fname == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	if (SMB_VFS_MKNOD(vfs->conn, smb_fname, mode, dev) == -1) {
 		printf("mknod: error=%d (%s)\n", errno, strerror(errno));
 		return NT_STATUS_UNSUCCESSFUL;
 	}
-- 
2.7.4


>From cc4bcf73c9e698bad2e226839ff5defba8afc5d2 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 19 May 2017 16:15:55 -0700
Subject: [PATCH 3/5] s3: VFS: Change SMB_VFS_CHFLAGS to use const struct
 smb_filename * instead of const char *.

We need to migrate all pathname based VFS calls to use a struct
to finish modernising the VFS with extra timestamp and flags parameters.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 examples/VFS/skel_opaque.c          |  3 ++-
 examples/VFS/skel_transparent.c     |  5 +++--
 source3/include/vfs.h               | 11 +++++++---
 source3/include/vfs_macros.h        |  8 ++++----
 source3/modules/vfs_catia.c         | 27 ++++++++++++++++++------
 source3/modules/vfs_ceph.c          |  5 +++--
 source3/modules/vfs_default.c       |  7 ++++---
 source3/modules/vfs_full_audit.c    |  8 +++++---
 source3/modules/vfs_glusterfs.c     |  3 ++-
 source3/modules/vfs_media_harmony.c | 21 ++++++++-----------
 source3/modules/vfs_shadow_copy2.c  | 25 +++++++++++++++++-----
 source3/modules/vfs_snapper.c       | 41 ++++++++++++++++++++++++++-----------
 source3/modules/vfs_time_audit.c    |  7 ++++---
 source3/modules/vfs_unityed_media.c | 22 ++++++++++----------
 source3/smbd/trans2.c               |  2 +-
 source3/smbd/vfs.c                  |  7 ++++---
 16 files changed, 130 insertions(+), 72 deletions(-)

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index ae0d4dc..aeb1ff3 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -507,7 +507,8 @@ static char *skel_realpath(vfs_handle_struct *handle, const char *path)
 	return NULL;
 }
 
-static int skel_chflags(vfs_handle_struct *handle, const char *path,
+static int skel_chflags(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
 			uint flags)
 {
 	errno = ENOSYS;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index 30f2b4e..f3adae3 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -596,10 +596,11 @@ static char *skel_realpath(vfs_handle_struct *handle, const char *path)
 	return SMB_VFS_NEXT_REALPATH(handle, path);
 }
 
-static int skel_chflags(vfs_handle_struct *handle, const char *path,
+static int skel_chflags(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
 			uint flags)
 {
-	return SMB_VFS_NEXT_CHFLAGS(handle, path, flags);
+	return SMB_VFS_NEXT_CHFLAGS(handle, smb_fname, flags);
 }
 
 static struct file_id skel_file_id_create(vfs_handle_struct *handle,
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index ec7f0d0..93ec6e8 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -214,6 +214,8 @@
 /* Version 37 - Change getxattr from const char *
 		to const struct smb_filename * */
 /* Version 37 - Change mknod from const char * to const struct smb_filename * */
+/* Version 37 - Change chflags from const char *
+		to const struct smb_filename * */
 
 #define SMB_VFS_INTERFACE_VERSION 37
 
@@ -734,7 +736,9 @@ struct vfs_fn_pointers {
 				mode_t mode,
 				SMB_DEV_T dev);
 	char *(*realpath_fn)(struct vfs_handle_struct *handle, const char *path);
-	int (*chflags_fn)(struct vfs_handle_struct *handle, const char *path, unsigned int flags);
+	int (*chflags_fn)(struct vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				unsigned int flags);
 	struct file_id (*file_id_create_fn)(struct vfs_handle_struct *handle,
 					    const SMB_STRUCT_STAT *sbuf);
 	struct tevent_req *(*copy_chunk_send_fn)(struct vfs_handle_struct *handle,
@@ -1231,8 +1235,9 @@ int smb_vfs_call_mknod(struct vfs_handle_struct *handle,
 			mode_t mode,
 			SMB_DEV_T dev);
 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path);
-int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
-			 unsigned int flags);
+int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			unsigned int flags);
 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
 					   const SMB_STRUCT_STAT *sbuf);
 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 30271a6..701dc53 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -336,10 +336,10 @@
 #define SMB_VFS_NEXT_REALPATH(handle, path) \
 	smb_vfs_call_realpath((handle)->next, (path))
 
-#define SMB_VFS_CHFLAGS(conn, path, flags) \
-	smb_vfs_call_chflags((conn)->vfs_handles, (path), (flags))
-#define SMB_VFS_NEXT_CHFLAGS(handle, path, flags) \
-	smb_vfs_call_chflags((handle)->next, (path), (flags))
+#define SMB_VFS_CHFLAGS(conn, smb_fname, flags) \
+	smb_vfs_call_chflags((conn)->vfs_handles, (smb_fname), (flags))
+#define SMB_VFS_NEXT_CHFLAGS(handle, smb_fname, flags) \
+	smb_vfs_call_chflags((handle)->next, (smb_fname), (flags))
 
 #define SMB_VFS_FILE_ID_CREATE(conn, sbuf) \
 	smb_vfs_call_file_id_create((conn)->vfs_handles, (sbuf))
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 2592367..ed16e43 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -1062,21 +1062,36 @@ catia_realpath(vfs_handle_struct *handle, const char *path)
 }
 
 static int catia_chflags(struct vfs_handle_struct *handle,
-			 const char *path, unsigned int flags)
+			const struct smb_filename *smb_fname,
+			unsigned int flags)
 {
-	char *mapped_name = NULL;
+	char *name = NULL;
+	struct smb_filename *catia_smb_fname = NULL;
 	NTSTATUS status;
 	int ret;
 
-	status = catia_string_replace_allocate(handle->conn, path,
-				        &mapped_name, vfs_translate_to_unix);
+	status = catia_string_replace_allocate(handle->conn,
+				smb_fname->base_name,
+				&name,
+				vfs_translate_to_unix);
 	if (!NT_STATUS_IS_OK(status)) {
 		errno = map_errno_from_nt_status(status);
 		return -1;
 	}
+	catia_smb_fname = synthetic_smb_fname(talloc_tos(),
+					name,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (catia_smb_fname == NULL) {
+		TALLOC_FREE(name);
+		errno = ENOMEM;
+		return -1;
+	}
 
-	ret = SMB_VFS_NEXT_CHFLAGS(handle, mapped_name, flags);
-	TALLOC_FREE(mapped_name);
+	ret = SMB_VFS_NEXT_CHFLAGS(handle, catia_smb_fname, flags);
+	TALLOC_FREE(name);
+	TALLOC_FREE(catia_smb_fname);
 
 	return ret;
 }
diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index d88ceac..d936738 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -1189,8 +1189,9 @@ static char *cephwrap_realpath(struct vfs_handle_struct *handle,  const char *pa
 	return result;
 }
 
-static int cephwrap_chflags(struct vfs_handle_struct *handle, const char *path,
-			   unsigned int flags)
+static int cephwrap_chflags(struct vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			unsigned int flags)
 {
 	errno = ENOSYS;
 	return -1;
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 6de5d64..b2c6c28 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -2465,11 +2465,12 @@ static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path)
 	return result;
 }
 
-static int vfswrap_chflags(vfs_handle_struct *handle, const char *path,
-			   unsigned int flags)
+static int vfswrap_chflags(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			unsigned int flags)
 {
 #ifdef HAVE_CHFLAGS
-	return chflags(path, flags);
+	return chflags(smb_fname->base_name, flags);
 #else
 	errno = ENOSYS;
 	return -1;
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index af165dd..634caf0 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -1686,13 +1686,15 @@ static char *smb_full_audit_realpath(vfs_handle_struct *handle,
 }
 
 static int smb_full_audit_chflags(vfs_handle_struct *handle,
-			    const char *path, unsigned int flags)
+			const struct smb_filename *smb_fname,
+			unsigned int flags)
 {
 	int result;
 
-	result = SMB_VFS_NEXT_CHFLAGS(handle, path, flags);
+	result = SMB_VFS_NEXT_CHFLAGS(handle, smb_fname, flags);
 
-	do_log(SMB_VFS_OP_CHFLAGS, (result != 0), handle, "%s", path);
+	do_log(SMB_VFS_OP_CHFLAGS, (result != 0), handle, "%s",
+		smb_fname->base_name);
 
 	return result;
 }
diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index 7c72777..878c507 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -1257,7 +1257,8 @@ static int vfs_gluster_mknod(struct vfs_handle_struct *handle,
 }
 
 static int vfs_gluster_chflags(struct vfs_handle_struct *handle,
-			       const char *path, unsigned int flags)
+				const struct smb_filename *smb_fname,
+				unsigned int flags)
 {
 	errno = ENOSYS;
 	return -1;
diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c
index 99a5e9b..37b396a 100644
--- a/source3/modules/vfs_media_harmony.c
+++ b/source3/modules/vfs_media_harmony.c
@@ -1923,33 +1923,30 @@ out:
  * Failure: set errno, return -1
  */
 static int mh_chflags(vfs_handle_struct *handle,
-		const char *path,
+		const struct smb_filename *smb_fname,
 		unsigned int flags)
 {
 	int status;
-	char *clientPath;
+	struct smb_filename *clientFname = NULL;
 	TALLOC_CTX *ctx;
 
 	DEBUG(MH_INFO_DEBUG, ("Entering mh_chflags\n"));
-	if (!is_in_media_files(path))
-	{
-		status = SMB_VFS_NEXT_CHFLAGS(handle, path, flags);
+	if (!is_in_media_files(smb_fname->base_name)) {
+		status = SMB_VFS_NEXT_CHFLAGS(handle, smb_fname, flags);
 		goto out;
 	}
 
-	clientPath = NULL;
 	ctx = talloc_tos();
 
-	if ((status = alloc_get_client_path(handle, ctx,
-				path,
-				&clientPath)))
-	{
+	if ((status = alloc_get_client_smb_fname(handle, ctx,
+				smb_fname,
+				&clientFname))) {
 		goto err;
 	}
 
-	status = SMB_VFS_NEXT_CHFLAGS(handle, clientPath, flags);
+	status = SMB_VFS_NEXT_CHFLAGS(handle, clientFname, flags);
 err:
-	TALLOC_FREE(clientPath);
+	TALLOC_FREE(clientFname);
 out:
 	return status;
 }
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 1fb492b..35c0854 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -2309,7 +2309,8 @@ static int shadow_copy2_rmdir(vfs_handle_struct *handle,
 	return ret;
 }
 
-static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname,
+static int shadow_copy2_chflags(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
 				unsigned int flags)
 {
 	time_t timestamp = 0;
@@ -2317,23 +2318,37 @@ static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname,
 	int saved_errno = 0;
 	int ret;
 	char *conv;
+	struct smb_filename *conv_smb_fname = NULL;
 
-	if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
-					 &timestamp, &stripped)) {
+	if (!shadow_copy2_strip_snapshot(talloc_tos(),
+					handle,
+					smb_fname->base_name,
+					&timestamp,
+					&stripped)) {
 		return -1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_CHFLAGS(handle, fname, flags);
+		return SMB_VFS_NEXT_CHFLAGS(handle, smb_fname, flags);
 	}
 	conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
 	TALLOC_FREE(stripped);
 	if (conv == NULL) {
 		return -1;
 	}
-	ret = SMB_VFS_NEXT_CHFLAGS(handle, conv, flags);
+	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+					conv,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (conv_smb_fname == NULL) {
+		TALLOC_FREE(conv);
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_CHFLAGS(handle, smb_fname, flags);
 	if (ret == -1) {
 		saved_errno = errno;
 	}
+	TALLOC_FREE(conv_smb_fname);
 	TALLOC_FREE(conv);
 	if (saved_errno != 0) {
 		errno = saved_errno;
diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c
index 43ea54f..19ac664 100644
--- a/source3/modules/vfs_snapper.c
+++ b/source3/modules/vfs_snapper.c
@@ -2654,30 +2654,47 @@ static int snapper_gmt_rmdir(vfs_handle_struct *handle,
 	return ret;
 }
 
-static int snapper_gmt_chflags(vfs_handle_struct *handle, const char *fname,
-			       unsigned int flags)
+static int snapper_gmt_chflags(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				unsigned int flags)
 {
-	time_t timestamp;
-	char *stripped;
-	int ret, saved_errno;
-	char *conv;
+	time_t timestamp = 0;
+	char *stripped = NULL;
+	int ret = -1;
+	int saved_errno = 0;
+	char *conv = NULL;
+	struct smb_filename *conv_smb_fname = NULL;
 
-	if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, fname,
-					&timestamp, &stripped)) {
+	if (!snapper_gmt_strip_snapshot(talloc_tos(), handle,
+				smb_fname->base_name, &timestamp, &stripped)) {
 		return -1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_CHFLAGS(handle, fname, flags);
+		return SMB_VFS_NEXT_CHFLAGS(handle, smb_fname, flags);
 	}
 	conv = snapper_gmt_convert(talloc_tos(), handle, stripped, timestamp);
 	TALLOC_FREE(stripped);
 	if (conv == NULL) {
 		return -1;
 	}
-	ret = SMB_VFS_NEXT_CHFLAGS(handle, conv, flags);
-	saved_errno = errno;
+	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+					conv,
+					NULL,
+					NULL,
+					fname->flags);
 	TALLOC_FREE(conv);
-	errno = saved_errno;
+	if (conv_smb_fname == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_CHFLAGS(handle, conv_smb_fname, flags);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(conv_smb_fname);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return ret;
 }
 
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index 3bbe2d9..aa882bb 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -1512,19 +1512,20 @@ static char *smb_time_audit_realpath(vfs_handle_struct *handle,
 }
 
 static int smb_time_audit_chflags(vfs_handle_struct *handle,
-				  const char *path, unsigned int flags)
+				const struct smb_filename *smb_fname,
+				unsigned int flags)
 {
 	int result;
 	struct timespec ts1,ts2;
 	double timediff;
 
 	clock_gettime_mono(&ts1);
-	result = SMB_VFS_NEXT_CHFLAGS(handle, path, flags);
+	result = SMB_VFS_NEXT_CHFLAGS(handle, smb_fname, flags);
 	clock_gettime_mono(&ts2);
 	timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
 	if (timediff > audit_timeout) {
-		smb_time_audit_log_fname("chflags", timediff, path);
+		smb_time_audit_log_smb_fname("chflags", timediff, smb_fname);
 	}
 
 	return result;
diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c
index cda6ad6..aa06ea3 100644
--- a/source3/modules/vfs_unityed_media.c
+++ b/source3/modules/vfs_unityed_media.c
@@ -1464,27 +1464,27 @@ err:
 }
 
 static int um_chflags(vfs_handle_struct *handle,
-		      const char *path,
-		      unsigned int flags)
+			const struct smb_filename *smb_fname,
+			unsigned int flags)
 {
 	int status;
-	char *client_path = NULL;
-
-	DEBUG(10, ("Entering um_chflags\n"));
+	struct smb_filename *client_fname = NULL;
 
-	if (!is_in_media_files(path)) {
-		return SMB_VFS_NEXT_CHFLAGS(handle, path, flags);
+	DEBUG(10, ("Entering um_mknod\n"));
+	if (!is_in_media_files(smb_fname->base_name)) {
+		return SMB_VFS_NEXT_CHFLAGS(handle, smb_fname, flags);
 	}
 
-	status = alloc_get_client_path(handle, talloc_tos(),
-				       path, &client_path);
+	status = alloc_get_client_smb_fname(handle, talloc_tos(),
+					    smb_fname, &client_fname);
 	if (status != 0) {
 		goto err;
 	}
 
-	status = SMB_VFS_NEXT_CHFLAGS(handle, client_path, flags);
+	status = SMB_VFS_NEXT_CHFLAGS(handle, client_fname, flags);
+
 err:
-	TALLOC_FREE(client_path);
+	TALLOC_FREE(client_fname);
 	return status;
 }
 
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 758644b..3e1cfa8 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -7905,7 +7905,7 @@ static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
 			/* XXX: we should be  using SMB_VFS_FCHFLAGS here. */
 			return NT_STATUS_NOT_SUPPORTED;
 		} else {
-			if (SMB_VFS_CHFLAGS(conn, smb_fname->base_name,
+			if (SMB_VFS_CHFLAGS(conn, smb_fname,
 					    stat_fflags) != 0) {
 				return map_nt_error_from_unix(errno);
 			}
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index b129bb1..9248091 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -2182,11 +2182,12 @@ char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
 	return handle->fns->realpath_fn(handle, path);
 }
 
-int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
-			 unsigned int flags)
+int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			unsigned int flags)
 {
 	VFS_FIND(chflags);
-	return handle->fns->chflags_fn(handle, path, flags);
+	return handle->fns->chflags_fn(handle, smb_fname, flags);
 }
 
 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
-- 
2.7.4


>From edb1a27d6ba19bbcc9b399839209e737d6572474 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Tue, 23 May 2017 10:40:47 -0700
Subject: [PATCH 4/5] s3: VFS: Change SMB_VFS_DISK_FREE to use const struct
 smb_filename * instead of const char *.

We need to migrate all pathname based VFS calls to use a struct
to finish modernising the VFS with extra timestamp and flags parameters.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 examples/VFS/skel_opaque.c         |  8 +++---
 examples/VFS/skel_transparent.c    | 10 +++++---
 source3/include/vfs.h              | 15 ++++++++---
 source3/include/vfs_macros.h       |  8 +++---
 source3/modules/vfs_cap.c          | 25 +++++++++++++++----
 source3/modules/vfs_ceph.c         |  9 ++++---
 source3/modules/vfs_default.c      | 10 +++++---
 source3/modules/vfs_fake_dfq.c     | 11 +++++---
 source3/modules/vfs_full_audit.c   | 10 +++++---
 source3/modules/vfs_glusterfs.c    |  8 +++---
 source3/modules/vfs_gpfs.c         | 24 ++++++++++--------
 source3/modules/vfs_shadow_copy2.c | 43 +++++++++++++++++++++-----------
 source3/modules/vfs_snapper.c      | 51 +++++++++++++++++++++++++-------------
 source3/modules/vfs_time_audit.c   | 12 ++++++---
 source3/smbd/dfree.c               |  2 +-
 source3/smbd/vfs.c                 |  9 ++++---
 source3/torture/cmd_vfs.c          | 12 ++++++++-
 17 files changed, 178 insertions(+), 89 deletions(-)

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index aeb1ff3..40951db 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -44,9 +44,11 @@ static void skel_disconnect(vfs_handle_struct *handle)
 	;
 }
 
-static uint64_t skel_disk_free(vfs_handle_struct *handle, const char *path,
-			       uint64_t *bsize,
-			       uint64_t *dfree, uint64_t *dsize)
+static uint64_t skel_disk_free(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				uint64_t *bsize,
+				uint64_t *dfree,
+				uint64_t *dsize)
 {
 	*bsize = 0;
 	*dfree = 0;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index f3adae3..83c0c2a 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -48,11 +48,13 @@ static void skel_disconnect(vfs_handle_struct *handle)
 	SMB_VFS_NEXT_DISCONNECT(handle);
 }
 
-static uint64_t skel_disk_free(vfs_handle_struct *handle, const char *path,
-			       uint64_t *bsize,
-			       uint64_t *dfree, uint64_t *dsize)
+static uint64_t skel_disk_free(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				uint64_t *bsize,
+				uint64_t *dfree,
+				uint64_t *dsize)
 {
-	return SMB_VFS_NEXT_DISK_FREE(handle, path, bsize, dfree, dsize);
+	return SMB_VFS_NEXT_DISK_FREE(handle, smb_fname, bsize, dfree, dsize);
 }
 
 static int skel_get_quota(vfs_handle_struct *handle, const char *path,
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 93ec6e8..4a7179a 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -216,6 +216,8 @@
 /* Version 37 - Change mknod from const char * to const struct smb_filename * */
 /* Version 37 - Change chflags from const char *
 		to const struct smb_filename * */
+/* Version 37 - Change disk_free from const char *
+		to const struct smb_filename * */
 
 #define SMB_VFS_INTERFACE_VERSION 37
 
@@ -600,8 +602,11 @@ struct vfs_fn_pointers {
 
 	int (*connect_fn)(struct vfs_handle_struct *handle, const char *service, const char *user);
 	void (*disconnect_fn)(struct vfs_handle_struct *handle);
-	uint64_t (*disk_free_fn)(struct vfs_handle_struct *handle, const char *path, uint64_t *bsize,
-			      uint64_t *dfree, uint64_t *dsize);
+	uint64_t (*disk_free_fn)(struct vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				uint64_t *bsize,
+				uint64_t *dfree,
+				uint64_t *dsize);
 	int (*get_quota_fn)(struct vfs_handle_struct *handle, const char *path,
 			    enum SMB_QUOTA_TYPE qtype, unid_t id,
 			    SMB_DISK_QUOTA *qt);
@@ -1056,8 +1061,10 @@ int smb_vfs_call_connect(struct vfs_handle_struct *handle,
 			 const char *service, const char *user);
 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle);
 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
-				const char *path, uint64_t *bsize,
-				uint64_t *dfree, uint64_t *dsize);
+				const struct smb_filename *smb_filename,
+				uint64_t *bsize,
+				uint64_t *dfree,
+				uint64_t *dsize);
 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle, const char *path,
 			   enum SMB_QUOTA_TYPE qtype, unid_t id,
 			   SMB_DISK_QUOTA *qt);
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 701dc53..cd34ec9 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -39,10 +39,10 @@
 #define SMB_VFS_NEXT_DISCONNECT(handle) \
 	smb_vfs_call_disconnect((handle)->next)
 
-#define SMB_VFS_DISK_FREE(conn, path, bsize, dfree ,dsize) \
-	smb_vfs_call_disk_free((conn)->vfs_handles, (path), (bsize), (dfree), (dsize))
-#define SMB_VFS_NEXT_DISK_FREE(handle, path, bsize, dfree ,dsize)\
-	smb_vfs_call_disk_free((handle)->next, (path), (bsize), (dfree), (dsize))
+#define SMB_VFS_DISK_FREE(conn, smb_fname, bsize, dfree ,dsize) \
+	smb_vfs_call_disk_free((conn)->vfs_handles, (smb_fname), (bsize), (dfree), (dsize))
+#define SMB_VFS_NEXT_DISK_FREE(handle, smb_fname, bsize, dfree ,dsize)\
+	smb_vfs_call_disk_free((handle)->next, (smb_fname), (bsize), (dfree), (dsize))
 
 #define SMB_VFS_GET_QUOTA(conn, path, qtype, id, qt)                           \
 	smb_vfs_call_get_quota((conn)->vfs_handles, (path), (qtype), (id), (qt))
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index eba5896..cf3bb94 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -29,16 +29,31 @@
 static char *capencode(TALLOC_CTX *ctx, const char *from);
 static char *capdecode(TALLOC_CTX *ctx, const char *from);
 
-static uint64_t cap_disk_free(vfs_handle_struct *handle, const char *path,
-			      uint64_t *bsize, uint64_t *dfree, uint64_t *dsize)
+static uint64_t cap_disk_free(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			uint64_t *bsize,
+			uint64_t *dfree,
+			uint64_t *dsize)
 {
-	char *cappath = capencode(talloc_tos(), path);
+	char *capname = capencode(talloc_tos(), smb_fname->base_name);
+	struct smb_filename *cap_smb_fname = NULL;
 
-	if (!cappath) {
+	if (!capname) {
+		errno = ENOMEM;
+		return (uint64_t)-1;
+	}
+	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+					capname,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (cap_smb_fname == NULL) {
+		TALLOC_FREE(capname);
 		errno = ENOMEM;
 		return (uint64_t)-1;
 	}
-	return SMB_VFS_NEXT_DISK_FREE(handle, cappath, bsize, dfree, dsize);
+	return SMB_VFS_NEXT_DISK_FREE(handle, cap_smb_fname,
+			bsize, dfree, dsize);
 }
 
 static int cap_get_quota(vfs_handle_struct *handle, const char *path,
diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index d936738..1244468 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -175,13 +175,16 @@ static void cephwrap_disconnect(struct vfs_handle_struct *handle)
 /* Disk operations */
 
 static uint64_t cephwrap_disk_free(struct vfs_handle_struct *handle,
-				   const char *path, uint64_t *bsize,
-				   uint64_t *dfree, uint64_t *dsize)
+				const struct smb_filename *smb_fname,
+				uint64_t *bsize,
+				uint64_t *dfree,
+				uint64_t *dsize)
 {
 	struct statvfs statvfs_buf;
 	int ret;
 
-	if (!(ret = ceph_statfs(handle->data, path, &statvfs_buf))) {
+	if (!(ret = ceph_statfs(handle->data, smb_fname->base_name,
+			&statvfs_buf))) {
 		/*
 		 * Provide all the correct values.
 		 */
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index b2c6c28..1c26728 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -55,11 +55,13 @@ static void vfswrap_disconnect(vfs_handle_struct *handle)
 
 /* Disk operations */
 
-static uint64_t vfswrap_disk_free(vfs_handle_struct *handle, const char *path,
-				  uint64_t *bsize, uint64_t *dfree,
-				  uint64_t *dsize)
+static uint64_t vfswrap_disk_free(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				uint64_t *bsize,
+				uint64_t *dfree,
+				uint64_t *dsize)
 {
-	if (sys_fsusage(path, dfree, dsize) != 0) {
+	if (sys_fsusage(smb_fname->base_name, dfree, dsize) != 0) {
 		return (uint64_t)-1;
 	}
 
diff --git a/source3/modules/vfs_fake_dfq.c b/source3/modules/vfs_fake_dfq.c
index f13ec7d..5e8879f 100644
--- a/source3/modules/vfs_fake_dfq.c
+++ b/source3/modules/vfs_fake_dfq.c
@@ -50,8 +50,11 @@ static uint64_t dfq_load_param(int snum, const char *path, const char *section,
 	return ret;
 }
 
-static uint64_t dfq_disk_free(vfs_handle_struct *handle, const char *path,
-			      uint64_t *bsize, uint64_t *dfree, uint64_t *dsize)
+static uint64_t dfq_disk_free(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				uint64_t *bsize,
+				uint64_t *dfree,
+				uint64_t *dsize)
 {
 	uint64_t free_1k;
 	int snum = SNUM(handle->conn);
@@ -61,13 +64,13 @@ static uint64_t dfq_disk_free(vfs_handle_struct *handle, const char *path,
 	/* look up the params based on real path to be resilient
 	 * to refactoring of path<->realpath
 	 */
-	rpath = SMB_VFS_NEXT_REALPATH(handle, path);
+	rpath = SMB_VFS_NEXT_REALPATH(handle, smb_fname->base_name);
 	if (rpath != NULL) {
 		dfq_bsize = dfq_load_param(snum, rpath, "df", "block size", 0);
 	}
 	if (dfq_bsize == 0) {
 		SAFE_FREE(rpath);
-		return SMB_VFS_NEXT_DISK_FREE(handle, path, bsize, dfree,
+		return SMB_VFS_NEXT_DISK_FREE(handle, smb_fname, bsize, dfree,
 					      dsize);
 	}
 
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 634caf0..9168257 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -676,16 +676,18 @@ static void smb_full_audit_disconnect(vfs_handle_struct *handle)
 }
 
 static uint64_t smb_full_audit_disk_free(vfs_handle_struct *handle,
-				    const char *path, uint64_t *bsize,
-				    uint64_t *dfree, uint64_t *dsize)
+				const struct smb_filename *smb_fname,
+				uint64_t *bsize,
+				uint64_t *dfree,
+				uint64_t *dsize)
 {
 	uint64_t result;
 
-	result = SMB_VFS_NEXT_DISK_FREE(handle, path, bsize, dfree, dsize);
+	result = SMB_VFS_NEXT_DISK_FREE(handle, smb_fname, bsize, dfree, dsize);
 
 	/* Don't have a reasonable notion of failure here */
 
-	do_log(SMB_VFS_OP_DISK_FREE, True, handle, "%s", path);
+	do_log(SMB_VFS_OP_DISK_FREE, True, handle, "%s", smb_fname->base_name);
 
 	return result;
 }
diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index 878c507..cabb861 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -375,13 +375,15 @@ static void vfs_gluster_disconnect(struct vfs_handle_struct *handle)
 }
 
 static uint64_t vfs_gluster_disk_free(struct vfs_handle_struct *handle,
-				      const char *path, uint64_t *bsize_p,
-				      uint64_t *dfree_p, uint64_t *dsize_p)
+				const struct smb_filename *smb_fname,
+				uint64_t *bsize_p,
+				uint64_t *dfree_p,
+				uint64_t *dsize_p)
 {
 	struct statvfs statvfs = { 0, };
 	int ret;
 
-	ret = glfs_statvfs(handle->data, path, &statvfs);
+	ret = glfs_statvfs(handle->data, smb_fname->base_name, &statvfs);
 	if (ret < 0) {
 		return -1;
 	}
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index 4dc9f76..0f85951 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -2160,9 +2160,11 @@ static void vfs_gpfs_disk_free_quota(struct gpfs_quotaInfo qi, time_t cur_time,
 	}
 }
 
-static uint64_t vfs_gpfs_disk_free(vfs_handle_struct *handle, const char *path,
-				   uint64_t *bsize,
-				   uint64_t *dfree, uint64_t *dsize)
+static uint64_t vfs_gpfs_disk_free(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				uint64_t *bsize,
+				uint64_t *dfree,
+				uint64_t *dsize)
 {
 	struct security_unix_token *utok;
 	struct gpfs_quotaInfo qi_user = { 0 }, qi_group = { 0 };
@@ -2173,14 +2175,14 @@ static uint64_t vfs_gpfs_disk_free(vfs_handle_struct *handle, const char *path,
 	SMB_VFS_HANDLE_GET_DATA(handle, config, struct gpfs_config_data,
 				return (uint64_t)-1);
 	if (!config->dfreequota) {
-		return SMB_VFS_NEXT_DISK_FREE(handle, path,
+		return SMB_VFS_NEXT_DISK_FREE(handle, smb_fname,
 					      bsize, dfree, dsize);
 	}
 
-	err = sys_fsusage(path, dfree, dsize);
+	err = sys_fsusage(smb_fname->base_name, dfree, dsize);
 	if (err) {
 		DEBUG (0, ("Could not get fs usage, errno %d\n", errno));
-		return SMB_VFS_NEXT_DISK_FREE(handle, path,
+		return SMB_VFS_NEXT_DISK_FREE(handle, smb_fname,
 					      bsize, dfree, dsize);
 	}
 
@@ -2192,15 +2194,17 @@ static uint64_t vfs_gpfs_disk_free(vfs_handle_struct *handle, const char *path,
 
 	utok = handle->conn->session_info->unix_token;
 
-	err = get_gpfs_quota(path, GPFS_USRQUOTA, utok->uid, &qi_user);
+	err = get_gpfs_quota(smb_fname->base_name,
+			GPFS_USRQUOTA, utok->uid, &qi_user);
 	if (err) {
-		return SMB_VFS_NEXT_DISK_FREE(handle, path,
+		return SMB_VFS_NEXT_DISK_FREE(handle, smb_fname,
 					      bsize, dfree, dsize);
 	}
 
-	err = get_gpfs_quota(path, GPFS_GRPQUOTA, utok->gid, &qi_group);
+	err = get_gpfs_quota(smb_fname->base_name,
+			GPFS_GRPQUOTA, utok->gid, &qi_group);
 	if (err) {
-		return SMB_VFS_NEXT_DISK_FREE(handle, path,
+		return SMB_VFS_NEXT_DISK_FREE(handle, smb_fname,
 					      bsize, dfree, dsize);
 	}
 
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 35c0854..e1f3039 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -2742,40 +2742,53 @@ done:
 }
 
 static uint64_t shadow_copy2_disk_free(vfs_handle_struct *handle,
-				       const char *path, uint64_t *bsize,
-				       uint64_t *dfree, uint64_t *dsize)
+				const struct smb_filename *smb_fname,
+				uint64_t *bsize,
+				uint64_t *dfree,
+				uint64_t *dsize)
 {
 	time_t timestamp = 0;
 	char *stripped = NULL;
-	ssize_t ret;
 	int saved_errno = 0;
-	char *conv;
+	char *conv = NULL;
+	struct smb_filename *conv_smb_fname = NULL;
+	uint64_t ret = (uint64_t)-1;
 
-	if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, path,
-					 &timestamp, &stripped)) {
-		return -1;
+	if (!shadow_copy2_strip_snapshot(talloc_tos(),
+				handle,
+				smb_fname->base_name,
+				&timestamp,
+				&stripped)) {
+		return (uint64_t)-1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_DISK_FREE(handle, path,
+		return SMB_VFS_NEXT_DISK_FREE(handle, smb_fname,
 					      bsize, dfree, dsize);
 	}
-
 	conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
 	TALLOC_FREE(stripped);
 	if (conv == NULL) {
-		return -1;
+		return (uint64_t)-1;
 	}
-
-	ret = SMB_VFS_NEXT_DISK_FREE(handle, conv, bsize, dfree, dsize);
-
-	if (ret == -1) {
+	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+					conv,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (conv_smb_fname == NULL) {
+		TALLOC_FREE(conv);
+		return (uint64_t)-1;
+	}
+	ret = SMB_VFS_NEXT_DISK_FREE(handle, conv_smb_fname,
+				bsize, dfree, dsize);
+	if (ret == (uint64_t)-1) {
 		saved_errno = errno;
 	}
 	TALLOC_FREE(conv);
+	TALLOC_FREE(conv_smb_fname);
 	if (saved_errno != 0) {
 		errno = saved_errno;
 	}
-
 	return ret;
 }
 
diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c
index 19ac664..dd7bb64 100644
--- a/source3/modules/vfs_snapper.c
+++ b/source3/modules/vfs_snapper.c
@@ -2982,36 +2982,53 @@ static int snapper_gmt_get_real_filename(struct vfs_handle_struct *handle,
 }
 
 static uint64_t snapper_gmt_disk_free(vfs_handle_struct *handle,
-				      const char *path, uint64_t *bsize,
-				      uint64_t *dfree, uint64_t *dsize)
+				const struct smb_filename *smb_fname,
+				uint64_t *bsize,
+				uint64_t *dfree,
+				uint64_t *dsize)
 {
-	time_t timestamp;
-	char *stripped;
-	ssize_t ret;
-	int saved_errno;
-	char *conv;
+	time_t timestamp = 0;
+	char *stripped = NULL;
+	uint64_t ret;
+	int saved_errno = 0;
+	char *conv = NULL;
+	struct smb_filename *conv_smb_fname = NULL;
 
-	if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, path,
-					&timestamp, &stripped)) {
-		return -1;
+	if (!snapper_gmt_strip_snapshot(talloc_tos(), handle,
+			smb_fname->base_name, &timestamp, &stripped)) {
+		return (uint64_t)-1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_DISK_FREE(handle, path,
+		return SMB_VFS_NEXT_DISK_FREE(handle, smb_fname,
 					      bsize, dfree, dsize);
 	}
 
 	conv = snapper_gmt_convert(talloc_tos(), handle, stripped, timestamp);
 	TALLOC_FREE(stripped);
 	if (conv == NULL) {
-		return -1;
+		return (uint64_t)-1;
+	}
+	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+					conv,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (conv_smb_fname == NULL) {
+		TALLOC_FREE(conv);
+		errno = ENOMEM;
+		return (uint64_t)-1;
 	}
 
-	ret = SMB_VFS_NEXT_DISK_FREE(handle, conv, bsize, dfree, dsize);
-
-	saved_errno = errno;
-	TALLOC_FREE(conv);
-	errno = saved_errno;
+	ret = SMB_VFS_NEXT_DISK_FREE(handle, conv_smb_fname,
+				bsize, dfree, dsize);
 
+	if (ret == (uint64_t)-1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(conv_smb_fname);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return ret;
 }
 
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index aa882bb..092474f 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -157,21 +157,25 @@ static void smb_time_audit_disconnect(vfs_handle_struct *handle)
 }
 
 static uint64_t smb_time_audit_disk_free(vfs_handle_struct *handle,
-					 const char *path, uint64_t *bsize,
-					 uint64_t *dfree, uint64_t *dsize)
+					const struct smb_filename *smb_fname,
+					uint64_t *bsize,
+					uint64_t *dfree,
+					uint64_t *dsize)
 {
 	uint64_t result;
 	struct timespec ts1,ts2;
 	double timediff;
 
 	clock_gettime_mono(&ts1);
-	result = SMB_VFS_NEXT_DISK_FREE(handle, path, bsize, dfree, dsize);
+	result = SMB_VFS_NEXT_DISK_FREE(handle, smb_fname, bsize, dfree, dsize);
 	clock_gettime_mono(&ts2);
 	timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
 	/* Don't have a reasonable notion of failure here */
 	if (timediff > audit_timeout) {
-		smb_time_audit_log_fname("disk_free", timediff, path);
+		smb_time_audit_log_fname("disk_free",
+				timediff,
+				smb_fname->base_name);
 	}
 
 	return result;
diff --git a/source3/smbd/dfree.c b/source3/smbd/dfree.c
index 7e58daa..a702d08 100644
--- a/source3/smbd/dfree.c
+++ b/source3/smbd/dfree.c
@@ -118,7 +118,7 @@ uint64_t sys_disk_free(connection_struct *conn, struct smb_filename *fname,
 			   syscmd, strerror(errno) ));
 	}
 
-	if (SMB_VFS_DISK_FREE(conn, path, bsize, dfree, dsize) ==
+	if (SMB_VFS_DISK_FREE(conn, fname, bsize, dfree, dsize) ==
 	    (uint64_t)-1) {
 		DBG_ERR("VFS disk_free failed. Error was : %s\n",
 			strerror(errno));
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 9248091..f91e9e3 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -1468,11 +1468,14 @@ void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
 }
 
 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
-				const char *path, uint64_t *bsize,
-				uint64_t *dfree, uint64_t *dsize)
+				const struct smb_filename *smb_fname,
+				uint64_t *bsize,
+				uint64_t *dfree,
+				uint64_t *dsize)
 {
 	VFS_FIND(disk_free);
-	return handle->fns->disk_free_fn(handle, path, bsize, dfree, dsize);
+	return handle->fns->disk_free_fn(handle, smb_fname,
+			bsize, dfree, dsize);
 }
 
 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle, const char *path,
diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
index 68def35..8d7d2a7 100644
--- a/source3/torture/cmd_vfs.c
+++ b/source3/torture/cmd_vfs.c
@@ -116,13 +116,23 @@ static NTSTATUS cmd_disconnect(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int a
 
 static NTSTATUS cmd_disk_free(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
+	struct smb_filename *smb_fname = NULL;
 	uint64_t diskfree, bsize, dfree, dsize;
 	if (argc != 2) {
 		printf("Usage: disk_free <path>\n");
 		return NT_STATUS_OK;
 	}
 
-	diskfree = SMB_VFS_DISK_FREE(vfs->conn, argv[1], &bsize, &dfree, &dsize);
+	smb_fname = synthetic_smb_fname(talloc_tos(),
+					argv[1],
+					NULL,
+					NULL,
+					ssf_flags());
+	if (smb_fname == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	diskfree = SMB_VFS_DISK_FREE(vfs->conn, smb_fname,
+				&bsize, &dfree, &dsize);
 	printf("disk_free: %lu, bsize = %lu, dfree = %lu, dsize = %lu\n",
 			(unsigned long)diskfree,
 			(unsigned long)bsize,
-- 
2.7.4


>From 80952e66b9ed9778619727e86de477f8856961b8 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 1 Jun 2017 11:45:25 -0700
Subject: [PATCH 5/5] s3: VFS: Change SMB_VFS_GET_QUOTA to use const struct
 smb_filename * instead of const char *.

We need to migrate all pathname based VFS calls to use a struct
to finish modernising the VFS with extra timestamp and flags parameters.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 examples/VFS/skel_opaque.c          |  8 ++++---
 examples/VFS/skel_transparent.c     | 10 ++++----
 source3/include/vfs.h               | 18 ++++++++++-----
 source3/include/vfs_macros.h        |  8 +++----
 source3/modules/vfs_cap.c           | 23 +++++++++++++++----
 source3/modules/vfs_ceph.c          |  6 +++--
 source3/modules/vfs_default.c       | 10 ++++----
 source3/modules/vfs_default_quota.c | 17 ++++++++------
 source3/modules/vfs_fake_dfq.c      | 20 +++++++++-------
 source3/modules/vfs_full_audit.c    | 11 +++++----
 source3/modules/vfs_glusterfs.c     |  7 +++---
 source3/modules/vfs_gpfs.c          | 11 +++++----
 source3/modules/vfs_shadow_copy2.c  | 31 ++++++++++++++++++-------
 source3/modules/vfs_snapper.c       | 46 +++++++++++++++++++++++++------------
 source3/modules/vfs_time_audit.c    | 12 ++++++----
 source3/smbd/ntquotas.c             | 20 +++++++++++++++-
 source3/smbd/quotas.c               | 10 ++++----
 source3/smbd/vfs.c                  | 10 ++++----
 18 files changed, 187 insertions(+), 91 deletions(-)

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 40951db..7dd258f 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -56,9 +56,11 @@ static uint64_t skel_disk_free(vfs_handle_struct *handle,
 	return 0;
 }
 
-static int skel_get_quota(vfs_handle_struct *handle, const char *path,
-			  enum SMB_QUOTA_TYPE qtype, unid_t id,
-			  SMB_DISK_QUOTA *dq)
+static int skel_get_quota(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				enum SMB_QUOTA_TYPE qtype,
+				unid_t id,
+				SMB_DISK_QUOTA *dq)
 {
 	errno = ENOSYS;
 	return -1;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index 83c0c2a..5e66be4 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -57,11 +57,13 @@ static uint64_t skel_disk_free(vfs_handle_struct *handle,
 	return SMB_VFS_NEXT_DISK_FREE(handle, smb_fname, bsize, dfree, dsize);
 }
 
-static int skel_get_quota(vfs_handle_struct *handle, const char *path,
-			  enum SMB_QUOTA_TYPE qtype, unid_t id,
-			  SMB_DISK_QUOTA *dq)
+static int skel_get_quota(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				enum SMB_QUOTA_TYPE qtype,
+				unid_t id,
+				SMB_DISK_QUOTA *dq)
 {
-	return SMB_VFS_NEXT_GET_QUOTA(handle, path, qtype, id, dq);
+	return SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname, qtype, id, dq);
 }
 
 static int skel_set_quota(vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype,
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 4a7179a..a0eca77 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -218,6 +218,8 @@
 		to const struct smb_filename * */
 /* Version 37 - Change disk_free from const char *
 		to const struct smb_filename * */
+/* Version 37 - Change get_quota from const char *
+		to const struct smb_filename * */
 
 #define SMB_VFS_INTERFACE_VERSION 37
 
@@ -607,9 +609,11 @@ struct vfs_fn_pointers {
 				uint64_t *bsize,
 				uint64_t *dfree,
 				uint64_t *dsize);
-	int (*get_quota_fn)(struct vfs_handle_struct *handle, const char *path,
-			    enum SMB_QUOTA_TYPE qtype, unid_t id,
-			    SMB_DISK_QUOTA *qt);
+	int (*get_quota_fn)(struct vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				enum SMB_QUOTA_TYPE qtype,
+				unid_t id,
+				SMB_DISK_QUOTA *qt);
 	int (*set_quota_fn)(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt);
 	int (*get_shadow_copy_data_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, struct shadow_copy_data *shadow_copy_data, bool labels);
 	int (*statvfs_fn)(struct vfs_handle_struct *handle, const char *path, struct vfs_statvfs_struct *statbuf);
@@ -1065,9 +1069,11 @@ uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
 				uint64_t *bsize,
 				uint64_t *dfree,
 				uint64_t *dsize);
-int smb_vfs_call_get_quota(struct vfs_handle_struct *handle, const char *path,
-			   enum SMB_QUOTA_TYPE qtype, unid_t id,
-			   SMB_DISK_QUOTA *qt);
+int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
+				const struct smb_filename *smb_filename,
+				enum SMB_QUOTA_TYPE qtype,
+				unid_t id,
+				SMB_DISK_QUOTA *qt);
 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
 			   enum SMB_QUOTA_TYPE qtype, unid_t id,
 			   SMB_DISK_QUOTA *qt);
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index cd34ec9..d49d340 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -44,10 +44,10 @@
 #define SMB_VFS_NEXT_DISK_FREE(handle, smb_fname, bsize, dfree ,dsize)\
 	smb_vfs_call_disk_free((handle)->next, (smb_fname), (bsize), (dfree), (dsize))
 
-#define SMB_VFS_GET_QUOTA(conn, path, qtype, id, qt)                           \
-	smb_vfs_call_get_quota((conn)->vfs_handles, (path), (qtype), (id), (qt))
-#define SMB_VFS_NEXT_GET_QUOTA(handle, path, qtype, id, qt)                    \
-	smb_vfs_call_get_quota((handle)->next, (path), (qtype), (id), (qt))
+#define SMB_VFS_GET_QUOTA(conn, smb_fname, qtype, id, qt)                           \
+	smb_vfs_call_get_quota((conn)->vfs_handles, (smb_fname), (qtype), (id), (qt))
+#define SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname, qtype, id, qt)                    \
+	smb_vfs_call_get_quota((handle)->next, (smb_fname), (qtype), (id), (qt))
 
 #define SMB_VFS_SET_QUOTA(conn, qtype, id, qt) \
 	smb_vfs_call_set_quota((conn)->vfs_handles, (qtype), (id), (qt))
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index cf3bb94..cfb02cb 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -56,17 +56,30 @@ static uint64_t cap_disk_free(vfs_handle_struct *handle,
 			bsize, dfree, dsize);
 }
 
-static int cap_get_quota(vfs_handle_struct *handle, const char *path,
-			 enum SMB_QUOTA_TYPE qtype, unid_t id,
-			 SMB_DISK_QUOTA *dq)
+static int cap_get_quota(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			enum SMB_QUOTA_TYPE qtype,
+			unid_t id,
+			SMB_DISK_QUOTA *dq)
 {
-	char *cappath = capencode(talloc_tos(), path);
+	char *cappath = capencode(talloc_tos(), smb_fname->base_name);
+	struct smb_filename *cap_smb_fname = NULL;
 
 	if (!cappath) {
 		errno = ENOMEM;
 		return -1;
 	}
-	return SMB_VFS_NEXT_GET_QUOTA(handle, cappath, qtype, id, dq);
+	cap_smb_fname = synthetic_smb_fname(talloc_tos(),
+					cappath,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (cap_smb_fname == NULL) {
+		TALLOC_FREE(cappath);
+		errno = ENOMEM;
+		return -1;
+	}
+	return SMB_VFS_NEXT_GET_QUOTA(handle, cap_smb_fname, qtype, id, dq);
 }
 
 static DIR *cap_opendir(vfs_handle_struct *handle,
diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index 1244468..5f74404 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -201,8 +201,10 @@ static uint64_t cephwrap_disk_free(struct vfs_handle_struct *handle,
 }
 
 static int cephwrap_get_quota(struct vfs_handle_struct *handle,
-			      const char *path, enum SMB_QUOTA_TYPE qtype,
-			      unid_t id, SMB_DISK_QUOTA *qt)
+				const struct smb_filename *smb_fname,
+				enum SMB_QUOTA_TYPE qtype,
+				unid_t id,
+				SMB_DISK_QUOTA *qt)
 {
 	/* libceph: Ceph does not implement this */
 #if 0
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 1c26728..664da95 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -69,15 +69,17 @@ static uint64_t vfswrap_disk_free(vfs_handle_struct *handle,
 	return *dfree / 2;
 }
 
-static int vfswrap_get_quota(struct vfs_handle_struct *handle, const char *path,
-			     enum SMB_QUOTA_TYPE qtype, unid_t id,
-			     SMB_DISK_QUOTA *qt)
+static int vfswrap_get_quota(struct vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				enum SMB_QUOTA_TYPE qtype,
+				unid_t id,
+				SMB_DISK_QUOTA *qt)
 {
 #ifdef HAVE_SYS_QUOTAS
 	int result;
 
 	START_PROFILE(syscall_get_quota);
-	result = sys_get_quota(path, qtype, id, qt);
+	result = sys_get_quota(smb_fname->base_name, qtype, id, qt);
 	END_PROFILE(syscall_get_quota);
 	return result;
 #else
diff --git a/source3/modules/vfs_default_quota.c b/source3/modules/vfs_default_quota.c
index 6f1d2a7..c27681a 100644
--- a/source3/modules/vfs_default_quota.c
+++ b/source3/modules/vfs_default_quota.c
@@ -92,13 +92,16 @@
 #define DEFAULT_QUOTA_GID_NOLIMIT(handle) \
 	lp_parm_bool(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"gid nolimit",DEFAULT_QUOTA_GID_NOLIMIT_DEFAULT)
 
-static int default_quota_get_quota(vfs_handle_struct *handle, const char *path,
-				   enum SMB_QUOTA_TYPE qtype, unid_t id,
-				   SMB_DISK_QUOTA *dq)
+static int default_quota_get_quota(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				enum SMB_QUOTA_TYPE qtype,
+				unid_t id,
+				SMB_DISK_QUOTA *dq)
 {
 	int ret = -1;
 
-	if ((ret = SMB_VFS_NEXT_GET_QUOTA(handle, path, qtype, id, dq)) != 0) {
+	if ((ret = SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname,
+				qtype, id, dq)) != 0) {
 		return ret;
 	}
 
@@ -124,8 +127,8 @@ static int default_quota_get_quota(vfs_handle_struct *handle, const char *path,
 				unid_t qid;
 				uint32_t qflags = dq->qflags;
 				qid.uid = DEFAULT_QUOTA_UID(handle);
-				SMB_VFS_NEXT_GET_QUOTA(
-				    handle, path, SMB_USER_QUOTA_TYPE, qid, dq);
+				SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname,
+					SMB_USER_QUOTA_TYPE, qid, dq);
 				dq->qflags = qflags;
 			}
 			break;
@@ -135,7 +138,7 @@ static int default_quota_get_quota(vfs_handle_struct *handle, const char *path,
 				unid_t qid;
 				uint32_t qflags = dq->qflags;
 				qid.gid = DEFAULT_QUOTA_GID(handle);
-				SMB_VFS_NEXT_GET_QUOTA(handle, path,
+				SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname,
 						       SMB_GROUP_QUOTA_TYPE,
 						       qid, dq);
 				dq->qflags = qflags;
diff --git a/source3/modules/vfs_fake_dfq.c b/source3/modules/vfs_fake_dfq.c
index 5e8879f..971db68 100644
--- a/source3/modules/vfs_fake_dfq.c
+++ b/source3/modules/vfs_fake_dfq.c
@@ -27,9 +27,11 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
 
-static int dfq_get_quota(struct vfs_handle_struct *handle, const char *path,
-			 enum SMB_QUOTA_TYPE qtype, unid_t id,
-			 SMB_DISK_QUOTA *qt);
+static int dfq_get_quota(struct vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			enum SMB_QUOTA_TYPE qtype,
+			unid_t id,
+			SMB_DISK_QUOTA *qt);
 
 static uint64_t dfq_load_param(int snum, const char *path, const char *section,
 			       const char *param, uint64_t def_val)
@@ -88,9 +90,11 @@ static uint64_t dfq_disk_free(vfs_handle_struct *handle,
 	return free_1k;
 }
 
-static int dfq_get_quota(struct vfs_handle_struct *handle, const char *path,
-			 enum SMB_QUOTA_TYPE qtype, unid_t id,
-			 SMB_DISK_QUOTA *qt)
+static int dfq_get_quota(struct vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			enum SMB_QUOTA_TYPE qtype,
+			unid_t id,
+			SMB_DISK_QUOTA *qt)
 {
 	int rc = 0;
 	int save_errno;
@@ -99,7 +103,7 @@ static int dfq_get_quota(struct vfs_handle_struct *handle, const char *path,
 	uint64_t bsize = 0;
 	char *rpath = NULL;
 
-	rpath = SMB_VFS_NEXT_REALPATH(handle, path);
+	rpath = SMB_VFS_NEXT_REALPATH(handle, smb_fname->base_name);
 	if (rpath == NULL) {
 		goto dflt;
 	}
@@ -160,7 +164,7 @@ static int dfq_get_quota(struct vfs_handle_struct *handle, const char *path,
 	goto out;
 
 dflt:
-	rc = SMB_VFS_NEXT_GET_QUOTA(handle, path, qtype, id, qt);
+	rc = SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname, qtype, id, qt);
 
 out:
 	save_errno = errno;
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 9168257..01cea1a 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -693,14 +693,17 @@ static uint64_t smb_full_audit_disk_free(vfs_handle_struct *handle,
 }
 
 static int smb_full_audit_get_quota(struct vfs_handle_struct *handle,
-				    const char *path, enum SMB_QUOTA_TYPE qtype,
-				    unid_t id, SMB_DISK_QUOTA *qt)
+				const struct smb_filename *smb_fname,
+				enum SMB_QUOTA_TYPE qtype,
+				unid_t id,
+				SMB_DISK_QUOTA *qt)
 {
 	int result;
 
-	result = SMB_VFS_NEXT_GET_QUOTA(handle, path, qtype, id, qt);
+	result = SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname, qtype, id, qt);
 
-	do_log(SMB_VFS_OP_GET_QUOTA, (result >= 0), handle, "%s", path);
+	do_log(SMB_VFS_OP_GET_QUOTA, (result >= 0), handle, "%s",
+			smb_fname->base_name);
 
 	return result;
 }
diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index cabb861..3d28381 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -402,9 +402,10 @@ static uint64_t vfs_gluster_disk_free(struct vfs_handle_struct *handle,
 }
 
 static int vfs_gluster_get_quota(struct vfs_handle_struct *handle,
-				 const char *path,
-				 enum SMB_QUOTA_TYPE qtype, unid_t id,
-				 SMB_DISK_QUOTA *qt)
+				const struct smb_filename *smb_fname,
+				enum SMB_QUOTA_TYPE qtype,
+				unid_t id,
+				SMB_DISK_QUOTA *qt)
 {
 	errno = ENOSYS;
 	return -1;
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index 0f85951..9d99aea 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -2217,9 +2217,11 @@ static uint64_t vfs_gpfs_disk_free(vfs_handle_struct *handle,
 	return *dfree / 2;
 }
 
-static int vfs_gpfs_get_quota(vfs_handle_struct *handle, const char *path,
-			  enum SMB_QUOTA_TYPE qtype, unid_t id,
-			  SMB_DISK_QUOTA *dq)
+static int vfs_gpfs_get_quota(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				enum SMB_QUOTA_TYPE qtype,
+				unid_t id,
+				SMB_DISK_QUOTA *dq)
 {
 	switch(qtype) {
 		/*
@@ -2237,7 +2239,8 @@ static int vfs_gpfs_get_quota(vfs_handle_struct *handle, const char *path,
 			errno = ENOSYS;
 			return -1;
 		default:
-			return SMB_VFS_NEXT_GET_QUOTA(handle, path, qtype, id, dq);
+			return SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname,
+					qtype, id, dq);
 	}
 }
 
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index e1f3039..faacc45 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -2792,22 +2792,28 @@ static uint64_t shadow_copy2_disk_free(vfs_handle_struct *handle,
 	return ret;
 }
 
-static int shadow_copy2_get_quota(vfs_handle_struct *handle, const char *path,
-				  enum SMB_QUOTA_TYPE qtype, unid_t id,
-				  SMB_DISK_QUOTA *dq)
+static int shadow_copy2_get_quota(vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				enum SMB_QUOTA_TYPE qtype,
+				unid_t id,
+				SMB_DISK_QUOTA *dq)
 {
 	time_t timestamp = 0;
 	char *stripped = NULL;
 	int ret;
 	int saved_errno = 0;
 	char *conv;
+	struct smb_filename *conv_smb_fname = NULL;
 
-	if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, path, &timestamp,
-					 &stripped)) {
+	if (!shadow_copy2_strip_snapshot(talloc_tos(),
+				handle,
+				smb_fname->base_name,
+				&timestamp,
+				&stripped)) {
 		return -1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_GET_QUOTA(handle, path, qtype, id, dq);
+		return SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname, qtype, id, dq);
 	}
 
 	conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
@@ -2815,13 +2821,22 @@ static int shadow_copy2_get_quota(vfs_handle_struct *handle, const char *path,
 	if (conv == NULL) {
 		return -1;
 	}
-
-	ret = SMB_VFS_NEXT_GET_QUOTA(handle, conv, qtype, id, dq);
+	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+					conv,
+					NULL,
+					NULL,
+					smb_fname->flags);
+	if (conv_smb_fname == NULL) {
+		TALLOC_FREE(conv);
+		return -1;
+	}
+	ret = SMB_VFS_NEXT_GET_QUOTA(handle, conv_smb_fname, qtype, id, dq);
 
 	if (ret == -1) {
 		saved_errno = errno;
 	}
 	TALLOC_FREE(conv);
+	TALLOC_FREE(conv_smb_fname);
 	if (saved_errno != 0) {
 		errno = saved_errno;
 	}
diff --git a/source3/modules/vfs_snapper.c b/source3/modules/vfs_snapper.c
index dd7bb64..1da4112 100644
--- a/source3/modules/vfs_snapper.c
+++ b/source3/modules/vfs_snapper.c
@@ -3032,22 +3032,25 @@ static uint64_t snapper_gmt_disk_free(vfs_handle_struct *handle,
 	return ret;
 }
 
-static int snapper_gmt_get_quota(vfs_handle_struct *handle, const char *path,
-				 enum SMB_QUOTA_TYPE qtype, unid_t id,
-				 SMB_DISK_QUOTA *dq)
+static int snapper_gmt_get_quota(vfs_handle_struct *handle,
+			const struct smb_filename *smb_fname,
+			enum SMB_QUOTA_TYPE qtype,
+			unid_t id,
+			SMB_DISK_QUOTA *dq)
 {
-	time_t timestamp;
-	char *stripped;
+	time_t timestamp = 0;
+	char *stripped = NULL;
 	int ret;
-	int saved_errno;
-	char *conv;
+	int saved_errno = 0;
+	char *conv = NULL;
+	struct smb_filename *conv_smb_fname = NULL;
 
-	if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, path, &timestamp,
-					&stripped)) {
+	if (!snapper_gmt_strip_snapshot(talloc_tos(), handle,
+				smb_fname->base_name, &timestamp, &stripped)) {
 		return -1;
 	}
 	if (timestamp == 0) {
-		return SMB_VFS_NEXT_GET_QUOTA(handle, path, qtype, id, dq);
+		return SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname, qtype, id, dq);
 	}
 
 	conv = snapper_gmt_convert(talloc_tos(), handle, stripped, timestamp);
@@ -3055,13 +3058,26 @@ static int snapper_gmt_get_quota(vfs_handle_struct *handle, const char *path,
 	if (conv == NULL) {
 		return -1;
 	}
-
-	ret = SMB_VFS_NEXT_GET_QUOTA(handle, conv, qtype, id, dq);
-
-	saved_errno = errno;
+	conv_smb_fname = synthetic_smb_fname(talloc_tos(),
+					conv,
+					NULL,
+					NULL,
+					fname->flags);
 	TALLOC_FREE(conv);
-	errno = saved_errno;
+	if (conv_smb_fname == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
 
+	ret = SMB_VFS_NEXT_GET_QUOTA(handle, conv_smb_fname, qtype, id, dq);
+
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(conv_smb_fname);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 	return ret;
 }
 
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index 092474f..ebfcb8d 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -182,20 +182,24 @@ static uint64_t smb_time_audit_disk_free(vfs_handle_struct *handle,
 }
 
 static int smb_time_audit_get_quota(struct vfs_handle_struct *handle,
-				    const char *path, enum SMB_QUOTA_TYPE qtype,
-				    unid_t id, SMB_DISK_QUOTA *qt)
+					const struct smb_filename *smb_fname,
+					enum SMB_QUOTA_TYPE qtype,
+					unid_t id,
+					SMB_DISK_QUOTA *qt)
 {
 	int result;
 	struct timespec ts1,ts2;
 	double timediff;
 
 	clock_gettime_mono(&ts1);
-	result = SMB_VFS_NEXT_GET_QUOTA(handle, path, qtype, id, qt);
+	result = SMB_VFS_NEXT_GET_QUOTA(handle, smb_fname, qtype, id, qt);
 	clock_gettime_mono(&ts2);
 	timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
 	if (timediff > audit_timeout) {
-		smb_time_audit_log("get_quota", timediff);
+		smb_time_audit_log_fname("get_quota",
+				timediff,
+				smb_fname->base_name);
 	}
 	return result;
 }
diff --git a/source3/smbd/ntquotas.c b/source3/smbd/ntquotas.c
index 8a44f7c..7e2c036 100644
--- a/source3/smbd/ntquotas.c
+++ b/source3/smbd/ntquotas.c
@@ -74,6 +74,8 @@ NTSTATUS vfs_get_ntquota(files_struct *fsp, enum SMB_QUOTA_TYPE qtype,
 	int ret;
 	SMB_DISK_QUOTA D;
 	unid_t id;
+	struct smb_filename *smb_fname_cwd = NULL;
+	int saved_errno = 0;
 
 	ZERO_STRUCT(D);
 
@@ -91,7 +93,23 @@ NTSTATUS vfs_get_ntquota(files_struct *fsp, enum SMB_QUOTA_TYPE qtype,
 		return NT_STATUS_NO_SUCH_USER;
 	}
 
-	ret = SMB_VFS_GET_QUOTA(fsp->conn, ".", qtype, id, &D);
+	smb_fname_cwd = synthetic_smb_fname(talloc_tos(),
+				".",
+				NULL,
+				NULL,
+				0);
+	if (smb_fname_cwd == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	ret = SMB_VFS_GET_QUOTA(fsp->conn, smb_fname_cwd, qtype, id, &D);
+	if (ret == -1) {
+		saved_errno = errno;
+	}
+	TALLOC_FREE(smb_fname_cwd);
+	if (saved_errno != 0) {
+		errno = saved_errno;
+	}
 
 	if (psid)
 		qt->sid    = *psid;
diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c
index 2db18cd..2f18e36 100644
--- a/source3/smbd/quotas.c
+++ b/source3/smbd/quotas.c
@@ -494,7 +494,7 @@ bool disk_quotas(connection_struct *conn, struct smb_filename *fname,
 	 */
 	ZERO_STRUCT(D);
 	id.uid = -1;
-	r = SMB_VFS_GET_QUOTA(conn, fname->base_name, SMB_USER_FS_QUOTA_TYPE,
+	r = SMB_VFS_GET_QUOTA(conn, fname, SMB_USER_FS_QUOTA_TYPE,
 			      id, &D);
 	if (r == -1 && errno != ENOSYS) {
 		goto try_group_quota;
@@ -516,13 +516,13 @@ bool disk_quotas(connection_struct *conn, struct smb_filename *fname,
 
 		id.uid = fname->st.st_ex_uid;
 		become_root();
-		r = SMB_VFS_GET_QUOTA(conn, fname->base_name,
+		r = SMB_VFS_GET_QUOTA(conn, fname,
 				      SMB_USER_QUOTA_TYPE, id, &D);
 		save_errno = errno;
 		unbecome_root();
 		errno = save_errno;
 	} else {
-		r = SMB_VFS_GET_QUOTA(conn, fname->base_name,
+		r = SMB_VFS_GET_QUOTA(conn, fname,
 				      SMB_USER_QUOTA_TYPE, id, &D);
 	}
 
@@ -560,7 +560,7 @@ try_group_quota:
 	 */
 	ZERO_STRUCT(D);
 	id.gid = -1;
-	r = SMB_VFS_GET_QUOTA(conn, fname->base_name, SMB_GROUP_FS_QUOTA_TYPE,
+	r = SMB_VFS_GET_QUOTA(conn, fname, SMB_GROUP_FS_QUOTA_TYPE,
 			      id, &D);
 	if (r == -1 && errno != ENOSYS) {
 		return false;
@@ -572,7 +572,7 @@ try_group_quota:
 	id.gid = getegid();
 
 	ZERO_STRUCT(D);
-	r = SMB_VFS_GET_QUOTA(conn, fname->base_name, SMB_GROUP_QUOTA_TYPE, id,
+	r = SMB_VFS_GET_QUOTA(conn, fname, SMB_GROUP_QUOTA_TYPE, id,
 			      &D);
 
 	if (r == -1) {
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index f91e9e3..7177f88 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -1478,12 +1478,14 @@ uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
 			bsize, dfree, dsize);
 }
 
-int smb_vfs_call_get_quota(struct vfs_handle_struct *handle, const char *path,
-			   enum SMB_QUOTA_TYPE qtype, unid_t id,
-			   SMB_DISK_QUOTA *qt)
+int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
+				const struct smb_filename *smb_fname,
+				enum SMB_QUOTA_TYPE qtype,
+				unid_t id,
+				SMB_DISK_QUOTA *qt)
 {
 	VFS_FIND(get_quota);
-	return handle->fns->get_quota_fn(handle, path, qtype, id, qt);
+	return handle->fns->get_quota_fn(handle, smb_fname, qtype, id, qt);
 }
 
 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
-- 
2.7.4



More information about the samba-technical mailing list