]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
vfs_ceph_rgw: Add fntimes, fcntl and ftruncate methods
authorShachar Sharon <ssharon@redhat.com>
Mon, 5 Jan 2026 10:11:17 +0000 (15:41 +0530)
committerAnoop C S <anoopcs@samba.org>
Thu, 18 Jun 2026 14:56:29 +0000 (14:56 +0000)
Signed-off-by: Shachar Sharon <ssharon@redhat.com>
Reviewed-by: Vinit Agnihotri <vagnihot@redhat.com>
Reviewed-by: Anoop C S <anoopcs@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
source3/modules/vfs_ceph_rgw.c

index 803068b355952d48667cb0872dbbb6c2c6840618..602bdc310fa4443620640eb554eafdf8dbac3fd6 100644 (file)
@@ -1034,6 +1034,165 @@ out:
        return res;
 }
 
+static void vfs_ceph_rgw_fill_stat_mask_from_ft(struct smb_file_time *ft,
+                                               struct stat *st,
+                                               uint32_t *mask)
+{
+       struct timespec time_now = timespec_current();
+
+       if (!is_omit_timespec(&ft->atime)) {
+               if (ft->atime.tv_nsec == UTIME_NOW) {
+                       ft->atime = time_now;
+               }
+               st->st_atim = ft->atime;
+               *mask |= RGW_SETATTR_ATIME;
+       }
+       if (!is_omit_timespec(&ft->mtime)) {
+               if (ft->mtime.tv_nsec == UTIME_NOW) {
+                       ft->mtime = time_now;
+               }
+               st->st_mtim = ft->mtime;
+               *mask |= RGW_SETATTR_MTIME;
+       }
+       if (!is_omit_timespec(&ft->ctime)) {
+               if (ft->ctime.tv_nsec == UTIME_NOW) {
+                       ft->ctime = time_now;
+               }
+               st->st_ctim = ft->ctime;
+               *mask |= RGW_SETATTR_CTIME;
+       }
+}
+
+static int vfs_ceph_rgw_setattr(struct vfs_handle_struct *handle,
+                               files_struct *fsp,
+                               uint32_t mask,
+                               struct stat *st)
+{
+       int rc = -ENOMEM;
+       struct vfs_ceph_rgw_config *config = NULL;
+       struct vfs_ceph_rgw_fh *fh = NULL;
+
+       SMB_VFS_HANDLE_GET_DATA(handle,
+                               config,
+                               struct vfs_ceph_rgw_config,
+                               goto out);
+
+       rc = vfs_ceph_rgw_fetch_fh(handle, fsp, &fh);
+       if (rc != 0) {
+               DBG_ERR("[CEPH_RGW] Unable to fetch handle\n");
+               goto out;
+       }
+
+       rc = rgw_setattr(config->rgw_root_fs,
+                        fh->rgw_fh,
+                        st,
+                        mask,
+                        RGW_SETATTR_FLAG_NONE);
+       if (rc < 0) {
+               DBG_ERR("[CEPH_RGW] Unable to set attributes\n");
+               goto out;
+       }
+
+out:
+       return rc;
+}
+
+static int vfs_ceph_rgw_fntimes(struct vfs_handle_struct *handle,
+                               files_struct *fsp,
+                               struct smb_file_time *ft)
+{
+       int rc = -ENOMEM;
+       uint32_t mask = 0;
+       struct stat st = {0};
+
+       START_PROFILE_X(SNUM(handle->conn), syscall_fntimes);
+
+       vfs_ceph_rgw_fill_stat_mask_from_ft(ft, &st, &mask);
+       if (mask == 0) {
+               rc = 0;
+               goto out;
+       }
+
+       rc = vfs_ceph_rgw_setattr(handle, fsp, mask, &st);
+       if (rc < 0) {
+               DBG_ERR("[CEPH_RGW] Unable to set fntimes. rc = %d\n", rc);
+               goto out;
+       }
+
+       if (!is_omit_timespec(&ft->create_time)) {
+               set_create_timespec_ea(fsp, ft->create_time);
+       }
+
+out:
+       END_PROFILE_X(syscall_fntimes);
+       return status_code(rc);
+}
+
+static int vfs_ceph_rgw_fcntl(vfs_handle_struct *handle,
+                             files_struct *fsp,
+                             int cmd,
+                             va_list cmd_arg)
+{
+       int result = 0;
+
+       START_PROFILE_X(SNUM(handle->conn), syscall_fcntl);
+       /*
+        * SMB_VFS_FCNTL() is currently only called by vfs_set_blocking() to
+        * clear O_NONBLOCK, etc for LOCK_MAND and FIFOs. Ignore it.
+        */
+       if (cmd == F_GETFL || cmd == F_SETFL) {
+               goto out;
+       }
+       DBG_ERR("[CEPH_RGW] unexpected fcntl: %d\n", cmd);
+       result = -1;
+       errno = EINVAL;
+out:
+       END_PROFILE_X(syscall_fcntl);
+       return result;
+}
+
+static int vfs_ceph_rgw_ftruncate(struct vfs_handle_struct *handle,
+                                 files_struct *fsp,
+                                 off_t len)
+{
+       int rc = -ENOMEM;
+       struct vfs_ceph_rgw_fh *fh = NULL;
+       struct vfs_ceph_rgw_config *config = NULL;
+
+       START_PROFILE_X(SNUM(handle->conn), syscall_ftruncate);
+
+       DBG_DEBUG("[CEPH_RGW] ftruncate: name='%s' len=%jd\n",
+                 fsp_str_dbg(fsp),
+                 (intmax_t)len);
+
+       SMB_VFS_HANDLE_GET_DATA(handle,
+                               config,
+                               struct vfs_ceph_rgw_config,
+                               goto out);
+
+       rc = vfs_ceph_rgw_fetch_fh(handle, fsp, &fh);
+       if (rc != 0) {
+               goto out;
+       }
+
+       if (len < 0) {
+               rc = -EINVAL;
+               goto out;
+       }
+
+       rc = rgw_truncate(config->rgw_root_fs,
+                         fh->rgw_fh,
+                         (uint64_t)len,
+                         RGW_TRUNCATE_FLAG_NONE);
+out:
+       DBG_DEBUG("[CEPH_RGW] ftruncate: name=%s len=%jd rc=%d\n",
+                 fsp_str_dbg(fsp),
+                 (intmax_t)len,
+                 rc);
+       END_PROFILE_X(syscall_ftruncate);
+       return status_code(rc);
+}
+
 static bool vfs_ceph_rgw_mount_bucket(struct vfs_ceph_rgw_config *config)
 {
        int rc = 0;
@@ -1294,12 +1453,12 @@ static struct vfs_fn_pointers ceph_rgw_fns = {
        .fchown_fn = vfs_not_implemented_fchown,
        .lchown_fn = vfs_not_implemented_lchown,
        .chdir_fn = vfs_ceph_rgw_chdir,
-       .fntimes_fn = vfs_not_implemented_fntimes,
-       .ftruncate_fn = vfs_not_implemented_ftruncate,
+       .fntimes_fn = vfs_ceph_rgw_fntimes,
+       .ftruncate_fn = vfs_ceph_rgw_ftruncate,
        .fallocate_fn = vfs_not_implemented_fallocate,
        .lock_fn = vfs_not_implemented_lock,
        .filesystem_sharemode_fn = vfs_not_implemented_filesystem_sharemode,
-       .fcntl_fn = vfs_not_implemented_fcntl,
+       .fcntl_fn = vfs_ceph_rgw_fcntl,
        .linux_setlease_fn = vfs_not_implemented_linux_setlease,
        .getlock_fn = vfs_not_implemented_getlock,
        .symlinkat_fn = vfs_not_implemented_symlinkat,