From: Stefan Metzmacher Date: Wed, 23 May 2018 10:03:02 +0000 (+0200) Subject: vfs_btrfs: make use of become_user_by_fsp() in order to switch between src and dst fsp X-Git-Tag: tevent-0.9.37~293 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d75da9f61f16eac3c137e16f98e16f4022b79b0;p=thirdparty%2Fsamba.git vfs_btrfs: make use of become_user_by_fsp() in order to switch between src and dst fsp We can use become_user_by_fsp()/unbecome_user() as it spans only parts of the btrfs_offload_write_send() function and never goes async in between. This may matter if at least one share uses "force user". Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme --- diff --git a/source3/modules/vfs_btrfs.c b/source3/modules/vfs_btrfs.c index 515859d6b90..a11cb66d8e7 100644 --- a/source3/modules/vfs_btrfs.c +++ b/source3/modules/vfs_btrfs.c @@ -199,7 +199,26 @@ static NTSTATUS btrfs_offload_read_recv(struct tevent_req *req, struct btrfs_offload_write_state { struct vfs_handle_struct *handle; off_t copied; + bool need_unbecome_user; }; + +static void btrfs_offload_write_cleanup(struct tevent_req *req, + enum tevent_req_state req_state) +{ + struct btrfs_offload_write_state *state = + tevent_req_data(req, + struct btrfs_offload_write_state); + bool ok; + + if (!state->need_unbecome_user) { + return; + } + + ok = unbecome_user(); + SMB_ASSERT(ok); + state->need_unbecome_user = false; +} + static void btrfs_offload_write_done(struct tevent_req *subreq); static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *handle, @@ -224,6 +243,7 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han bool handle_offload_write = true; bool do_locking = false; NTSTATUS status; + bool ok; req = tevent_req_create(mem_ctx, &state, struct btrfs_offload_write_state); @@ -233,6 +253,8 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han state->handle = handle; + tevent_req_set_cleanup_fn(req, btrfs_offload_write_cleanup); + status = vfs_offload_token_db_fetch_fsp(btrfs_offload_ctx, token, &src_fsp); if (tevent_req_nterror(req, status)) { @@ -289,6 +311,13 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han return tevent_req_post(req, ev); } + ok = become_user_by_fsp(src_fsp); + if (!ok) { + tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); + return tevent_req_post(req, ev); + } + state->need_unbecome_user = true; + status = vfs_stat_fsp(src_fsp); if (tevent_req_nterror(req, status)) { return tevent_req_post(req, ev); @@ -307,17 +336,24 @@ static struct tevent_req *btrfs_offload_write_send(struct vfs_handle_struct *han num, READ_LOCK, &src_lck); + if (!SMB_VFS_STRICT_LOCK_CHECK(src_fsp->conn, src_fsp, &src_lck)) { + tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT); + return tevent_req_post(req, ev); + } + } + + ok = unbecome_user(); + SMB_ASSERT(ok); + state->need_unbecome_user = false; + + if (do_locking) { init_strict_lock_struct(dest_fsp, - dest_fsp->op->global->open_persistent_id, + dest_fsp->op->global->open_persistent_id, dest_off, num, WRITE_LOCK, &dest_lck); - if (!SMB_VFS_STRICT_LOCK_CHECK(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_CHECK(dest_fsp->conn, dest_fsp, &dest_lck)) { tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT); return tevent_req_post(req, ev);