Ejemplo n.º 1
0
static pfs_aentry_t *getAentry(pfs_cache_t *clink, char *key, char *value, int mode)
{
    int kLen, fullsize;
    pfs_aentry_t *aentry = clink->u.aentry;
    pfs_aentry_t *aentryLast = NULL;
    pfs_aentry_t *end;

    kLen = strlen(key);
    fullsize = (kLen + strlen(value) + 7) & ~3;
    for (end = (pfs_aentry_t *)((u8 *)aentry + 1024); aentry < end; aentry = (pfs_aentry_t *)((u8 *)aentry + aentry->aLen)) { //Other than critical errors, do nothing about the filesystem errors.
        if (aentry->aLen & 3)
            PFS_PRINTF(PFS_DRV_NAME " Error: aentry allocated length/4 != 0\n");
        if (aentry->aLen < ((aentry->kLen + aentry->vLen + 7) & ~3)) {
            PFS_PRINTF(PFS_DRV_NAME " Panic: aentry is too small\n");
            return NULL;
        }
        if (end < (pfs_aentry_t *)((u8 *)aentry + aentry->aLen))
            PFS_PRINTF(PFS_DRV_NAME " Error: aentry too big\n");

        switch (mode) {
            case PFS_AENTRY_MODE_LOOKUP:
                if (kLen == aentry->kLen)
                    if (memcmp(key, aentry->str, kLen) == 0)
                        return aentry;
                break;

            case PFS_AENTRY_MODE_ADD:
                if (aentry->kLen == 0) {
                    if (aentry->aLen >= fullsize)
                        return aentry;
                }
                if (aentry->aLen - ((aentry->kLen + aentry->vLen + 7) & ~3) < fullsize)
                    continue;
                return aentry;

            case PFS_AENTRY_MODE_DELETE:
            default:
                if (kLen == aentry->kLen) {
                    if (memcmp(key, aentry->str, kLen) == 0) {
                        if (aentryLast != NULL) {
                            aentryLast->aLen += aentry->aLen;
                            return aentry;
                        }
                        // delete it :P
                        aentry->kLen = 0;
                        aentry->vLen = 0;
                        return aentry;
                    }
                }
                aentryLast = aentry;
                break;
        }
    }
    return NULL;
}
Ejemplo n.º 2
0
// Sets 'blockpos' to point to the next block segment for the inode (and moves onto the
// next block descriptor inode if necessary)
int pfsBlockSeekNextSegment(pfs_cache_t *clink, pfs_blockpos_t *blockpos)
{
	pfs_cache_t *nextSegment;
	int result=0;

	if (blockpos->byte_offset)
	{
		PFS_PRINTF(PFS_DRV_NAME": Panic: This is a bug!\n");
		return -1;
	}

	// If we're at the end of the block descriptor array for the current
	// inode, then move onto the next inode
	if (pfsFixIndex(blockpos->block_segment+1)==0)
	{
		if ((nextSegment=pfsBlockGetNextSegment(pfsCacheUsedAdd(blockpos->inode), &result)) == NULL)
			return result;
		pfsCacheFree(blockpos->inode);
		blockpos->inode=nextSegment;
		if (clink->u.inode->number_data-1 == ++blockpos->block_segment)
			return -EINVAL;
	}

	blockpos->block_offset=0;
	blockpos->block_segment++;
	return result;
}
Ejemplo n.º 3
0
int pfsCheckZoneSize(u32 zone_size)
{
    if ((zone_size & (zone_size - 1)) || (zone_size < (2 * 1024)) || (zone_size > (128 * 1024))) {
        PFS_PRINTF(PFS_DRV_NAME ": Error: Invalid zone size\n");
        return 0;
    }

    return 1;
}
Ejemplo n.º 4
0
// Returns the next block descriptor inode
pfs_cache_t *pfsBlockGetNextSegment(pfs_cache_t *clink, int *result)
{
	pfsCacheFree(clink);

	if (clink->u.inode->next_segment.number)
		return pfsCacheGetData(clink->pfsMount,
		clink->u.inode->next_segment.subpart,
		clink->u.inode->next_segment.number << clink->pfsMount->inode_scale,
		PFS_CACHE_FLAG_SEGI, result);

	PFS_PRINTF(PFS_DRV_NAME": Error: There is no next segment descriptor\n");
	*result=-EINVAL;
	return NULL;
}
Ejemplo n.º 5
0
int pfsInodeSync(pfs_blockpos_t *blockpos, u64 size, u32 used_segments)
{
	int result=0;
	u32 i;
	u16 count;

	for(i=pfsBlockSyncPos(blockpos, size); i; )
	{
		count=blockpos->inode->u.inode->data[pfsFixIndex(blockpos->block_segment)].count;

		i+=blockpos->block_offset;

		if (i < count){
			blockpos->block_offset=i;
			break;
		}

		i-=count;

		if (blockpos->block_segment + 1 == used_segments)
		{
			blockpos->block_offset=count;
			if (i || blockpos->byte_offset){
				PFS_PRINTF(PFS_DRV_NAME": panic: fp exceeds file.\n");
				return -EINVAL;
			}
		}else{
			blockpos->block_offset=0;
			blockpos->block_segment++;
		}

		if (pfsFixIndex(blockpos->block_segment))
			continue;

		if ((blockpos->inode = pfsBlockGetNextSegment(blockpos->inode, &result)) == 0)
			break;

		i++;
	}

	return result;
}
Ejemplo n.º 6
0
void pfsInodePrint(pfs_inode_t *inode)
{
	PFS_PRINTF(PFS_DRV_NAME": pfsInodePrint: Checksum = 0x%lX, Magic = 0x%lX\n", inode->checksum, inode->magic);
	PFS_PRINTF(PFS_DRV_NAME":     Mode = 0x%X, attr = 0x%X\n", inode->mode, inode->attr);
	PFS_PRINTF(PFS_DRV_NAME":     size = 0x%08lX%08lX\n", (u32)(inode->size >> 32), (u32)(inode->size));
}
Ejemplo n.º 7
0
// Attempts to allocate 'blocks' new blocks for an inode
int pfsBlockAllocNewSegment(pfs_cache_t *clink, pfs_blockpos_t *blockpos, u32 blocks)
{
	pfs_blockinfo_t bi, *bi2;
	int result=0;
	pfs_mount_t *pfsMount=clink->pfsMount;
	u32 i, old_blocks = blocks;

	if (pfsCacheIsFull())
		return -ENOMEM;

	// create "indirect segment descriptor" if necessary
	if (pfsFixIndex(clink->u.inode->number_data) == 0)
	{
		pfs_cache_t *clink2;

		bi2 = &blockpos->inode->u.inode->data[pfsFixIndex(blockpos->block_segment)];
		bi.subpart=bi2->subpart;
		bi.count=1;
		bi.number=bi2->number+bi2->count;
		result=pfsBitmapSearchFreeZone(pfsMount, &bi, clink->u.inode->number_blocks);
		if (result<0)
		{
			PFS_PRINTF(PFS_DRV_NAME": Error: Couldnt allocate zone! (1)\n");
			return result;
		}

		clink2=pfsCacheGetData(pfsMount, bi.subpart, bi.number << pfsMount->inode_scale,
								PFS_CACHE_FLAG_SEGI | PFS_CACHE_FLAG_NOLOAD, &result);
		memset(clink2->u.inode, 0, sizeof(pfs_inode_t));
		clink2->u.inode->magic=PFS_SEGI_MAGIC;

		memcpy(&clink2->u.inode->inode_block, &clink->u.inode->inode_block, sizeof(pfs_blockinfo_t));
		memcpy(&clink2->u.inode->last_segment, blockpos->inode->u.inode->data, sizeof(pfs_blockinfo_t));
		memcpy(clink2->u.inode->data, &bi, sizeof(pfs_blockinfo_t));

		clink2->flags |= PFS_CACHE_FLAG_DIRTY;

		clink->u.inode->number_blocks+=bi.count;
		clink->u.inode->number_data++;

		memcpy(&clink->u.inode->last_segment, &bi, sizeof(pfs_blockinfo_t));

		clink->u.inode->number_segdesg++;

		clink->flags |= PFS_CACHE_FLAG_DIRTY;
		blockpos->block_segment++;
		blockpos->block_offset=0;

		memcpy(&blockpos->inode->u.inode->next_segment, &bi, sizeof(pfs_blockinfo_t));

		blockpos->inode->flags |= PFS_CACHE_FLAG_DIRTY;
		pfsCacheFree(blockpos->inode);
		blockpos->inode=clink2;
	}

	bi2 = &blockpos->inode->u.inode->data[pfsFixIndex(blockpos->block_segment)];
	bi.subpart = bi2->subpart;
	bi.count = blocks;
	bi.number = bi2->number + bi2->count;

	result = pfsBitmapSearchFreeZone(pfsMount, &bi, clink->u.inode->number_blocks);
	if(result < 0)
	{
		PFS_PRINTF(PFS_DRV_NAME": Error: Couldnt allocate zone! (2)\n");
		return result;
	}

	clink->u.inode->number_blocks += bi.count;
	clink->u.inode->number_data++;
	clink->flags |= PFS_CACHE_FLAG_DIRTY;
	blockpos->block_offset=0;
	blockpos->block_segment++;

	i = pfsFixIndex(clink->u.inode->number_data-1);
	memcpy(&blockpos->inode->u.inode->data[i], &bi, sizeof(pfs_blockinfo_t));

	blockpos->inode->flags |= PFS_CACHE_FLAG_DIRTY;
	blocks -= bi.count;
	if (blocks)
		blocks -= pfsBlockExpandSegment(clink, blockpos, blocks);

	return old_blocks - blocks;
}