Beispiel #1
0
YMStreamRef __YMPlexerCreateStreamWithID(__ym_plexer_t *p, YMPlexerStreamID streamID, bool isLocal, YMStringRef userNameToRelease)
{
    __ym_plexer_stream_user_info_t *userInfo = (__ym_plexer_stream_user_info_t *)YMALLOC(sizeof(__ym_plexer_stream_user_info_t));
    userInfo->plexer = YMRetain(p);
    userInfo->streamID = streamID;
    userInfo->isLocallyOriginated = isLocal;
    userInfo->lastServiceTime = (struct timeval *)YMALLOC(sizeof(struct timeval));
    if ( 0 != gettimeofday(userInfo->lastServiceTime, NULL) ) {
        ymlog("warning: error setting initial service time for s%llu: %d (%s)",streamID,errno,strerror(errno));
        YMGetTheBeginningOfPosixTimeForCurrentPlatform(userInfo->lastServiceTime);
    }
    
    YMStringRef memberName = YMStringCreateWithFormat("%s-%s-s%llu-%s",p->master?"m":"s",isLocal?">":"<",streamID,YMSTR(userNameToRelease),NULL);
    userInfo->lock = YMLockCreateWithOptionsAndName(YMInternalLockType, memberName);
    userInfo->bytesAvailable = 0;
    userInfo->userClosed = false;
    userInfo->rawWritten = 0;
    userInfo->muxerWritten = 0;
    userInfo->rawRead = 0;
    userInfo->muxerRead = 0;
    YMStreamRef theStream = _YMStreamCreate(memberName, (ym_stream_user_info_t *)userInfo, __ym_plexer_free_stream_info);
    YMRelease(memberName);
    _YMStreamSetDataAvailableCallback(theStream, __ym_plexer_stream_data_available_proc, p);
    
    YMRelease(userNameToRelease);
    
    return theStream;
}
static int  CheckInit(yaffs_Device *dev)
{
	static int initialised = 0;
	
	int i;
	int fail = 0;
	int nAllocated = 0;
	
	if(initialised) 
	{
		return YAFFS_OK;
	}

	initialised = 1;
	
	
	ramdisk.nBlocks = (SIZE_IN_MB * 1024 * 1024)/(16 * 1024);
	
	ramdisk.block = YMALLOC(sizeof(yflash_Block *) * ramdisk.nBlocks);
	
	if(!ramdisk.block) return 0;
	
	for(i=0; i <ramdisk.nBlocks; i++)
	{
		ramdisk.block[i] = NULL;
	}
	
	for(i=0; i <ramdisk.nBlocks && !fail; i++)
	{
		if((ramdisk.block[i] = YMALLOC(sizeof(yflash_Block))) == 0)
		{
			fail = 1;
		}
		else
		{
			yflash_EraseBlockInNAND(dev,i);
			nAllocated++;
		}
	}
	
	if(fail)
	{
		for(i = 0; i < nAllocated; i++)
		{
			YFREE(ramdisk.block[i]);
		}
		YFREE(ramdisk.block);
		
		T(YAFFS_TRACE_ALWAYS,("Allocation failed, could only allocate %dMB of %dMB requested.\n",
		   nAllocated/64,ramdisk.nBlocks * YAFFS_BYTES_PER_BLOCK));
		return 0;
	}
	
	
	
	return 1;
}
Beispiel #3
0
YMPlexerRef YMPlexerCreate(YMStringRef name, YMSecurityProviderRef provider, bool master)
{
	__YMRegisterSigpipe();
    
    __ym_plexer_t *p = (__ym_plexer_t *)_YMAlloc(_YMPlexerTypeID,sizeof(__ym_plexer_t));
    
    p->name = YMStringCreateWithFormat("%s:%s",master?"s":"c",name?YMSTR(name):"*",NULL);
    p->provider = YMRetain(provider);
    
    p->active = false;
    p->master = master;
    p->stopped = false;
    p->myStreamsEven = false;
    
    p->localStreamsByID = YMDictionaryCreate();
    YMStringRef aString = YMStringCreateWithFormat("%s-local",YMSTR(p->name), NULL);
    p->localAccessLock = YMLockCreateWithOptionsAndName(YMInternalLockType,aString);
    YMRelease(aString);
    p->localPlexBufferSize = YMPlexerDefaultBufferSize;
    p->localPlexBuffer = YMALLOC(p->localPlexBufferSize);
    
    p->remoteStreamsByID = YMDictionaryCreate();
    aString = YMStringCreateWithFormat("%s-remote",YMSTR(p->name),NULL);
    p->remoteAccessLock = YMLockCreateWithOptionsAndName(YMInternalLockType,aString);
    YMRelease(aString);
    p->remotePlexBufferSize = YMPlexerDefaultBufferSize;
    p->remotePlexBuffer = YMALLOC(p->remotePlexBufferSize);
    
    aString = YMStringCreateWithFormat("%s-down",YMSTR(p->name),NULL);
    p->localServiceThread = YMThreadCreate(aString, __ym_plexer_service_downstream_proc, (void *)YMRetain(p));
    YMRelease(aString);
    
    aString = YMStringCreateWithFormat("%s-up",YMSTR(p->name),NULL);
    p->remoteServiceThread = YMThreadCreate(aString, __ym_plexer_service_upstream_proc, (void *)YMRetain(p));
    YMRelease(aString);
    
    aString = YMStringCreateWithFormat("%s-event",YMSTR(p->name),NULL);
    p->eventDeliveryThread = YMThreadDispatchCreate(aString);
    YMRelease(aString);
    
    aString = YMStringCreateWithFormat("%s-interrupt",YMSTR(p->name),NULL);
    p->interruptionLock = YMLockCreateWithOptionsAndName(YMInternalLockType,aString);
    YMRelease(aString);
    
    aString = YMStringCreateWithFormat("%s-down-signal",YMSTR(p->name),NULL);
    p->downstreamReadySemaphore = YMSemaphoreCreateWithName(aString,0);
    YMRelease(aString);
    
    p->interruptedFunc = NULL;
    p->newIncomingFunc = NULL;
    p->closingFunc = NULL;
    p->callbackContext = NULL;
    
    return p;
}
Beispiel #4
0
static int yaffs_create_free_objs(yaffs_dev_t *dev, int n_obj)
{
	yaffs_Allocator *allocator = dev->allocator;

	int i;
	yaffs_obj_t *newObjects;
	yaffs_obj_tList *list;

	if(!allocator){
		YBUG();
		return YAFFS_FAIL;
	}

	if (n_obj < 1)
		return YAFFS_OK;

	/* make these things */
	newObjects = YMALLOC(n_obj * sizeof(yaffs_obj_t));
	list = YMALLOC(sizeof(yaffs_obj_tList));

	if (!newObjects || !list) {
		if (newObjects){
			YFREE(newObjects);
			newObjects = NULL;
		}
		if (list){
			YFREE(list);
			list = NULL;
		}
		T(YAFFS_TRACE_ALLOCATE,
		  (TSTR("yaffs: Could not allocate more objects" TENDSTR)));
		return YAFFS_FAIL;
	}

	/* Hook them into the free list */
	for (i = 0; i < n_obj - 1; i++) {
		newObjects[i].siblings.next =
				(struct ylist_head *)(&newObjects[i + 1]);
	}

	newObjects[n_obj - 1].siblings.next = (void *)allocator->freeObjects;
	allocator->freeObjects = newObjects;
	allocator->nFreeObjects += n_obj;
	allocator->n_objCreated += n_obj;

	/* Now add this bunch of Objects to a list for freeing up. */

	list->objects = newObjects;
	list->next = allocator->allocatedObjectList;
	allocator->allocatedObjectList = list;

	return YAFFS_OK;
}
int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting)
{
	
	/* Got the functions we need? */
	if (!dev->writeChunkWithTagsToNAND ||
	    !dev->readChunkWithTagsFromNAND ||
	    !dev->eraseBlockInNAND ||
	    !dev->markNANDBlockBad)
		return 0;

	if(forWriting && !yaffs_CheckpointSpaceOk(dev))
		return 0;
			
	if(!dev->checkpointBuffer)
		dev->checkpointBuffer = YMALLOC(dev->nBytesPerChunk);
	if(!dev->checkpointBuffer)
		return 0;

	
	dev->checkpointPageSequence = 0;
	
	dev->checkpointOpenForWrite = forWriting;
	
	dev->checkpointByteCount = 0;
	dev->checkpointCurrentBlock = -1;
	dev->checkpointCurrentChunk = -1;
	dev->checkpointNextBlock = dev->startBlock;
	
	/* Erase all the blocks in the checkpoint area */
	if(forWriting){
		memset(dev->checkpointBuffer,0,dev->nBytesPerChunk);
		dev->checkpointByteOffset = 0;
		return yaffs_CheckpointErase(dev);
		
		
	} else {
		int i;
		/* Set to a value that will kick off a read */
		dev->checkpointByteOffset = dev->nBytesPerChunk;
		/* A checkpoint block list of 1 checkpoint block per 16 block is (hopefully)
		 * going to be way more than we need */
		dev->checkpointMaxBlocks = (dev->endBlock - dev->startBlock)/16 + 2;
		dev->checkpointBlockList = YMALLOC(sizeof(int) * dev->checkpointMaxBlocks);
		for(i = 0; i < dev->checkpointMaxBlocks; i++)
			dev->checkpointBlockList[i] = -1;
	}
	
	return 1;
}
Beispiel #6
0
/* Process a SETDB command. */
yerr_t command_setdb(tcp_thread_t *thread, ydynabin_t *buff) {
	unsigned char *pdbname_len, dbname_len;
	char *dbname = NULL;
	void *ptr;
	yerr_t result = YENOERR;

	YLOG_ADD(YLOG_DEBUG, "SETDB command");
	// read dbname length
	if (connection_read_data(thread, buff, sizeof(dbname_len)) != YENOERR)
		goto error;
	pdbname_len = ydynabin_forward(buff, sizeof(dbname_len));
	dbname_len = *pdbname_len;
	YFREE(thread->dbname);
	if (dbname_len > 0) {
		// read dbname
		if (connection_read_data(thread, buff, (size_t)dbname_len) != YENOERR)
			goto error;
		ptr = ydynabin_forward(buff, (size_t)dbname_len);
		if ((dbname = YMALLOC((size_t)dbname_len + 1)) == NULL)
			goto error;
		memcpy(dbname, ptr, (size_t)dbname_len);
		thread->dbname = dbname;
	}
	// send the response to the client
	YLOG_ADD(YLOG_DEBUG, "SETDB command OK");
	CONNECTION_SEND_OK(thread);
	return (result);
error:
	YLOG_ADD(YLOG_WARN, "SETDB error");
	CONNECTION_SEND_ERROR(thread, RESP_ERR_SERVER);
	return (YEIO);
}
Beispiel #7
0
YMStringRef YMStringCreateWithCString(const char *cString)
{
    size_t length = strlen(cString);
    char *copy = YMALLOC(length + 1);
    strncpy(copy, cString, length + 1);
    
    return __YMStringCreate(copy, length);
}
Beispiel #8
0
/*-----------------*/
YDECK *Ydeck_init( ) 
{   
  YDECKPTR deckPtr ;
  
  deckPtr = (YDECKPTR) YMALLOC( 1, YDECK );
  deckPtr->top= &deckEndS;              /* init to point to sentinal */
  deckPtr->bottom= &deckEndS;           /* init to point to sentinal */
  deckPtr->current= &deckEndS;          /* init to point to sentinal */
  deckPtr->size=0;
  return(deckPtr);  
} /* end Ydeck_init */
Beispiel #9
0
int yaffs2_checkpt_open(yaffs_dev_t *dev, int writing)
{


	dev->checkpt_open_write = writing;

	/* Got the functions we need? */
	if (!dev->param.write_chunk_tags_fn ||
		!dev->param.read_chunk_tags_fn ||
		!dev->param.erase_fn ||
		!dev->param.bad_block_fn)
		return 0;

	if (writing && !yaffs2_checkpt_space_ok(dev))
		return 0;

	if (!dev->checkpt_buffer)
		dev->checkpt_buffer = YMALLOC_DMA(dev->param.total_bytes_per_chunk);
	if (!dev->checkpt_buffer)
		return 0;


	dev->checkpt_page_seq = 0;
	dev->checkpt_byte_count = 0;
	dev->checkpt_sum = 0;
	dev->checkpt_xor = 0;
	dev->checkpt_cur_block = -1;
	dev->checkpt_cur_chunk = -1;
	dev->checkpt_next_block = dev->internal_start_block;

	/* Erase all the blocks in the checkpoint area */
	if (writing) {
		memset(dev->checkpt_buffer, 0, dev->data_bytes_per_chunk);
		dev->checkpt_byte_offs = 0;
		return yaffs_checkpt_erase(dev);
	} else {
		int i;
		/* Set to a value that will kick off a read */
		dev->checkpt_byte_offs = dev->data_bytes_per_chunk;
		/* A checkpoint block list of 1 checkpoint block per 16 block is (hopefully)
		 * going to be way more than we need */
		dev->blocks_in_checkpt = 0;
		dev->checkpt_max_blocks = (dev->internal_end_block - dev->internal_start_block)/16 + 2;
		dev->checkpt_block_list = YMALLOC(sizeof(int) * dev->checkpt_max_blocks);
		if(!dev->checkpt_block_list)
			return 0;

		for (i = 0; i < dev->checkpt_max_blocks; i++)
			dev->checkpt_block_list[i] = -1;
	}

	return 1;
}
Beispiel #10
0
/*
 * yht_new()
 * Creates a new hash table.
 */
yhashtable_t *yht_new(yht_size_t size, yht_function_t destroy_func, void *destroy_data) {
	yhashtable_t	*hash;

	hash = (yhashtable_t*)YMALLOC(sizeof(yhashtable_t));
	hash->buckets = (yht_bucket_t*)YCALLOC(size, sizeof(yht_bucket_t));
	hash->size = size;
	hash->used = 0;
	hash->items = NULL;
	hash->next_offset = 0;
	hash->destroy_func = destroy_func;
	hash->destroy_data = destroy_data;
	return (hash);
}
void yaffs_InitialiseRawTnodesAndObjects(yaffs_Device *dev)
{
	yaffs_Allocator *allocator;

	if(!dev->allocator){
		allocator = YMALLOC(sizeof(yaffs_Allocator));
		if(allocator){
			dev->allocator = allocator;
			yaffs_InitialiseRawTnodes(dev);
			yaffs_InitialiseRawObjects(dev);
		}
	} else
		YBUG();
}
Beispiel #12
0
void yaffs_init_raw_tnodes_and_objs(yaffs_dev_t *dev)
{
	yaffs_Allocator *allocator;

	if(!dev->allocator){
		allocator = YMALLOC(sizeof(yaffs_Allocator));
		if(allocator){
			dev->allocator = allocator;
			yaffs_init_raw_tnodes(dev);
			yaffs_init_raw_objs(dev);
		}
	} else
		YBUG();
}
Beispiel #13
0
YMStringRef YMStringCreateByAppendingString(YMStringRef base, YMStringRef append)
{
    const char* cBase = YMStringGetCString(base);
    const char *cAppend = YMStringGetCString(append);
    
    size_t baseLen = strlen(cBase);
    size_t appendLen = strlen(cAppend);
    size_t newStringLen = baseLen + appendLen + 1;
    char *newString = (char *)YMALLOC(newStringLen);
    memcpy(newString, cBase, baseLen);
    memcpy(newString + baseLen, cAppend, appendLen);
    newString[newStringLen - 1] = '\0';
    
    return __YMStringCreate(newString, baseLen + appendLen);
}
Beispiel #14
0
void __YMPlexerDispatchFunctionWithName(__ym_plexer_t *p, YMStreamRef stream, YMThreadRef targetThread, ym_dispatch_user_func function, YMStringRef nameToRelease)
{
    _ym_plexer_and_stream_t *notifyDef = (_ym_plexer_and_stream_t *)YMALLOC(sizeof(_ym_plexer_and_stream_t));
    notifyDef->p = (__ym_plexer_t *)YMRetain(p);
    notifyDef->s = stream ? YMRetain(stream) : NULL;
    ym_thread_dispatch_user_t dispatch = { function, NULL, true, notifyDef, nameToRelease };
    
//#define YMPLEXER_NO_EVENT_QUEUE // for debugging
#ifdef YMPLEXER_NO_EVENT_QUEUE
    __unused const void *silence = targetThread;
    function(&dispatch);
    free(notifyDef);
#else
    YMThreadDispatchDispatch(targetThread, dispatch);
#endif
    
    YMRelease(nameToRelease);
}
Beispiel #15
0
YMStringRef YMStringCreateWithFormat(const char *format,...)
{
    va_list formatArgs2,formatArgs;
    va_start(formatArgs2,format);
    va_copy(formatArgs,formatArgs2);
    int length = vsnprintf(NULL, 0, format, formatArgs2) + 1;
    
    char *newStr = NULL;
    if ( length == 0 )
        newStr = "";
    else if ( length < 0 )
        ymerr("snprintf failed on format: %s", format);
    else {
        newStr = (char *)YMALLOC(length);
        vsnprintf(newStr, length, format, formatArgs);
        va_end(formatArgs);
    }    
    va_end(formatArgs2);
    return __YMStringCreate(newStr, length - 1);
}
Beispiel #16
0
struct yaffs_DeviceStruct *ynandsim_CreateRamSim(const YCHAR *name,
				__u32 devId, __u32 nBlocks,
				__u32 startBlock, __u32 endBlock)
{
	SimData *sim;
	ynandif_Geometry *g;

    ynandsim_InitDevice();
	sim = ynandsim_AllocSimData(devId, nBlocks, startBlock, endBlock);

	g = YMALLOC(sizeof(ynandif_Geometry));

	if(!sim || !g){
		if(g)
			YFREE(g);
		return NULL;
	}

	if((endBlock == 0) || (endBlock >= (startBlock + sim->nBlocks)))
		endBlock = (startBlock + sim->nBlocks) - 1;

	memset(g,0,sizeof(ynandif_Geometry));
	g->startBlock = startBlock;
	g->endBlock = endBlock;
	g->dataSize = DATA_SIZE;
	g->spareSize= SPARE_SIZE;
	g->pagesPerBlock = PAGES_PER_BLOCK;
	g->hasECC = 1;
	g->inbandTags = 0;
	g->useYaffs2 = 1;
	g->initialise = ynandsim_Initialise;
	g->deinitialise = ynandsim_Deinitialise;
	g->readChunk = ynandsim_ReadChunk,
	g->writeChunk = ynandsim_WriteChunk,
	g->eraseBlock = ynandsim_EraseBlock,
	g->checkBlockOk = ynandsim_CheckBlockOk,
	g->markBlockBad = ynandsim_MarkBlockBad,
	g->privateData = (void *)sim;

	return yaffs_AddDeviceFromGeometry(name,g);
}
Beispiel #17
0
bool YMmDNSServiceSetTXTRecord( YMmDNSServiceRef s_, YMmDNSTxtRecordKeyPair *keyPairs[], size_t nPairs )
{
    __ym_mdns_service_t *s = (__ym_mdns_service_t *)s_;
    
    if ( keyPairs == NULL || nPairs == 0 )
        return false;
    
    size_t idx;
    
    TXTRecordRef *txtRecord = (TXTRecordRef *)YMALLOC(sizeof(TXTRecordRef));
    TXTRecordCreate(txtRecord, 0, NULL);
    for ( idx = 0; idx < nPairs; idx++ ) {
        YMmDNSTxtRecordKeyPair **_keyPairs = (YMmDNSTxtRecordKeyPair **)keyPairs;
        const char *key = YMSTR(_keyPairs[idx]->key);
        const uint8_t *value = _keyPairs[idx]->value;
        uint8_t valueLen = _keyPairs[idx]->valueLen;
        
        TXTRecordSetValue(txtRecord, key, valueLen, value);
    }
    
    s->txtRecord = (uint8_t *)txtRecord;
    
    return true;
}
static int  CheckInit(void)
{
	static int initialised = 0;
	
	int i,j;
	
	int fail = 0;
	int nBlocks; 

	int nAllocated = 0;
	
	if(initialised) 
	{
		return YAFFS_OK;
	}
	
	
	ned.nBlocks = nBlocks = nandemul2k_CalcNBlocks();

	
	ned.block = YMALLOC(sizeof(nandemul_Block*) * nBlocks );
	
	if(!ned.block) return YAFFS_FAIL;
	
	
	

		
	for(i=fail=0; i <nBlocks; i++)
	{
		
		nandemul_Block *blk;
		
		if(!(blk = ned.block[i] = YMALLOC(sizeof(nandemul_Block))))
		{
		 fail = 1;
		}  
		else
		{
			for(j = 0; j < PAGES_PER_BLOCK; j++)
			{
				if((blk->page[j] = YMALLOC(sizeof(nandemul_Page))) == 0)
				{
					fail = 1;
				}
			}
			nandemul_ReallyEraseBlock(i);
			ned.block[i]->damaged = 0;
			nAllocated++;
		}
	}
	
	if(fail)
	{
		//Todo thump pages
		
		for(i = 0; i < nAllocated; i++)
		{
			YFREE(ned.block[i]);
		}
		YFREE(ned.block);
		
		T(YAFFS_TRACE_ALWAYS,("Allocation failed, could only allocate %dMB of %dMB requested.\n",
		   nAllocated/64,sizeInMB));
		return 0;
	}
	
	ned.nBlocks = nBlocks;
	
	initialised = 1;
	
	return 1;
}
Beispiel #19
0
int yaffs1_scan(yaffs_dev_t *dev)
{
	yaffs_ext_tags tags;
	int blk;
	int result;

	int chunk;
	int c;
	int deleted;
	yaffs_block_state_t state;
	yaffs_obj_t *hard_list = NULL;
	yaffs_block_info_t *bi;
	__u32 seq_number;
	yaffs_obj_header *oh;
	yaffs_obj_t *in;
	yaffs_obj_t *parent;

	int alloc_failed = 0;

	struct yaffs_shadow_fixer_s *shadow_fixers = NULL;


	__u8 *chunk_data;



	T(YAFFS_TRACE_SCAN,
	  (TSTR("yaffs1_scan starts  intstartblk %d intendblk %d..." TENDSTR),
	   dev->internal_start_block, dev->internal_end_block));

	chunk_data = yaffs_get_temp_buffer(dev, __LINE__);

	dev->seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER;

	/* Scan all the blocks to determine their state */
	bi = dev->block_info;
	for (blk = dev->internal_start_block; blk <= dev->internal_end_block; blk++) {
		yaffs_clear_chunk_bits(dev, blk);
		bi->pages_in_use = 0;
		bi->soft_del_pages = 0;

		yaffs_query_init_block_state(dev, blk, &state, &seq_number);

		bi->block_state = state;
		bi->seq_number = seq_number;

		if (bi->seq_number == YAFFS_SEQUENCE_BAD_BLOCK)
			bi->block_state = state = YAFFS_BLOCK_STATE_DEAD;

		T(YAFFS_TRACE_SCAN_DEBUG,
		  (TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk,
		   state, seq_number));

		if (state == YAFFS_BLOCK_STATE_DEAD) {
			T(YAFFS_TRACE_BAD_BLOCKS,
			  (TSTR("block %d is bad" TENDSTR), blk));
		} else if (state == YAFFS_BLOCK_STATE_EMPTY) {
			T(YAFFS_TRACE_SCAN_DEBUG,
			  (TSTR("Block empty " TENDSTR)));
			dev->n_erased_blocks++;
			dev->n_free_chunks += dev->param.chunks_per_block;
		}
		bi++;
	}

	/* For each block.... */
	for (blk= dev->internal_start_block;
		!alloc_failed && blk <= dev->internal_end_block;
		blk++) {

		YYIELD();

		bi = yaffs_get_block_info(dev, blk);
		state = bi->block_state;

		deleted = 0;

		/* For each chunk in each block that needs scanning....*/
		for (c = 0; !alloc_failed && c < dev->param.chunks_per_block &&
		     state == YAFFS_BLOCK_STATE_NEEDS_SCANNING; c++) {
			/* Read the tags and decide what to do */
			chunk = blk * dev->param.chunks_per_block + c;

			result = yaffs_rd_chunk_tags_nand(dev, chunk, NULL,
							&tags);

			/* Let's have a good look at this chunk... */

			if (tags.ecc_result == YAFFS_ECC_RESULT_UNFIXED || tags.is_deleted) {
				/* YAFFS1 only...
				 * A deleted chunk
				 */
				deleted++;
				dev->n_free_chunks++;
				/*T((" %d %d deleted\n",blk,c)); */
			} else if (!tags.chunk_used) {
				/* An unassigned chunk in the block
				 * This means that either the block is empty or
				 * this is the one being allocated from
				 */

				if (c == 0) {
					/* We're looking at the first chunk in the block so the block is unused */
					state = YAFFS_BLOCK_STATE_EMPTY;
					dev->n_erased_blocks++;
				} else {
					/* this is the block being allocated from */
					T(YAFFS_TRACE_SCAN,
					  (TSTR
					   (" Allocating from %d %d" TENDSTR),
					   blk, c));
					state = YAFFS_BLOCK_STATE_ALLOCATING;
					dev->alloc_block = blk;
					dev->alloc_page = c;
					dev->alloc_block_finder = blk;
					/* Set block finder here to encourage the allocator to go forth from here. */

				}

				dev->n_free_chunks += (dev->param.chunks_per_block - c);
			} else if (tags.chunk_id > 0) {
				/* chunk_id > 0 so it is a data chunk... */
				unsigned int endpos;

				yaffs_set_chunk_bit(dev, blk, c);
				bi->pages_in_use++;

				in = yaffs_find_or_create_by_number(dev,
								      tags.
								      obj_id,
								      YAFFS_OBJECT_TYPE_FILE);
				/* PutChunkIntoFile checks for a clash (two data chunks with
				 * the same chunk_id).
				 */

				if (!in)
					alloc_failed = 1;

				if (in) {
					if (!yaffs_put_chunk_in_file(in, tags.chunk_id, chunk, 1))
						alloc_failed = 1;
				}

				endpos =
				    (tags.chunk_id - 1) * dev->data_bytes_per_chunk +
				    tags.n_bytes;
				if (in &&
				    in->variant_type == YAFFS_OBJECT_TYPE_FILE
				    && in->variant.file_variant.scanned_size <
				    endpos) {
					in->variant.file_variant.
					    scanned_size = endpos;
					if (!dev->param.use_header_file_size) {
						in->variant.file_variant.
						    file_size =
						    in->variant.file_variant.
						    scanned_size;
					}

				}
				/* T((" %d %d data %d %d\n",blk,c,tags.obj_id,tags.chunk_id));   */
			} else {
				/* chunk_id == 0, so it is an ObjectHeader.
				 * Thus, we read in the object header and make the object
				 */
				yaffs_set_chunk_bit(dev, blk, c);
				bi->pages_in_use++;

				result = yaffs_rd_chunk_tags_nand(dev, chunk,
								chunk_data,
								NULL);

				oh = (yaffs_obj_header *) chunk_data;

				in = yaffs_find_by_number(dev,
							      tags.obj_id);
				if (in && in->variant_type != oh->type) {
					/* This should not happen, but somehow
					 * Wev'e ended up with an obj_id that has been reused but not yet
					 * deleted, and worse still it has changed type. Delete the old object.
					 */

					yaffs_del_obj(in);

					in = 0;
				}

				in = yaffs_find_or_create_by_number(dev,
								      tags.
								      obj_id,
								      oh->type);

				if (!in)
					alloc_failed = 1;

				if (in && oh->shadows_obj > 0) {

					struct yaffs_shadow_fixer_s *fixer;
					fixer = YMALLOC(sizeof(struct yaffs_shadow_fixer_s));
					if (fixer) {
						fixer->next = shadow_fixers;
						shadow_fixers = fixer;
						fixer->obj_id = tags.obj_id;
						fixer->shadowed_id = oh->shadows_obj;
						T(YAFFS_TRACE_SCAN,
						  (TSTR
						   (" Shadow fixer: %d shadows %d" TENDSTR),
						   fixer->obj_id, fixer->shadowed_id));

					}

				}

				if (in && in->valid) {
					/* We have already filled this one. We have a duplicate and need to resolve it. */

					unsigned existing_serial = in->serial;
					unsigned new_serial = tags.serial_number;

					if (((existing_serial + 1) & 3) == new_serial) {
						/* Use new one - destroy the exisiting one */
						yaffs_chunk_del(dev,
								  in->hdr_chunk,
								  1, __LINE__);
						in->valid = 0;
					} else {
						/* Use existing - destroy this one. */
						yaffs_chunk_del(dev, chunk, 1,
								  __LINE__);
					}
				}

				if (in && !in->valid &&
				    (tags.obj_id == YAFFS_OBJECTID_ROOT ||
				     tags.obj_id == YAFFS_OBJECTID_LOSTNFOUND)) {
					/* We only load some info, don't fiddle with directory structure */
					in->valid = 1;
					in->variant_type = oh->type;

					in->yst_mode = oh->yst_mode;
#ifdef CONFIG_YAFFS_WINCE
					in->win_atime[0] = oh->win_atime[0];
					in->win_ctime[0] = oh->win_ctime[0];
					in->win_mtime[0] = oh->win_mtime[0];
					in->win_atime[1] = oh->win_atime[1];
					in->win_ctime[1] = oh->win_ctime[1];
					in->win_mtime[1] = oh->win_mtime[1];
#else
					in->yst_uid = oh->yst_uid;
					in->yst_gid = oh->yst_gid;
					in->yst_atime = oh->yst_atime;
					in->yst_mtime = oh->yst_mtime;
					in->yst_ctime = oh->yst_ctime;
					in->yst_rdev = oh->yst_rdev;
#endif
					in->hdr_chunk = chunk;
					in->serial = tags.serial_number;

				} else if (in && !in->valid) {
					/* we need to load this info */

					in->valid = 1;
					in->variant_type = oh->type;

					in->yst_mode = oh->yst_mode;
#ifdef CONFIG_YAFFS_WINCE
					in->win_atime[0] = oh->win_atime[0];
					in->win_ctime[0] = oh->win_ctime[0];
					in->win_mtime[0] = oh->win_mtime[0];
					in->win_atime[1] = oh->win_atime[1];
					in->win_ctime[1] = oh->win_ctime[1];
					in->win_mtime[1] = oh->win_mtime[1];
#else
					in->yst_uid = oh->yst_uid;
					in->yst_gid = oh->yst_gid;
					in->yst_atime = oh->yst_atime;
					in->yst_mtime = oh->yst_mtime;
					in->yst_ctime = oh->yst_ctime;
					in->yst_rdev = oh->yst_rdev;
#endif
					in->hdr_chunk = chunk;
					in->serial = tags.serial_number;

					yaffs_set_obj_name_from_oh(in, oh);
					in->dirty = 0;

					/* directory stuff...
					 * hook up to parent
					 */

					parent =
					    yaffs_find_or_create_by_number
					    (dev, oh->parent_obj_id,
					     YAFFS_OBJECT_TYPE_DIRECTORY);
					if (!parent)
						alloc_failed = 1;
					if (parent && parent->variant_type ==
					    YAFFS_OBJECT_TYPE_UNKNOWN) {
						/* Set up as a directory */
						parent->variant_type =
							YAFFS_OBJECT_TYPE_DIRECTORY;
						YINIT_LIST_HEAD(&parent->variant.
								dir_variant.
								children);
					} else if (!parent || parent->variant_type !=
						   YAFFS_OBJECT_TYPE_DIRECTORY) {
						/* Hoosterman, another problem....
						 * We're trying to use a non-directory as a directory
						 */

						T(YAFFS_TRACE_ERROR,
						  (TSTR
						   ("yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
						    TENDSTR)));
						parent = dev->lost_n_found;
					}

					yaffs_add_obj_to_dir(parent, in);

					if (0 && (parent == dev->del_dir ||
						  parent == dev->unlinked_dir)) {
						in->deleted = 1;	/* If it is unlinked at start up then it wants deleting */
						dev->n_deleted_files++;
					}
					/* Note re hardlinks.
					 * Since we might scan a hardlink before its equivalent object is scanned
					 * we put them all in a list.
					 * After scanning is complete, we should have all the objects, so we run through this
					 * list and fix up all the chains.
					 */

					switch (in->variant_type) {
					case YAFFS_OBJECT_TYPE_UNKNOWN:
						/* Todo got a problem */
						break;
					case YAFFS_OBJECT_TYPE_FILE:
						if (dev->param.use_header_file_size)

							in->variant.file_variant.
							    file_size =
							    oh->file_size;

						break;
					case YAFFS_OBJECT_TYPE_HARDLINK:
						in->variant.hardlink_variant.
							equiv_id =
							oh->equiv_id;
						in->hard_links.next =
							(struct ylist_head *)
							hard_list;
						hard_list = in;
						break;
					case YAFFS_OBJECT_TYPE_DIRECTORY:
						/* Do nothing */
						break;
					case YAFFS_OBJECT_TYPE_SPECIAL:
						/* Do nothing */
						break;
					case YAFFS_OBJECT_TYPE_SYMLINK:
						in->variant.symlink_variant.alias =
						    yaffs_clone_str(oh->alias);
						if (!in->variant.symlink_variant.alias)
							alloc_failed = 1;
						break;
					}

				}
			}
		}

		if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
			/* If we got this far while scanning, then the block is fully allocated.*/
			state = YAFFS_BLOCK_STATE_FULL;
		}

		if (state == YAFFS_BLOCK_STATE_ALLOCATING) {
			/* If the block was partially allocated then treat it as fully allocated.*/
			state = YAFFS_BLOCK_STATE_FULL;
			dev->alloc_block = -1;
		}

		bi->block_state = state;

		/* Now let's see if it was dirty */
		if (bi->pages_in_use == 0 &&
		    !bi->has_shrink_hdr &&
		    bi->block_state == YAFFS_BLOCK_STATE_FULL) {
			yaffs_block_became_dirty(dev, blk);
		}

	}


	/* Ok, we've done all the scanning.
	 * Fix up the hard link chains.
	 * We should now have scanned all the objects, now it's time to add these
	 * hardlinks.
	 */

	yaffs_link_fixup(dev, hard_list);

	/* Fix up any shadowed objects */
	{
		struct yaffs_shadow_fixer_s *fixer;
		yaffs_obj_t *obj;

		while (shadow_fixers) {
			fixer = shadow_fixers;
			shadow_fixers = fixer->next;
			/* Complete the rename transaction by deleting the shadowed object
			 * then setting the object header to unshadowed.
			 */
			obj = yaffs_find_by_number(dev, fixer->shadowed_id);
			if (obj)
				yaffs_del_obj(obj);

			obj = yaffs_find_by_number(dev, fixer->obj_id);

			if (obj)
				yaffs_update_oh(obj, NULL, 1, 0, 0, NULL);

			YFREE(fixer);
		}
	}

	yaffs_release_temp_buffer(dev, chunk_data, __LINE__);

	if (alloc_failed)
		return YAFFS_FAIL;

	T(YAFFS_TRACE_SCAN, (TSTR("yaffs1_scan ends" TENDSTR)));


	return YAFFS_OK;
}
yaffs_Object *yaffs_AllocateRawObject(yaffs_Device *dev)
{
	dev = dev;
	return (yaffs_Object *) YMALLOC(sizeof(yaffs_Object));
}
Beispiel #21
0
/*
 * _yht_add
 * Add an element to a hash table, using a string or an integer key.
 */
static void _yht_add(yhashtable_t *hashtable, yht_hash_value_t hash_value, char *key, void *data) {
	float			load_factor;
	yht_hash_value_t	modulo_value;
	yht_bucket_t		*bucket;
	yht_element_t		*element;
	yht_list_t		*item;

	/* resize the table if its load factor would excess the limit */
	load_factor = (float)(hashtable->used + 1) / hashtable->size;
	if (load_factor > YHT_MAX_LOAD_FACTOR)
		yht_resize(hashtable, (hashtable->size * 2));
	/* compute the key's hash value */
	if (key != NULL)
		hash_value = yht_hash(key);
	modulo_value = hash_value % hashtable->size;
	/* checking the bucket */
	bucket = &(hashtable->buckets[modulo_value]);
	if (bucket->nbr_elements == 0) {
		/* create the first element */
		element = (yht_element_t*)YMALLOC(sizeof(yht_element_t));
		item = (yht_list_t*)YMALLOC(sizeof(yht_list_t));
		element->previous = element->next = element;
		/* add the element to the bucket */
		bucket->elements = element;
	} else {
		/* there is already some elements in the bucket, checking if the element exists and must be updated */
		size_t	offset;

		for (offset = 0, element = bucket->elements;
		     offset < bucket->nbr_elements;
		     offset++, element = element->next) {
			if (element->hash_value == hash_value &&
			    ((key == NULL && element->key == NULL) ||
			     (key != NULL && element->key != NULL && !strcmp(key, element->key)))) {
				/* an existing element was found */
				/* removing old data */
				if (hashtable->destroy_func != NULL)
					hashtable->destroy_func(element->hash_value, element->key, element->data, hashtable->destroy_data);
				/* updating the element */
				element->key = key;
				element->data = data;
				return;
			}
		}
		/* no element was already existing with this key */
		element = (yht_element_t*)YMALLOC(sizeof(yht_element_t));
		item = (yht_list_t*)YMALLOC(sizeof(yht_list_t));
		/* add the element to the bucket */
		element->next = bucket->elements;
		element->previous = bucket->elements->previous;
		bucket->elements->previous->next = element;
		bucket->elements->previous = element;
	}
	/* filling the element and the item */
	element->hash_value = hash_value;
	element->key = key;
	element->data = data;
	element->item = item;
	item->element = element;
	/* update the bucket */
	bucket->nbr_elements++;
	/* update the hash table */
	hashtable->used++;
	/* add the item to the list */
	if (hashtable->items == NULL) {
		hashtable->items = item;
		item->next = item->previous = item;
	}else {
		item->next = hashtable->items;
		item->previous = hashtable->items->previous;
		hashtable->items->previous->next = item;
		hashtable->items->previous = item;
	}
}
void yaffs_InitialiseRawTnodesAndObjects(yaffs_Device *dev)
{
	yaffs_Allocator *allocator;
	unsigned mount_id = yaffs_DeviceToLC(dev)->mount_id;

	T(YAFFS_TRACE_ALLOCATE,(TSTR("Initialising yaffs allocator\n")));

	if(dev->allocator)
		YBUG();
	else if(mount_id >= 10){
		T(YAFFS_TRACE_ALWAYS,(TSTR("Bad mount_id %u\n"),mount_id));
	} else {
		 allocator = YMALLOC(sizeof(yaffs_Allocator));
		 memset(allocator,0,sizeof(yaffs_Allocator));
		 dev->allocator = allocator;

		if(!dev->allocator){
			T(YAFFS_TRACE_ALWAYS,
				(TSTR("yaffs allocator creation failed\n")));
			YBUG();
			return;

		}

		sprintf(allocator->tnode_name,"yaffs_t_%u",mount_id);
		sprintf(allocator->object_name,"yaffs_o_%u",mount_id);

		allocator->tnode_cache =
			kmem_cache_create(allocator->tnode_name,
				dev->tnodeSize,
				0, 0,
				fake_ctor_list[mount_id]);
		if(allocator->tnode_cache)
			T(YAFFS_TRACE_ALLOCATE,
				(TSTR("tnode cache \"%s\" %p\n"),
				allocator->tnode_name,allocator->tnode_cache));
		else {
			T(YAFFS_TRACE_ALWAYS,
				(TSTR("yaffs cache creation failed\n")));
			YBUG();
		}


		allocator->object_cache = 
			kmem_cache_create(allocator->object_name,
				sizeof(yaffs_Object),
				0, 0,
				fake_ctor_list[mount_id]);

		if(allocator->object_cache)
			T(YAFFS_TRACE_ALLOCATE,
				(TSTR("object cache \"%s\" %p\n"),
				allocator->object_name,allocator->object_cache));

		else {
			T(YAFFS_TRACE_ALWAYS,
				(TSTR("yaffs cache creation failed\n")));
			YBUG();
		}
	} 
}
Beispiel #23
0
int yaffs_StartUp(void)
{
	struct mtd_info *mtd = &nand_info[0];
	int yaffsVersion = 2;
	int nBlocks;

	yaffs_Device *flashDev = calloc(1, sizeof(yaffs_Device));
	yaffsfs_config[0].dev = flashDev;

	/* store the mtd device for later use */
	flashDev->genericDevice = mtd;

	// Stuff to configure YAFFS
	// Stuff to initialise anything special (eg lock semaphore).
	yaffsfs_LocalInitialisation();

	// Set up devices

/* XXX U-BOOT XXX */
#if 0
	// /ram
	ramDev.nBytesPerChunk = 512;
	ramDev.nChunksPerBlock = 32;
	ramDev.nReservedBlocks = 2; // Set this smaller for RAM
	ramDev.startBlock = 1; // Can't use block 0
	ramDev.endBlock = 127; // Last block in 2MB.
	ramDev.useNANDECC = 1;
	ramDev.nShortOpCaches = 0;	// Disable caching on this device.
	ramDev.genericDevice = (void *) 0;	// Used to identify the device in fstat.
	ramDev.writeChunkWithTagsToNAND = yramdisk_WriteChunkWithTagsToNAND;
	ramDev.readChunkWithTagsFromNAND = yramdisk_ReadChunkWithTagsFromNAND;
	ramDev.eraseBlockInNAND = yramdisk_EraseBlockInNAND;
	ramDev.initialiseNAND = yramdisk_InitialiseNAND;

	// /boot
	bootDev.nBytesPerChunk = 612;
	bootDev.nChunksPerBlock = 32;
	bootDev.nReservedBlocks = 5;
	bootDev.startBlock = 1; // Can't use block 0
	bootDev.endBlock = 127; // Last block in 2MB.
	bootDev.useNANDECC = 0; // use YAFFS's ECC
	bootDev.nShortOpCaches = 10; // Use caches
	bootDev.genericDevice = (void *) 1;	// Used to identify the device in fstat.
	bootDev.writeChunkToNAND = yflash_WriteChunkToNAND;
	bootDev.readChunkFromNAND = yflash_ReadChunkFromNAND;
	bootDev.eraseBlockInNAND = yflash_EraseBlockInNAND;
	bootDev.initialiseNAND = yflash_InitialiseNAND;
#endif

		// /flash
	flashDev->nReservedBlocks = 5;
//  flashDev->nShortOpCaches = (options.no_cache) ? 0 : 10;
	flashDev->nShortOpCaches = 10; // Use caches
	flashDev->useNANDECC = 0; // do not use YAFFS's ECC

	if (yaffsVersion == 2)
	{
		flashDev->writeChunkWithTagsToNAND = nandmtd2_WriteChunkWithTagsToNAND;
		flashDev->readChunkWithTagsFromNAND = nandmtd2_ReadChunkWithTagsFromNAND;
		flashDev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad;
		flashDev->queryNANDBlock = nandmtd2_QueryNANDBlock;
		flashDev->spareBuffer = YMALLOC(mtd->oobsize);
		flashDev->isYaffs2 = 1;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
		flashDev->nDataBytesPerChunk = mtd->writesize;
		flashDev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
#else
		flashDev->nDataBytesPerChunk = mtd->oobblock;
		flashDev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
#endif
		nBlocks = mtd->size / mtd->erasesize;

		flashDev->nCheckpointReservedBlocks = 10;
		flashDev->startBlock = 0;
		flashDev->endBlock = nBlocks - 1;
	}
	else
	{
		flashDev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
		flashDev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
		flashDev->isYaffs2 = 0;
		nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
		flashDev->startBlock = 320;
		flashDev->endBlock = nBlocks - 1;
		flashDev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
		flashDev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
	}

	/* ... and common functions */
	flashDev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
	flashDev->initialiseNAND = nandmtd_InitialiseNAND;

	yaffs_initialise(yaffsfs_config);

	return 0;
}
Beispiel #24
0
/* Process a DEL command. */
yerr_t command_del(tcp_thread_t *thread, ybool_t sync, ybool_t compress, ybool_t serialized, ydynabin_t *buff) {
	uint16_t *pkey_len, key_len;
	void *ptr, *key = NULL;
	writer_msg_t *msg = NULL;
	char answer;

	YLOG_ADD(YLOG_DEBUG, "DEL command");
	// read key length
	if (connection_read_data(thread, buff, sizeof(key_len)) != YENOERR)
		goto error;
	pkey_len = ydynabin_forward(buff, sizeof(key_len));
	key_len = ntohs(*pkey_len);
	// read key
	if (connection_read_data(thread, buff, (size_t)key_len) != YENOERR)
		goto error;
	ptr = ydynabin_forward(buff, (size_t)key_len);
	if ((key = YMALLOC((size_t)key_len)) == NULL)
		goto error;
	memcpy(key, ptr, (size_t)key_len);

	if (!sync) {
		// send the response
		connection_send_response(thread, RESP_OK, YFALSE, YFALSE, NULL, 0);
	}

	// creation of the message
	if ((msg = YMALLOC(sizeof(writer_msg_t))) == NULL)
		goto error;
	msg->type = WRITE_DEL;
	ybin_set(&msg->name, key, key_len);
	if (!sync) {
		msg->dbname = thread->dbname ? strdup(thread->dbname) : NULL;
		// send the message to the writer thread
		if (nn_send(thread->write_sock, &msg, sizeof(msg), 0) < 0) {
			YLOG_ADD(YLOG_WARN, "Unable to send message to writer thread.");
			goto error;
		}
		return (YENOERR);
	}
	// synchronized
	if (database_del(thread->finedb->database, thread->transaction, thread->dbname, msg->name) == YENOERR) {
		YLOG_ADD(YLOG_DEBUG, "Deletion done on database.");
		answer = 1;
	} else {
		YLOG_ADD(YLOG_WARN, "Unable to delete data on database.");
		answer = 0;
	}
	YFREE(key);
	YFREE(msg);
	YLOG_ADD(YLOG_DEBUG, "DEL command %s", (answer ? "OK" : "failed"));
	if (!sync)
		return (YENOERR);
	return (connection_send_response(thread, (answer ? RESP_OK : RESP_ERR_BAD_NAME),
	                                 YFALSE, YFALSE, NULL, 0));
error:
	YLOG_ADD(YLOG_WARN, "PUT error");
	YFREE(key);
	YFREE(msg);
	CONNECTION_SEND_ERROR(thread, RESP_ERR_SERVER);
	return (YEIO);
}
yaffs_Tnode *yaffs_AllocateRawTnode(yaffs_Device *dev)
{
	return (yaffs_Tnode *)YMALLOC(dev->tnodeSize);
}
Beispiel #26
0
/* List the keys stored in database. */
void command_list(cli_t *cli, char *pt) {
	char *buffer, c;
	size_t sz, offset, length, rc;

	LTRIM(pt);
	// create sending buffer
	sz = 1;
	if (cli->dbname)
		sz += 1 + strlen(cli->dbname);
	buffer = YMALLOC(sz);
	// set the code byte
	buffer[0] = PROTO_LIST;
	if (cli->dbname)
		buffer[0] = REQUEST_ADD_DBNAME(buffer[0]);
	// dbname
	offset = 1;
	if (cli->dbname) {
		length = strlen(cli->dbname);
		buffer[offset] = (char)length;
		offset++;
		memcpy(&buffer[offset], cli->dbname, length);
		offset += length;
	}
	{
		size_t n;
		for (n = 0; n < sz; n++)
			printf("%02x ", buffer[n]);
		printf("\n");
	}

	// send data
	rc = write(cli->fd, buffer, sz);
	YFREE(buffer);
	if (rc != sz) {
		printf("%c[Connection error%c[0m\n", 27, 27);
		return;
	}

	// get response
	if (read(cli->fd, &c, 1) != 1) {
		printf("%c[Connection error%c[0m\n", 27, 27);
		return;
	}
	if (RESPONSE_CODE(c) != RESP_OK) {
		printf("%c[2mERROR: %s%c[0m\n", 27,
		       (RESPONSE_CODE(c) == RESP_PROTO ? "protocol" :
		        (RESPONSE_CODE(c) == RESP_SERVER_ERR ? "server" :
		         (RESPONSE_CODE(c) == RESP_NO_DATA ? "no data" : "unknown"))), 27);
		return;
	}
	printf("%c[2mOK%c[0m\n", 27, 27);
	for (; ; ) {
		uint16_t ln = 0, lh;

		if (read(cli->fd, &ln, 2) < 2)
			break;
		lh = ntohs(ln);
		buffer = YMALLOC(lh + 1);
		if (read(cli->fd, buffer, lh) != lh) {
			printf("%c[Connection error%c[0m\n", 27, 27);
			YFREE(buffer);
			return;
		}
		printf("%c[2m%s%c[0m\n", 27, buffer, 27);
		YFREE(buffer);
	}
}
Beispiel #27
0
yaffs_tnode_t *yaffs_alloc_raw_tnode(yaffs_dev_t *dev)
{
	return (yaffs_tnode_t *)YMALLOC(dev->tnode_size);
}
Beispiel #28
0
static int yaffs_create_tnodes(yaffs_dev_t *dev, int n_tnodes)
{
	yaffs_Allocator *allocator = (yaffs_Allocator *)dev->allocator;
	int i;
	yaffs_tnode_t *newTnodes;
	__u8 *mem;
	yaffs_tnode_t *curr;
	yaffs_tnode_t *next;
	yaffs_tnodelist_t *tnl;

	if(!allocator){
		YBUG();
		return YAFFS_FAIL;
	}

	if (n_tnodes < 1)
		return YAFFS_OK;


	/* make these things */

	newTnodes = YMALLOC(n_tnodes * dev->tnode_size);
	mem = (__u8 *)newTnodes;

	if (!newTnodes) {
		T(YAFFS_TRACE_ERROR,
			(TSTR("yaffs: Could not allocate Tnodes" TENDSTR)));
		return YAFFS_FAIL;
	}

	/* New hookup for wide tnodes */
	for (i = 0; i < n_tnodes - 1; i++) {
		curr = (yaffs_tnode_t *) &mem[i * dev->tnode_size];
		next = (yaffs_tnode_t *) &mem[(i+1) * dev->tnode_size];
		curr->internal[0] = next;
	}

	curr = (yaffs_tnode_t *) &mem[(n_tnodes - 1) * dev->tnode_size];
	curr->internal[0] = allocator->freeTnodes;
	allocator->freeTnodes = (yaffs_tnode_t *)mem;

	allocator->nFreeTnodes += n_tnodes;
	allocator->n_tnodesCreated += n_tnodes;

	/* Now add this bunch of tnodes to a list for freeing up.
	 * NB If we can't add this to the management list it isn't fatal
	 * but it just means we can't free this bunch of tnodes later.
	 */

	tnl = YMALLOC(sizeof(yaffs_tnodelist_t));
	if (!tnl) {
		T(YAFFS_TRACE_ERROR,
		  (TSTR
		   ("yaffs: Could not add tnodes to management list" TENDSTR)));
		   return YAFFS_FAIL;
	} else {
		tnl->tnodes = newTnodes;
		tnl->next = allocator->allocatedTnodeList;
		allocator->allocatedTnodeList = tnl;
	}

	T(YAFFS_TRACE_ALLOCATE, (TSTR("yaffs: Tnodes added" TENDSTR)));

	return YAFFS_OK;
}
int yaffs1_Scan(yaffs_Device *dev)
{
	yaffs_ExtendedTags tags;
	int blk;
	int blockIterator;
	int startIterator;
	int endIterator;
	int result;

	int chunk;
	int c;
	int deleted;
	yaffs_BlockState state;
	yaffs_Object *hardList = NULL;
	yaffs_BlockInfo *bi;
	__u32 sequenceNumber;
	yaffs_ObjectHeader *oh;
	yaffs_Object *in;
	yaffs_Object *parent;

	int alloc_failed = 0;

	struct yaffs_ShadowFixerStruct *shadowFixerList = NULL;


	__u8 *chunkData;



	T(YAFFS_TRACE_SCAN,
	  (TSTR("yaffs1_Scan starts  intstartblk %d intendblk %d..." TENDSTR),
	   dev->internalStartBlock, dev->internalEndBlock));

	chunkData = yaffs_GetTempBuffer(dev, __LINE__);

	dev->sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER;

	/* Scan all the blocks to determine their state */
	bi = dev->blockInfo;
	for (blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++) {
		yaffs_ClearChunkBits(dev, blk);
		bi->pagesInUse = 0;
		bi->softDeletions = 0;

		yaffs_QueryInitialBlockState(dev, blk, &state, &sequenceNumber);

		bi->blockState = state;
		bi->sequenceNumber = sequenceNumber;

		if (bi->sequenceNumber == YAFFS_SEQUENCE_BAD_BLOCK)
			bi->blockState = state = YAFFS_BLOCK_STATE_DEAD;

		T(YAFFS_TRACE_SCAN_DEBUG,
		  (TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk,
		   state, sequenceNumber));

		if (state == YAFFS_BLOCK_STATE_DEAD) {
			T(YAFFS_TRACE_BAD_BLOCKS,
			  (TSTR("block %d is bad" TENDSTR), blk));
		} else if (state == YAFFS_BLOCK_STATE_EMPTY) {
			T(YAFFS_TRACE_SCAN_DEBUG,
			  (TSTR("Block empty " TENDSTR)));
			dev->nErasedBlocks++;
			dev->nFreeChunks += dev->param.nChunksPerBlock;
		}
		bi++;
	}

	startIterator = dev->internalStartBlock;
	endIterator = dev->internalEndBlock;

	/* For each block.... */
	for (blockIterator = startIterator; !alloc_failed && blockIterator <= endIterator;
	     blockIterator++) {

		YYIELD();

		YYIELD();

		blk = blockIterator;

		bi = yaffs_GetBlockInfo(dev, blk);
		state = bi->blockState;

		deleted = 0;

		/* For each chunk in each block that needs scanning....*/
		for (c = 0; !alloc_failed && c < dev->param.nChunksPerBlock &&
		     state == YAFFS_BLOCK_STATE_NEEDS_SCANNING; c++) {
			/* Read the tags and decide what to do */
			chunk = blk * dev->param.nChunksPerBlock + c;

			result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk, NULL,
							&tags);

			/* Let's have a good look at this chunk... */

			if (tags.eccResult == YAFFS_ECC_RESULT_UNFIXED || tags.chunkDeleted) {
				/* YAFFS1 only...
				 * A deleted chunk
				 */
				deleted++;
				dev->nFreeChunks++;
				/*T((" %d %d deleted\n",blk,c)); */
			} else if (!tags.chunkUsed) {
				/* An unassigned chunk in the block
				 * This means that either the block is empty or
				 * this is the one being allocated from
				 */

				if (c == 0) {
					/* We're looking at the first chunk in the block so the block is unused */
					state = YAFFS_BLOCK_STATE_EMPTY;
					dev->nErasedBlocks++;
				} else {
					/* this is the block being allocated from */
					T(YAFFS_TRACE_SCAN,
					  (TSTR
					   (" Allocating from %d %d" TENDSTR),
					   blk, c));
					state = YAFFS_BLOCK_STATE_ALLOCATING;
					dev->allocationBlock = blk;
					dev->allocationPage = c;
					dev->allocationBlockFinder = blk;
					/* Set block finder here to encourage the allocator to go forth from here. */

				}

				dev->nFreeChunks += (dev->param.nChunksPerBlock - c);
			} else if (tags.chunkId > 0) {
				/* chunkId > 0 so it is a data chunk... */
				unsigned int endpos;

				yaffs_SetChunkBit(dev, blk, c);
				bi->pagesInUse++;

				in = yaffs_FindOrCreateObjectByNumber(dev,
								      tags.
								      objectId,
								      YAFFS_OBJECT_TYPE_FILE);
				/* PutChunkIntoFile checks for a clash (two data chunks with
				 * the same chunkId).
				 */

				if (!in)
					alloc_failed = 1;

				if (in) {
					if (!yaffs_PutChunkIntoFile(in, tags.chunkId, chunk, 1))
						alloc_failed = 1;
				}

				endpos =
				    (tags.chunkId - 1) * dev->nDataBytesPerChunk +
				    tags.byteCount;
				if (in &&
				    in->variantType == YAFFS_OBJECT_TYPE_FILE
				    && in->variant.fileVariant.scannedFileSize <
				    endpos) {
					in->variant.fileVariant.
					    scannedFileSize = endpos;
					if (!dev->param.useHeaderFileSize) {
						in->variant.fileVariant.
						    fileSize =
						    in->variant.fileVariant.
						    scannedFileSize;
					}

				}
				/* T((" %d %d data %d %d\n",blk,c,tags.objectId,tags.chunkId));   */
			} else {
				/* chunkId == 0, so it is an ObjectHeader.
				 * Thus, we read in the object header and make the object
				 */
				yaffs_SetChunkBit(dev, blk, c);
				bi->pagesInUse++;

				result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk,
								chunkData,
								NULL);

				oh = (yaffs_ObjectHeader *) chunkData;

				in = yaffs_FindObjectByNumber(dev,
							      tags.objectId);
				if (in && in->variantType != oh->type) {
					/* This should not happen, but somehow
					 * Wev'e ended up with an objectId that has been reused but not yet
					 * deleted, and worse still it has changed type. Delete the old object.
					 */

					yaffs_DeleteObject(in);

					in = 0;
				}

				in = yaffs_FindOrCreateObjectByNumber(dev,
								      tags.
								      objectId,
								      oh->type);

				if (!in)
					alloc_failed = 1;

				if (in && oh->shadowsObject > 0) {

					struct yaffs_ShadowFixerStruct *fixer;
					fixer = YMALLOC(sizeof(struct yaffs_ShadowFixerStruct));
					if (fixer) {
						fixer->next = shadowFixerList;
						shadowFixerList = fixer;
						fixer->objectId = tags.objectId;
						fixer->shadowedId = oh->shadowsObject;
					}

				}

				if (in && in->valid) {
					/* We have already filled this one. We have a duplicate and need to resolve it. */

					unsigned existingSerial = in->serial;
					unsigned newSerial = tags.serialNumber;

					if (((existingSerial + 1) & 3) == newSerial) {
						/* Use new one - destroy the exisiting one */
						yaffs_DeleteChunk(dev,
								  in->hdrChunk,
								  1, __LINE__);
						in->valid = 0;
					} else {
						/* Use existing - destroy this one. */
						yaffs_DeleteChunk(dev, chunk, 1,
								  __LINE__);
					}
				}

				if (in && !in->valid &&
				    (tags.objectId == YAFFS_OBJECTID_ROOT ||
				     tags.objectId == YAFFS_OBJECTID_LOSTNFOUND)) {
					/* We only load some info, don't fiddle with directory structure */
					in->valid = 1;
					in->variantType = oh->type;

					in->yst_mode = oh->yst_mode;
#ifdef CONFIG_YAFFS_WINCE
					in->win_atime[0] = oh->win_atime[0];
					in->win_ctime[0] = oh->win_ctime[0];
					in->win_mtime[0] = oh->win_mtime[0];
					in->win_atime[1] = oh->win_atime[1];
					in->win_ctime[1] = oh->win_ctime[1];
					in->win_mtime[1] = oh->win_mtime[1];
#else
					in->yst_uid = oh->yst_uid;
					in->yst_gid = oh->yst_gid;
					in->yst_atime = oh->yst_atime;
					in->yst_mtime = oh->yst_mtime;
					in->yst_ctime = oh->yst_ctime;
					in->yst_rdev = oh->yst_rdev;
#endif
					in->hdrChunk = chunk;
					in->serial = tags.serialNumber;

				} else if (in && !in->valid) {
					/* we need to load this info */

					in->valid = 1;
					in->variantType = oh->type;

					in->yst_mode = oh->yst_mode;
#ifdef CONFIG_YAFFS_WINCE
					in->win_atime[0] = oh->win_atime[0];
					in->win_ctime[0] = oh->win_ctime[0];
					in->win_mtime[0] = oh->win_mtime[0];
					in->win_atime[1] = oh->win_atime[1];
					in->win_ctime[1] = oh->win_ctime[1];
					in->win_mtime[1] = oh->win_mtime[1];
#else
					in->yst_uid = oh->yst_uid;
					in->yst_gid = oh->yst_gid;
					in->yst_atime = oh->yst_atime;
					in->yst_mtime = oh->yst_mtime;
					in->yst_ctime = oh->yst_ctime;
					in->yst_rdev = oh->yst_rdev;
#endif
					in->hdrChunk = chunk;
					in->serial = tags.serialNumber;

					yaffs_SetObjectNameFromOH(in, oh);
					in->dirty = 0;

					/* directory stuff...
					 * hook up to parent
					 */

					parent =
					    yaffs_FindOrCreateObjectByNumber
					    (dev, oh->parentObjectId,
					     YAFFS_OBJECT_TYPE_DIRECTORY);
					if (!parent)
						alloc_failed = 1;
					if (parent && parent->variantType ==
					    YAFFS_OBJECT_TYPE_UNKNOWN) {
						/* Set up as a directory */
						parent->variantType =
							YAFFS_OBJECT_TYPE_DIRECTORY;
						YINIT_LIST_HEAD(&parent->variant.
								directoryVariant.
								children);
					} else if (!parent || parent->variantType !=
						   YAFFS_OBJECT_TYPE_DIRECTORY) {
						/* Hoosterman, another problem....
						 * We're trying to use a non-directory as a directory
						 */

						T(YAFFS_TRACE_ERROR,
						  (TSTR
						   ("yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
						    TENDSTR)));
						parent = dev->lostNFoundDir;
					}

					yaffs_AddObjectToDirectory(parent, in);

					if (0 && (parent == dev->deletedDir ||
						  parent == dev->unlinkedDir)) {
						in->deleted = 1;	/* If it is unlinked at start up then it wants deleting */
						dev->nDeletedFiles++;
					}
					/* Note re hardlinks.
					 * Since we might scan a hardlink before its equivalent object is scanned
					 * we put them all in a list.
					 * After scanning is complete, we should have all the objects, so we run through this
					 * list and fix up all the chains.
					 */

					switch (in->variantType) {
					case YAFFS_OBJECT_TYPE_UNKNOWN:
						/* Todo got a problem */
						break;
					case YAFFS_OBJECT_TYPE_FILE:
						if (dev->param.useHeaderFileSize)

							in->variant.fileVariant.
							    fileSize =
							    oh->fileSize;

						break;
					case YAFFS_OBJECT_TYPE_HARDLINK:
						in->variant.hardLinkVariant.
							equivalentObjectId =
							oh->equivalentObjectId;
						in->hardLinks.next =
							(struct ylist_head *)
							hardList;
						hardList = in;
						break;
					case YAFFS_OBJECT_TYPE_DIRECTORY:
						/* Do nothing */
						break;
					case YAFFS_OBJECT_TYPE_SPECIAL:
						/* Do nothing */
						break;
					case YAFFS_OBJECT_TYPE_SYMLINK:
						in->variant.symLinkVariant.alias =
						    yaffs_CloneString(oh->alias);
						if (!in->variant.symLinkVariant.alias)
							alloc_failed = 1;
						break;
					}

				}
			}
		}

		if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
			/* If we got this far while scanning, then the block is fully allocated.*/
			state = YAFFS_BLOCK_STATE_FULL;
		}

		if (state == YAFFS_BLOCK_STATE_ALLOCATING) {
			/* If the block was partially allocated then treat it as fully allocated.*/
			state = YAFFS_BLOCK_STATE_FULL;
			dev->allocationBlock = -1;
		}

		bi->blockState = state;

		/* Now let's see if it was dirty */
		if (bi->pagesInUse == 0 &&
		    !bi->hasShrinkHeader &&
		    bi->blockState == YAFFS_BLOCK_STATE_FULL) {
			yaffs_BlockBecameDirty(dev, blk);
		}

	}


	/* Ok, we've done all the scanning.
	 * Fix up the hard link chains.
	 * We should now have scanned all the objects, now it's time to add these
	 * hardlinks.
	 */

	yaffs_HardlinkFixup(dev, hardList);

	/* Fix up any shadowed objects */
	{
		struct yaffs_ShadowFixerStruct *fixer;
		yaffs_Object *obj;

		while (shadowFixerList) {
			fixer = shadowFixerList;
			shadowFixerList = fixer->next;
			/* Complete the rename transaction by deleting the shadowed object
			 * then setting the object header to unshadowed.
			 */
			obj = yaffs_FindObjectByNumber(dev, fixer->shadowedId);
			if (obj)
				yaffs_DeleteObject(obj);

			obj = yaffs_FindObjectByNumber(dev, fixer->objectId);

			if (obj)
				yaffs_UpdateObjectHeader(obj, NULL, 1, 0, 0, NULL);

			YFREE(fixer);
		}
	}

	yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);

	if (alloc_failed)
		return YAFFS_FAIL;

	T(YAFFS_TRACE_SCAN, (TSTR("yaffs1_Scan ends" TENDSTR)));


	return YAFFS_OK;
}
Beispiel #30
0
yaffs_obj_t *yaffs_alloc_raw_obj(yaffs_dev_t *dev)
{
	dev = dev;
	return (yaffs_obj_t *) YMALLOC(sizeof(yaffs_obj_t));
}