Пример #1
0
/**
 * Fuegt einen Bereich zur Freelist hinzu
 * \param start		Erster Block der freizugebenden Daten
 * \param end		Letzter Block der freizugebenden Daten
 * \param *buffer	Puffer fuer mindestens BOTFS_BLOCK_SIZE Byte
 * \return			0, falls kein Fehler
 */
static int8_t add_to_freelist(uint16_t start, uint16_t end, void * buffer) {
	/* Auf Freiblock direkt nach dieser Datei pruefen */
	botfs_freelist_entry_t * pFree = search_freelist(test_block_start, end + 1, 1, buffer);
	if (pFree != NULL) {
		PRINT_MSG("add_to_freelist(): Freiblock folgt auf Datei");
		/* Datei mit Freiblock dahinter verschmelzen */
		end += pFree->size;
		/* Freiblock loeschen */
		pFree->size = 0;
		/* Block zurueckschreiben */
		botfs_seek(&botfs_vol_data.freelist, -1, SEEK_CUR);
		if (botfs_write(&botfs_vol_data.freelist, buffer) != 0) {
			PRINT_MSG("add_to_freelist(): add_to_freelist(): write()-error");
			return -11;
		}
	}
	/* Auf Freiblock direkt vor dieser Datei pruefen */
	pFree = search_freelist(test_block_end, start, 1, buffer);
	if (pFree != NULL) {
		PRINT_MSG("add_to_freelist(): Datei folgt auf Freiblock");
		/* Freiblock auf Datei ausdehnen */
		pFree->size += end - start + 1;
		/* Block zurueckschreiben */
		botfs_seek(&botfs_vol_data.freelist, -1, SEEK_CUR);
		if (botfs_write(&botfs_vol_data.freelist, buffer) != 0) {
			PRINT_MSG("add_to_freelist(): write()-error");
			return -12;
		}
		return 0;
	}

	/* Kein Freelist-Eintrag passt, Neuen erzeugen */
	PRINT_MSG("add_to_freelist(): erzeuge neuen Freelist-Eintrag");
	pFree = search_freelist(test_size, 1, 0, buffer);
	if (pFree == NULL) {
		return -13;
	}
	pFree->block = start;
	pFree->size = end - start + 1;
	PRINT_MSG("add_to_freelist(): block=0x%04x, size=0x%04x", pFree->block, pFree->size);
	/* Block zurueckschreiben */
	botfs_seek(&botfs_vol_data.freelist, -1, SEEK_CUR);
	if (botfs_write(&botfs_vol_data.freelist, buffer) != 0) {
		PRINT_MSG("add_to_freelist(): write()-error");
		return -14;
	}

	return 0;
}
Пример #2
0
/*****************************************************************************
 << MEMORY ALLOCATION (DM_MALLOC) >>
 *****************************************************************************/
int doDM_MALLOC(dm_ioctl_parm *parm)
{
	unsigned long size;
	int n;
	dm_blockinfo *ptr;

	size = parm->size;	

	/* (1)size != Ingeter * DM_BLOCKUNIT_SIZE */
	/* (2)size < DM_BLOCKUNIT_SIZE            */
	/* (3)size > DM_MALLOC_MAX_SIZE           */
	/* we supporse that (1),(2) and (3) are blocked in library layer */
	
	/* get number of required blocks */
	n = size >> DM_BLOCKUNIT_SIZE_SHIFT;

	/* find from "free list" */
	ptr = search_freelist(n);
	if(ptr == NULL){
		/* finding from "free list" failed, so execute fast search */
		ptr = alloc_newblock(n);
		if(ptr == NULL){
			/* fast search failed, find from whole fo DM */
			ptr = search_freeblock(n);
			if(ptr == NULL){
				/* All failed */
				parm->offset = -1;
				printk(KERN_ERR "[DM] %s failed!\n", __FUNCTION__);
				return (-ENOMEM);
			}
		}
	}

	/* in case you got space to allocate ... */

	/* copy the information to user area */
	parm->offset = ptr->offset;

	/* increment total number of allocated blocks */
	dm_malloc_count += n;

	return 0;

}
Пример #3
0
/**
 * Legt eine neue Datei an
 * \param *filename	Dateiname
 * \param size		Groesse der Datei in Bloecken
 * \param alignment	Ausrichtung des Dateianfangs an einer X-Blockgrenze (normalerweise 0)
 * \param *buffer	Puffer fuer mindestens BOTFS_BLOCK_SIZE Byte
 * \return			0, falls kein Fehler
 */
int8_t botfs_create(const char * filename, uint16_t size, uint16_t alignment, void * buffer) {
	botfs_acquire_lock_low(&botfs_mutex);
	/* Datei bereits vorhanden? */
	if (search_file(filename, buffer) != NULL) {
		botfs_release_lock_low(&botfs_mutex);
		PRINT_MSG("botfs_create(): file existing");
		return -1;
	}
	++size;	// Header braucht einen Block
	PRINT_MSG("botfs_create(): creating file \"%s\" with size 0x%x blocks", filename, size);

	alignment = alignment > 0 ? alignment - 1 : 0;

	/* freien Speicherbereich suchen */
	botfs_freelist_entry_t * pFree = search_freelist(test_size, size + alignment, 1, buffer);
	if (pFree == NULL) {
		botfs_release_lock_low(&botfs_mutex);
		PRINT_MSG("botfs_create(): no space left");
		return -2;
	}

	PRINT_MSG("botfs_create(): pFree->block=0x%x", pFree->block);
	PRINT_MSG("botfs_create():  sector=0x%x", get_sector(pFree->block));

	/* Alignment des ersten Datenblocks berechnen */
	uint16_t offset = (uint16_t) (((get_sector(pFree->block + BOTFS_HEADER_SIZE) + alignment) & ~alignment) - get_sector(pFree->block + BOTFS_HEADER_SIZE));
	PRINT_MSG("botfs_create(): alignment-offset=0x%x", offset);

	/* Freelist aktualisieren */
	pFree->size -= size + offset;
	uint16_t start = pFree->block + offset;
	PRINT_MSG("botfs_create(): start=0x%x", start);
	PRINT_MSG("botfs_create(): first_data=0x%x", start + BOTFS_HEADER_SIZE);
	pFree->block += size + offset;
	uint16_t end = pFree->block - 1;
	PRINT_MSG("botfs_create(): end=0x%x", end);

	/* Freelist-Block zurueckschreiben */
	botfs_seek(&botfs_vol_data.freelist, -1, SEEK_CUR);
	if (botfs_write(&botfs_vol_data.freelist, buffer) != 0) {
		botfs_release_lock_low(&botfs_mutex);
		PRINT_MSG("botfs_create(): can't write freelist");
		return -3;
	}

	/* Alingment-Offset als frei markieren */
	if (offset != 0) {
		PRINT_MSG("botfs_create(): freeing 0x%x - 0x%x", start - offset, start - 1);
		if (add_to_freelist(start - offset, start - 1, buffer) != 0) {
			botfs_release_lock_low(&botfs_mutex);
			PRINT_MSG("botfs_create(): can't update freelist");
			// Freelist muesste man hier eigentlich wieder zuruecksetzen
			return -4;
		}
	}

	/* leeren Root-Dir-Eintrag suchen */
	botfs_file_t * pFile = search_file("", buffer);
	if (pFile == NULL) {
		botfs_release_lock_low(&botfs_mutex);
		PRINT_MSG("botfs_create(): no dir-entry left");
		// Freelist muesste man hier eigentlich wieder zuruecksetzen
		return -4;
	}
	char * ptr = pFile->name;
	if (filename[0] != '/') {
		*ptr = '/';
		ptr++;
	}
	strncpy(ptr, filename, BOTFS_MAX_FILENAME - 1);
	pFile->descr.start = start;
	pFile->descr.end = end;

	/* Root-Dir-Block zurueckschreiben */
	botfs_seek(&botfs_vol_data.rootdir, -1, SEEK_CUR);
	if (botfs_write(&botfs_vol_data.rootdir, buffer) != 0) {
		botfs_release_lock_low(&botfs_mutex);
		PRINT_MSG("botfs_create(): can't write rootdir");
		// Freelist muesste man hier eigentlich wieder zuruecksetzen
		return -5;
	}

	/* Datei-Header erzeugen */
	botfs_file_header_t * pHeader = buffer;
	memset(pHeader, 0, sizeof(botfs_file_header_t));
	/* Datei als komplett belegt kennzeichnen */
	pHeader->used_blocks.start = start + BOTFS_HEADER_SIZE;
	pHeader->used_blocks.end = end;
	pHeader->used_blocks.bytes_last_block = BOTFS_BLOCK_SIZE;
	PRINT_MSG("botfs_create(): writing file-header...");
	if (botfs_write_low(start, buffer) != 0) {
		botfs_release_lock_low(&botfs_mutex);
		PRINT_MSG("botfs_create(): can't write file-header");
		// Freelist muesste man hier eigentlich wieder zuruecksetzen
		return -6;
	}
	botfs_release_lock_low(&botfs_mutex);
	return 0;
}