vfs_ceph: Implement SMB_VFS_FSTATAT
authorAnoop C S <anoopcs@samba.org>
Tue, 9 Jan 2024 05:41:40 +0000 (11:11 +0530)
committerGünther Deschner <gd@samba.org>
Fri, 26 Jan 2024 16:56:59 +0000 (16:56 +0000)
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 Jan 26 16:56:59 UTC 2024 on atb-devel-224

source3/modules/vfs_ceph.c
source3/wscript

index 88712e872a5a71ad8f4ec304b3b4aab4003150eb..4387918198e99b32b33341425a8920013b1999a4 100644 (file)
@@ -945,6 +945,51 @@ static int cephwrap_fstat(struct vfs_handle_struct *handle, files_struct *fsp, S
        return result;
 }
 
+static int cephwrap_fstatat(struct vfs_handle_struct *handle,
+                           const struct files_struct *dirfsp,
+                           const struct smb_filename *smb_fname,
+                           SMB_STRUCT_STAT *sbuf,
+                           int flags)
+{
+       int result = -1;
+       struct ceph_statx stx = { 0 };
+#ifdef HAVE_CEPH_STATXAT
+       int dirfd = fsp_get_pathref_fd(dirfsp);
+
+       DBG_DEBUG("[CEPH] fstatat(%p, %d, %s)\n",
+                 handle, dirfd, smb_fname->base_name);
+       result = ceph_statxat(handle->data, dirfd, smb_fname->base_name,
+                             &stx, SAMBA_STATX_ATTR_MASK, 0);
+#else
+       struct smb_filename *full_fname = NULL;
+
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                                 dirfsp,
+                                                 smb_fname);
+       if (full_fname == NULL) {
+               errno = ENOMEM;
+               return -1;
+       }
+
+       DBG_DEBUG("[CEPH] fstatat(%p, %s)\n",
+                 handle, smb_fname_str_dbg(full_fname));
+       result = ceph_statx(handle->data, full_fname->base_name,
+                           &stx, SAMBA_STATX_ATTR_MASK, 0);
+
+       TALLOC_FREE(full_fname);
+#endif
+
+       DBG_DEBUG("[CEPH] fstatat(...) = %d\n", result);
+       if (result < 0) {
+               WRAP_RETURN(result);
+       }
+
+       init_stat_ex_from_ceph_statx(sbuf, &stx);
+       DBG_DEBUG("[CEPH] mode = 0x%x\n", sbuf->st_ex_mode);
+
+       return 0;
+}
+
 static int cephwrap_lstat(struct vfs_handle_struct *handle,
                         struct smb_filename *smb_fname)
 {
@@ -1859,6 +1904,7 @@ static struct vfs_fn_pointers ceph_fns = {
        .stat_fn = cephwrap_stat,
        .fstat_fn = cephwrap_fstat,
        .lstat_fn = cephwrap_lstat,
+       .fstatat_fn = cephwrap_fstatat,
        .unlinkat_fn = cephwrap_unlinkat,
        .fchmod_fn = cephwrap_fchmod,
        .fchown_fn = cephwrap_fchown,
index 060e8d3ffe0e7b56f7f64d267b5755cb5bf8e9c5..b76ced59aa4733b969e799d1f9a78cd57669d0b2 100644 (file)
@@ -1681,7 +1681,7 @@ int main(void) {
                                 headers='cephfs/libcephfs.h')
             conf.DEFINE('HAVE_MANDATORY_CEPH_API', '1')
             for api in ['ceph_mkdirat', 'ceph_openat', 'ceph_unlinkat',
-                        'ceph_symlinkat', 'ceph_readlinkat']:
+                        'ceph_symlinkat', 'ceph_readlinkat', 'ceph_statxat']:
                 if not conf.CHECK_FUNCS_IN(api, 'cephfs',
                                            headers='cephfs/libcephfs.h'):
                     conf.undefine('HAVE_MANDATORY_CEPH_API')