From 6f9442a705b7ca67c78137db537f556385aa8558 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 10 Jan 2012 14:13:49 +0100 Subject: s3: Move the share_mode_lock handling to its own file Signed-off-by: Jeremy Allison --- source3/locking/locking.c | 415 ---------------------------------------------- 1 file changed, 415 deletions(-) (limited to 'source3/locking/locking.c') diff --git a/source3/locking/locking.c b/source3/locking/locking.c index d98d19b399..9199591d9e 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. ********************************************************************/ @@ -509,287 +448,12 @@ char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e) (unsigned int)e->name_hash); } -/******************************************************************* - Get all share mode entries for a dev/inode pair. -********************************************************************/ - -static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx, - const TDB_DATA dbuf) -{ - struct share_mode_data *d; - int i; - struct server_id *pids; - bool *pid_exists; - enum ndr_err_code ndr_err; - DATA_BLOB blob; - - d = talloc_zero(mem_ctx, struct share_mode_data); - if (d == NULL) { - DEBUG(0, ("talloc failed\n")); - goto fail; - } - - blob.data = dbuf.dptr; - blob.length = dbuf.dsize; - - ndr_err = ndr_pull_struct_blob( - &blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DEBUG(1, ("ndr_pull_share_mode_lock failed\n")); - goto fail; - } - - d->modified = false; - d->fresh = false; - - if (DEBUGLEVEL >= 10) { - DEBUG(10, ("parse_share_modes:\n")); - NDR_PRINT_DEBUG(share_mode_data, d); - } - - /* - * Ensure that each entry has a real process attached. - */ - - pids = talloc_array(talloc_tos(), struct server_id, - d->num_share_modes); - if (pids == NULL) { - DEBUG(0, ("talloc failed\n")); - goto fail; - } - pid_exists = talloc_array(talloc_tos(), bool, d->num_share_modes); - if (pid_exists == NULL) { - DEBUG(0, ("talloc failed\n")); - goto fail; - } - - for (i=0; inum_share_modes; i++) { - pids[i] = d->share_modes[i].pid; - } - if (!serverids_exist(pids, d->num_share_modes, pid_exists)) { - DEBUG(0, ("serverid_exists failed\n")); - goto fail; - } - - i = 0; - while (i < d->num_share_modes) { - struct share_mode_entry *e = &d->share_modes[i]; - if (!pid_exists[i]) { - *e = d->share_modes[d->num_share_modes-1]; - d->num_share_modes -= 1; - d->modified = True; - continue; - } - i += 1; - } - TALLOC_FREE(pid_exists); - TALLOC_FREE(pids); - return d; -fail: - TALLOC_FREE(d); - return NULL; -} - -static TDB_DATA unparse_share_modes(struct share_mode_data *d) -{ - DATA_BLOB blob; - enum ndr_err_code ndr_err; - - if (DEBUGLEVEL >= 10) { - DEBUG(10, ("unparse_share_modes:\n")); - NDR_PRINT_DEBUG(share_mode_data, d); - } - - if (d->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, d, d, (ndr_push_flags_fn_t)ndr_push_share_mode_data); - 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_data_destructor(struct share_mode_data *d) -{ - NTSTATUS status; - TDB_DATA data; - - if (!d->modified) { - return 0; - } - - data = unparse_share_modes(d); - - if (data.dptr == NULL) { - if (!d->fresh) { - /* There has been an entry before, delete it */ - - status = dbwrap_record_delete(d->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(d->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 struct share_mode_data *fresh_share_mode_lock( - TALLOC_CTX *mem_ctx, const char *servicepath, - const struct smb_filename *smb_fname, - const struct timespec *old_write_time) -{ - struct share_mode_data *d; - - if ((servicepath == NULL) || (smb_fname == NULL) || - (old_write_time == NULL)) { - return NULL; - } - - d = talloc_zero(mem_ctx, struct share_mode_data); - if (d == NULL) { - goto fail; - } - d->base_name = talloc_strdup(d, smb_fname->base_name); - if (d->base_name == NULL) { - goto fail; - } - if (smb_fname->stream_name != NULL) { - d->stream_name = talloc_strdup(d, smb_fname->stream_name); - if (d->stream_name == NULL) { - goto fail; - } - } - d->servicepath = talloc_strdup(d, servicepath); - if (d->servicepath == NULL) { - goto fail; - } - d->old_write_time = *old_write_time; - d->modified = false; - d->fresh = true; - return d; -fail: - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(d); - return NULL; -} - -struct share_mode_lock *get_share_mode_lock_fresh(TALLOC_CTX *mem_ctx, - const struct file_id id, - const char *servicepath, - const struct smb_filename *smb_fname, - const struct timespec *old_write_time) -{ - struct share_mode_lock *lck; - struct share_mode_data *d; - struct file_id tmp; - struct db_record *rec; - TDB_DATA key = locking_key(&id, &tmp); - TDB_DATA value; - - rec = dbwrap_fetch_locked(lock_db, mem_ctx, key); - if (rec == NULL) { - DEBUG(3, ("Could not lock share entry\n")); - return NULL; - } - - value = dbwrap_record_get_value(rec); - - if (value.dptr == NULL) { - d = fresh_share_mode_lock(mem_ctx, servicepath, smb_fname, - old_write_time); - } else { - d = parse_share_modes(mem_ctx, value); - } - - if (d == NULL) { - DEBUG(1, ("Could not get share mode lock\n")); - TALLOC_FREE(rec); - return NULL; - } - d->id = id; - d->record = talloc_move(d, &rec); - talloc_set_destructor(d, share_mode_data_destructor); - - lck = talloc(mem_ctx, struct share_mode_lock); - if (lck == NULL) { - DEBUG(1, ("talloc failed\n")); - TALLOC_FREE(d); - return NULL; - } - lck->data = talloc_move(lck, &d); - return lck; -} - struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, const struct file_id id) { return get_share_mode_lock_fresh(mem_ctx, id, NULL, NULL, NULL); } -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; - - status = dbwrap_fetch(lock_db, talloc_tos(), key, &data); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("Could not fetch share entry\n")); - return NULL; - } - if (data.dptr == NULL) { - return NULL; - } - lck = talloc(mem_ctx, struct share_mode_lock); - if (lck == NULL) { - TALLOC_FREE(data.dptr); - return NULL; - } - lck->data = parse_share_modes(mem_ctx, data); - TALLOC_FREE(data.dptr); - if (lck->data == NULL) { - TALLOC_FREE(lck); - return NULL; - } - return lck; -} - /******************************************************************* Sets the service name and filename for rename. At this point we emit "file renamed" messages to all @@ -1373,82 +1037,3 @@ bool set_write_time(struct file_id fileid, struct timespec write_time) TALLOC_FREE(lck); return True; } - - -struct forall_state { - void (*fn)(const struct share_mode_entry *entry, - const char *sharepath, - const char *fname, - void *private_data); - void *private_data; -}; - -static int traverse_fn(struct db_record *rec, void *_state) -{ - struct forall_state *state = (struct forall_state *)_state; - uint32_t i; - TDB_DATA key; - TDB_DATA value; - DATA_BLOB blob; - enum ndr_err_code ndr_err; - struct share_mode_data *d; - - key = dbwrap_record_get_key(rec); - value = dbwrap_record_get_value(rec); - - /* Ensure this is a locking_key record. */ - if (key.dsize != sizeof(struct file_id)) - return 0; - - d = talloc(talloc_tos(), struct share_mode_data); - if (d == NULL) { - return 0; - } - - blob.data = value.dptr; - blob.length = value.dsize; - - ndr_err = ndr_pull_struct_blob( - &blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DEBUG(1, ("ndr_pull_share_mode_lock failed\n")); - return 0; - } - for (i=0; inum_share_modes; i++) { - state->fn(&d->share_modes[i], - d->servicepath, d->base_name, - state->private_data); - } - TALLOC_FREE(d); - - return 0; -} - -/******************************************************************* - Call the specified function on each entry under management by the - share mode system. -********************************************************************/ - -int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, - const char *, void *), - void *private_data) -{ - struct forall_state state; - NTSTATUS status; - int count; - - if (lock_db == NULL) - return 0; - - state.fn = fn; - state.private_data = private_data; - - status = dbwrap_traverse_read(lock_db, traverse_fn, (void *)&state, - &count); - - if (!NT_STATUS_IS_OK(status)) { - return -1; - } else { - return count; - } -} -- cgit