diff options
-rw-r--r-- | source3/smbd/open.c | 94 |
1 files changed, 26 insertions, 68 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 7a85552910..1fd8c11e2d 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1204,8 +1204,18 @@ static bool delay_for_exclusive_oplocks(files_struct *fsp, return true; } +static bool file_has_brlocks(files_struct *fsp) +{ + struct byte_range_lock *br_lck; + + br_lck = brl_get_locks_readonly(fsp); + if (!br_lck) + return false; + + return br_lck->num_locks > 0 ? true : false; +} + static void grant_fsp_oplock_type(files_struct *fsp, - const struct byte_range_lock *br_lck, int oplock_request, bool got_level2_oplock, bool got_a_none_oplock) @@ -1223,7 +1233,7 @@ static void grant_fsp_oplock_type(files_struct *fsp, DEBUG(10,("grant_fsp_oplock_type: oplock type 0x%x on file %s\n", fsp->oplock_type, fsp_str_dbg(fsp))); return; - } else if (br_lck && br_lck->num_locks > 0) { + } else if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) { DEBUG(10,("grant_fsp_oplock_type: file %s has byte range locks\n", fsp_str_dbg(fsp))); fsp->oplock_type = NO_OPLOCK; @@ -1593,52 +1603,6 @@ void remove_deferred_open_entry(struct file_id id, uint64_t mid, TALLOC_FREE(lck); } -/**************************************************************** - Ensure we get the brlock lock followed by the share mode lock - in the correct order to prevent deadlocks if other smbd's are - using the brlock database on this file simultaneously with this open - (that code also gets the locks in brlock -> share mode lock order). -****************************************************************/ - -static bool acquire_ordered_locks(TALLOC_CTX *mem_ctx, - files_struct *fsp, - const struct file_id id, - const char *connectpath, - const struct smb_filename *smb_fname, - const struct timespec *p_old_write_time, - struct share_mode_lock **p_lck, - struct byte_range_lock **p_br_lck) -{ - /* Ordering - we must get the br_lck for this - file before the share mode. */ - if (lp_locking(fsp->conn->params)) { - *p_br_lck = brl_get_locks_readonly(fsp); - if (*p_br_lck == NULL) { - DEBUG(0, ("Could not get br_lock\n")); - return false; - } - /* Note - we don't need to free the returned - br_lck explicitly as it was allocated on talloc_tos() - and so will be autofreed (and release the lock) - once the frame context disappears. - - If it was set to fsp->brlock_rec then it was - talloc_move'd to hang off the fsp pointer and - in this case is guarenteed to not be holding the - lock on the brlock database. */ - } - - *p_lck = get_share_mode_lock_fresh( - mem_ctx, id, connectpath, smb_fname, p_old_write_time); - - if (*p_lck == NULL) { - DEBUG(0, ("Could not get share mode lock\n")); - TALLOC_FREE(*p_br_lck); - return false; - } - return true; -} - /**************************************************************************** Open a file with a share mode. Passed in an already created files_struct *. ****************************************************************************/ @@ -1975,7 +1939,6 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, } if (file_existed) { - struct byte_range_lock *br_lck = NULL; struct share_mode_entry *batch_entry = NULL; struct share_mode_entry *exclusive_entry = NULL; bool got_level2_oplock = false; @@ -1985,14 +1948,11 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, struct timespec old_write_time = smb_fname->st.st_ex_mtime; id = vfs_file_id_from_sbuf(conn, &smb_fname->st); - if (!acquire_ordered_locks(talloc_tos(), - fsp, - id, - conn->connectpath, - smb_fname, - &old_write_time, - &lck, - &br_lck)) { + lck = get_share_mode_lock_fresh(talloc_tos(), id, + conn->connectpath, + smb_fname, &old_write_time); + if (lck == NULL) { + DEBUG(0, ("Could not get share mode lock\n")); return NT_STATUS_SHARING_VIOLATION; } @@ -2046,7 +2006,6 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, } grant_fsp_oplock_type(fsp, - br_lck, oplock_request, got_level2_oplock, got_a_none_oplock); @@ -2208,7 +2167,6 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, } if (!file_existed) { - struct byte_range_lock *br_lck = NULL; struct share_mode_entry *batch_entry = NULL; struct share_mode_entry *exclusive_entry = NULL; bool got_level2_oplock = false; @@ -2232,14 +2190,15 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, id = fsp->file_id; - if (!acquire_ordered_locks(talloc_tos(), - fsp, - id, - conn->connectpath, - smb_fname, - &old_write_time, - &lck, - &br_lck)) { + lck = get_share_mode_lock_fresh(talloc_tos(), id, + conn->connectpath, + smb_fname, &old_write_time); + + if (lck == NULL) { + DEBUG(0, ("open_file_ntcreate: Could not get share " + "mode lock for %s\n", + smb_fname_str_dbg(smb_fname))); + fd_close(fsp); return NT_STATUS_SHARING_VIOLATION; } @@ -2309,7 +2268,6 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, } grant_fsp_oplock_type(fsp, - br_lck, oplock_request, got_level2_oplock, got_a_none_oplock); |