From: Anoop C S Date: Thu, 6 Feb 2025 12:20:10 +0000 (+0530) Subject: vfs_shadow_copy2: Use VFS interface to derive mount point X-Git-Tag: tevent-0.17.0~858 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7d0adade09fa264201a125b28dd76c163451260;p=thirdparty%2Fsamba.git vfs_shadow_copy2: Use VFS interface to derive mount point shadow_copy2_find_mount_point() does direct stat() calls locally while trying to automatically detect the mount point. This cannot be always true as there are virtual file systems like CephFS, GlusterFS etc. without their share path locally available on the system. Instead use the VFS interface to make the stat calls hit the underlying file system irrespective of their local presence in the system. BUG: https://bugzilla.samba.org/show_bug.cgi?id=15797 Signed-off-by: Anoop C S Reviewed-by: Ralph Boehme Reviewed-by: John Mulligan Autobuild-User(master): Anoop C S Autobuild-Date(master): Fri Feb 7 06:23:12 UTC 2025 on atb-devel-224 --- diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 8db3e664f19..42626653e0f 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -726,31 +726,42 @@ static bool _shadow_copy2_strip_snapshot_converted(TALLOC_CTX *mem_ctx, static char *shadow_copy2_find_mount_point(TALLOC_CTX *mem_ctx, vfs_handle_struct *handle) { - char *path = talloc_strdup(mem_ctx, handle->conn->connectpath); + struct smb_filename *smb_fname_cpath = NULL; dev_t dev; - struct stat st; char *p; - if (stat(path, &st) != 0) { - talloc_free(path); + smb_fname_cpath = synthetic_smb_fname(mem_ctx, + handle->conn->connectpath, + NULL, + NULL, + 0, + 0); + if (smb_fname_cpath == NULL) { + errno = ENOMEM; + return NULL; + } + + if (SMB_VFS_NEXT_STAT(handle, smb_fname_cpath) != 0) { + TALLOC_FREE(smb_fname_cpath); return NULL; } - dev = st.st_dev; + dev = smb_fname_cpath->st.st_ex_dev; - while ((p = strrchr(path, '/')) && p > path) { + while ((p = strrchr(smb_fname_cpath->base_name, '/')) && + p > smb_fname_cpath->base_name) { *p = 0; - if (stat(path, &st) != 0) { - talloc_free(path); + if (SMB_VFS_NEXT_STAT(handle, smb_fname_cpath) != 0) { + TALLOC_FREE(smb_fname_cpath); return NULL; } - if (st.st_dev != dev) { + if (smb_fname_cpath->st.st_ex_dev != dev) { *p = '/'; break; } } - return path; + return smb_fname_cpath->base_name; } /**