Example #1
0
/* 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;
}
Example #2
0
/* 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;
}
Example #3
0
/* 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;
}
Example #4
0
/* 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;
}
Example #5
0
/* return 0 if good, 1 if not */
static GOOD_OR_BAD Cache_Add_Common(struct tree_node *tn)
{
	struct tree_opaque *opaque;
	enum { no_add, yes_add, just_update } state = no_add;

	node_show(tn);
	LEVEL_DEBUG("Add to cache sn " SNformat " pointer=%p index=%d size=%d", SNvar(tn->tk.sn), tn->tk.p, tn->tk.extension, tn->dsize);
	CACHE_WLOCK;
	if (cache.time_to_kill < NOW_TIME) {	// old database has timed out
		FlipTree() ;
	}
	if (Globals.cache_size && (cache.old_ram_size + cache.new_ram_size > Globals.cache_size)) {
		// failed size test
		owfree(tn);
	} else if ((opaque = tsearch(tn, &cache.temporary_tree_new, tree_compare))) {
		//printf("Cache_Add_Common to %p\n",opaque);
		if (tn != opaque->key) {
			cache.new_ram_size += sizeof(tn) - sizeof(opaque->key);
			owfree(opaque->key);
			opaque->key = tn;
			state = just_update;
		} else {
			state = yes_add;
			cache.new_ram_size += sizeof(tn);
		}
	} else {					// nothing found or added?!? free our memory segment
		owfree(tn);
	}
	CACHE_WUNLOCK;
	/* Added or updated, update statistics */
	switch (state) {
		case yes_add: // add new entry
			STATLOCK;
			AVERAGE_IN(&new_avg);
			++cache_adds;			/* statistics */
			STATUNLOCK;
			return gbGOOD;
		case just_update: // update the time mark and data
			STATLOCK;
			AVERAGE_MARK(&new_avg);
			++cache_adds;			/* statistics */
			STATUNLOCK;
			return gbGOOD;
		default: // unable to add
			return gbBAD;
	}
}
Example #6
0
/* return 0 if good, 1 if not */
static GOOD_OR_BAD Cache_Add_Persistent(struct tree_node *tn)
{
	struct tree_opaque *opaque;
	enum { no_add, yes_add, just_update } state = no_add;
	LEVEL_DEBUG("Adding data to permanent store");

	PERSISTENT_WLOCK;
	opaque = tsearch(tn, &cache.persistent_tree, tree_compare) ;
	if ( opaque != NULL ) {
		//printf("CACHE ADD pointer=%p, key=%p\n",tn,opaque->key);
		if (tn != opaque->key) {
			owfree(opaque->key);
			opaque->key = tn;
			state = just_update;
		} else {
			state = yes_add;
		}
	} else {					// nothing found or added?!? free our memory segment
		owfree(tn);
	}
	PERSISTENT_WUNLOCK;

	switch (state) {
	case yes_add:
		STATLOCK;
		AVERAGE_IN(&store_avg);
		STATUNLOCK;
		return gbGOOD;
	case just_update:
		STATLOCK;
		AVERAGE_MARK(&store_avg);
		STATUNLOCK;
		return gbGOOD;
	default:
		return gbBAD;
	}
}