]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
vfs_shadow_copy2: Use VFS interface to derive mount point
authorAnoop C S <anoopcs@samba.org>
Thu, 6 Feb 2025 12:20:10 +0000 (17:50 +0530)
committerJule Anger <janger@samba.org>
Mon, 10 Mar 2025 09:46:55 +0000 (09:46 +0000)
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 <anoopcs@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
Reviewed-by: John Mulligan <jmulligan@samba.org>
Autobuild-User(master): Anoop C S <anoopcs@samba.org>
Autobuild-Date(master): Fri Feb  7 06:23:12 UTC 2025 on atb-devel-224

(cherry picked from commit c7d0adade09fa264201a125b28dd76c163451260)

Autobuild-User(v4-20-test): Jule Anger <janger@samba.org>
Autobuild-Date(v4-20-test): Mon Mar 10 09:46:55 UTC 2025 on atb-devel-224

source3/modules/vfs_shadow_copy2.c

index 309be6e293eb9d708594a0926cf9f064ee721495..74d60f2da6f25f3f5121c2ed3471e95bfa4cd7ff 100644 (file)
@@ -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;
 }
 
 /**