From debf8ba799ea7a4535e29c20a5f9377932c81938 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 4 Jan 2018 17:22:16 +0100 Subject: [PATCH] vfs_fileid: add fileid:algorithm = fsname_norootdir Based-on-a-patch-by: Ralph Wuerthner Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Sat Jan 6 04:41:24 CET 2018 on sn-devel-144 --- docs-xml/manpages/vfs_fileid.8.xml | 6 ++++ source3/modules/vfs_fileid.c | 45 ++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/docs-xml/manpages/vfs_fileid.8.xml b/docs-xml/manpages/vfs_fileid.8.xml index 78f054aa0e5..edfdef20712 100644 --- a/docs-xml/manpages/vfs_fileid.8.xml +++ b/docs-xml/manpages/vfs_fileid.8.xml @@ -81,6 +81,12 @@ id by hashing the hostname. This can be used to deliberately break lock coherency in a cluster. + The fsname_norootdir algorithm + generates device ids by hashing the kernel device name, except + for the root directory of shares where it will use the hostname + algorithm. This can be used to deliberately break lock coherency + in a cluster for the root directory of a share. + diff --git a/source3/modules/vfs_fileid.c b/source3/modules/vfs_fileid.c index bac8ff08731..98cc32d62d5 100644 --- a/source3/modules/vfs_fileid.c +++ b/source3/modules/vfs_fileid.c @@ -278,6 +278,33 @@ static uint64_t fileid_device_mapping_fsid(struct fileid_handle_data *data, return m->devid; } +static int get_connectpath_ino(struct vfs_handle_struct *handle, + ino_t *ino) +{ + struct smb_filename *fname = NULL; + int ret; + + fname = synthetic_smb_fname(talloc_tos(), + handle->conn->connectpath, + NULL, + NULL, + 0); + if (fname == NULL) { + DBG_ERR("synthetic_smb_fname failed\n"); + return -1; + } + + ret = SMB_VFS_NEXT_STAT(handle, fname); + TALLOC_FREE(fname); + if (ret != 0) { + DBG_ERR("stat failed for %s with %s\n", + handle->conn->connectpath, strerror(errno)); + return -1; + } + + return 0; +} + static int fileid_connect(struct vfs_handle_struct *handle, const char *service, const char *user) { @@ -303,6 +330,8 @@ static int fileid_connect(struct vfs_handle_struct *handle, return -1; } + data->nolockinode = 0; + /* * "fileid:mapping" is only here as fallback for old setups * "fileid:algorithm" is the option new setups should use @@ -321,6 +350,16 @@ static int fileid_connect(struct vfs_handle_struct *handle, data->device_mapping_fn = fileid_device_mapping_fsid; } else if (strcmp("hostname", algorithm) == 0) { data->device_mapping_fn = fileid_device_mapping_hostname; + } else if (strcmp("fsname_norootdir", algorithm) == 0) { + data->device_mapping_fn = fileid_device_mapping_fsname; + + ret = get_connectpath_ino(handle, &data->nolockinode); + if (ret != 0) { + saved_errno = errno; + SMB_VFS_NEXT_DISCONNECT(handle); + errno = saved_errno; + return -1; + } } else { SMB_VFS_NEXT_DISCONNECT(handle); DEBUG(0,("fileid_connect(): unknown algorithm[%s]\n", algorithm)); @@ -380,14 +419,14 @@ static int fileid_connect(struct vfs_handle_struct *handle, } data->nolockinode = lp_parm_ulong(SNUM(handle->conn), "fileid", - "nolockinode", 0); + "nolockinode", data->nolockinode); SMB_VFS_HANDLE_SET_DATA(handle, data, NULL, struct fileid_handle_data, return -1); - DEBUG(10, ("fileid_connect(): connect to service[%s] with algorithm[%s]\n", - service, algorithm)); + DBG_DEBUG("connect to service[%s] with algorithm[%s] nolockinode %lli\n", + service, algorithm, (long long) data->nolockinode); return 0; }