/* return 0 if ok */ static ZERO_OR_ERROR FS_w_local(struct one_wire_query *owq) { // Device already locked struct parsedname *pn = PN(owq); struct filetype * ft = pn->selected_filetype ; /* Writable? */ if ( ft->write == NO_WRITE_FUNCTION ) { return -ENOTSUP; } /* Special case for "fake" adapter */ switch (get_busmode(pn->selected_connection)) { case bus_mock: case bus_fake: case bus_tester: return 0 ; default: // non-virtual devices get handled below break ; } /* Non-array? */ if ( ft->ag == NON_AGGREGATE ) { LEVEL_DEBUG("Write a non-array element %s",pn->path); return FS_write_owq(owq); } /* array */ switch ( ft->ag->combined ) { case ag_sparse: // avoid cache return (ft->write) (owq);; case ag_aggregate: switch (pn->extension) { case EXTENSION_BYTE: LEVEL_DEBUG("Write an aggregate .BYTE %s",pn->path); return FS_write_owq(owq); case EXTENSION_ALL: LEVEL_DEBUG("Write an aggregate .ALL %s",pn->path); return FS_write_all(owq); default: LEVEL_DEBUG("Write an aggregate element %s",pn->path); return FS_write_a_part(owq) ; } case ag_mixed: switch (pn->extension) { case EXTENSION_BYTE: LEVEL_DEBUG("Write a mixed .BYTE %s",pn->path); OWQ_Cache_Del_parts(owq); return FS_write_owq(owq); case EXTENSION_ALL: LEVEL_DEBUG("Write a mixed .ALL %s",pn->path); OWQ_Cache_Del_parts(owq); return FS_write_all(owq); default: LEVEL_DEBUG("Write a mixed element %s",pn->path); OWQ_Cache_Del_ALL(owq); OWQ_Cache_Del_BYTE(owq); return FS_write_owq(owq); } case ag_separate: switch (pn->extension) { case EXTENSION_BYTE: LEVEL_DEBUG("Write a separate .BYTE %s",pn->path); return FS_write_as_bits(owq); case EXTENSION_ALL: LEVEL_DEBUG("Write a separate .ALL %s",pn->path); return FS_write_in_parts(owq); default: LEVEL_DEBUG("Write a separate element %s",pn->path); return FS_write_owq(owq); } default: return -ENOENT ; } }
/* Real read -- called from read Integrates with cache -- read not called if cached value already set */ static SIZE_OR_ERROR FS_r_local(struct one_wire_query *owq) { // Bus and device already locked struct parsedname *pn = PN(owq); struct filetype * ft = pn->selected_filetype ; /* Readable? */ if (ft->read == NO_READ_FUNCTION) { return -ENOTSUP; } // Check buffer length adjust_file_size(owq) ; if ( OWQ_size(owq) == 0 ) { // Mounting fuse with "direct_io" will cause a second read with offset // at end-of-file... Just return 0 if offset == size LEVEL_DEBUG("Call for read at very end of file") ; return 0 ; } // Special check for alias -- it's ok for fake and tester and mock as well if ( ft->read == FS_r_alias ) { return FS_read_owq(owq) ; } if (ft->change != fc_static && ft->format != ft_alias && IsRealDir(pn)) { switch (pn->selected_connection->Adapter) { case adapter_fake: /* Special case for "fake" adapter */ return FS_read_fake(owq); case adapter_tester: /* Special case for "tester" adapter */ return FS_read_tester(owq); case adapter_mock: /* Special case for "mock" adapter */ if ( GOOD( OWQ_Cache_Get(owq)) ) { // cached return 0; } return FS_read_fake(owq); default: break ; } } if ( ft->ag == NON_AGGREGATE ) { /* non array property */ return FS_read_owq(owq) ; } /* Array property * Read separately? * Read together and manually separate? */ /* array */ switch ( ft->ag->combined ) { case ag_sparse: // skip cache test and storing return (ft->read) (owq); case ag_aggregate: switch (pn->extension) { case EXTENSION_BYTE: LEVEL_DEBUG("Read an aggregate .BYTE %s",pn->path); return FS_read_owq(owq); case EXTENSION_ALL: LEVEL_DEBUG("Read an aggregate .ALL %s",pn->path); return FS_read_all(owq); default: LEVEL_DEBUG("Read an aggregate element %s",pn->path); return FS_read_a_part(owq); } case ag_mixed: switch (pn->extension) { case EXTENSION_BYTE: LEVEL_DEBUG("Read a mixed .BYTE %s",pn->path); OWQ_Cache_Del_parts(owq); return FS_read_owq(owq); case EXTENSION_ALL: LEVEL_DEBUG("Read a mixed .ALL %s",pn->path); OWQ_Cache_Del_parts(owq); return FS_read_all(owq); default: LEVEL_DEBUG("Read a mixed element %s",pn->path); OWQ_Cache_Del_ALL(owq); OWQ_Cache_Del_BYTE(owq); return FS_read_owq(owq); } case ag_separate: switch (pn->extension) { case EXTENSION_BYTE: LEVEL_DEBUG("Read a separate .BYTE %s",pn->path); return FS_read_all_bits(owq); case EXTENSION_ALL: LEVEL_DEBUG("Read a separate .ALL %s",pn->path); return FS_read_in_parts(owq); default: LEVEL_DEBUG("Read a separate element %s",pn->path); return FS_read_owq(owq); } default: return -ENOENT ; } }