/* After parsing, but before sending to various devices. Will repeat 3 times if needed */ SIZE_OR_ERROR FS_read_postparse(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); SIZE_OR_ERROR read_or_error; // ServerRead jumps in here, perhaps with non-file entry if (pn->selected_device == NO_DEVICE || pn->selected_filetype == NO_FILETYPE) { return -EISDIR; } /* Normal read. Try three times */ LEVEL_DEBUG("%s", pn->path); STATLOCK; AVERAGE_IN(&read_avg); AVERAGE_IN(&all_avg); STATUNLOCK; /* First try */ STAT_ADD1(read_tries[0]); read_or_error = (pn->type == ePN_real) ? FS_read_real(owq) : FS_r_virtual(owq); STATLOCK; if (read_or_error >= 0) { ++read_success; /* statistics */ read_bytes += read_or_error; /* statistics */ } AVERAGE_OUT(&read_avg); AVERAGE_OUT(&all_avg); STATUNLOCK; LEVEL_DEBUG("%s return %d", pn->path, read_or_error); return read_or_error; }
/* After parsing, choose special read based on path type */ static SIZE_OR_ERROR FS_read_distribute(struct one_wire_query *owq) { // Device not locked SIZE_OR_ERROR read_or_error = 0; LEVEL_DEBUG("%s", PN(owq)->path); STATLOCK; AVERAGE_IN(&read_avg); AVERAGE_IN(&all_avg); STATUNLOCK; /* handle DeviceSimultaneous */ if (PN(owq)->selected_device == DeviceSimultaneous) { read_or_error = FS_r_simultaneous(owq); } else { read_or_error = FS_r_given_bus(owq); } STATLOCK; if (read_or_error >= 0) { ++read_success; /* statistics */ read_bytes += read_or_error; /* statistics */ } AVERAGE_OUT(&read_avg); AVERAGE_OUT(&all_avg); STATUNLOCK; LEVEL_DEBUG("%s returns %d", PN(owq)->path, read_or_error); //printf("FS_read_distribute: pid=%ld return %d\n", pthread_self(), read_or_error); return read_or_error; }
/* return size if ok, else negative */ SIZE_OR_ERROR FS_write_postparse(struct one_wire_query *owq) { ZERO_OR_ERROR write_or_error; struct parsedname *pn = PN(owq); if (Globals.readonly) { LEVEL_DEBUG("Attempt to write but readonly set on command line."); return -EROFS; // read-only invokation } if (IsDir(pn)) { LEVEL_DEBUG("Attempt to write to a directory."); return -EISDIR; // not a file } STATLOCK; AVERAGE_IN(&write_avg); AVERAGE_IN(&all_avg); ++write_calls; /* statistics */ STATUNLOCK; write_or_error = FS_write_post_stats( owq ) ; STATLOCK; // write_or_error is still ZERO_OR_ERROR mode if ( write_or_error == 0 ) { LEVEL_DEBUG("Successful write to %s",pn->path) ; } else { LEVEL_DEBUG("Error writing to %s",pn->path) ; } if (write_or_error == 0) { ++write_success; /* statistics */ write_bytes += OWQ_size(owq); /* statistics */ // write_or_error now SIZE_OR_ERROR mode write_or_error = OWQ_size(owq); /* here's where the size is used! */ } AVERAGE_OUT(&write_avg); AVERAGE_OUT(&all_avg); STATUNLOCK; return write_or_error; }
/* After parsing, but before sending to various devices. Will repeat 3 times if needed */ SIZE_OR_ERROR FS_read_postparse(struct one_wire_query *owq) { struct parsedname *pn = PN(owq); SIZE_OR_ERROR read_or_error; /* Normal read. Try three times */ LEVEL_DEBUG("%s", pn->path); STATLOCK; AVERAGE_IN(&read_avg); AVERAGE_IN(&all_avg); STATUNLOCK; /* First try */ STAT_ADD1(read_tries[0]); /* Check file type. */ if (pn->selected_device == NO_DEVICE || pn->selected_filetype == NO_FILETYPE) { if (KnownBus(pn) && BusIsServer(pn->selected_connection)) { /* Pass unknown remote filetype to remote owserver. */ read_or_error = FS_r_given_bus(owq); } else { /* Local unknown filetypes are directories. */ return -EISDIR; } } else { /* Local known filetypes are handled here. */ read_or_error = (pn->type == ePN_real) ? FS_read_real(owq) : FS_r_virtual(owq); } STATLOCK; if (read_or_error >= 0) { ++read_success; /* statistics */ read_bytes += read_or_error; /* statistics */ } AVERAGE_OUT(&read_avg); AVERAGE_OUT(&all_avg); STATUNLOCK; LEVEL_DEBUG("%s return %d", pn->path, read_or_error); return read_or_error; }
static GOOD_OR_BAD Cache_Del_Persistent(const struct tree_node *tn) { struct tree_opaque *opaque; struct tree_node *tn_found = NULL; PERSISTENT_WLOCK; opaque = tfind(tn, &cache.persistent_tree, tree_compare) ; if ( opaque != NULL ) { tn_found = opaque->key; tdelete(tn, &cache.persistent_tree, tree_compare); } PERSISTENT_WUNLOCK; if ( tn_found == NULL ) { return gbBAD; } owfree(tn_found); STATLOCK; AVERAGE_OUT(&store_avg); STATUNLOCK; return gbGOOD; }