off_t src_off,
struct files_struct *dest_fsp,
off_t dest_off,
- off_t num)
+ off_t num,
+ uint32_t flags)
{
struct tevent_req *req;
struct skel_cc_state *cc_state;
off_t src_off,
struct files_struct *dest_fsp,
off_t dest_off,
- off_t num)
+ off_t num,
+ uint32_t flags)
{
struct tevent_req *req;
struct tevent_req *subreq;
cc_state->handle = handle;
subreq = SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, cc_state, ev,
src_fsp, src_off,
- dest_fsp, dest_off, num);
+ dest_fsp, dest_off, num, flags);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
/* Bump to version 36 - Samba 4.6 will ship with that */
/* Version 36 - Remove is_offline and set_offline */
/* Version 37 - Module init functions now take a TALLOC_CTX * parameter. */
+/* Version 37 - Add vfs_copy_chunk_flags for DUP_EXTENTS_TO_FILE */
#define SMB_VFS_INTERFACE_VERSION 37
VFS_FALLOCATE_FL_PUNCH_HOLE = 0x0002,
};
+/*
+ * @VFS_COPY_CHUNK_FL_MUST_CLONE: indicates that copy_chunk_send_fn() copy must
+ * be handled as a COW clone, AKA reflink.
+ * @VFS_COPY_CHUNK_FL_MASK_ALL: all valid copychunk flags.
+ */
+enum vfs_copy_chunk_flags {
+ VFS_COPY_CHUNK_FL_MUST_CLONE = 0x0001,
+
+ VFS_COPY_CHUNK_FL_MASK_ALL = 0x0001,
+};
+
struct vfs_aio_state {
int error;
uint64_t duration;
off_t src_off,
struct files_struct *dest_fsp,
off_t dest_off,
- off_t num);
+ off_t to_copy,
+ uint32_t flags);
NTSTATUS (*copy_chunk_recv_fn)(struct vfs_handle_struct *handle,
struct tevent_req *req,
off_t *copied);
off_t src_off,
struct files_struct *dest_fsp,
off_t dest_off,
- off_t num);
+ off_t num,
+ uint32_t flags);
NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
struct tevent_req *req,
off_t *copied);
#define SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle, fsp, attributes) \
smb_vfs_call_fset_dos_attributes((handle)->next, (fsp), (attributes))
-#define SMB_VFS_COPY_CHUNK_SEND(conn, mem_ctx, ev, src_fsp, src_off, dest_fsp, dest_off, num) \
- smb_vfs_call_copy_chunk_send((conn)->vfs_handles, (mem_ctx), (ev), (src_fsp), (src_off), (dest_fsp), (dest_off), (num))
-#define SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, mem_ctx, ev, src_fsp, src_off, dest_fsp, dest_off, num) \
- smb_vfs_call_copy_chunk_send((handle)->next, (mem_ctx), (ev), (src_fsp), (src_off), (dest_fsp), (dest_off), (num))
+#define SMB_VFS_COPY_CHUNK_SEND(conn, mem_ctx, ev, src_fsp, src_off, dest_fsp, dest_off, num, flags) \
+ smb_vfs_call_copy_chunk_send((conn)->vfs_handles, (mem_ctx), (ev), (src_fsp), (src_off), (dest_fsp), (dest_off), (num), (flags))
+#define SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, mem_ctx, ev, src_fsp, src_off, dest_fsp, dest_off, num, flags) \
+ smb_vfs_call_copy_chunk_send((handle)->next, (mem_ctx), (ev), (src_fsp), (src_off), (dest_fsp), (dest_off), (num), (flags))
#define SMB_VFS_COPY_CHUNK_RECV(conn, req, copied) \
smb_vfs_call_copy_chunk_recv((conn)->vfs_handles, (req), (copied))
off_t src_off,
struct files_struct *dest_fsp,
off_t dest_off,
- off_t num)
+ off_t num,
+ uint32_t flags)
{
struct tevent_req *req;
struct btrfs_cc_state *cc_state;
if (req == NULL) {
return NULL;
}
+
+ if (flags & ~VFS_COPY_CHUNK_FL_MASK_ALL) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+
cc_state->handle = handle;
if (num == 0) {
src_fsp,
src_off,
dest_fsp,
- dest_off, num);
+ dest_off,
+ num, flags);
if (tevent_req_nomem(cc_state->subreq, req)) {
return tevent_req_post(req, ev);
}
src_fsp,
src_off,
dest_fsp,
- dest_off, num);
+ dest_off,
+ num, flags);
if (tevent_req_nomem(cc_state->subreq, req)) {
return tevent_req_post(req, ev);
}
off_t src_off,
struct files_struct *dest_fsp,
off_t dest_off,
- off_t to_copy)
+ off_t to_copy,
+ uint32_t flags)
{
struct tevent_req *req;
struct vfs_cc_state *state = NULL;
return NULL;
}
+ if (flags & ~VFS_COPY_CHUNK_FL_MASK_ALL) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+
+ if (flags & VFS_COPY_CHUNK_FL_MUST_CLONE) {
+ DEBUG(10, ("COW clones not supported by vfs_default\n"));
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+
*state = (struct vfs_cc_state) {
.ev = ev,
.src_fsp = src_fsp,
off_t src_off,
struct files_struct *dest_fsp,
off_t dest_off,
- off_t num)
+ off_t num,
+ uint32_t flags)
{
struct tevent_req *req, *subreq;
struct fruit_copy_chunk_state *fruit_copy_chunk_state;
src_off,
dest_fsp,
dest_off,
- to_copy);
+ to_copy,
+ flags);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
off_t src_off,
struct files_struct *dest_fsp,
off_t dest_off,
- off_t num)
+ off_t num,
+ uint32_t flags)
{
struct tevent_req *req;
req = SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, mem_ctx, ev, src_fsp,
- src_off, dest_fsp, dest_off, num);
+ src_off, dest_fsp, dest_off, num,
+ flags);
do_log(SMB_VFS_OP_COPY_CHUNK_SEND, req, handle, "");
off_t src_off,
struct files_struct *dest_fsp,
off_t dest_off,
- off_t num)
+ off_t num,
+ uint32_t flags)
{
struct tevent_req *req;
struct tevent_req *subreq;
clock_gettime_mono(&cc_state->ts_send);
subreq = SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, cc_state, ev,
src_fsp, src_off,
- dest_fsp, dest_off, num);
+ dest_fsp, dest_off, num, flags);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
0,
state->dst_fsp,
0,
+ 0,
0);
if (subreq == NULL) {
return NT_STATUS_NO_MEMORY;
chunk->source_off,
state->dst_fsp,
chunk->target_off,
- length);
+ length,
+ 0);
if (tevent_req_nomem(subreq, req)) {
return NT_STATUS_NO_MEMORY;
}
off_t src_off,
struct files_struct *dest_fsp,
off_t dest_off,
- off_t num)
+ off_t num,
+ uint32_t flags)
{
VFS_FIND(copy_chunk_send);
return handle->fns->copy_chunk_send_fn(handle, mem_ctx, ev, src_fsp,
- src_off, dest_fsp, dest_off, num);
+ src_off, dest_fsp, dest_off, num,
+ flags);
}
NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,