diff options
author | Jeremy Allison <jra@samba.org> | 2013-01-16 16:30:04 -0800 |
---|---|---|
committer | David Disseldorp <ddiss@samba.org> | 2013-01-18 01:47:01 +0100 |
commit | f0852a3483424d1242390011a65c427d3dbd80f2 (patch) | |
tree | 98ecdaeaea9181410380813106b885315bf08022 | |
parent | f2d028ef552adf13eed10b7db47e35bfa89a9c02 (diff) | |
download | samba-f0852a3483424d1242390011a65c427d3dbd80f2.tar.gz samba-f0852a3483424d1242390011a65c427d3dbd80f2.tar.bz2 samba-f0852a3483424d1242390011a65c427d3dbd80f2.zip |
Remove locking across the lifetime of the copychunk call.
Previous commit handles this around each read/write call.
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: David Disseldorp <ddiss@samba.org>
Autobuild-User(master): David Disseldorp <ddiss@samba.org>
Autobuild-Date(master): Fri Jan 18 01:47:01 CET 2013 on sn-devel-104
-rw-r--r-- | source3/smbd/smb2_ioctl_network_fs.c | 117 |
1 files changed, 1 insertions, 116 deletions
diff --git a/source3/smbd/smb2_ioctl_network_fs.c b/source3/smbd/smb2_ioctl_network_fs.c index 7fc75076a1..a8d64e3b69 100644 --- a/source3/smbd/smb2_ioctl_network_fs.c +++ b/source3/smbd/smb2_ioctl_network_fs.c @@ -63,94 +63,6 @@ static NTSTATUS copychunk_check_limits(struct srv_copychunk_copy *cc_copy) return NT_STATUS_OK; } -static void copychunk_unlock_all(struct files_struct *src_fsp, - struct files_struct *dst_fsp, - struct lock_struct *rd_locks, - struct lock_struct *wr_locks, - uint32_t num_locks) -{ - - uint32_t i; - - for (i = 0; i < num_locks; i++) { - SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &rd_locks[i]); - SMB_VFS_STRICT_UNLOCK(dst_fsp->conn, dst_fsp, &wr_locks[i]); - } -} - -/* request read and write locks for each chunk */ -static NTSTATUS copychunk_lock_all(TALLOC_CTX *mem_ctx, - struct srv_copychunk_copy *cc_copy, - struct files_struct *src_fsp, - struct files_struct *dst_fsp, - struct lock_struct **rd_locks, - struct lock_struct **wr_locks, - uint32_t *num_locks) -{ - NTSTATUS status; - uint32_t i; - struct lock_struct *rlocks; - struct lock_struct *wlocks; - - rlocks = talloc_array(mem_ctx, struct lock_struct, - cc_copy->chunk_count); - if (rlocks == NULL) { - status = NT_STATUS_NO_MEMORY; - goto err_out; - } - - wlocks = talloc_array(mem_ctx, struct lock_struct, - cc_copy->chunk_count); - if (wlocks == NULL) { - status = NT_STATUS_NO_MEMORY; - goto err_rlocks_free; - } - - for (i = 0; i < cc_copy->chunk_count; i++) { - init_strict_lock_struct(src_fsp, - src_fsp->op->global->open_persistent_id, - cc_copy->chunks[i].source_off, - cc_copy->chunks[i].length, - READ_LOCK, - &rlocks[i]); - init_strict_lock_struct(dst_fsp, - dst_fsp->op->global->open_persistent_id, - cc_copy->chunks[i].target_off, - cc_copy->chunks[i].length, - WRITE_LOCK, - &wlocks[i]); - - if (!SMB_VFS_STRICT_LOCK(src_fsp->conn, src_fsp, &rlocks[i])) { - status = NT_STATUS_FILE_LOCK_CONFLICT; - goto err_unlock; - } - if (!SMB_VFS_STRICT_LOCK(dst_fsp->conn, dst_fsp, &wlocks[i])) { - /* unlock last rlock, otherwise missed by cleanup */ - SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, - &rlocks[i]); - status = NT_STATUS_FILE_LOCK_CONFLICT; - goto err_unlock; - } - } - - *rd_locks = rlocks; - *wr_locks = wlocks; - *num_locks = i; - - return NT_STATUS_OK; - -err_unlock: - if (i > 0) { - /* cleanup all locks successfully issued so far */ - copychunk_unlock_all(src_fsp, dst_fsp, rlocks, wlocks, i); - } - talloc_free(wlocks); -err_rlocks_free: - talloc_free(rlocks); -err_out: - return status; -} - struct fsctl_srv_copychunk_state { struct connection_struct *conn; uint32_t dispatch_count; @@ -160,9 +72,6 @@ struct fsctl_srv_copychunk_state { off_t total_written; struct files_struct *src_fsp; struct files_struct *dst_fsp; - struct lock_struct *wlocks; - struct lock_struct *rlocks; - uint32_t num_locks; enum { COPYCHUNK_OUT_EMPTY = 0, COPYCHUNK_OUT_LIMITS, @@ -297,17 +206,6 @@ static struct tevent_req *fsctl_srv_copychunk_send(TALLOC_CTX *mem_ctx, /* any errors from here onwards should carry copychunk response data */ state->out_data = COPYCHUNK_OUT_RSP; - state->status = copychunk_lock_all(state, - &cc_copy, - state->src_fsp, - state->dst_fsp, - &state->rlocks, - &state->wlocks, - &state->num_locks); - if (tevent_req_nterror(req, state->status)) { - return tevent_req_post(req, ev); - } - for (i = 0; i < cc_copy.chunk_count; i++) { struct tevent_req *vfs_subreq; chunk = &cc_copy.chunks[i]; @@ -323,17 +221,12 @@ static struct tevent_req *fsctl_srv_copychunk_send(TALLOC_CTX *mem_ctx, state->status = NT_STATUS_NO_MEMORY; if (state->dispatch_count == 0) { /* nothing dispatched, return immediately */ - copychunk_unlock_all(state->src_fsp, - state->dst_fsp, - state->rlocks, - state->wlocks, - state->num_locks); tevent_req_nterror(req, state->status); return tevent_req_post(req, ev); } else { /* * wait for dispatched to complete before - * returning error, locks held. + * returning error. */ break; } @@ -343,7 +236,6 @@ static struct tevent_req *fsctl_srv_copychunk_send(TALLOC_CTX *mem_ctx, state->dispatch_count++; } - /* hold locks until all dispatched requests are completed */ return req; } @@ -383,13 +275,6 @@ static void fsctl_srv_copychunk_vfs_done(struct tevent_req *subreq) return; } - /* all VFS copy_chunk requests done */ - copychunk_unlock_all(state->src_fsp, - state->dst_fsp, - state->rlocks, - state->wlocks, - state->num_locks); - if (!tevent_req_nterror(req, state->status)) { tevent_req_done(req); } |