Currently identical to SMB_VFS_READLINK().
Next, add to all VFS modules that implement
readlink and eventually remove readlink.
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Böhme <slow@samba.org>
return -1;
}
+static int skel_vfs_readlinkat(vfs_handle_struct *handle,
+ files_struct *dirfsp,
+ const struct smb_filename *smb_fname,
+ char *buf,
+ size_t bufsiz)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
static int skel_linkat(vfs_handle_struct *handle,
files_struct *srcfsp,
const struct smb_filename *old_smb_fname,
.getlock_fn = skel_getlock,
.symlink_fn = skel_symlink,
.readlink_fn = skel_vfs_readlink,
+ .readlinkat_fn = skel_vfs_readlinkat,
.linkat_fn = skel_linkat,
.mknodat_fn = skel_mknodat,
.realpath_fn = skel_realpath,
return SMB_VFS_NEXT_READLINK(handle, smb_fname, buf, bufsiz);
}
+static int skel_vfs_readlinkat(vfs_handle_struct *handle,
+ files_struct *dirfsp,
+ const struct smb_filename *smb_fname,
+ char *buf,
+ size_t bufsiz)
+{
+ return SMB_VFS_NEXT_READLINKAT(handle,
+ dirfsp,
+ smb_fname,
+ buf,
+ bufsiz);
+}
+
static int skel_linkat(vfs_handle_struct *handle,
files_struct *srcfsp,
const struct smb_filename *old_smb_fname,
.getlock_fn = skel_getlock,
.symlink_fn = skel_symlink,
.readlink_fn = skel_vfs_readlink,
+ .readlinkat_fn = skel_vfs_readlinkat,
.linkat_fn = skel_linkat,
.mknodat_fn = skel_mknodat,
.realpath_fn = skel_realpath,
SMBPROFILE_STATS_BASIC(syscall_linux_setlease) \
SMBPROFILE_STATS_BASIC(syscall_fcntl_getlock) \
SMBPROFILE_STATS_BASIC(syscall_readlink) \
+ SMBPROFILE_STATS_BASIC(syscall_readlinkat) \
SMBPROFILE_STATS_BASIC(syscall_symlink) \
SMBPROFILE_STATS_BASIC(syscall_linkat) \
SMBPROFILE_STATS_BASIC(syscall_mknodat) \
/* Version 42 - Move SMB_VFS_RENAME -> SMB_VFS_RENAMEAT */
/* Version 42 - Move SMB_VFS_LINK -> SMB_VFS_LINKAT. */
/* Version 42 - Move SMB_VFS_MKNOD -> SMB_VFS_MKDNODAT. */
+/* Version 42 - Add SMB_VFS_READLINKAT. */
#define SMB_VFS_INTERFACE_VERSION 42
const struct smb_filename *smb_fname,
char *buf,
size_t bufsiz);
+ int (*readlinkat_fn)(struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const struct smb_filename *smb_fname,
+ char *buf,
+ size_t bufsiz);
int (*linkat_fn)(struct vfs_handle_struct *handle,
struct files_struct *srcfsp,
const struct smb_filename *old_smb_fname,
const struct smb_filename *smb_fname,
char *buf,
size_t bufsiz);
+int smb_vfs_call_readlinkat(struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const struct smb_filename *smb_fname,
+ char *buf,
+ size_t bufsiz);
int smb_vfs_call_linkat(struct vfs_handle_struct *handle,
struct files_struct *srcfsp,
const struct smb_filename *old_smb_fname,
const struct smb_filename *smb_fname,
char *buf,
size_t bufsiz);
+int vfs_not_implemented_vfs_readlinkat(vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const struct smb_filename *smb_fname,
+ char *buf,
+ size_t bufsiz);
int vfs_not_implemented_linkat(vfs_handle_struct *handle,
struct files_struct *srcfsp,
const struct smb_filename *old_smb_fname,
#define SMB_VFS_NEXT_READLINK(handle, smb_fname, buf, bufsiz) \
smb_vfs_call_readlink((handle)->next, (smb_fname), (buf), (bufsiz))
+#define SMB_VFS_READLINKAT(conn, dirfsp, smb_fname, buf, bufsiz) \
+ smb_vfs_call_readlinkat((conn)->vfs_handles, (dirfsp), (smb_fname), (buf), (bufsiz))
+#define SMB_VFS_NEXT_READLINKAT(handle, dirfsp, smb_fname, buf, bufsiz) \
+ smb_vfs_call_readlinkat((handle)->next, (dirfsp), (smb_fname), (buf), (bufsiz))
+
#define SMB_VFS_LINKAT(conn, srcfsp, oldpath, dstfsp, newpath, flags) \
smb_vfs_call_linkat((conn)->vfs_handles, (srcfsp), (oldpath), (dstfsp), (newpath), (flags))
#define SMB_VFS_NEXT_LINKAT(handle, srcfsp, oldpath, dstfsp, newpath, flags) \
return result;
}
+static int vfswrap_readlinkat(vfs_handle_struct *handle,
+ files_struct *dirfsp,
+ const struct smb_filename *smb_fname,
+ char *buf,
+ size_t bufsiz)
+{
+ int result;
+
+ START_PROFILE(syscall_readlinkat);
+
+ SMB_ASSERT(dirfsp == dirfsp->conn->cwd_fsp);
+
+ result = readlinkat(dirfsp->fh->fd,
+ smb_fname->base_name,
+ buf,
+ bufsiz);
+
+ END_PROFILE(syscall_readlinkat);
+ return result;
+}
+
static int vfswrap_linkat(vfs_handle_struct *handle,
files_struct *srcfsp,
const struct smb_filename *old_smb_fname,
.getlock_fn = vfswrap_getlock,
.symlink_fn = vfswrap_symlink,
.readlink_fn = vfswrap_readlink,
+ .readlinkat_fn = vfswrap_readlinkat,
.linkat_fn = vfswrap_linkat,
.mknodat_fn = vfswrap_mknodat,
.realpath_fn = vfswrap_realpath,
return -1;
}
+int vfs_not_implemented_vfs_readlinkat(vfs_handle_struct *handle,
+ files_struct *dirfsp,
+ const struct smb_filename *smb_fname,
+ char *buf,
+ size_t bufsiz)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
int vfs_not_implemented_linkat(vfs_handle_struct *handle,
files_struct *srcfsp,
const struct smb_filename *old_smb_fname,
.getlock_fn = vfs_not_implemented_getlock,
.symlink_fn = vfs_not_implemented_symlink,
.readlink_fn = vfs_not_implemented_vfs_readlink,
+ .readlinkat_fn = vfs_not_implemented_vfs_readlinkat,
.linkat_fn = vfs_not_implemented_linkat,
.mknodat_fn = vfs_not_implemented_mknodat,
.realpath_fn = vfs_not_implemented_realpath,
return handle->fns->readlink_fn(handle, smb_fname, buf, bufsiz);
}
+int smb_vfs_call_readlinkat(struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const struct smb_filename *smb_fname,
+ char *buf,
+ size_t bufsiz)
+{
+ VFS_FIND(readlinkat);
+ return handle->fns->readlinkat_fn(handle,
+ dirfsp,
+ smb_fname,
+ buf,
+ bufsiz);
+}
+
int smb_vfs_call_linkat(struct vfs_handle_struct *handle,
struct files_struct *srcfsp,
const struct smb_filename *old_smb_fname,