コード例 #1
0
ファイル: block.c プロジェクト: AzagraMac/PS2_SDK
// Sets 'blockpos' to point to the next block segment for the inode (and moves onto the
// next block descriptor inode if necessary)
int blockSeekNextSegment(pfs_cache_t *clink, pfs_blockpos_t *blockpos)
{
	pfs_cache_t *nextSegment;
	int result=0;

	if (blockpos->byte_offset)   
	{
		printf("ps2fs: 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 (fixIndex(blockpos->block_segment+1)==0)
	{
		if ((nextSegment=blockGetNextSegment(cacheUsedAdd(blockpos->inode), &result)) == NULL)
			return result;
		cacheAdd(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;
}
コード例 #2
0
ファイル: block.c プロジェクト: AzagraMac/PS2_SDK
int blockInitPos(pfs_cache_t *clink, pfs_blockpos_t *blockpos, u64 position)
{
	blockpos->inode=cacheUsedAdd(clink);
	blockpos->byte_offset=0;

	if (clink->u.inode->size)
	{
		blockpos->block_segment=1;
		blockpos->block_offset=0;
	}else{
		blockpos->block_segment=0;
		blockpos->block_offset=1;
	}
	return inodeSync(blockpos, position, clink->u.inode->number_data);
}
コード例 #3
0
ファイル: dir.c プロジェクト: scuriumk/ps2sdk
// Gets a dir entry from the inode specified by clink
pfs_cache_t *getDentry(pfs_cache_t *clink, char *path, pfs_dentry **dentry, u32 *size, int option)
{
	pfs_blockpos_t block_pos;
	u32	result;
	pfs_dentry *d;
	u16 aLen;
	pfs_dentry *d2;
	pfs_cache_t *dentCache;
	u32 dentryLen=0;
	int len=0;

	if (path)
	{
		len = strlen(path);
		dentryLen = (len+8+3) &~4;
	}
	*size = 0;

	block_pos.inode = cacheUsedAdd(clink);
	block_pos.block_segment = 1;
	block_pos.block_offset = 0;
	block_pos.byte_offset = 0;
	dentCache = getDentriesChunk(&block_pos, (int *)&result);

	if (dentCache)
	{
		d2=d=dentCache->u.dentry;
		while(*size < clink->u.inode->size)
		{
			// Read another dentry chunk if we need to
			if ((int)d2 >= ((int)dentCache->u.inode + metaSize))
			{
				if (inodeSync(&block_pos, metaSize, clink->u.inode->number_data))
					break;
				cacheAdd(dentCache);

				if ((dentCache=getDentriesChunk(&block_pos, (int *)&result))==0)
					break;
				d=dentCache->u.dentry;
			}

			for (d2=(pfs_dentry*)((int)d+512); d < d2; (int)d+=aLen)
			{
				aLen=(d->aLen & 0xFFF);

				if (aLen & 3){
					printf("ps2fs: Error: dir-entry allocated length/4 != 0\n");
					goto _exit;
				}
				if (aLen < ((d->pLen + 8 + 3) & 0x1FC)){
					printf("ps2fs: Error: dir-entry is too small\n");
					goto _exit;
				}
				if ((u32)d2 < ((u32)d + aLen)){
					printf("ps2fs: Error: dir-entry across sectors\n");
					goto _exit;
				}

				// decide if the current dentry meets the required criteria, based on 'option'
				switch(option)
				{
					case 0: // result = 1 when paths are equal
						result = (len==d->pLen) && (memcmp(path, d->path, d->pLen)==0);
						break;
					case 1: // hrm..
						result = ((d->inode) || (aLen < dentryLen)) ? ((aLen - ((d->pLen + 8 + 3) & 0x1FC))
								> dentryLen) : 1;
						break;
					case 2: // result = 1 when dir path is not empty, "." or ".."
						result = d->pLen && strcmp(d->path, ".") && strcmp(d->path, "..");
						break;
					default:
						goto _exit;
				}

				if (result)
				{
					*dentry=d;
					cacheAdd(block_pos.inode);
					return dentCache;
				}
				*size+=aLen;
			}
		}
_exit:		cacheAdd(dentCache);
	}
	cacheAdd(block_pos.inode);
	return NULL;
}
コード例 #4
0
ファイル: pfs_fioctl.c プロジェクト: scuriumk/ps2sdk
void ioctl2Free(pfs_cache_t *pfree)
{
	pfs_blockinfo b;
	int result;
	pfs_mount_t *pfsMount = pfree->pfsMount;
	pfs_inode *inode = pfree->u.inode;
	u32 nextsegdesc = 1, limit = inode->number_data, i, j = 0, zones;
	pfs_blockinfo *bi;
	pfs_cache_t *clink;

	zones = inode->size / pfsMount->zsize;
	if(inode->size % pfsMount->zsize)
		zones++;
	if(inode->number_segdesg + zones == inode->number_blocks)
		return;

	j = zones;
	b.number = 0;
	clink = cacheUsedAdd(pfree);

	// iterate through each of the block segments used by the inode
	for (i = 1; i < limit && j; i++)
	{
		if(fixIndex(i) == 0)
		{
			if ((clink = blockGetNextSegment(clink, &result)) == 0)
				return;

			nextsegdesc++;
		}
		else
			if(j < clink->u.inode->data[fixIndex(i)].count)
			{
				clink->u.inode->data[fixIndex(i)].count -= j;
				b.subpart = clink->u.inode->data[fixIndex(i)].subpart;
				b.count = j;
				b.number = clink->u.inode->data[fixIndex(i)].number +
					clink->u.inode->data[fixIndex(i)].count;
				j = 0;
				clink->flags |= CACHE_FLAG_DIRTY;
			}
			else
				j -= clink->u.inode->data[fixIndex(i)].count;
	}

	pfree->u.inode->number_data = i;
	pfree->u.inode->number_blocks = zones + nextsegdesc;
	pfree->u.inode->number_segdesg = nextsegdesc;
	pfree->u.inode->last_segment.number = clink->u.inode->data[0].number;
	pfree->u.inode->last_segment.subpart= clink->u.inode->data[0].subpart;
	pfree->u.inode->last_segment.count  = clink->u.inode->data[0].count;
	pfree->flags |= CACHE_FLAG_DIRTY;

	if (b.number)
		bitmapFreeBlockSegment(pfsMount, &b);

	while(i < limit)
	{
		if (fixIndex(i) == 0)
		{
			if((clink = blockGetNextSegment(clink, &result)) == 0)
				return;
		}
		bi = &clink->u.inode->data[fixIndex(i++)];
		bitmapFreeBlockSegment(pfsMount, bi);
		cacheMarkClean(pfsMount, bi->subpart, bi->number<<pfsMount->inode_scale,
			(bi->number+bi->count)<<pfsMount->inode_scale);
	}

	cacheAdd(clink);
}