[SCM] Samba Shared Repository - branch master updated

Günther Deschner gd at samba.org
Sat Jul 13 22:55:01 UTC 2019


The branch, master has been updated
       via  5522aa1a4c3 vfs:glusterfs_fuse: ensure fileids are constant across nodes
      from  36b48aa7837 s3:net: add 'net vfs getntacl' command

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


- Log -----------------------------------------------------------------
commit 5522aa1a4c34ee1a1e81db73cf41594bb10bd989
Author: Michael Adam <obnox at samba.org>
Date:   Sat May 18 11:28:54 2019 +0200

    vfs:glusterfs_fuse: ensure fileids are constant across nodes
    
    Instead of adding a new gluster-specific mode to the fileid module,
    this patches provides a fileid algorithm as part of the glusterfs_fuse
    vfs module. This can not be configured further, simply adding the
    glusterfs_fuse vfs module to the vfs objects configuration will enable
    the new fileid mode.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13972
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Signed-off-by: Guenther Deschner <gd at samba.org>
    
    Autobuild-User(master): Günther Deschner <gd at samba.org>
    Autobuild-Date(master): Sat Jul 13 22:54:56 UTC 2019 on sn-devel-184

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

Summary of changes:
 docs-xml/manpages/vfs_glusterfs_fuse.8.xml |   8 ++
 source3/modules/vfs_glusterfs_fuse.c       | 193 ++++++++++++++++++++++++++++-
 2 files changed, 200 insertions(+), 1 deletion(-)


Changeset truncated at 500 lines:

diff --git a/docs-xml/manpages/vfs_glusterfs_fuse.8.xml b/docs-xml/manpages/vfs_glusterfs_fuse.8.xml
index b9f7f42c6f2..f2aa624353e 100644
--- a/docs-xml/manpages/vfs_glusterfs_fuse.8.xml
+++ b/docs-xml/manpages/vfs_glusterfs_fuse.8.xml
@@ -48,6 +48,14 @@
 		case of an exisiting filename.
 	</para>
 
+	<para>
+		Furthermore, this module implements a substitute file-id
+		mechanism. The default file-id mechanism is not working
+		correctly for gluster fuse mount re-exports, so in order to
+		avoid data loss, users exporting gluster fuse mounts with
+		Samba should enable this module.
+	</para>
+
 	<para>
 		This module can be combined with other modules, but it
 		should be the last module in the <command>vfs objects</command>
diff --git a/source3/modules/vfs_glusterfs_fuse.c b/source3/modules/vfs_glusterfs_fuse.c
index 51515aa0df4..c621f9abf8e 100644
--- a/source3/modules/vfs_glusterfs_fuse.c
+++ b/source3/modules/vfs_glusterfs_fuse.c
@@ -59,10 +59,201 @@ static int vfs_gluster_fuse_get_real_filename(struct vfs_handle_struct *handle,
 	return 0;
 }
 
+struct device_mapping_entry {
+	SMB_DEV_T device;       /* the local device, for reference */
+	uint64_t mapped_device; /* the mapped device */
+};
+
+struct vfs_glusterfs_fuse_handle_data {
+	unsigned num_mapped_devices;
+	struct device_mapping_entry *mapped_devices;
+};
+
+/* a 64 bit hash, based on the one in tdb, copied from vfs_fileied */
+static uint64_t vfs_glusterfs_fuse_uint64_hash(const uint8_t *s, size_t len)
+{
+	uint64_t value; /* Used to compute the hash value.  */
+	uint32_t i;     /* Used to cycle through random values. */
+
+	/* Set the initial value from the key size. */
+	for (value = 0x238F13AFLL * len, i=0; i < len; i++)
+		value = (value + (((uint64_t)s[i]) << (i*5 % 24)));
+
+	return (1103515243LL * value + 12345LL);
+}
+
+static void vfs_glusterfs_fuse_load_devices(
+		struct vfs_glusterfs_fuse_handle_data *data)
+{
+	FILE *f;
+	struct mntent *m;
+
+	data->num_mapped_devices = 0;
+	TALLOC_FREE(data->mapped_devices);
+
+	f = setmntent("/etc/mtab", "r");
+	if (!f) {
+		return;
+	}
+
+	while ((m = getmntent(f))) {
+		struct stat st;
+		char *p;
+		uint64_t mapped_device;
+
+		if (stat(m->mnt_dir, &st) != 0) {
+			/* TODO: log? */
+			continue;
+		}
+
+		/* strip the host part off of the fsname */
+		p = strrchr(m->mnt_fsname, ':');
+		if (p == NULL) {
+			p = m->mnt_fsname;
+		} else {
+			/* TODO: consider the case of '' ? */
+			p++;
+		}
+
+		mapped_device = vfs_glusterfs_fuse_uint64_hash(
+						(const uint8_t *)p,
+						strlen(p));
+
+		data->mapped_devices = talloc_realloc(data,
+						data->mapped_devices,
+						struct device_mapping_entry,
+						data->num_mapped_devices + 1);
+		if (data->mapped_devices == NULL) {
+			goto nomem;
+		}
+
+		data->mapped_devices[data->num_mapped_devices].device =
+								st.st_dev;
+		data->mapped_devices[data->num_mapped_devices].mapped_device =
+								mapped_device;
+
+		data->num_mapped_devices++;
+	}
+
+	endmntent(f);
+	return;
+
+nomem:
+	data->num_mapped_devices = 0;
+	TALLOC_FREE(data->mapped_devices);
+
+	endmntent(f);
+	return;
+}
+
+static int vfs_glusterfs_fuse_map_device_cached(
+				struct vfs_glusterfs_fuse_handle_data *data,
+				SMB_DEV_T device,
+				uint64_t *mapped_device)
+{
+	unsigned i;
+
+	for (i = 0; i < data->num_mapped_devices; i++) {
+		if (data->mapped_devices[i].device == device) {
+			*mapped_device = data->mapped_devices[i].mapped_device;
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
+static int vfs_glusterfs_fuse_map_device(
+				struct vfs_glusterfs_fuse_handle_data *data,
+				SMB_DEV_T device,
+				uint64_t *mapped_device)
+{
+	int ret;
+
+	ret = vfs_glusterfs_fuse_map_device_cached(data, device, mapped_device);
+	if (ret == 0) {
+		return 0;
+	}
+
+	vfs_glusterfs_fuse_load_devices(data);
+
+	ret = vfs_glusterfs_fuse_map_device_cached(data, device, mapped_device);
+
+	return ret;
+}
+
+static struct file_id vfs_glusterfs_fuse_file_id_create(
+			struct vfs_handle_struct *handle,
+			const SMB_STRUCT_STAT *sbuf)
+{
+	struct vfs_glusterfs_fuse_handle_data *data;
+	struct file_id id;
+	uint64_t mapped_device;
+	int ret;
+
+	ZERO_STRUCT(id);
+
+	id = SMB_VFS_NEXT_FILE_ID_CREATE(handle, sbuf);
+
+	SMB_VFS_HANDLE_GET_DATA(handle, data,
+				struct vfs_glusterfs_fuse_handle_data,
+				return id);
+
+	ret = vfs_glusterfs_fuse_map_device(data, sbuf->st_ex_dev,
+					    &mapped_device);
+	if (ret == 0) {
+		id.devid = mapped_device;
+	} else {
+		DBG_WARNING("Failed to map device [%jx], falling back to "
+			    "standard file_id [%jx]",
+			    (uintmax_t)sbuf->st_ex_dev,
+			    (uintmax_t)id.devid);
+	}
+
+	DBG_DEBUG("Returning dev [%jx] inode [%jx]\n",
+		  (uintmax_t)id.devid, (uintmax_t)id.inode);
+
+	return id;
+}
+
+static int vfs_glusterfs_fuse_connect(struct vfs_handle_struct *handle,
+				      const char *service, const char *user)
+{
+	struct vfs_glusterfs_fuse_handle_data *data;
+	int ret = SMB_VFS_NEXT_CONNECT(handle, service, user);
+
+	if (ret < 0) {
+		return ret;
+	}
+
+	data = talloc_zero(handle->conn, struct vfs_glusterfs_fuse_handle_data);
+	if (data == NULL) {
+		DBG_ERR("talloc_zero() failed.\n");
+		SMB_VFS_NEXT_DISCONNECT(handle);
+		return -1;
+	}
+
+	/*
+	 * Fill the cache in the tree connect, so that the first file/dir access
+	 * has chances of being fast...
+	 */
+	vfs_glusterfs_fuse_load_devices(data);
+
+	SMB_VFS_HANDLE_SET_DATA(handle, data, NULL,
+				struct vfs_glusterfs_fuse_handle_data,
+				return -1);
+
+	DBG_DEBUG("vfs_glusterfs_fuse_connect(): connected to service[%s]\n",
+		  service);
+
+	return 0;
+}
+
 struct vfs_fn_pointers glusterfs_fuse_fns = {
 
-	/* File Operations */
+	.connect_fn = vfs_glusterfs_fuse_connect,
 	.get_real_filename_fn = vfs_gluster_fuse_get_real_filename,
+	.file_id_create_fn = vfs_glusterfs_fuse_file_id_create,
 };
 
 static_decl_vfs;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list