The branch, master has been updated via 6c1d98e Add comments to all functions (to help me understand it better). via 6da246b s3: Fix nested get_share_mode_lock calls via 6f9442a s3: Move the share_mode_lock handling to its own file via cfebba9 s3: Put an indirection layer into share_mode_lock via 9cf6d73 s3: Introduce get_share_mode_lock_fresh() via 540e51f s3: Replace fill_share_mode_lock() from 15cdbba s4:repl_cleartext_pwd.py: add optional 'clear_utf16_name' parameter
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 6c1d98eac06df7f033d8a69bb5be985067f96c9b Author: Jeremy Allison <j...@samba.org> Date: Thu Jan 12 14:46:45 2012 -0800 Add comments to all functions (to help me understand it better). Autobuild-User: Jeremy Allison <j...@samba.org> Autobuild-Date: Fri Jan 13 01:35:03 CET 2012 on sn-devel-104 commit 6da246bae1b000cb3191e114e978510ccacb7e90 Author: Volker Lendecke <v...@samba.org> Date: Tue Jan 10 17:07:29 2012 +0100 s3: Fix nested get_share_mode_lock calls This forces us to only do one real get_share_mode_lock call and share the data between the nested get_share_mode_lock calls. Signed-off-by: Jeremy Allison <j...@samba.org> commit 6f9442a705b7ca67c78137db537f556385aa8558 Author: Volker Lendecke <v...@samba.org> Date: Tue Jan 10 14:13:49 2012 +0100 s3: Move the share_mode_lock handling to its own file Signed-off-by: Jeremy Allison <j...@samba.org> commit cfebba96bdab2097b6115f10b649ec6c23c72519 Author: Volker Lendecke <v...@samba.org> Date: Tue Jan 10 13:56:37 2012 +0100 s3: Put an indirection layer into share_mode_lock Signed-off-by: Jeremy Allison <j...@samba.org> commit 9cf6d735d43f6f905b19f52d38c93aa30092333d Author: Volker Lendecke <v...@samba.org> Date: Mon Jan 9 14:30:53 2012 +0100 s3: Introduce get_share_mode_lock_fresh() This slightly simplifies the code path for all callers which assume that a share mode exists already. Only the callers in open_file_ntcreate and open_directory will ever create new share modes. Signed-off-by: Jeremy Allison <j...@samba.org> commit 540e51f77e07cc65b6b097f8ff01cd10f04644d0 Author: Volker Lendecke <v...@samba.org> Date: Mon Jan 9 14:09:28 2012 +0100 s3: Replace fill_share_mode_lock() This replaces fill_share_mode_lock() with the two routines fresh_share_mode_lock() and parse_share_modes(). This lifts the decision whether a share mode already existed on level up. Signed-off-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: source3/Makefile.in | 2 +- source3/include/smb.h | 4 + source3/librpc/idl/open_files.idl | 2 +- source3/locking/locking.c | 557 +++++-------------------------------- source3/locking/proto.h | 11 +- source3/locking/share_mode_lock.c | 542 ++++++++++++++++++++++++++++++++++++ source3/smbd/close.c | 30 +-- source3/smbd/open.c | 53 ++-- source3/smbd/oplock.c | 15 +- source3/smbd/reply.c | 7 +- source3/smbd/trans2.c | 7 +- source3/utils/status.c | 8 +- source3/wscript_build | 2 +- 13 files changed, 687 insertions(+), 553 deletions(-) create mode 100644 source3/locking/share_mode_lock.c Changeset truncated at 500 lines: diff --git a/source3/Makefile.in b/source3/Makefile.in index c3dbd31..b92097c 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -793,7 +793,7 @@ RPC_SERVER_OBJ = $(RPC_LSARPC_OBJ) $(RPC_WINREG_OBJ) $(RPC_INITSHUTDOWN_OBJ) \ RPC_CLIENT_SCHANNEL_OBJ = rpc_client/cli_pipe_schannel.o LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o \ - librpc/gen_ndr/ndr_open_files.o + librpc/gen_ndr/ndr_open_files.o locking/share_mode_lock.o PRIVILEGES_BASIC_OBJ = ../libcli/security/privileges.o diff --git a/source3/include/smb.h b/source3/include/smb.h index 2adfa36..11a05f9 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -163,6 +163,10 @@ struct wb_context; struct rpc_cli_smbd_conn; struct fncall_context; +struct share_mode_lock { + struct share_mode_data *data; +}; + struct vfs_fsp_data { struct vfs_fsp_data *next; struct vfs_handle_struct *owner; diff --git a/source3/librpc/idl/open_files.idl b/source3/librpc/idl/open_files.idl index 9f06a0c..cefb75a 100644 --- a/source3/librpc/idl/open_files.idl +++ b/source3/librpc/idl/open_files.idl @@ -44,5 +44,5 @@ interface open_files uint8 fresh; uint8 modified; [ignore] db_record *record; - } share_mode_lock; + } share_mode_data; } diff --git a/source3/locking/locking.c b/source3/locking/locking.c index db4f45f..7063b54 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -52,9 +52,6 @@ #define NO_LOCKING_COUNT (-1) -/* the locking database handle */ -static struct db_context *lock_db; - /**************************************************************************** Debugging aids :-). ****************************************************************************/ @@ -431,64 +428,6 @@ void locking_close_file(struct messaging_context *msg_ctx, } } -/**************************************************************************** - Initialise the locking functions. -****************************************************************************/ - -static bool locking_init_internal(bool read_only) -{ - brl_init(read_only); - - if (lock_db) - return True; - - lock_db = db_open(NULL, lock_path("locking.tdb"), - lp_open_files_db_hash_size(), - TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, - read_only?O_RDONLY:O_RDWR|O_CREAT, 0644); - - if (!lock_db) { - DEBUG(0,("ERROR: Failed to initialise locking database\n")); - return False; - } - - if (!posix_locking_init(read_only)) - return False; - - return True; -} - -bool locking_init(void) -{ - return locking_init_internal(false); -} - -bool locking_init_readonly(void) -{ - return locking_init_internal(true); -} - -/******************************************************************* - Deinitialize the share_mode management. -******************************************************************/ - -bool locking_end(void) -{ - brl_shutdown(); - TALLOC_FREE(lock_db); - return true; -} - -/******************************************************************* - Form a static locking key for a dev/inode pair. -******************************************************************/ - -static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp) -{ - *tmp = *id; - return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp)); -} - /******************************************************************* Print out a share mode. ********************************************************************/ @@ -510,279 +449,14 @@ char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e) } /******************************************************************* - Get all share mode entries for a dev/inode pair. + Fetch a share mode where we know one MUST exist. This call reference + counts it internally to allow for nested lock fetches. ********************************************************************/ -static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck) -{ - int i; - struct server_id *pids; - bool *pid_exists; - enum ndr_err_code ndr_err; - DATA_BLOB blob; - - blob.data = dbuf.dptr; - blob.length = dbuf.dsize; - - ndr_err = ndr_pull_struct_blob( - &blob, lck, lck, - (ndr_pull_flags_fn_t)ndr_pull_share_mode_lock); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DEBUG(1, ("ndr_pull_share_mode_lock failed\n")); - return false; - } - - lck->modified = false; - - if (DEBUGLEVEL >= 10) { - DEBUG(10, ("parse_share_modes:\n")); - NDR_PRINT_DEBUG(share_mode_lock, lck); - } - - /* - * Ensure that each entry has a real process attached. - */ - - pids = talloc_array(talloc_tos(), struct server_id, - lck->num_share_modes); - if (pids == NULL) { - smb_panic("parse_share_modes: talloc_array failed"); - } - pid_exists = talloc_array(talloc_tos(), bool, lck->num_share_modes); - if (pid_exists == NULL) { - smb_panic("parse_share_modes: talloc_array failed"); - } - - for (i=0; i<lck->num_share_modes; i++) { - pids[i] = lck->share_modes[i].pid; - } - - if (!serverids_exist(pids, lck->num_share_modes, pid_exists)) { - smb_panic("parse_share_modes: serverids_exist failed"); - } - - i = 0; - while (i < lck->num_share_modes) { - struct share_mode_entry *e = &lck->share_modes[i]; - if (!pid_exists[i]) { - *e = lck->share_modes[lck->num_share_modes-1]; - lck->num_share_modes -= 1; - lck->modified = True; - continue; - } - i += 1; - } - TALLOC_FREE(pid_exists); - TALLOC_FREE(pids); - - return True; -} - -static TDB_DATA unparse_share_modes(struct share_mode_lock *lck) -{ - DATA_BLOB blob; - enum ndr_err_code ndr_err; - - if (DEBUGLEVEL >= 10) { - DEBUG(10, ("unparse_share_modes:\n")); - NDR_PRINT_DEBUG(share_mode_lock, lck); - } - - if (lck->num_share_modes == 0) { - DEBUG(10, ("No used share mode found\n")); - return make_tdb_data(NULL, 0); - } - - ndr_err = ndr_push_struct_blob( - &blob, lck, lck, - (ndr_push_flags_fn_t)ndr_push_share_mode_lock); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - smb_panic("ndr_push_share_mode_lock failed"); - } - - return make_tdb_data(blob.data, blob.length); -} - -static int share_mode_lock_destructor(struct share_mode_lock *lck) -{ - NTSTATUS status; - TDB_DATA data; - - if (!lck->modified) { - return 0; - } - - data = unparse_share_modes(lck); - - if (data.dptr == NULL) { - if (!lck->fresh) { - /* There has been an entry before, delete it */ - - status = dbwrap_record_delete(lck->record); - if (!NT_STATUS_IS_OK(status)) { - char *errmsg; - - DEBUG(0, ("delete_rec returned %s\n", - nt_errstr(status))); - - if (asprintf(&errmsg, "could not delete share " - "entry: %s\n", - nt_errstr(status)) == -1) { - smb_panic("could not delete share" - "entry"); - } - smb_panic(errmsg); - } - } - goto done; - } - - status = dbwrap_record_store(lck->record, data, TDB_REPLACE); - if (!NT_STATUS_IS_OK(status)) { - char *errmsg; - - DEBUG(0, ("store returned %s\n", nt_errstr(status))); - - if (asprintf(&errmsg, "could not store share mode entry: %s", - nt_errstr(status)) == -1) { - smb_panic("could not store share mode entry"); - } - smb_panic(errmsg); - } - - done: - - return 0; -} - -static bool fill_share_mode_lock(struct share_mode_lock *lck, - struct file_id id, - const char *servicepath, - const struct smb_filename *smb_fname, - TDB_DATA share_mode_data, - const struct timespec *old_write_time) -{ - bool fresh; - - /* Ensure we set every field here as the destructor must be - valid even if parse_share_modes fails. */ - - lck->servicepath = NULL; - lck->base_name = NULL; - lck->stream_name = NULL; - lck->id = id; - lck->num_share_modes = 0; - lck->share_modes = NULL; - lck->num_delete_tokens = 0; - lck->delete_tokens = NULL; - ZERO_STRUCT(lck->old_write_time); - ZERO_STRUCT(lck->changed_write_time); - - fresh = (share_mode_data.dptr == NULL); - - if (fresh) { - bool has_stream; - if (smb_fname == NULL || servicepath == NULL - || old_write_time == NULL) { - return False; - } - - has_stream = smb_fname->stream_name != NULL; - - lck->base_name = talloc_strdup(lck, smb_fname->base_name); - lck->stream_name = talloc_strdup(lck, smb_fname->stream_name); - lck->servicepath = talloc_strdup(lck, servicepath); - if (lck->base_name == NULL || - (has_stream && lck->stream_name == NULL) || - lck->servicepath == NULL) { - DEBUG(0, ("talloc failed\n")); - return False; - } - lck->old_write_time = *old_write_time; - lck->modified = false; - } else { - if (!parse_share_modes(share_mode_data, lck)) { - DEBUG(0, ("Could not parse share modes\n")); - return False; - } - } - lck->fresh = fresh; - - return True; -} - struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, - const struct file_id id, - const char *servicepath, - const struct smb_filename *smb_fname, - const struct timespec *old_write_time) + const struct file_id id) { - struct share_mode_lock *lck; - struct file_id tmp; - struct db_record *rec; - TDB_DATA key = locking_key(&id, &tmp); - TDB_DATA value; - - if (!(lck = talloc(mem_ctx, struct share_mode_lock))) { - DEBUG(0, ("talloc failed\n")); - return NULL; - } - - rec = dbwrap_fetch_locked(lock_db, lck, key); - if (rec == NULL) { - DEBUG(3, ("Could not lock share entry\n")); - TALLOC_FREE(lck); - return NULL; - } - - value = dbwrap_record_get_value(rec); - - if (!fill_share_mode_lock(lck, id, servicepath, smb_fname, - value, old_write_time)) { - DEBUG(3, ("fill_share_mode_lock failed\n")); - TALLOC_FREE(lck); - return NULL; - } - - lck->record = rec; - talloc_set_destructor(lck, share_mode_lock_destructor); - - return lck; -} - -struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, - const struct file_id id) -{ - struct share_mode_lock *lck; - struct file_id tmp; - TDB_DATA key = locking_key(&id, &tmp); - TDB_DATA data; - NTSTATUS status; - - if (!(lck = talloc(mem_ctx, struct share_mode_lock))) { - DEBUG(0, ("talloc failed\n")); - return NULL; - } - - status = dbwrap_fetch(lock_db, lck, key, &data); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("Could not fetch share entry\n")); - TALLOC_FREE(lck); - return NULL; - } - if (data.dptr == NULL) { - TALLOC_FREE(lck); - return NULL; - } - - if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) { - DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record " - "around (file not open)\n")); - TALLOC_FREE(lck); - return NULL; - } - - return lck; + return get_share_mode_lock_fresh(mem_ctx, id, NULL, NULL, NULL); } /******************************************************************* @@ -799,6 +473,7 @@ bool rename_share_filename(struct messaging_context *msg_ctx, uint32_t new_name_hash, const struct smb_filename *smb_fname_dst) { + struct share_mode_data *d = lck->data; size_t sp_len; size_t bn_len; size_t sn_len; @@ -822,48 +497,48 @@ bool rename_share_filename(struct messaging_context *msg_ctx, strip_two_chars = true; } - lck->servicepath = talloc_strdup(lck, servicepath); - lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name + + d->servicepath = talloc_strdup(d, servicepath); + d->base_name = talloc_strdup(d, smb_fname_dst->base_name + (strip_two_chars ? 2 : 0)); - lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name); - if (lck->base_name == NULL || - (has_stream && lck->stream_name == NULL) || - lck->servicepath == NULL) { + d->stream_name = talloc_strdup(d, smb_fname_dst->stream_name); + if (d->base_name == NULL || + (has_stream && d->stream_name == NULL) || + d->servicepath == NULL) { DEBUG(0, ("rename_share_filename: talloc failed\n")); return False; } - lck->modified = True; + d->modified = True; - sp_len = strlen(lck->servicepath); - bn_len = strlen(lck->base_name); - sn_len = has_stream ? strlen(lck->stream_name) : 0; + sp_len = strlen(d->servicepath); + bn_len = strlen(d->base_name); + sn_len = has_stream ? strlen(d->stream_name) : 0; msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 + sn_len + 1; /* Set up the name changed message. */ - frm = talloc_array(lck, char, msg_len); + frm = talloc_array(d, char, msg_len); if (!frm) { return False; } - push_file_id_24(frm, &lck->id); + push_file_id_24(frm, &d->id); DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len )); strlcpy(&frm[24], - lck->servicepath ? lck->servicepath : "", + d->servicepath ? d->servicepath : "", sp_len+1); strlcpy(&frm[24 + sp_len + 1], - lck->base_name ? lck->base_name : "", + d->base_name ? d->base_name : "", bn_len+1); strlcpy(&frm[24 + sp_len + 1 + bn_len + 1], - lck->stream_name ? lck->stream_name : "", + d->stream_name ? d->stream_name : "", sn_len+1); /* Send the messages. */ - for (i=0; i<lck->num_share_modes; i++) { - struct share_mode_entry *se = &lck->share_modes[i]; + for (i=0; i<d->num_share_modes; i++) { + struct share_mode_entry *se = &d->share_modes[i]; if (!is_valid_share_mode_entry(se)) { continue; } @@ -885,9 +560,9 @@ bool rename_share_filename(struct messaging_context *msg_ctx, "pid %s file_id %s sharepath %s base_name %s " "stream_name %s\n", procid_str_static(&se->pid), - file_id_string_tos(&lck->id), - lck->servicepath, lck->base_name, - has_stream ? lck->stream_name : "")); + file_id_string_tos(&d->id), + d->servicepath, d->base_name, + has_stream ? d->stream_name : "")); messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME, (uint8 *)frm, msg_len); @@ -922,9 +597,9 @@ void get_file_infos(struct file_id id, if (write_time) { struct timespec wt; - wt = lck->changed_write_time; + wt = lck->data->changed_write_time; if (null_timespec(wt)) { - wt = lck->old_write_time; + wt = lck->data->old_write_time; } -- Samba Shared Repository