[SCM] Samba Shared Repository - branch master updated
Ralph Böhme
slow at samba.org
Wed May 10 10:28:02 UTC 2017
The branch, master has been updated
via de01e11 smbd/smb2_ioctl: instruct VFS to ignore locks for dup extents
via c4fd960 vfs: add VFS_COPY_CHUNK_FL_IGNORE_LOCKS for dup extents
via b97d8c8 smbd/smb2_ioctl: validate dup_extent request lengths
via fb31e35 smbd/smb2_ioctl: check sparseness for dup extents
via e953184 vfs_btrfs: report FILE_SUPPORTS_BLOCK_REFCOUNTING capability
via a222108 smbd/smb2_ioctl: check for for overlap of dup extent ranges
via 373d301 smbd/smb2_ioctl: add support for FSCTL_DUPLICATE_EXTENTS_TO_FILE
via fc2b366 vfs: add parameter to copy chunk VFS function to handle dup_extents
via 3361b5f torture/ioctl: expect dup_extents(dest=compressed) to pass
via 3b4d626 torture/ioctl: fix dup_extents destination truncate
from da95471 packaging: Remove Mandrake
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit de01e117d65219e5765e8e83730aa00c4bac5b6b
Author: David Disseldorp <ddiss at samba.org>
Date: Thu May 4 15:09:36 2017 +0200
smbd/smb2_ioctl: instruct VFS to ignore locks for dup extents
As described in the previous commit - Windows Server 2016 (ReFS) ignores
locks for FSCTL_DUPLICATE_EXTENTS_TO_FILE. Do the same for Samba.
Signed-off-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Ralph Böhme <slow at samba.org>
Autobuild-User(master): Ralph Böhme <slow at samba.org>
Autobuild-Date(master): Wed May 10 12:27:00 CEST 2017 on sn-devel-144
commit c4fd96016610171a31ad54a7883b3682680ef8d1
Author: David Disseldorp <ddiss at samba.org>
Date: Thu May 4 14:55:43 2017 +0200
vfs: add VFS_COPY_CHUNK_FL_IGNORE_LOCKS for dup extents
As confirmed by the Microsoft Protocol Open Specifications Team: Windows
Server 2016 (ReFS) ignores locks for FSCTL_DUPLICATE_EXTENTS_TO_FILE...
From: Jeff McCashland
To: David Disseldorp
CC: "cifs-protocol at lists.samba.org" <cifs-protocol at lists.samba.org>
Subject: RE: [116100414754619] FSCTL_DUPLICATE_EXTENTS_TO_FILE appears
to completely bypass file locks
Date: Mon, 12 Dec 2016 20:44:08 +0000
Hi David,
We have made the following spec changes for the next doc release:
In section 2.1.5.9.4 FSCTL_DUPLICATE_EXTENTS_TO_FILE behavior notes have
been added to the following paragraphs.
Before:
§ The object store MUST check for byte range lock conflicts on
Open.Stream using the algorithm described in section 2.1.4.10 with
ByteOffset set to InputBuffer.TargetFileOffset, Length set to
InputBuffer.ByteCount, IsExclusive set to TRUE, LockIntent set to FALSE,
and Open set to Open. If a conflict is detected, the operation MUST be
failed with STATUS_FILE_LOCK_CONFLICT.
§ The object store MUST check for byte range lock conflicts on Source
using the algorithm described in section 2.1.4.10 with ByteOffset set to
InputBuffer.SourceFileOffset, Length set to InputBuffer.ByteCount,
IsExclusive set to FALSE, LockIntent set to FALSE, and Open set to
InputBuffer.FileHandle. If a conflict is detected, the operation MUST be
failed with STATUS_FILE_LOCK_CONFLICT.
After:
§ The object store SHOULD<WBN1> check for byte range lock conflicts on
Open.Stream using the algorithm described in section 2.1.4.10 with
ByteOffset set to InputBuffer.TargetFileOffset, Length set to
InputBuffer.ByteCount, IsExclusive set to TRUE, LockIntent set to FALSE,
and Open set to Open. If a conflict is detected, the operation MUST be
failed with STATUS_FILE_LOCK_CONFLICT.
§ The object store SHOULD<WBN2> check for byte range lock conflicts on
Source using the algorithm described in section 2.1.4.10 with ByteOffset
set to InputBuffer.SourceFileOffset, Length set to
InputBuffer.ByteCount, IsExclusive set to FALSE, LockIntent set to
FALSE, and Open set to InputBuffer.FileHandle. If a conflict is
detected, the operation MUST be failed with STATUS_FILE_LOCK_CONFLICT.
WBN1: The ReFS file system in Windows Server 2016 does not check for
byte range lock conflicts on Open.Stream.
WBN2: The ReFS file system in Windows Server 2016 does not check for
byte range lock conflicts on Source.
Signed-off-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Ralph Böhme <slow at samba.org>
commit b97d8c81a7d4be7ba4e050dea4c963645721132c
Author: David Disseldorp <ddiss at samba.org>
Date: Sat Oct 1 23:40:13 2016 +0200
smbd/smb2_ioctl: validate dup_extent request lengths
FSCTL_DUPLICATE_EXTENTS_TO_FILE has some interesting behaviour when
exceeding the destination file length - the clone is truncated to only
cover the existing file region. If the existing length is zero, then
nothing is cloned.
Signed-off-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Ralph Böhme <slow at samba.org>
commit fb31e359bf8e80ece6641bc1a7e6a1e2a5e67ddb
Author: David Disseldorp <ddiss at samba.org>
Date: Fri Sep 30 20:53:07 2016 +0200
smbd/smb2_ioctl: check sparseness for dup extents
FSCTL_DUPLICATE_EXTENTS_TO_FILE should fail if the source is marked
sparse while the target is not:
From: Jeff McCashland
To: David Disseldorp
Subject: RE: FSCTL_DUPLICATE_EXTENTS_TO_FILE questions, 116092214702946
Date: Tue, 27 Dec 2016 18:06:14 +0000
...
We have updated the spec for future release:
Section 2.3.8 FSCTL_DUPLICATE_EXTENTS_TO_FILE Reply
Changed description of STATUS_NOT_SUPPORTED error code to:
"--The source and target destination ranges overlap on the same file.
--Source file is sparse, while -target is a non-sparse file.
--The source range is beyond the source file's allocation size."
Signed-off-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Ralph Böhme <slow at samba.org>
commit e95318466255323ab22e772c12219cc738d15177
Author: Aurelien Aptel <aaptel at suse.com>
Date: Thu Jul 30 16:33:08 2015 +0200
vfs_btrfs: report FILE_SUPPORTS_BLOCK_REFCOUNTING capability
Signed-off-by: Aurelien Aptel <aaptel at suse.com>
Reviewed-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Ralph Böhme <slow at samba.org>
commit a222108284dca32f216fc9047715ba5dbc9ecbdf
Author: David Disseldorp <ddiss at samba.org>
Date: Tue Sep 20 09:48:37 2016 -0700
smbd/smb2_ioctl: check for for overlap of dup extent ranges
Signed-off-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Ralph Böhme <slow at samba.org>
commit 373d3015bc7c42d8ab28e72cd76806cce1d9c78f
Author: Aurelien Aptel <aaptel at suse.com>
Date: Thu Jul 30 16:16:15 2015 +0200
smbd/smb2_ioctl: add support for FSCTL_DUPLICATE_EXTENTS_TO_FILE
Signed-off-by: Aurelien Aptel <aaptel at suse.com>
Signed-off-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit fc2b3662b813e936458860c3c041ee50e5dd1a88
Author: Aurelien Aptel <aaptel at suse.com>
Date: Mon Aug 24 18:22:56 2015 +0200
vfs: add parameter to copy chunk VFS function to handle dup_extents
FSCTL_DUPLICATE_EXTENTS_TO_FILE must be handled as a COW clone. Add a
copy-chunk flags parameter to the VFS to handle this.
Signed-off-by: Aurelien Aptel <aaptel at suse.com>
Signed-off-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Ralph Böhme <slow at samba.org>
commit 3361b5fca390c9ab130160dbbdd25a0be97bd818
Author: David Disseldorp <ddiss at samba.org>
Date: Fri Sep 30 21:35:09 2016 +0200
torture/ioctl: expect dup_extents(dest=compressed) to pass
The MS-FSCC spec doesn't mention anything about dup-extents against
compressed files.
This can't be tested against Windows, as ReFS doesn't support
compression, but COW clones of compressed files work on Btrfs.
Signed-off-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Ralph Böhme <slow at samba.org>
commit 3b4d6267d1108d44b79b8bf5d92ec01c917a3397
Author: David Disseldorp <ddiss at samba.org>
Date: Wed May 3 09:26:43 2017 +0200
torture/ioctl: fix dup_extents destination truncate
The dup_extents_compressed_dest test fails to correctly truncate the
dup_extents destination. Fix it.
Signed-off-by: David Disseldorp <ddiss at samba.org>
Reviewed-by: Ralph Böhme <slow at samba.org>
-----------------------------------------------------------------------
Summary of changes:
examples/VFS/skel_opaque.c | 3 +-
examples/VFS/skel_transparent.c | 5 +-
source3/include/vfs.h | 21 ++-
source3/include/vfs_macros.h | 8 +-
source3/modules/vfs_btrfs.c | 68 ++++----
source3/modules/vfs_default.c | 86 ++++++----
source3/modules/vfs_fruit.c | 6 +-
source3/modules/vfs_full_audit.c | 6 +-
source3/modules/vfs_time_audit.c | 5 +-
source3/smbd/smb2_ioctl_filesys.c | 300 +++++++++++++++++++++++++++++++++++
source3/smbd/smb2_ioctl_network_fs.c | 4 +-
source3/smbd/vfs.c | 6 +-
source4/torture/smb2/ioctl.c | 13 +-
13 files changed, 450 insertions(+), 81 deletions(-)
Changeset truncated at 500 lines:
diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index ffd951c..af119f3 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -531,7 +531,8 @@ static struct tevent_req *skel_copy_chunk_send(struct vfs_handle_struct *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 skel_cc_state *cc_state;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index afadbc1..e974529 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -619,7 +619,8 @@ static struct tevent_req *skel_copy_chunk_send(struct vfs_handle_struct *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;
@@ -633,7 +634,7 @@ static struct tevent_req *skel_copy_chunk_send(struct vfs_handle_struct *handle,
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);
}
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index f6df93a..7908980 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -196,6 +196,7 @@
/* 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
@@ -548,6 +549,20 @@ enum vfs_fallocate_flags {
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_IGNORE_LOCKS = 0x0002,
+
+ VFS_COPY_CHUNK_FL_MASK_ALL =
+ (VFS_COPY_CHUNK_FL_MUST_CLONE
+ | VFS_COPY_CHUNK_FL_IGNORE_LOCKS),
+};
+
struct vfs_aio_state {
int error;
uint64_t duration;
@@ -709,7 +724,8 @@ struct vfs_fn_pointers {
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);
@@ -1241,7 +1257,8 @@ struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle
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);
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 40c93f8..0cbcf89 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -415,10 +415,10 @@
#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))
diff --git a/source3/modules/vfs_btrfs.c b/source3/modules/vfs_btrfs.c
index ab4fd99..e306ece 100644
--- a/source3/modules/vfs_btrfs.c
+++ b/source3/modules/vfs_btrfs.c
@@ -39,7 +39,8 @@ static uint32_t btrfs_fs_capabilities(struct vfs_handle_struct *handle,
/* inherit default capabilities, expose compression support */
fs_capabilities = SMB_VFS_NEXT_FS_CAPABILITIES(handle, &ts_res);
- fs_capabilities |= FILE_FILE_COMPRESSION;
+ fs_capabilities |= (FILE_FILE_COMPRESSION
+ | FILE_SUPPORTS_BLOCK_REFCOUNTING);
*_ts_res = ts_res;
return fs_capabilities;
@@ -92,7 +93,8 @@ static struct tevent_req *btrfs_copy_chunk_send(struct vfs_handle_struct *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 btrfs_cc_state *cc_state;
@@ -106,6 +108,12 @@ static struct tevent_req *btrfs_copy_chunk_send(struct vfs_handle_struct *handle
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) {
@@ -119,7 +127,8 @@ static struct tevent_req *btrfs_copy_chunk_send(struct vfs_handle_struct *handle
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);
}
@@ -145,27 +154,29 @@ static struct tevent_req *btrfs_copy_chunk_send(struct vfs_handle_struct *handle
return tevent_req_post(req, ev);
}
- init_strict_lock_struct(src_fsp,
- src_fsp->op->global->open_persistent_id,
- src_off,
- num,
- READ_LOCK,
- &src_lck);
- init_strict_lock_struct(dest_fsp,
- dest_fsp->op->global->open_persistent_id,
- dest_off,
- num,
- WRITE_LOCK,
- &dest_lck);
-
- if (!SMB_VFS_STRICT_LOCK(src_fsp->conn, src_fsp, &src_lck)) {
- tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
- return tevent_req_post(req, ev);
- }
- if (!SMB_VFS_STRICT_LOCK(dest_fsp->conn, dest_fsp, &dest_lck)) {
- SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &src_lck);
- tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
- return tevent_req_post(req, ev);
+ if (!(flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
+ init_strict_lock_struct(src_fsp,
+ src_fsp->op->global->open_persistent_id,
+ src_off,
+ num,
+ READ_LOCK,
+ &src_lck);
+ init_strict_lock_struct(dest_fsp,
+ dest_fsp->op->global->open_persistent_id,
+ dest_off,
+ num,
+ WRITE_LOCK,
+ &dest_lck);
+
+ if (!SMB_VFS_STRICT_LOCK(src_fsp->conn, src_fsp, &src_lck)) {
+ tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
+ return tevent_req_post(req, ev);
+ }
+ if (!SMB_VFS_STRICT_LOCK(dest_fsp->conn, dest_fsp, &dest_lck)) {
+ SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &src_lck);
+ tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
+ return tevent_req_post(req, ev);
+ }
}
ZERO_STRUCT(cr_args);
@@ -175,8 +186,10 @@ static struct tevent_req *btrfs_copy_chunk_send(struct vfs_handle_struct *handle
cr_args.src_length = (uint64_t)num;
ret = ioctl(dest_fsp->fh->fd, BTRFS_IOC_CLONE_RANGE, &cr_args);
- SMB_VFS_STRICT_UNLOCK(dest_fsp->conn, dest_fsp, &dest_lck);
- SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &src_lck);
+ if (!(flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
+ SMB_VFS_STRICT_UNLOCK(dest_fsp->conn, dest_fsp, &dest_lck);
+ SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &src_lck);
+ }
if (ret < 0) {
/*
* BTRFS_IOC_CLONE_RANGE only supports 'sectorsize' aligned
@@ -196,7 +209,8 @@ static struct tevent_req *btrfs_copy_chunk_send(struct vfs_handle_struct *handle
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);
}
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index d660120..fa89f7f 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1605,6 +1605,7 @@ struct vfs_cc_state {
off_t to_copy;
off_t remaining;
size_t next_io_size;
+ uint32_t flags;
};
static NTSTATUS copy_chunk_loop(struct tevent_req *req);
@@ -1616,7 +1617,8 @@ static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *hand
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;
@@ -1630,6 +1632,17 @@ static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *hand
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,
@@ -1638,6 +1651,7 @@ static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *hand
.dst_off = dest_off,
.to_copy = to_copy,
.remaining = to_copy,
+ .flags = flags,
};
state->buf = talloc_array(state, uint8_t, num);
if (tevent_req_nomem(state->buf, req)) {
@@ -1692,18 +1706,20 @@ static NTSTATUS copy_chunk_loop(struct tevent_req *req)
state->next_io_size = MIN(state->remaining, talloc_array_length(state->buf));
- init_strict_lock_struct(state->src_fsp,
+ if (!(state->flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
+ init_strict_lock_struct(state->src_fsp,
state->src_fsp->op->global->open_persistent_id,
- state->src_off,
- state->next_io_size,
- READ_LOCK,
- &state->read_lck);
-
- ok = SMB_VFS_STRICT_LOCK(state->src_fsp->conn,
- state->src_fsp,
- &state->read_lck);
- if (!ok) {
- return NT_STATUS_FILE_LOCK_CONFLICT;
+ state->src_off,
+ state->next_io_size,
+ READ_LOCK,
+ &state->read_lck);
+
+ ok = SMB_VFS_STRICT_LOCK(state->src_fsp->conn,
+ state->src_fsp,
+ &state->read_lck);
+ if (!ok) {
+ return NT_STATUS_FILE_LOCK_CONFLICT;
+ }
}
subreq = SMB_VFS_PREAD_SEND(state,
@@ -1731,10 +1747,12 @@ static void vfswrap_copy_chunk_read_done(struct tevent_req *subreq)
ssize_t nread;
bool ok;
- SMB_VFS_STRICT_UNLOCK(state->src_fsp->conn,
- state->src_fsp,
- &state->read_lck);
- ZERO_STRUCT(state->read_lck);
+ if (!(state->flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
+ SMB_VFS_STRICT_UNLOCK(state->src_fsp->conn,
+ state->src_fsp,
+ &state->read_lck);
+ ZERO_STRUCT(state->read_lck);
+ }
nread = SMB_VFS_PREAD_RECV(subreq, &aio_state);
TALLOC_FREE(subreq);
@@ -1752,19 +1770,21 @@ static void vfswrap_copy_chunk_read_done(struct tevent_req *subreq)
state->src_off += nread;
- init_strict_lock_struct(state->dst_fsp,
+ if (!(state->flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
+ init_strict_lock_struct(state->dst_fsp,
state->dst_fsp->op->global->open_persistent_id,
- state->dst_off,
- state->next_io_size,
- WRITE_LOCK,
- &state->write_lck);
-
- ok = SMB_VFS_STRICT_LOCK(state->dst_fsp->conn,
- state->dst_fsp,
- &state->write_lck);
- if (!ok) {
- tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
- return;
+ state->dst_off,
+ state->next_io_size,
+ WRITE_LOCK,
+ &state->write_lck);
+
+ ok = SMB_VFS_STRICT_LOCK(state->dst_fsp->conn,
+ state->dst_fsp,
+ &state->write_lck);
+ if (!ok) {
+ tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
+ return;
+ }
}
subreq = SMB_VFS_PWRITE_SEND(state,
@@ -1789,10 +1809,12 @@ static void vfswrap_copy_chunk_write_done(struct tevent_req *subreq)
ssize_t nwritten;
NTSTATUS status;
- SMB_VFS_STRICT_UNLOCK(state->dst_fsp->conn,
- state->dst_fsp,
- &state->write_lck);
- ZERO_STRUCT(state->write_lck);
+ if (!(state->flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
+ SMB_VFS_STRICT_UNLOCK(state->dst_fsp->conn,
+ state->dst_fsp,
+ &state->write_lck);
+ ZERO_STRUCT(state->write_lck);
+ }
nwritten = SMB_VFS_PWRITE_RECV(subreq, &aio_state);
TALLOC_FREE(subreq);
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 273540e..ee8cdb7 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -5233,7 +5233,8 @@ static struct tevent_req *fruit_copy_chunk_send(struct vfs_handle_struct *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, *subreq;
struct fruit_copy_chunk_state *fruit_copy_chunk_state;
@@ -5283,7 +5284,8 @@ static struct tevent_req *fruit_copy_chunk_send(struct vfs_handle_struct *handle
src_off,
dest_fsp,
dest_off,
- to_copy);
+ to_copy,
+ flags);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 6614fbb..4c2eb87 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -1889,12 +1889,14 @@ static struct tevent_req *smb_full_audit_copy_chunk_send(struct vfs_handle_struc
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, "");
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index 2ac3d97..52bd00e 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -1886,7 +1886,8 @@ static struct tevent_req *smb_time_audit_copy_chunk_send(struct vfs_handle_struc
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;
@@ -1901,7 +1902,7 @@ static struct tevent_req *smb_time_audit_copy_chunk_send(struct vfs_handle_struc
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);
}
diff --git a/source3/smbd/smb2_ioctl_filesys.c b/source3/smbd/smb2_ioctl_filesys.c
index 64b5454..fbff97c 100644
--- a/source3/smbd/smb2_ioctl_filesys.c
+++ b/source3/smbd/smb2_ioctl_filesys.c
@@ -31,6 +31,275 @@
#include "librpc/gen_ndr/ndr_ioctl.h"
#include "smb2_ioctl_private.h"
+/*
+ * XXX this may reduce dup_extents->byte_count so that it's less than the
+ * target file size.
+ */
+static NTSTATUS fsctl_dup_extents_check_lengths(struct files_struct *src_fsp,
+ struct files_struct *dst_fsp,
+ struct fsctl_dup_extents_to_file *dup_extents)
+{
+ NTSTATUS status;
+
+ if ((dup_extents->source_off + dup_extents->byte_count
+ < dup_extents->source_off)
+ || (dup_extents->target_off + dup_extents->byte_count
+ < dup_extents->target_off)) {
+ return NT_STATUS_INVALID_PARAMETER; /* wrap */
+ }
+
+ status = vfs_stat_fsp(src_fsp);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /*
+ * XXX vfs_btrfs and vfs_default have size checks in the copychunk
+ * handler, as this needs to be rechecked after the src has potentially
+ * been extended by a previous chunk in the compound copychunk req.
+ */
+ if (src_fsp->fsp_name->st.st_ex_size
+ < dup_extents->source_off + dup_extents->byte_count) {
+ DEBUG(2, ("dup_extents req exceeds src size\n"));
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+
+ status = vfs_stat_fsp(dst_fsp);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (dst_fsp->fsp_name->st.st_ex_size
+ < dup_extents->target_off + dup_extents->byte_count) {
+
+ if (dst_fsp->fsp_name->st.st_ex_size - dup_extents->target_off
+ > dst_fsp->fsp_name->st.st_ex_size) {
+ return NT_STATUS_INVALID_PARAMETER; /* wrap */
+ }
+
--
Samba Shared Repository
More information about the samba-cvs
mailing list