/** * 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; }
/***************************************************************************** << 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; }
/** * 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; }