Currently identical to SMB_VFS_LINK().
Next, move add to all VFS modules that implement
link and eventually remove link.
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Böhme <slow@samba.org>
return -1;
}
+static int skel_linkat(vfs_handle_struct *handle,
+ files_struct *srcfsp,
+ const struct smb_filename *old_smb_fname,
+ files_struct *dstfsp,
+ const struct smb_filename *new_smb_fname,
+ int flags)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
static int skel_mknod(vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
mode_t mode,
.symlink_fn = skel_symlink,
.readlink_fn = skel_vfs_readlink,
.link_fn = skel_link,
+ .linkat_fn = skel_linkat,
.mknod_fn = skel_mknod,
.realpath_fn = skel_realpath,
.chflags_fn = skel_chflags,
return SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname);
}
+static int skel_linkat(vfs_handle_struct *handle,
+ files_struct *srcfsp,
+ const struct smb_filename *old_smb_fname,
+ files_struct *dstfsp,
+ const struct smb_filename *new_smb_fname,
+ int flags)
+{
+ return SMB_VFS_NEXT_LINKAT(handle,
+ srcfsp,
+ old_smb_fname,
+ dstfsp,
+ new_smb_fname,
+ flags);
+}
+
static int skel_mknod(vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
mode_t mode,
.symlink_fn = skel_symlink,
.readlink_fn = skel_vfs_readlink,
.link_fn = skel_link,
+ .linkat_fn = skel_linkat,
.mknod_fn = skel_mknod,
.realpath_fn = skel_realpath,
.chflags_fn = skel_chflags,
SMBPROFILE_STATS_BASIC(syscall_readlink) \
SMBPROFILE_STATS_BASIC(syscall_symlink) \
SMBPROFILE_STATS_BASIC(syscall_link) \
+ SMBPROFILE_STATS_BASIC(syscall_linkat) \
SMBPROFILE_STATS_BASIC(syscall_mknod) \
SMBPROFILE_STATS_BASIC(syscall_realpath) \
SMBPROFILE_STATS_BASIC(syscall_get_quota) \
/* Version 42 - Remove share_access member from struct files_struct */
/* Version 42 - Make "lease" a const* in create_file_fn */
/* Version 42 - Move SMB_VFS_RENAME -> SMB_VFS_RENAMEAT */
+/* Version 42 - Add SMB_VFS_LINKAT. */
#define SMB_VFS_INTERFACE_VERSION 42
int (*link_fn)(struct vfs_handle_struct *handle,
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname);
+ int (*linkat_fn)(struct vfs_handle_struct *handle,
+ struct files_struct *srcfsp,
+ const struct smb_filename *old_smb_fname,
+ struct files_struct *dstfsp,
+ const struct smb_filename *new_smb_fname,
+ int flags);
int (*mknod_fn)(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
mode_t mode,
int smb_vfs_call_link(struct vfs_handle_struct *handle,
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname);
+int smb_vfs_call_linkat(struct vfs_handle_struct *handle,
+ struct files_struct *srcfsp,
+ const struct smb_filename *old_smb_fname,
+ struct files_struct *dstfsp,
+ const struct smb_filename *new_smb_fname,
+ int flags);
int smb_vfs_call_mknod(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
mode_t mode,
int vfs_not_implemented_link(vfs_handle_struct *handle,
const struct smb_filename *old_smb_fname,
const struct smb_filename *new_smb_fname);
+int vfs_not_implemented_linkat(vfs_handle_struct *handle,
+ struct files_struct *srcfsp,
+ const struct smb_filename *old_smb_fname,
+ struct files_struct *dstfsp,
+ const struct smb_filename *new_smb_fname,
+ int flags);
int vfs_not_implemented_mknod(vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
mode_t mode,
#define SMB_VFS_NEXT_LINK(handle, oldpath, newpath) \
smb_vfs_call_link((handle)->next, (oldpath), (newpath))
+#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) \
+ smb_vfs_call_linkat((handle)->next, (srcfsp), (oldpath), (dstfsp), (newpath), (flags))
+
#define SMB_VFS_MKNOD(conn, smb_fname, mode, dev) \
smb_vfs_call_mknod((conn)->vfs_handles, (smb_fname), (mode), (dev))
#define SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev) \
return result;
}
+static int vfswrap_linkat(vfs_handle_struct *handle,
+ files_struct *srcfsp,
+ const struct smb_filename *old_smb_fname,
+ files_struct *dstfsp,
+ const struct smb_filename *new_smb_fname,
+ int flags)
+{
+ int result;
+
+ START_PROFILE(syscall_linkat);
+
+ SMB_ASSERT(srcfsp == srcfsp->conn->cwd_fsp);
+ SMB_ASSERT(dstfsp == dstfsp->conn->cwd_fsp);
+
+ result = linkat(srcfsp->fh->fd,
+ old_smb_fname->base_name,
+ dstfsp->fh->fd,
+ new_smb_fname->base_name,
+ flags);
+
+ END_PROFILE(syscall_linkat);
+ return result;
+}
+
static int vfswrap_mknod(vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
mode_t mode,
.symlink_fn = vfswrap_symlink,
.readlink_fn = vfswrap_readlink,
.link_fn = vfswrap_link,
+ .linkat_fn = vfswrap_linkat,
.mknod_fn = vfswrap_mknod,
.realpath_fn = vfswrap_realpath,
.chflags_fn = vfswrap_chflags,
return -1;
}
+int vfs_not_implemented_linkat(vfs_handle_struct *handle,
+ files_struct *srcfsp,
+ const struct smb_filename *old_smb_fname,
+ files_struct *dstfsp,
+ const struct smb_filename *new_smb_fname,
+ int flags)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
int vfs_not_implemented_mknod(vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
mode_t mode,
.symlink_fn = vfs_not_implemented_symlink,
.readlink_fn = vfs_not_implemented_vfs_readlink,
.link_fn = vfs_not_implemented_link,
+ .linkat_fn = vfs_not_implemented_linkat,
.mknod_fn = vfs_not_implemented_mknod,
.realpath_fn = vfs_not_implemented_realpath,
.chflags_fn = vfs_not_implemented_chflags,
return handle->fns->link_fn(handle, old_smb_fname, new_smb_fname);
}
+int smb_vfs_call_linkat(struct vfs_handle_struct *handle,
+ struct files_struct *srcfsp,
+ const struct smb_filename *old_smb_fname,
+ struct files_struct *dstfsp,
+ const struct smb_filename *new_smb_fname,
+ int flags)
+{
+ VFS_FIND(linkat);
+ return handle->fns->linkat_fn(handle,
+ srcfsp,
+ old_smb_fname,
+ dstfsp,
+ new_smb_fname,
+ flags);
+}
+
int smb_vfs_call_mknod(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
mode_t mode,