Пример #1
0
/*
 * adfDelFromCache
 *
 * delete one cache entry from its block. don't do 'records garbage collecting'
 */
RETCODE adfDelFromCache(struct Volume *vol, struct bEntryBlock *parent, 
    SECTNUM headerKey)
{
    struct bDirCacheBlock dirc;
    SECTNUM nSect, prevSect;
    struct CacheEntry caEntry;
    int offset, oldOffset, n;
    BOOL found;
    int entryLen;
    int i;
    RETCODE rc = RC_OK;

    prevSect = -1;
	nSect = parent->extension;
    found = FALSE;
    do {
        adfReadDirCBlock(vol, nSect, &dirc);
        offset = 0; n = 0;
        while(n < dirc.recordsNb && !found) {
            oldOffset = offset;
            adfGetCacheEntry(&dirc, &offset, &caEntry);
            found = (caEntry.header==headerKey);
            if (found) {
                entryLen = offset-oldOffset;
                if (dirc.recordsNb>1 || prevSect==-1) {
                    if (n<dirc.recordsNb-1) {
                        /* not the last of the block : switch the following records */
                        for(i=oldOffset; i<(488-entryLen); i++)
                            dirc.records[i] = dirc.records[i+entryLen];
                        /* and clear the following bytes */
                        for(i=488-entryLen; i<488; i++)
                            dirc.records[i] = 0;
                    }
                    else {
                        /* the last record of this cache block */
                        for(i=oldOffset; i<offset; i++)
                            dirc.records[i] = 0;
                    }
                    dirc.recordsNb--;
                    if (adfWriteDirCBlock(vol, dirc.headerKey, &dirc)!=RC_OK)
						return -1;
                }
                else {
                    /* dirc.recordsNb ==1 or == 0 , prevSect!=-1 : 
                    * the only record in this dirc block and a previous dirc block exists 
                    */
                    adfSetBlockFree(vol, dirc.headerKey);
                    adfReadDirCBlock(vol, prevSect, &dirc);
                    dirc.nextDirC = 0L;
                    adfWriteDirCBlock(vol, prevSect, &dirc);

                    adfUpdateBitmap(vol);
                }
            }
            n++;
        }
        prevSect = nSect;
        nSect = dirc.nextDirC;
    }while(nSect!=0 && !found);

    if (!found)
        (*adfEnv.wFct)("adfUpdateCache : entry not found");

    return rc;
}
Пример #2
0
/*
 * adfRemoveEntry
 *
 */
RETCODE adfRemoveEntry(struct Volume *vol, SECTNUM pSect, char *name)
{
    struct bEntryBlock parent, previous, entry;
    SECTNUM nSect2, nSect;
    int hashVal;
    BOOL intl;
    char buf[200];

    if (adfReadEntryBlock( vol, pSect, &parent )!=RC_OK)
		return RC_ERROR;
    nSect = adfNameToEntryBlk(vol, parent.hashTable, name, &entry, &nSect2);
    if (nSect==-1) {
      sprintf(buf, "adfRemoveEntry : entry '%s' not found", name);
        (*adfEnv.wFct)(buf);
        return RC_ERROR;
    }
    /* if it is a directory, is it empty ? */
    if ( entry.secType==ST_DIR && !isDirEmpty((struct bDirBlock*)&entry) ) {
      sprintf(buf, "adfRemoveEntry : directory '%s' not empty", name);
        (*adfEnv.wFct)(buf);
        return RC_ERROR;
    }
/*    printf("name=%s  nSect2=%ld\n",name, nSect2);*/

    /* in parent hashTable */
    if (nSect2==0) {
        intl = isINTL(vol->dosType) || isDIRCACHE(vol->dosType);
        hashVal = adfGetHashValue( (unsigned char*)name, intl );
/*printf("hashTable=%d nexthash=%d\n",parent.hashTable[hashVal],
 entry.nextSameHash);*/
        parent.hashTable[hashVal] = entry.nextSameHash;
        if (adfWriteEntryBlock(vol, pSect, &parent)!=RC_OK)
			return RC_ERROR;
    }
    /* in linked list */
    else {
        if (adfReadEntryBlock(vol, nSect2, &previous)!=RC_OK)
			return RC_ERROR;
        previous.nextSameHash = entry.nextSameHash;
        if (adfWriteEntryBlock(vol, nSect2, &previous)!=RC_OK)
			return RC_ERROR;
    }

    if (entry.secType==ST_FILE) {
        adfFreeFileBlocks(vol, (struct bFileHeaderBlock*)&entry);
        if (adfEnv.useNotify)
             (*adfEnv.notifyFct)(pSect,ST_FILE);
    }
    else if (entry.secType==ST_DIR) {
        adfSetBlockFree(vol, nSect);
        /* free dir cache block : the directory must be empty, so there's only one cache block */
        if (isDIRCACHE(vol->dosType))
            adfSetBlockFree(vol, entry.extension);
        if (adfEnv.useNotify)
            (*adfEnv.notifyFct)(pSect,ST_DIR);
    }
    else {
      sprintf(buf, "adfRemoveEntry : secType %d not supported", entry.secType);
        (*adfEnv.wFct)(buf);
        return RC_ERROR;
    }

    if (isDIRCACHE(vol->dosType))
        adfDelFromCache(vol, &parent, entry.headerKey);

    adfUpdateBitmap(vol);

    return RC_OK;
}
Пример #3
0
/*
 * adfUpdateCache
 *
 */
RETCODE adfUpdateCache(struct Volume *vol, struct bEntryBlock *parent, 
    struct bEntryBlock *entry, BOOL entryLenChg)
{
    struct bDirCacheBlock dirc;
    SECTNUM nSect;
    struct CacheEntry caEntry, newEntry;
    int offset, oldOffset, n;
    BOOL found;
    int i, oLen, nLen;
    int sLen; /* shift length */

    nLen = adfEntry2CacheEntry(entry, &newEntry);

    nSect = parent->extension;
    found = FALSE;
    do {
/*printf("dirc=%ld\n",nSect);*/
        if (adfReadDirCBlock(vol, nSect, &dirc)!=RC_OK)
			return RC_ERROR;
        offset = 0; n = 0;
        /* search entry to update with its header_key */
        while(n < dirc.recordsNb && !found) {
            oldOffset = offset;
            /* offset is updated */
            adfGetCacheEntry(&dirc, &offset, &caEntry);
            oLen = offset-oldOffset;
            sLen = oLen-nLen;
/*printf("olen=%d nlen=%d\n",oLen,nLen);*/
            found = (caEntry.header==newEntry.header);
            if (found) {
                if (!entryLenChg || oLen==nLen) {
                    /* same length : remplace the old values */
                    adfPutCacheEntry(&dirc, &oldOffset, &newEntry);
/*if (entryLenChg) puts("oLen==nLen");*/
                    if (adfWriteDirCBlock(vol, dirc.headerKey, &dirc)!=RC_OK)
                        return RC_ERROR;
                }
                else if (oLen>nLen) {
/*puts("oLen>nLen");*/
                    /* the new record is shorter, write it, 
                     * then shift down the following records 
                     */
                    adfPutCacheEntry(&dirc, &oldOffset, &newEntry);
                    for(i=oldOffset+nLen; i<(488-sLen); i++)
                        dirc.records[i] = dirc.records[i+sLen];
                    /* then clear the following bytes */
                    for(i=488-sLen; i<488; i++)
                        dirc.records[i] = (char)0;

                    if (adfWriteDirCBlock(vol, dirc.headerKey, &dirc)!=RC_OK)
                        return RC_ERROR;
                }
                else {
                    /* the new record is larger */
/*puts("oLen<nLen");*/
                    adfDelFromCache(vol,parent,entry->headerKey);
                    adfAddInCache(vol,parent,entry);
/*puts("oLen<nLen end");*/

                }
            }
            n++;
        }
        nSect = dirc.nextDirC;
    }while(nSect!=0 && !found);

    if (found) {
        if (adfUpdateBitmap(vol)!=RC_OK)
			return RC_ERROR;
    }
    else
        (*adfEnv.wFct)("adfUpdateCache : entry not found");

    return RC_OK;
}
Пример #4
0
/*
 * adfCreateVol
 *
 * 
 */
struct Volume* adfCreateVol( struct Device* dev, int32_t start, int32_t len, 
    char* volName, int volType,struct DateTime * voldate )
{
    struct bBootBlock boot;
    struct bRootBlock root;
/*    struct bDirCacheBlock dirc;*/
    SECTNUM blkList[2];
    struct Volume* vol;
    int nlen;

    if (adfEnv.useProgressBar)
        (*adfEnv.progressBar)(0);

    vol=(struct Volume*)calloc(1,sizeof(struct Volume));
    if (!vol) { 
		(*adfEnv.eFct)("adfCreateVol : malloc vol");
        return NULL;
    }
	
    vol->dev = dev;
    vol->firstBlock = (dev->heads * dev->sectors)*start;
    vol->lastBlock = (vol->firstBlock + (dev->heads * dev->sectors)*len)-1;
    vol->rootBlock = (vol->lastBlock - vol->firstBlock+1)/2;
/*printf("first=%ld last=%ld root=%ld\n",vol->firstBlock,
 vol->lastBlock, vol->rootBlock);
*/
    vol->curDirPtr = vol->rootBlock;

    vol->readOnly = dev->readOnly;

    vol->mounted = TRUE;

    nlen = min( MAXNAMELEN, strlen(volName) );
    vol->volName = (char*)calloc(1,nlen+1);
    if (!vol->volName) { 
		(*adfEnv.eFct)("adfCreateVol : malloc");
		free(vol); return NULL;
    }
    memcpy(vol->volName, volName, nlen);
    vol->volName[nlen]='\0';

    if (adfEnv.useProgressBar)
        (*adfEnv.progressBar)(25);

    memset(&boot, 0, 1024);
    boot.dosType[3] = volType;
/*printf("first=%d last=%d\n", vol->firstBlock, vol->lastBlock);
printf("name=%s root=%d\n", vol->volName, vol->rootBlock);
*/
    if (adfWriteBootBlock(vol, &boot)!=RC_OK) {
        free(vol->volName); free(vol);
        return NULL;
    }

    if (adfEnv.useProgressBar)
        (*adfEnv.progressBar)(20);

    if (adfCreateBitmap( vol )!=RC_OK) {
        free(vol->volName); free(vol);
        return NULL;
    }

    if (adfEnv.useProgressBar)
        (*adfEnv.progressBar)(40);


/*for(i=0; i<127; i++)
printf("%3d %x, ",i,vol->bitmapTable[0]->map[i]);
*/
    if ( isDIRCACHE(volType) )
        adfGetFreeBlocks( vol, 2, blkList );
    else
        adfGetFreeBlocks( vol, 1, blkList );


/*printf("[0]=%d [1]=%d\n",blkList[0],blkList[1]);*/

    memset(&root, 0, LOGICAL_BLOCK_SIZE);

    if (strlen(volName)>MAXNAMELEN)
        volName[MAXNAMELEN]='\0';
    root.nameLen = (char)strlen(volName);
    memcpy(root.diskName,volName,root.nameLen);

	if(voldate)
	{

		adfTime2AmigaTime(*voldate,&(root.coDays),&(root.coMins),&(root.coTicks));
	}
	else
	{
		adfTime2AmigaTime(adfGiveCurrentTime(),&(root.coDays),&(root.coMins),&(root.coTicks));
	}

    /* dircache block */
    if ( isDIRCACHE(volType) ) {
        root.extension = 0L;
        root.secType = ST_ROOT; /* needed by adfCreateEmptyCache() */
        adfCreateEmptyCache(vol, (struct bEntryBlock*)&root, blkList[1]);
    }

    if (adfEnv.useProgressBar)
        (*adfEnv.progressBar)(60);

    if (adfWriteRootBlock(vol, blkList[0], &root)!=RC_OK) {
        free(vol->volName); free(vol);
        return NULL;
    }

   /* fills root->bmPages[] and writes filled bitmapExtBlocks */
    if (adfWriteNewBitmap(vol)!=RC_OK)
		return NULL;

    if (adfEnv.useProgressBar)
        (*adfEnv.progressBar)(80);

    if (adfUpdateBitmap(vol)!=RC_OK)
		return NULL;

    if (adfEnv.useProgressBar)
        (*adfEnv.progressBar)(100);
/*printf("free blocks %ld\n",adfCountFreeBlocks(vol));*/

    /* will be managed by adfMount() later */
    adfFreeBitmap(vol);

    vol->mounted = FALSE;

    return(vol);
}