/** * Creates a new filter of the given name and parameters. * @arg filter_name The name of the filter * @arg custom_config Optional, can be null. Configs that override the defaults. * @return 0 on success, -1 if the filter already exists. * -2 for internal error. -3 if there is a pending delete. */ int filtmgr_create_filter(bloom_filtmgr *mgr, char *filter_name, bloom_config *custom_config) { int res = 0; pthread_mutex_lock(&mgr->write_lock); // Bail if the filter already exists. bloom_filter_wrapper *filt = find_filter(mgr, filter_name); if (filt) { res = (filt->is_active) ? -1 : -3; goto LEAVE; } // Scan the pending delete queue LOCK_BLOOM_SPIN(&mgr->pending_lock); if (mgr->pending_deletes) { bloom_filter_list *node = mgr->pending_deletes; while (node) { if (!strcmp(node->filter_name, filter_name)) { res = -3; // Pending delete UNLOCK_BLOOM_SPIN(&mgr->pending_lock); goto LEAVE; } node = node->next; } } UNLOCK_BLOOM_SPIN(&mgr->pending_lock); // Use a custom config if provided, else the default bloom_config *config = (custom_config) ? custom_config : mgr->config; // Add the filter to the new version if (add_filter(mgr, filter_name, config, 1, 1)) { res = -2; // Internal error } LEAVE: pthread_mutex_unlock(&mgr->write_lock); return res; }
// Gets the bloom filter in a thread safe way. static bloom_filter_wrapper* take_filter(bloom_filtmgr *mgr, char *filter_name) { bloom_filter_wrapper *filt = find_filter(mgr, filter_name); return (filt && filt->is_active) ? filt : NULL; }
void *fsal_up_thread(void *Arg) { fsal_status_t status; int rc; fsal_up_arg_t *fsal_up_args = (fsal_up_arg_t *)Arg; fsal_up_event_bus_context_t fsal_up_context; fsal_up_event_bus_parameter_t fsal_up_bus_param; fsal_up_event_bus_filter_t * pupebfilter = NULL; fsal_up_filter_list_t *filter = NULL; fsal_up_event_t *pevent_head, *event, *tmpevent; fsal_up_event_functions_t *event_func; fsal_count_t nb_events_found, event_nb; fsal_time_t timeout; char thr_name[40]; memset(&fsal_up_bus_param, 0, sizeof(fsal_up_event_bus_parameter_t)); memset(&fsal_up_context, 0, sizeof(fsal_up_event_bus_context_t)); snprintf(thr_name, sizeof(thr_name), "FSAL UP Thread for filesystem %llu.%llu", fsal_up_args->export_entry->filesystem_id.major, fsal_up_args->export_entry->filesystem_id.minor); SetNameFunction(thr_name); #ifndef _NO_BUDDY_SYSTEM if((rc = BuddyInit(&nfs_param.buddy_param_fsal_up)) != BUDDY_SUCCESS) { /* Failed init */ LogFatal(COMPONENT_FSAL_UP, "FSAL_UP: Memory manager could not be initialized"); Fatal(); } LogInfo(COMPONENT_FSAL_UP, "FSAL_UP: Memory manager for filesystem %llu.%llu export id %d" " successfully initialized", fsal_up_args->export_entry->filesystem_id.major, fsal_up_args->export_entry->filesystem_id.minor, fsal_up_args->export_entry->id); #endif /* Set the FSAL UP functions that will be used to process events. */ event_func = get_fsal_up_functions(fsal_up_args->export_entry->fsal_up_type); if (event_func == NULL) { LogCrit(COMPONENT_FSAL_UP, "Error: FSAL UP TYPE: %s does not exist. " "Exiting FSAL UP thread.", fsal_up_args->export_entry->fsal_up_type); Mem_Free(Arg); return NULL; } /* Get fsal up context from FSAL */ /* It is expected that the export entry and event_pool will be referenced * in the returned callback context structure. */ memcpy(&fsal_up_context.FS_export_context, &fsal_up_args->export_entry->FS_export_context, sizeof(fsal_export_context_t)); fsal_up_context.event_pool = &nfs_param.fsal_up_param.event_pool; LogDebug(COMPONENT_FSAL_UP, "Initializing FSAL Callback context."); status = FSAL_UP_Init(&fsal_up_bus_param, &fsal_up_context); if (FSAL_IS_ERROR(status)) { LogCrit(COMPONENT_FSAL_UP, "Error: Could not initialize FSAL UP for" " filesystem %llu.%llu export %d. Exiting FSAL UP thread.", fsal_up_args->export_entry->filesystem_id.major, fsal_up_args->export_entry->filesystem_id.minor, fsal_up_args->export_entry->id); } /* Add filters ... later if needed we could add arguments to filters * configurable from configuration files. */ for(filter = fsal_up_args->export_entry->fsal_up_filter_list; filter != NULL; filter = filter->next) { LogEvent(COMPONENT_FSAL_UP, "Applying filter \"%s\" to FSAL UP thread " "for filesystem id %llu.%llu export id %d.", filter->name, fsal_up_args->export_entry->filesystem_id.major, fsal_up_args->export_entry->filesystem_id.minor, fsal_up_args->export_entry->id); /* Find predefined filter */ pupebfilter = find_filter(filter->name); if (pupebfilter == NULL) { LogCrit(COMPONENT_FSAL_UP, "Error: Could not find filter named \"%s\".", filter->name); } /* Applying filter */ FSAL_UP_AddFilter(pupebfilter, &fsal_up_context); } /* Set the timeout for getting events. */ timeout = fsal_up_args->export_entry->fsal_up_timeout; /* Start querying for events and processing. */ while(1) { /* pevent is passed in as a single empty node, it's expected the * FSAL will use the event_pool in the bus_context to populate * this array by adding to the pevent_head->next attribute. */ event_nb = 0; nb_events_found = 0; pevent_head = NULL; LogDebug(COMPONENT_FSAL_UP, "Requesting event from FSAL Callback interface."); status = FSAL_UP_GetEvents(&pevent_head, /* out */ &event_nb, /* in/out */ timeout, /* in */ &nb_events_found, /* out */ &fsal_up_context);/* in */ if (FSAL_IS_ERROR(status)) { if (status.major == ERR_FSAL_TIMEOUT) LogDebug(COMPONENT_FSAL_UP, "FSAL_UP_EB_GetEvents() hit the timeout" " limit of %u.%u seconds for filesystem id %llu.%llu export id" " %d.", timeout.seconds, timeout.nseconds, fsal_up_args->export_entry->filesystem_id.major, fsal_up_args->export_entry->filesystem_id.minor, fsal_up_args->export_entry->id); else if (status.major == ERR_FSAL_NOTSUPP) { LogCrit(COMPONENT_FSAL_UP, "Exiting FSAL UP Thread for filesystem" " id %llu.%llu export id %u because the FSAL Callback" " Interface is not supported for this FSAL type.", fsal_up_args->export_entry->filesystem_id.major, fsal_up_args->export_entry->filesystem_id.minor, fsal_up_args->export_entry->id); return NULL; } else LogDebug(COMPONENT_FSAL_UP, "Error: FSAL_UP_EB_GetEvents() " "failed"); } LogDebug(COMPONENT_FSAL_UP, "Received %lu events to process for filesystem" " id %llu.%llu export id %u.", event_nb, fsal_up_args->export_entry->filesystem_id.major, fsal_up_args->export_entry->filesystem_id.minor, fsal_up_args->export_entry->id); /* process the list of events */ for(event = pevent_head; event != NULL;) { status = process_event(event, event_func); if (FSAL_IS_ERROR(status)) { LogDebug(COMPONENT_FSAL_UP, "Error: Event could not be processed " "for filesystem %llu.%llu export id %u.", fsal_up_args->export_entry->filesystem_id.major, fsal_up_args->export_entry->filesystem_id.minor, fsal_up_args->export_entry->id); } tmpevent = event; event = event->next_event; ReleaseToPool(tmpevent, &nfs_param.fsal_up_param.event_pool); event_nb--; } LogDebug(COMPONENT_FSAL_UP, "%lu events not found for filesystem" " %llu.%llu export id %u", event_nb, fsal_up_args->export_entry->filesystem_id.major, fsal_up_args->export_entry->filesystem_id.minor, fsal_up_args->export_entry->id); } Mem_Free(Arg); return NULL; } /* fsal_up_thread */