]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
vfs_ceph_new: Do not resolve by inode number
authorAnoop C S <anoopcs@samba.org>
Tue, 25 Feb 2025 12:10:13 +0000 (17:40 +0530)
committerJule Anger <janger@samba.org>
Thu, 13 Mar 2025 17:06:25 +0000 (17:06 +0000)
CephFS snapshots within snap directory shares the same inode number from
its parent. Until unless we resolve by name we may incorrectly point at
an inode which is not a snapshot directory. Therefore to be functionally
correct we avoid resolving by inode number but proper name.

For example:

path (ino = 3)
  |
  --- dir (ino = 4)
  |
  --- .snap (ino = 3)
        |
        --- snap1 (ino = 3)
              |
              --- dir (ino = 4)

In this case an attempt to resolve 'snap1' by inode number 3 results in
pointing at 'path' which is not the desired outcome.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15818

Signed-off-by: Anoop C S <anoopcs@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
Autobuild-User(master): Günther Deschner <gd@samba.org>
Autobuild-Date(master): Fri Mar  7 18:20:47 UTC 2025 on atb-devel-224

(cherry picked from commit a96f0542c8317a7dd0470b32350de6893fd98723)

Autobuild-User(v4-22-test): Jule Anger <janger@samba.org>
Autobuild-Date(v4-22-test): Thu Mar 13 17:06:25 UTC 2025 on atb-devel-224

source3/modules/vfs_ceph_new.c

index 8f84a83ed02a38e5e1247a1413d95cca0e5e302b..05c2a72d57f8ec7791c6fa446d11c642dbb4bb06 100644 (file)
@@ -113,7 +113,6 @@ struct vfs_ceph_config {
        enum vfs_cephfs_proxy_mode proxy;
        void *libhandle;
 
-       CEPH_FN(ceph_ll_lookup_inode);
        CEPH_FN(ceph_ll_walk);
        CEPH_FN(ceph_ll_getattr);
        CEPH_FN(ceph_ll_setattr);
@@ -395,7 +394,6 @@ static bool vfs_cephfs_load_lib(struct vfs_ceph_config *config)
                break;
        }
 
-       CHECK_CEPH_FN(libhandle, ceph_ll_lookup_inode);
        CHECK_CEPH_FN(libhandle, ceph_ll_walk);
        CHECK_CEPH_FN(libhandle, ceph_ll_getattr);
        CHECK_CEPH_FN(libhandle, ceph_ll_setattr);
@@ -797,21 +795,6 @@ static void vfs_ceph_assign_fh_fd(struct vfs_ceph_fh *cfh)
 
 /* Ceph low-level wrappers */
 
-static int vfs_ceph_ll_lookup_inode(const struct vfs_handle_struct *handle,
-                                   uint64_t inoval,
-                                   Inode **pout)
-{
-       struct inodeno_t ino = {.val = inoval};
-       struct vfs_ceph_config *config = NULL;
-
-       SMB_VFS_HANDLE_GET_DATA(handle, config, struct vfs_ceph_config,
-                               return -ENOMEM);
-
-       DBG_DEBUG("[CEPH] ceph_ll_lookup_inode: ino=%" PRIu64 "\n", inoval);
-
-       return config->ceph_ll_lookup_inode_fn(config->mount, ino, pout);
-}
-
 static int vfs_ceph_ll_walk(const struct vfs_handle_struct *handle,
                            const char *name,
                            struct Inode **pin,
@@ -1841,60 +1824,30 @@ static int64_t vfs_ceph_ll_nonblocking_readv_writev(
 
 /* Ceph Inode-refernce get/put wrappers */
 static int vfs_ceph_iget(const struct vfs_handle_struct *handle,
-                        uint64_t ino,
                         const char *name,
                         unsigned int flags,
                         struct vfs_ceph_iref *iref)
 {
        struct Inode *inode = NULL;
        int ret = -1;
+       struct ceph_statx stx = {.stx_ino = 0};
 
-       if (ino > CEPH_INO_ROOT) {
-               /* get-by-ino */
-               ret = vfs_ceph_ll_lookup_inode(handle, ino, &inode);
-               if (ret != 0) {
-                       return ret;
-               }
-       } else {
-               /* get-by-path */
-               struct ceph_statx stx = {.stx_ino = 0};
-
-               ret = vfs_ceph_ll_walk(handle,
-                                      name,
-                                      &inode,
-                                      &stx,
-                                      CEPH_STATX_INO,
-                                      flags);
-               if (ret != 0) {
-                       return ret;
-               }
-               ino = stx.stx_ino;
+       ret = vfs_ceph_ll_walk(handle,
+                              name,
+                              &inode,
+                              &stx,
+                              CEPH_STATX_INO,
+                              flags);
+       if (ret != 0) {
+               return ret;
        }
        iref->inode = inode;
-       iref->ino = ino;
+       iref->ino = stx.stx_ino;
        iref->owner = true;
        DBG_DEBUG("[CEPH] iget: %s ino=%" PRIu64 "\n", name, iref->ino);
        return 0;
 }
 
-static int vfs_ceph_iget_by_fname(const struct vfs_handle_struct *handle,
-                                 const struct smb_filename *smb_fname,
-                                 struct vfs_ceph_iref *iref)
-{
-       return vfs_ceph_iget(handle, 0, smb_fname->base_name, 0, iref);
-}
-
-static int vfs_ceph_igetl(const struct vfs_handle_struct *handle,
-                         const struct smb_filename *smb_fname,
-                         struct vfs_ceph_iref *iref)
-{
-       return vfs_ceph_iget(handle,
-                            0,
-                            smb_fname->base_name,
-                            AT_SYMLINK_NOFOLLOW,
-                            iref);
-}
-
 static int vfs_ceph_igetd(struct vfs_handle_struct *handle,
                          const struct files_struct *dirfsp,
                          struct vfs_ceph_iref *iref)
@@ -1913,25 +1866,16 @@ static int vfs_ceph_igetd(struct vfs_handle_struct *handle,
 
        /* case-2: resolve by current work-dir */
        if (fsp_get_pathref_fd(dirfsp) == AT_FDCWD) {
-               return vfs_ceph_iget(handle, 0, ".", 0, iref);
+               return vfs_ceph_iget(handle, ".", 0, iref);
        }
 
        /* case-3: resolve by parent dir and name */
        return vfs_ceph_iget(handle,
-                            dirfsp->file_id.inode,
                             dirfsp->fsp_name->base_name,
                             AT_SYMLINK_NOFOLLOW,
                             iref);
 }
 
-static int vfs_ceph_igetf(struct vfs_handle_struct *handle,
-                         const struct files_struct *fsp,
-                         struct vfs_ceph_iref *iref)
-{
-       return vfs_ceph_iget(
-               handle, fsp->file_id.inode, fsp->fsp_name->base_name, 0, iref);
-}
-
 static void vfs_ceph_iput(const struct vfs_handle_struct *handle,
                          struct vfs_ceph_iref *iref)
 {
@@ -1996,7 +1940,7 @@ static int vfs_ceph_statvfs(struct vfs_handle_struct *handle,
        struct vfs_ceph_iref iref = {0};
        int ret;
 
-       ret = vfs_ceph_iget_by_fname(handle, smb_fname, &iref);
+       ret = vfs_ceph_iget(handle, smb_fname->base_name, 0, &iref);
        if (ret != 0) {
                goto out;
        }
@@ -2937,7 +2881,7 @@ static int vfs_ceph_stat(struct vfs_handle_struct *handle,
                goto out;
        }
 
-       result = vfs_ceph_iget_by_fname(handle, smb_fname, &iref);
+       result = vfs_ceph_iget(handle, smb_fname->base_name, 0, &iref);
        if (result != 0) {
                goto out;
        }
@@ -3033,7 +2977,10 @@ static int vfs_ceph_lstat(struct vfs_handle_struct *handle,
                goto out;
        }
 
-       result = vfs_ceph_igetl(handle, smb_fname, &iref);
+       result = vfs_ceph_iget(handle,
+                              smb_fname->base_name,
+                              AT_SYMLINK_NOFOLLOW,
+                              &iref);
        if (result != 0) {
                goto out;
        }
@@ -3171,7 +3118,10 @@ static int vfs_ceph_lchown(struct vfs_handle_struct *handle,
                  uid,
                  gid);
 
-       result = vfs_ceph_igetl(handle, smb_fname, &iref);
+       result = vfs_ceph_iget(handle,
+                              smb_fname->base_name,
+                              AT_SYMLINK_NOFOLLOW,
+                              &iref);
        if (result != 0) {
                goto out;
        }
@@ -3684,7 +3634,7 @@ static ssize_t vfs_ceph_fgetxattr(struct vfs_handle_struct *handle,
        } else {
                struct vfs_ceph_iref iref = {0};
 
-               ret = vfs_ceph_igetf(handle, fsp, &iref);
+               ret = vfs_ceph_iget(handle, fsp->fsp_name->base_name, 0, &iref);
                if (ret != 0) {
                        goto out;
                }
@@ -3727,7 +3677,7 @@ static ssize_t vfs_ceph_flistxattr(struct vfs_handle_struct *handle,
        } else {
                struct vfs_ceph_iref iref = {0};
 
-               ret = vfs_ceph_igetf(handle, fsp, &iref);
+               ret = vfs_ceph_iget(handle, fsp->fsp_name->base_name, 0, &iref);
                if (ret != 0) {
                        goto out;
                }
@@ -3766,7 +3716,7 @@ static int vfs_ceph_fremovexattr(struct vfs_handle_struct *handle,
        } else {
                struct vfs_ceph_iref iref = {0};
 
-               ret = vfs_ceph_igetf(handle, fsp, &iref);
+               ret = vfs_ceph_iget(handle, fsp->fsp_name->base_name, 0, &iref);
                if (ret != 0) {
                        goto out;
                }
@@ -3812,7 +3762,7 @@ static int vfs_ceph_fsetxattr(struct vfs_handle_struct *handle,
        } else {
                struct vfs_ceph_iref iref = {0};
 
-               ret = vfs_ceph_igetf(handle, fsp, &iref);
+               ret = vfs_ceph_iget(handle, fsp->fsp_name->base_name, 0, &iref);
                if (ret != 0) {
                        goto out;
                }