return -1;
}
+static int skel_renameat(vfs_handle_struct *handle,
+ files_struct *srcfsp,
+ const struct smb_filename *smb_fname_src,
+ files_struct *dstfsp,
+ const struct smb_filename *smb_fname_dst)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
static struct tevent_req *skel_fsync_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
.sendfile_fn = skel_sendfile,
.recvfile_fn = skel_recvfile,
.rename_fn = skel_rename,
+ .renameat_fn = skel_renameat,
.fsync_send_fn = skel_fsync_send,
.fsync_recv_fn = skel_fsync_recv,
.stat_fn = skel_stat,
return SMB_VFS_NEXT_RENAME(handle, smb_fname_src, smb_fname_dst);
}
+static int skel_renameat(vfs_handle_struct *handle,
+ files_struct *srcfsp,
+ const struct smb_filename *smb_fname_src,
+ files_struct *dstfsp,
+ const struct smb_filename *smb_fname_dst)
+{
+ return SMB_VFS_NEXT_RENAMEAT(handle,
+ srcfsp,
+ smb_fname_src,
+ dstfsp,
+ smb_fname_dst);
+}
+
struct skel_fsync_state {
int ret;
struct vfs_aio_state vfs_aio_state;
.sendfile_fn = skel_sendfile,
.recvfile_fn = skel_recvfile,
.rename_fn = skel_rename,
+ .renameat_fn = skel_renameat,
.fsync_send_fn = skel_fsync_send,
.fsync_recv_fn = skel_fsync_recv,
.stat_fn = skel_stat,
SMBPROFILE_STATS_BYTES(syscall_sendfile) \
SMBPROFILE_STATS_BYTES(syscall_recvfile) \
SMBPROFILE_STATS_BASIC(syscall_rename) \
- SMBPROFILE_STATS_BASIC(syscall_rename_at) \
+ SMBPROFILE_STATS_BASIC(syscall_renameat) \
SMBPROFILE_STATS_BYTES(syscall_asys_fsync) \
SMBPROFILE_STATS_BASIC(syscall_stat) \
SMBPROFILE_STATS_BASIC(syscall_fstat) \
/* Bump to version 42, Samba 4.12 will ship with that */
/* Version 42 - Remove share_access member from struct files_struct */
/* Version 42 - Make "lease" a const* in create_file_fn */
+/* Version 42 - Add SMB_VFS_RENAMEAT. */
#define SMB_VFS_INTERFACE_VERSION 42
int (*rename_fn)(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname_src,
const struct smb_filename *smb_fname_dst);
+ int (*renameat_fn)(struct vfs_handle_struct *handle,
+ struct files_struct *srcdir_fsp,
+ const struct smb_filename *smb_fname_src,
+ struct files_struct *dstdir_fsp,
+ const struct smb_filename *smb_fname_dst);
struct tevent_req *(*fsync_send_fn)(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
int smb_vfs_call_rename(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname_src,
const struct smb_filename *smb_fname_dst);
+int smb_vfs_call_renameat(struct vfs_handle_struct *handle,
+ struct files_struct *srcfsp,
+ const struct smb_filename *smb_fname_src,
+ struct files_struct *dstfsp,
+ const struct smb_filename *smb_fname_dst);
struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
int vfs_not_implemented_rename(vfs_handle_struct *handle,
const struct smb_filename *smb_fname_src,
const struct smb_filename *smb_fname_dst);
+int vfs_not_implemented_renameat(vfs_handle_struct *handle,
+ files_struct *srcfsp,
+ const struct smb_filename *smb_fname_src,
+ files_struct *dstfsp,
+ const struct smb_filename *smb_fname_dst);
struct tevent_req *vfs_not_implemented_fsync_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
#define SMB_VFS_NEXT_RENAME(handle, old, new) \
smb_vfs_call_rename((handle)->next, (old), (new))
+#define SMB_VFS_RENAMEAT(conn, oldfsp, old, newfsp, new) \
+ smb_vfs_call_renameat((conn)->vfs_handles, (oldfsp), (old), (newfsp), (new))
+#define SMB_VFS_NEXT_RENAMEAT(handle, oldfsp, old, newfsp, new) \
+ smb_vfs_call_renameat((handle)->next, (oldfsp), (old), (newfsp), (new))
+
#define SMB_VFS_FSYNC(fsp) \
smb_vfs_call_fsync((fsp)->conn->vfs_handles, (fsp))
#define SMB_VFS_NEXT_FSYNC(handle, fsp) \
return result;
}
+static int vfswrap_renameat(vfs_handle_struct *handle,
+ files_struct *srcfsp,
+ const struct smb_filename *smb_fname_src,
+ files_struct *dstfsp,
+ const struct smb_filename *smb_fname_dst)
+{
+ int result = -1;
+
+ START_PROFILE(syscall_renameat);
+
+ SMB_ASSERT(srcfsp->fh->fd == AT_FDCWD);
+ SMB_ASSERT(dstfsp->fh->fd == AT_FDCWD);
+
+ if (smb_fname_src->stream_name || smb_fname_dst->stream_name) {
+ errno = ENOENT;
+ goto out;
+ }
+
+ result = rename(smb_fname_src->base_name, smb_fname_dst->base_name);
+
+ out:
+ END_PROFILE(syscall_renameat);
+ return result;
+}
+
static int vfswrap_stat(vfs_handle_struct *handle,
struct smb_filename *smb_fname)
{
.sendfile_fn = vfswrap_sendfile,
.recvfile_fn = vfswrap_recvfile,
.rename_fn = vfswrap_rename,
+ .renameat_fn = vfswrap_renameat,
.fsync_send_fn = vfswrap_fsync_send,
.fsync_recv_fn = vfswrap_fsync_recv,
.stat_fn = vfswrap_stat,
int len;
gid_t gid;
- len = full_path_tos(handle->conn->cwd_fname->base_name,
+ len = full_path_tos(handle->conn->cwd_fsp->fsp_name->base_name,
smb_fname->base_name,
path, sizeof(path),
&full_path, &to_free);
return -1;
}
+int vfs_not_implemented_renameat(vfs_handle_struct *handle,
+ files_struct *srcfsp,
+ const struct smb_filename *smb_fname_src,
+ files_struct *dstfsp,
+ const struct smb_filename *smb_fname_dst)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
struct tevent_req *vfs_not_implemented_fsync_send(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
.sendfile_fn = vfs_not_implemented_sendfile,
.recvfile_fn = vfs_not_implemented_recvfile,
.rename_fn = vfs_not_implemented_rename,
+ .renameat_fn = vfs_not_implemented_renameat,
.fsync_send_fn = vfs_not_implemented_fsync_send,
.fsync_recv_fn = vfs_not_implemented_fsync_recv,
.stat_fn = vfs_not_implemented_stat,
return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
}
+int smb_vfs_call_renameat(struct vfs_handle_struct *handle,
+ files_struct *srcfsp,
+ const struct smb_filename *smb_fname_src,
+ files_struct *dstfsp,
+ const struct smb_filename *smb_fname_dst)
+{
+ VFS_FIND(renameat);
+ return handle->fns->renameat_fn(handle,
+ srcfsp,
+ smb_fname_src,
+ dstfsp,
+ smb_fname_dst);
+}
+
struct smb_vfs_call_fsync_state {
int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
int retval;