From: Anoop C S Date: Tue, 25 Feb 2025 12:10:13 +0000 (+0530) Subject: vfs_ceph_new: Do not resolve by inode number X-Git-Tag: tevent-0.17.0~581 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a96f0542c8317a7dd0470b32350de6893fd98723;p=thirdparty%2Fsamba.git vfs_ceph_new: Do not resolve by inode number 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 Reviewed-by: Guenther Deschner Autobuild-User(master): Günther Deschner Autobuild-Date(master): Fri Mar 7 18:20:47 UTC 2025 on atb-devel-224 --- diff --git a/source3/modules/vfs_ceph_new.c b/source3/modules/vfs_ceph_new.c index e8da512273a..4ef800951d2 100644 --- a/source3/modules/vfs_ceph_new.c +++ b/source3/modules/vfs_ceph_new.c @@ -107,7 +107,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); @@ -389,7 +388,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); @@ -791,21 +789,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, @@ -1835,60 +1818,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) @@ -1907,25 +1860,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) { @@ -1991,7 +1935,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; } @@ -2932,7 +2876,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; } @@ -3028,7 +2972,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; } @@ -3166,7 +3113,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; } @@ -3683,7 +3633,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; } @@ -3729,7 +3679,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; } @@ -3768,7 +3718,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; } @@ -3814,7 +3764,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; }