summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/modules/vfs_default.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index d937c4a862..8a03ea372a 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1372,12 +1372,34 @@ static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *hand
/* could use 2.6.33+ sendfile here to do this in kernel */
while (vfs_cc_state->copied < num) {
ssize_t ret;
+ struct lock_struct lck;
+ int saved_errno;
+
off_t this_num = MIN(sizeof(vfs_cc_state->buf),
num - vfs_cc_state->copied);
+ init_strict_lock_struct(src_fsp,
+ src_fsp->op->global->open_persistent_id,
+ src_off,
+ this_num,
+ READ_LOCK,
+ &lck);
+
+ if (!SMB_VFS_STRICT_LOCK(src_fsp->conn, src_fsp, &lck)) {
+ tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
+ return tevent_req_post(req, ev);
+ }
+
ret = SMB_VFS_PREAD(src_fsp, vfs_cc_state->buf,
this_num, src_off);
if (ret == -1) {
+ saved_errno = errno;
+ }
+
+ SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &lck);
+
+ if (ret == -1) {
+ errno = saved_errno;
tevent_req_nterror(req, map_nt_error_from_unix(errno));
return tevent_req_post(req, ev);
}
@@ -1386,11 +1408,31 @@ static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *hand
tevent_req_nterror(req, NT_STATUS_IO_DEVICE_ERROR);
return tevent_req_post(req, ev);
}
+
src_off += ret;
+ init_strict_lock_struct(dest_fsp,
+ dest_fsp->op->global->open_persistent_id,
+ dest_off,
+ this_num,
+ WRITE_LOCK,
+ &lck);
+
+ if (!SMB_VFS_STRICT_LOCK(dest_fsp->conn, dest_fsp, &lck)) {
+ tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
+ return tevent_req_post(req, ev);
+ }
+
ret = SMB_VFS_PWRITE(dest_fsp, vfs_cc_state->buf,
this_num, dest_off);
if (ret == -1) {
+ saved_errno = errno;
+ }
+
+ SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &lck);
+
+ if (ret == -1) {
+ errno = saved_errno;
tevent_req_nterror(req, map_nt_error_from_unix(errno));
return tevent_req_post(req, ev);
}