]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: VFS: vfs_ceph_snapshots. Implement readlinkat().
authorJeremy Allison <jra@samba.org>
Thu, 22 Aug 2019 21:10:31 +0000 (14:10 -0700)
committerJeremy Allison <jra@samba.org>
Fri, 23 Aug 2019 18:49:35 +0000 (18:49 +0000)
Currently identical to readlink().

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Böhme <slow@samba.org>
source3/modules/vfs_ceph_snapshots.c

index ff412ee9a6cd34447e81b1019cf2760285206f16..c5dba01b3131589546643bf9f06f2a0131eeffc5 100644 (file)
@@ -1135,6 +1135,57 @@ static int ceph_snap_gmt_readlink(vfs_handle_struct *handle,
        return ret;
 }
 
+static int ceph_snap_gmt_readlinkat(vfs_handle_struct *handle,
+                               files_struct *dirfsp,
+                               const struct smb_filename *csmb_fname,
+                               char *buf,
+                               size_t bufsiz)
+{
+       time_t timestamp = 0;
+       char stripped[PATH_MAX + 1];
+       char conv[PATH_MAX + 1];
+       int ret;
+       struct smb_filename *new_fname;
+       int saved_errno;
+
+       ret = ceph_snap_gmt_strip_snapshot(handle,
+                                       csmb_fname->base_name,
+                                       &timestamp, stripped, sizeof(stripped));
+       if (ret < 0) {
+               errno = -ret;
+               return -1;
+       }
+       if (timestamp == 0) {
+               return SMB_VFS_NEXT_READLINKAT(handle,
+                               dirfsp,
+                               csmb_fname,
+                               buf,
+                               bufsiz);
+       }
+       ret = ceph_snap_gmt_convert(handle, stripped,
+                                       timestamp, conv, sizeof(conv));
+       if (ret < 0) {
+               errno = -ret;
+               return -1;
+       }
+       new_fname = cp_smb_filename(talloc_tos(), csmb_fname);
+       if (new_fname == NULL) {
+               errno = ENOMEM;
+               return -1;
+       }
+       new_fname->base_name = conv;
+
+       ret = SMB_VFS_NEXT_READLINKAT(handle,
+                               dirfsp,
+                               new_fname,
+                               buf,
+                               bufsiz);
+       saved_errno = errno;
+       TALLOC_FREE(new_fname);
+       errno = saved_errno;
+       return ret;
+}
+
 static int ceph_snap_gmt_mknodat(vfs_handle_struct *handle,
                        files_struct *dirfsp,
                        const struct smb_filename *csmb_fname,
@@ -1625,6 +1676,7 @@ static struct vfs_fn_pointers ceph_snap_fns = {
        .chdir_fn = ceph_snap_gmt_chdir,
        .ntimes_fn = ceph_snap_gmt_ntimes,
        .readlink_fn = ceph_snap_gmt_readlink,
+       .readlinkat_fn = ceph_snap_gmt_readlinkat,
        .mknodat_fn = ceph_snap_gmt_mknodat,
        .realpath_fn = ceph_snap_gmt_realpath,
        .get_nt_acl_fn = ceph_snap_gmt_get_nt_acl,