diff options
Diffstat (limited to 'source3')
| -rw-r--r-- | source3/modules/vfs_default.c | 42 | 
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);  		}  | 
