[SCM] Samba Shared Repository - branch master updated

Christof Schmitt cs at samba.org
Tue Nov 19 22:45:02 UTC 2019


The branch, master has been updated
       via  7ae46019df1 vfs_gpfs: Use update_stat_ex_create_time
       via  f2339fe0dde vfs_gpfs: Create fileid from filesystem metadata
       via  ba5d4803bab vfs_gpfs: Use gpfs_fstat_x in vfs_gpfs_fget_dos_attributes
       via  2c3436f05d7 vfs_gpfs: Use gpfs_stat_x in vfs_gpfs_get_dos_attributes
       via  586ffd5b601 gpfswrap: Add wrappers for gpfs_fstat_x and gpfs_stat_x
      from  b68b7d51681 vfs: Fix CID 1455914 Unused value

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 7ae46019df1c5369cfd15f99448b94e425eddcc4
Author: Christof Schmitt <cs at samba.org>
Date:   Wed Sep 18 15:41:13 2019 -0700

    vfs_gpfs: Use update_stat_ex_create_time
    
    Make the code a bit easier to read by avoiding direct access to the
    statex struct.
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Christof Schmitt <cs at samba.org>
    Autobuild-Date(master): Tue Nov 19 22:44:53 UTC 2019 on sn-devel-184

commit f2339fe0dde2daedfab07d51709d7584c7f00e60
Author: Christof Schmitt <cs at samba.org>
Date:   Mon Aug 19 16:23:11 2019 -0700

    vfs_gpfs: Create fileid from filesystem metadata
    
    MacOS SMB clients require that file ids are not quickly reused when
    files are deleted and new files are created with the same name. Inode
    numbers do not satisfy that requirement, as they will be quickly reused.
    
    To address this problem, create a unique id from the available file
    system specific metadata. As that id is larger than the available 64bit,
    use a hash to generate a 64bit id for usage as fileid.
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit ba5d4803bab3f8fd980a5776f375b4e57b82cc85
Author: Christof Schmitt <cs at samba.org>
Date:   Mon Aug 19 16:06:57 2019 -0700

    vfs_gpfs: Use gpfs_fstat_x in vfs_gpfs_fget_dos_attributes
    
    This is no functional change, but allows to use additional metadata
    later on.
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 2c3436f05d7f728d5993e9ac9f3de18518647a8a
Author: Christof Schmitt <cs at samba.org>
Date:   Mon Aug 19 15:41:45 2019 -0700

    vfs_gpfs: Use gpfs_stat_x in vfs_gpfs_get_dos_attributes
    
    This is no functional change, but allows to use additional metadata
    later on.
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 586ffd5b6010b833b4d5b743f69b1629c36b6e7d
Author: Christof Schmitt <cs at samba.org>
Date:   Mon Aug 19 15:35:18 2019 -0700

    gpfswrap: Add wrappers for gpfs_fstat_x and gpfs_stat_x
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/util/gpfswrap.c        |  28 +++++++++++++
 lib/util/gpfswrap.h        |   4 ++
 source3/modules/vfs_gpfs.c | 100 +++++++++++++++++++++++++++++++++++++--------
 3 files changed, 116 insertions(+), 16 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/util/gpfswrap.c b/lib/util/gpfswrap.c
index 32be942bc7c..7bc2ec06c15 100644
--- a/lib/util/gpfswrap.c
+++ b/lib/util/gpfswrap.c
@@ -44,6 +44,10 @@ static int (*gpfs_init_trace_fn)(void);
 static int (*gpfs_query_trace_fn)(void);
 static void (*gpfs_add_trace_fn)(int level, const char *msg);
 static void (*gpfs_fini_trace_fn)(void);
+static int (*gpfs_fstat_x_fn)(int fd, unsigned int *litemask,
+			      struct gpfs_iattr64 *iattr, size_t len);
+static int (*gpfs_stat_x_fn)(const char *pathname, unsigned int *litemask,
+			     struct gpfs_iattr64 *iattr, size_t len);
 
 int gpfswrap_init(void)
 {
@@ -76,6 +80,8 @@ int gpfswrap_init(void)
 	gpfs_query_trace_fn	      = dlsym(l, "gpfs_query_trace");
 	gpfs_add_trace_fn	      = dlsym(l, "gpfs_add_trace");
 	gpfs_fini_trace_fn	      = dlsym(l, "gpfs_fini_trace");
+	gpfs_fstat_x_fn	      = dlsym(l, "gpfs_fstat_x");
+	gpfs_stat_x_fn		      = dlsym(l, "gpfs_stat_x");
 
 	return 0;
 }
@@ -259,3 +265,25 @@ void gpfswrap_fini_trace(void)
 
 	gpfs_fini_trace_fn();
 }
+
+int gpfswrap_fstat_x(int fd, unsigned int *litemask,
+		     struct gpfs_iattr64 *iattr, size_t len)
+{
+	if (gpfs_fstat_x_fn == NULL) {
+		errno = ENOSYS;
+		return -1;
+	}
+
+	return gpfs_fstat_x_fn(fd, litemask, iattr, len);
+}
+
+int gpfswrap_stat_x(const char *pathname, unsigned int *litemask,
+		    struct gpfs_iattr64 *iattr, size_t len)
+{
+	if (gpfs_stat_x_fn == NULL) {
+		errno = ENOSYS;
+		return -1;
+	}
+
+	return gpfs_stat_x_fn(pathname, litemask, iattr, len);
+}
diff --git a/lib/util/gpfswrap.h b/lib/util/gpfswrap.h
index 40202104064..3141360a584 100644
--- a/lib/util/gpfswrap.h
+++ b/lib/util/gpfswrap.h
@@ -47,5 +47,9 @@ int gpfswrap_init_trace(void);
 int gpfswrap_query_trace(void);
 void gpfswrap_add_trace(int level, const char *msg);
 void gpfswrap_fini_trace(void);
+int gpfswrap_fstat_x(int fd, unsigned int *litemask,
+		     struct gpfs_iattr64 *iattr, size_t len);
+int gpfswrap_stat_x(const char *pathname, unsigned int *litemask,
+		    struct gpfs_iattr64 *iattr, size_t len);
 
 #endif
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index b17a0fdd6c6..558f57c2417 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -31,6 +31,10 @@
 #include "lib/util/tevent_unix.h"
 #include "lib/util/gpfswrap.h"
 
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+#include "lib/crypto/gnutls_helpers.h"
+
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
 
@@ -1567,7 +1571,8 @@ static unsigned int vfs_gpfs_dosmode_to_winattrs(uint32_t dosmode)
 }
 
 static int get_dos_attr_with_capability(struct smb_filename *smb_fname,
-					struct gpfs_winattr *attr)
+					unsigned int *litemask,
+					struct gpfs_iattr64 *iattr)
 {
 	int saved_errno = 0;
 	int ret;
@@ -1594,7 +1599,8 @@ static int get_dos_attr_with_capability(struct smb_filename *smb_fname,
 
 	set_effective_capability(DAC_OVERRIDE_CAPABILITY);
 
-	ret = gpfswrap_get_winattrs_path(smb_fname->base_name, attr);
+	ret = gpfswrap_stat_x(smb_fname->base_name, litemask,
+			      iattr, sizeof(*iattr));
 	if (ret == -1) {
 		saved_errno = errno;
 	}
@@ -1607,12 +1613,55 @@ static int get_dos_attr_with_capability(struct smb_filename *smb_fname,
 	return ret;
 }
 
+static NTSTATUS vfs_gpfs_get_file_id(struct gpfs_iattr64 *iattr,
+				     uint64_t *fileid)
+{
+	uint8_t input[sizeof(gpfs_ino64_t) +
+		      sizeof(gpfs_gen64_t) +
+		      sizeof(gpfs_snapid64_t)];
+	uint8_t digest[gnutls_hash_get_len(GNUTLS_DIG_SHA1)];
+	int rc;
+
+	DBG_DEBUG("ia_inode 0x%llx, ia_gen 0x%llx, ia_modsnapid 0x%llx\n",
+		  iattr->ia_inode, iattr->ia_gen, iattr->ia_modsnapid);
+
+	SBVAL(input,
+	      0, iattr->ia_inode);
+	SBVAL(input,
+	      sizeof(gpfs_ino64_t), iattr->ia_gen);
+	SBVAL(input,
+	      sizeof(gpfs_ino64_t) + sizeof(gpfs_gen64_t), iattr->ia_modsnapid);
+
+	GNUTLS_FIPS140_SET_LAX_MODE();
+	rc = gnutls_hash_fast(GNUTLS_DIG_SHA1, input, sizeof(input), &digest);
+	GNUTLS_FIPS140_SET_STRICT_MODE();
+
+	if (rc != 0) {
+		return gnutls_error_to_ntstatus(rc,
+						NT_STATUS_HASH_NOT_SUPPORTED);
+	}
+
+	memcpy(fileid, &digest, sizeof(*fileid));
+	DBG_DEBUG("file_id 0x%" PRIx64 "\n", *fileid);
+
+	return NT_STATUS_OK;
+}
+
+static struct timespec gpfs_timestruc64_to_timespec(struct gpfs_timestruc64 g)
+{
+	return (struct timespec) { .tv_sec = g.tv_sec, .tv_nsec = g.tv_nsec };
+}
+
 static NTSTATUS vfs_gpfs_get_dos_attributes(struct vfs_handle_struct *handle,
 					    struct smb_filename *smb_fname,
 					    uint32_t *dosmode)
 {
 	struct gpfs_config_data *config;
-	struct gpfs_winattr attrs = { };
+	struct gpfs_iattr64 iattr = { };
+	unsigned int litemask = 0;
+	struct timespec ts;
+	uint64_t file_id;
+	NTSTATUS status;
 	int ret;
 
 	SMB_VFS_HANDLE_GET_DATA(handle, config,
@@ -1624,13 +1673,15 @@ static NTSTATUS vfs_gpfs_get_dos_attributes(struct vfs_handle_struct *handle,
 						       smb_fname, dosmode);
 	}
 
-	ret = gpfswrap_get_winattrs_path(smb_fname->base_name, &attrs);
+	ret = gpfswrap_stat_x(smb_fname->base_name, &litemask,
+			      &iattr, sizeof(iattr));
 	if (ret == -1 && errno == ENOSYS) {
 		return SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle, smb_fname,
 						       dosmode);
 	}
 	if (ret == -1 && errno == EACCES) {
-		ret = get_dos_attr_with_capability(smb_fname, &attrs);
+		ret = get_dos_attr_with_capability(smb_fname, &litemask,
+						   &iattr);
 	}
 
 	if (ret == -1 && errno == EBADF) {
@@ -1647,10 +1698,16 @@ static NTSTATUS vfs_gpfs_get_dos_attributes(struct vfs_handle_struct *handle,
 		return map_nt_error_from_unix(errno);
 	}
 
-	*dosmode |= vfs_gpfs_winattrs_to_dosmode(attrs.winAttrs);
-	smb_fname->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_BTIME;
-	smb_fname->st.st_ex_btime.tv_sec = attrs.creationTime.tv_sec;
-	smb_fname->st.st_ex_btime.tv_nsec = attrs.creationTime.tv_nsec;
+	status = vfs_gpfs_get_file_id(&iattr, &file_id);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	ts = gpfs_timestruc64_to_timespec(iattr.ia_createtime);
+
+	*dosmode |= vfs_gpfs_winattrs_to_dosmode(iattr.ia_winflags);
+	update_stat_ex_create_time(&smb_fname->st, ts);
+	update_stat_ex_file_id(&smb_fname->st, file_id);
 
 	return NT_STATUS_OK;
 }
@@ -1660,7 +1717,11 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle,
 					     uint32_t *dosmode)
 {
 	struct gpfs_config_data *config;
-	struct gpfs_winattr attrs = { };
+	struct gpfs_iattr64 iattr = { };
+	unsigned int litemask;
+	struct timespec ts;
+	uint64_t file_id;
+	NTSTATUS status;
 	int ret;
 
 	SMB_VFS_HANDLE_GET_DATA(handle, config,
@@ -1671,7 +1732,7 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle,
 		return SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
 	}
 
-	ret = gpfswrap_get_winattrs(fsp->fh->fd, &attrs);
+	ret = gpfswrap_fstat_x(fsp->fh->fd, &litemask, &iattr, sizeof(iattr));
 	if (ret == -1 && errno == ENOSYS) {
 		return SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
 	}
@@ -1688,7 +1749,8 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle,
 
 		set_effective_capability(DAC_OVERRIDE_CAPABILITY);
 
-		ret = gpfswrap_get_winattrs(fsp->fh->fd, &attrs);
+		ret = gpfswrap_fstat_x(fsp->fh->fd, &litemask,
+				       &iattr, sizeof(iattr));
 		if (ret == -1) {
 			saved_errno = errno;
 		}
@@ -1706,10 +1768,16 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle,
 		return map_nt_error_from_unix(errno);
 	}
 
-	*dosmode |= vfs_gpfs_winattrs_to_dosmode(attrs.winAttrs);
-	fsp->fsp_name->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_BTIME;
-	fsp->fsp_name->st.st_ex_btime.tv_sec = attrs.creationTime.tv_sec;
-	fsp->fsp_name->st.st_ex_btime.tv_nsec = attrs.creationTime.tv_nsec;
+	status = vfs_gpfs_get_file_id(&iattr, &file_id);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	ts = gpfs_timestruc64_to_timespec(iattr.ia_createtime);
+
+	*dosmode |= vfs_gpfs_winattrs_to_dosmode(iattr.ia_winflags);
+	update_stat_ex_create_time(&fsp->fsp_name->st, ts);
+	update_stat_ex_file_id(&fsp->fsp_name->st, file_id);
 
 	return NT_STATUS_OK;
 }


-- 
Samba Shared Repository



More information about the samba-cvs mailing list