Example #1
0
static int ioctl2Attr(pfs_cache_t *clink, int cmd, void *arg, void *outbuf, u32 *offset)
{ // attr set, attr delete, attr lookup, attr read cmds
    int rv;
    pfs_cache_t *flink;

    if ((flink = pfsCacheGetData(clink->pfsMount, clink->sub, clink->block + 1, PFS_CACHE_FLAG_NOTHING, &rv)) == NULL)
        return rv;

    switch (cmd) {
        case PIOCATTRADD:
            rv = ioctl2AttrAdd(flink, arg);
            break;

        case PIOCATTRDEL:
            rv = ioctl2AttrDelete(flink, arg);
            break;

        case PIOCATTRLOOKUP:
            rv = ioctl2AttrLookUp(flink, arg, outbuf);
            break;

        case PIOCATTRREAD:
            rv = ioctl2AttrRead(flink, outbuf, offset);
            break;
    }
    pfsCacheFree(flink);

    return rv;
}
Example #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;
}
Example #3
0
static int devctlFsckStat(pfs_mount_t *pfsMount, int mode)
{
    int rv;
    pfs_cache_t *clink;

    if ((clink = pfsCacheAllocClean(&rv)) != NULL) {
        rv = pfsFsckStat(pfsMount, clink->u.superblock, PFS_FSCK_STAT_ERRORS_FIXED, mode);
        pfsCacheFree(clink);
    }
    return rv;
}
Example #4
0
pfs_cache_t *pfsGetDentriesAtPos(pfs_cache_t *clink, u64 position, int *offset, int *result)
{
	pfs_blockpos_t blockpos;
	pfs_cache_t *r;
	*result=pfsBlockInitPos(clink, &blockpos, position);
	if (*result)	return 0;

	*offset=blockpos.byte_offset % pfsMetaSize;

	r=pfsGetDentriesChunk(&blockpos, result);
	pfsCacheFree(blockpos.inode);

	return r;
}
Example #5
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;
}
Example #6
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;
}