struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, struct file_id id) { struct share_mode_lock *lck; TDB_DATA key = locking_key(&id); 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(lck, data); TALLOC_FREE(data.dptr); if (lck->data == NULL) { TALLOC_FREE(lck); return NULL; } return lck; }
static void fetch_share_mode_unlocked_parser( TDB_DATA key, TDB_DATA data, void *private_data) { struct share_mode_lock *lck = talloc_get_type_abort( private_data, struct share_mode_lock); lck->data = parse_share_modes(lck, data); }
static struct share_mode_lock *get_share_mode_lock_internal( TALLOC_CTX *mem_ctx, 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 db_record *rec; TDB_DATA key = locking_key(&id); 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(5, ("get_share_mode_lock_internal: " "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, SMB_DEV_T dev, SMB_INO_T ino, const char *servicepath, const char *fname) { struct share_mode_lock *lck; TDB_DATA key = locking_key(dev, ino); TDB_DATA data; lck = TALLOC_P(mem_ctx, struct share_mode_lock); if (lck == NULL) { DEBUG(0, ("talloc failed\n")); return NULL; } /* Ensure we set every field here as the destructor must be valid even if parse_share_modes fails. */ lck->servicepath = NULL; lck->filename = NULL; lck->dev = dev; lck->ino = ino; lck->num_share_modes = 0; lck->share_modes = NULL; lck->delete_token = NULL; lck->delete_on_close = False; lck->initial_delete_on_close = False; lck->fresh = False; lck->modified = False; if (tdb_chainlock(tdb, key) != 0) { DEBUG(3, ("Could not lock share entry\n")); TALLOC_FREE(lck); return NULL; } /* We must set the destructor immediately after the chainlock ensure the lock is cleaned up on any of the error return paths below. */ talloc_set_destructor(lck, share_mode_lock_destructor); data = tdb_fetch(tdb, key); lck->fresh = (data.dptr == NULL); if (lck->fresh) { if (fname == NULL || servicepath == NULL) { TALLOC_FREE(lck); return NULL; } lck->filename = talloc_strdup(lck, fname); lck->servicepath = talloc_strdup(lck, servicepath); if (lck->filename == NULL || lck->servicepath == NULL) { DEBUG(0, ("talloc failed\n")); TALLOC_FREE(lck); return NULL; } } else { if (!parse_share_modes(data, lck)) { DEBUG(0, ("Could not parse share modes\n")); TALLOC_FREE(lck); SAFE_FREE(data.dptr); return NULL; } } SAFE_FREE(data.dptr); return lck; }