예제 #1
0
파일: apa.c 프로젝트: EvertonSilva/ps2sdk
apa_cache *apaInsertPartition(u32 device, input_param *params, u32 sector, int *err)
{	// add's a new partition useing a empty block...
	apa_cache *clink_empty;
	apa_cache *clink_this;
	apa_cache *clink_next;

	if((clink_this=cacheGetHeader(device, sector, 0, err))==0)
		return 0;
	while(clink_this->header->length!=params->size) {
		if((clink_next=cacheGetHeader(device, clink_this->header->next, 0, err))==NULL) { // get next
			cacheAdd(clink_this);
			return 0;
		}
		clink_this->header->length>>=1;
		clink_empty=apaRemovePartition(device, (clink_this->header->start+clink_this->header->length),
			clink_this->header->next, clink_this->header->start, clink_this->header->length);
		clink_this->header->next=clink_empty->header->start;
		clink_this->flags|=CACHE_FLAG_DIRTY;
		clink_next->header->prev=clink_empty->header->start;
		clink_next->flags|=CACHE_FLAG_DIRTY;

		cacheFlushAllDirty(device);
		cacheAdd(clink_empty);
		cacheAdd(clink_next);
	}
	cacheAdd(clink_this);
	clink_this=apaFillHeader(device, params, clink_this->header->start, clink_this->header->next,
		clink_this->header->prev, params->size, err);
	cacheFlushAllDirty(device);
	return clink_this;
}
예제 #2
0
int ioctl2DeleteLastSub(hdd_file_slot_t *fileSlot)
{
	int			rv;
	u32 		device=fileSlot->f->unit;
	apa_cache	*mainPart;
	apa_cache	*subPart;

	if(!(fileSlot->f->mode & O_WRONLY))
		return -EACCES;

	if(fileSlot->nsub==0)
		return -ENOENT;

	if(!(mainPart=cacheGetHeader(device, fileSlot->start, 0, &rv)))
		return rv;

	if((subPart=cacheGetHeader(device,
		mainPart->header->subs[mainPart->header->nsub-1].start, 0, &rv))) {
		fileSlot->nsub--;
		mainPart->header->nsub--;
		mainPart->flags|=CACHE_FLAG_DIRTY;
		cacheFlushAllDirty(device);
		rv=apaDelete(subPart);
	}
	cacheAdd(mainPart);
	return rv;
}
예제 #3
0
int ioctl2AddSub(hdd_file_slot_t *fileSlot, char *argp)
{
	int			rv;
	u32 		device=fileSlot->f->unit;
	input_param	params;
	u32			emptyBlocks[32];
	apa_cache	*clink;
	u32			sector=0;
	u32			length;

	if(!(fileSlot->f->mode & O_WRONLY))
		return -EACCES;

	if(!(fileSlot->nsub < APA_MAXSUB))
		return -EFBIG;

	memset(&params, 0, sizeof(input_param));

	if((rv=fioPartitionSizeLookUp(argp)) < 0)
		return rv;

	params.size=rv;
	params.flags=APA_FLAG_SUB;
	params.type=fileSlot->type;
	params.main=fileSlot->start;
	params.number=fileSlot->nsub+1;
	if((rv=apaCheckPartitionMax(device, params.size)) < 0)
		return rv;

	// walk all looking for any empty blocks
	memset(&emptyBlocks, 0, sizeof(emptyBlocks));
	clink=cacheGetHeader(device, 0, 0, &rv);
	while(clink){
		sector=clink->sector;
		addEmptyBlock(clink->header, emptyBlocks);
		clink=apaGetNextHeader(clink, &rv);
	}
	if(rv!=0)
		return rv;

	if(!(clink=apaAddPartitionHere(device, &params, emptyBlocks, sector, &rv)))
		return rv;

	sector=clink->header->start;
	length=clink->header->length;
	cacheAdd(clink);
	if(!(clink=cacheGetHeader(device, fileSlot->start, 0, &rv)))
		return rv;

	clink->header->subs[clink->header->nsub].start=sector;
	clink->header->subs[clink->header->nsub].length=length;
	clink->header->nsub++;
	fileSlot->nsub++;
	((apa_subs *)(&fileSlot->start))[fileSlot->nsub].start=sector;	// !HACK!
	((apa_subs *)(&fileSlot->start))[fileSlot->nsub].length=length;	// !HACK!
	clink->flags|=CACHE_FLAG_DIRTY;
	cacheFlushAllDirty(device);
	cacheAdd(clink);
	return rv;
}
예제 #4
0
파일: apa.c 프로젝트: EvertonSilva/ps2sdk
int apaDelete(apa_cache *clink)
{
	int				rv=0;
	apa_cache		*clink_mbr;
	u32				device=clink->device;
	u32				start=clink->header->start;
	int				i;

	if(!start) {
		cacheAdd(clink);
		return -EACCES;
	}

	if(clink->header->next==0) {
		if((clink_mbr=cacheGetHeader(device, 0, 0, &rv))==NULL)
		{
			cacheAdd(clink);
			return rv;
		}
		do {
			cacheAdd(clink);
			if((clink=cacheGetHeader(clink->device, clink->header->prev, 0, &rv))==NULL)
				return 0;
			clink->header->next=0;
			clink->flags|=CACHE_FLAG_DIRTY;
			clink_mbr->header->prev=clink->header->start;
			clink_mbr->flags|=CACHE_FLAG_DIRTY;
			cacheFlushAllDirty(device);
		} while(clink->header->type==0);
		cacheAdd(clink_mbr);
	} else {
		u32 length=clink->header->length;

		for(i=0;i < 2;i++){
			if((clink=apaDeleteFixPrev(clink, &rv))==NULL)
				return 0;
			if((clink=apaDeleteFixNext(clink, &rv))==NULL)
				return 0;
		}
		if(clink->header->start==start && clink->header->length==length) {
			apaMakeEmpty(clink);
			cacheFlushAllDirty(clink->device);
		}
	}
	cacheAdd(clink);
	return rv;
}
예제 #5
0
int hddReName(iop_file_t *f, const char *oldname, const char *newname)
{
	int rv;
	int i;
	apa_cache	*clink;
	char tmpBuf[APA_IDMAX];

	if(f->unit >= 2 || hddDeviceBuf[f->unit].status!=0)
		return -ENODEV;// No such device

	WaitSema(fioSema);
	// look to see if can make(newname) or not...
	memset(tmpBuf, 0, APA_IDMAX);
	strncpy(tmpBuf, newname, APA_IDMAX - 1);
	tmpBuf[APA_IDMAX - 1] = '\0';
	if((clink=apaFindPartition(f->unit, tmpBuf, &rv))){
		cacheAdd(clink);
		SignalSema(fioSema);
		return -EEXIST;	// File exists
	}

	// look to see if open(oldname)
	memset(tmpBuf, 0, APA_IDMAX);
	strncpy(tmpBuf, oldname, APA_IDMAX - 1);
	tmpBuf[APA_IDMAX - 1] = '\0';
	for(i=0;i<maxOpen;i++)
	{
		if(fileSlots[i].f!=0)
			if(fileSlots[i].f->unit==f->unit)
				if(memcmp(fileSlots[i].id, oldname, APA_IDMAX)==0)
				{
					SignalSema(fioSema);
					return -EBUSY;
				}
	}

	// find :)
	if(!(clink=apaFindPartition(f->unit, tmpBuf, &rv)))
	{
		SignalSema(fioSema);
		return -ENOENT;
	}

	// do the renameing :) note: subs have no names!!
	memset(clink->header->id, 0, APA_IDMAX);		// all cmp are done with memcmp!
	strncpy(clink->header->id, newname, APA_IDMAX - 1);
	clink->header->id[APA_IDMAX - 1] = '\0';

	clink->flags|=CACHE_FLAG_DIRTY;
	cacheFlushAllDirty(f->unit);
	cacheAdd(clink);
	SignalSema(fioSema);
	return 0;
}
예제 #6
0
int pfsIoctl2(iop_file_t *f, int cmd, void *arg, size_t arglen,	void *buf, size_t buflen)
{
	int rv;
	pfs_file_slot_t *fileSlot = (pfs_file_slot_t *)f->privdata;
	pfs_mount_t *pfsMount;

	if(f->mode & O_DIROPEN)
		if(cmd==PFS_IOCTL2_ATTR_READ)
			return -EISDIR;

	if(!(f->mode & O_WRONLY)) {
		if(cmd!=PFS_IOCTL2_ATTR_LOOKUP)
			if(cmd!=PFS_IOCTL2_ATTR_READ)
				return -EACCES;
	}
	if((rv=checkFileSlot(fileSlot))<0)
		return rv;
	pfsMount=fileSlot->clink->pfsMount;

	switch(cmd)
	{
	case PFS_IOCTL2_MALLOC:
		rv=ioctl2Alloc(fileSlot->clink, *(int *)(arg), 1);
		break;

	case PFS_IOCTL2_FREE:
		ioctl2Free(fileSlot->clink);
		break;

	case PFS_IOCTL2_ATTR_ADD:
	case PFS_IOCTL2_ATTR_DEL:
	case PFS_IOCTL2_ATTR_LOOKUP:
	case PFS_IOCTL2_ATTR_READ:
		rv=ioctl2Attr(fileSlot->clink, cmd, arg, buf, &fileSlot->aentryOffset);
		break;

	default:
		rv=-EINVAL;
		break;
	}

	if(pfsMount->flags & FIO_ATTR_WRITEABLE)
		cacheFlushAllDirty(pfsMount);
	rv=checkForLastError(pfsMount, rv);
	SignalSema(pfsFioSema);

	return rv;
}
예제 #7
0
파일: apa.c 프로젝트: EvertonSilva/ps2sdk
apa_cache *apaDeleteFixNext(apa_cache *clink, int *err)
{
	apa_header		*header=clink->header;
	u32				length=header->length;
	u32				saved_length=header->length;
	u32				lnext=header->next;
	apa_cache		*clink1;
	apa_cache		*clink2;
	u32				device=clink->device;
	u32				tmp;

	while(lnext!=0)
	{
		if(!(clink1=cacheGetHeader(device, lnext, 0, err))) {
			cacheAdd(clink);
			return 0;
		}
		header=clink1->header;
		tmp=header->length+length;
		if(header->type!=0) {
			cacheAdd(clink1);
			break;
		}
		if((clink->header->start%tmp)!=0 || ((tmp-1) & tmp)) {
			cacheAdd(clink1);
			break;
		}
		length=tmp;
		cacheAdd(clink1);
		lnext=header->next;
	}
	if(length!=saved_length) {
		if(!(clink2=cacheGetHeader(device, lnext, 0, err))) {
			cacheAdd(clink);
			return NULL;
		}
		clink->header->length=length;
		clink->header->next=lnext;
		apaMakeEmpty(clink);
		clink2->header->prev=clink->header->start;
		clink2->flags|=CACHE_FLAG_DIRTY;
		cacheFlushAllDirty(device);
		cacheAdd(clink2);
	}
	return clink;
}
예제 #8
0
void devctlCloseAll()
{
	u32 i;

	for(i=0;i < pfsConfig.maxOpen;i++)
	{
		if(fileSlots[i].fd)
			closeFileSlot(&fileSlots[i]);
	}
	for(i=0;i < pfsConfig.maxOpen;i++)
	{
		pfs_mount_t *pfsMount;
		if((pfsMount=getMountedUnit(i))!=NULL)
			cacheFlushAllDirty(pfsMount);

	}
}
예제 #9
0
int devctlSetOsdMBR(u32 device, hddSetOsdMBR_t *mbrInfo)
{
	int rv;
	apa_cache *clink;

	if(!(clink=cacheGetHeader(device, APA_SECTOR_MBR, 0, &rv)))
		return rv;

	dprintf1("ps2hdd: mbr start: %ld\n"
			 "ps2hdd: mbr size : %ld\n", mbrInfo->start, mbrInfo->size);
	clink->header->mbr.osdStart=mbrInfo->start;
	clink->header->mbr.osdSize=mbrInfo->size;
	clink->flags|=CACHE_FLAG_DIRTY;
	cacheFlushAllDirty(device);
	cacheAdd(clink);
	return rv;
}
예제 #10
0
파일: apa.c 프로젝트: EvertonSilva/ps2sdk
apa_cache *apaDeleteFixPrev(apa_cache *clink, int *err)
{
	apa_cache		*clink2=clink;
	apa_header		*header=clink2->header;
	u32				device=clink->device;
	u32				length=clink->header->length;
	u32				saved_next=clink->header->next;
	u32				saved_length=clink->header->length;
	u32				tmp;


	while(header->start) {
		if(!(clink2=cacheGetHeader(device, header->prev, 0, err))) {
			cacheAdd(clink);
			return NULL;
		}
		header=clink2->header;
		tmp=header->length+length;
		if(header->type!=0) {
			cacheAdd(clink2);
			break;
		}
		if((header->start%tmp) || (tmp & (tmp-1))) {
			cacheAdd(clink2);
			break;
		}
		length=tmp;
		cacheAdd(clink);
		clink=clink2;
	}
	if(length!=saved_length) {
		if(!(clink2=cacheGetHeader(device, saved_next, 0, err))) {
			cacheAdd(clink);
			return NULL;
		}
		clink->header->length=length;
		clink->header->next=clink->header->start+length;
		clink2->header->prev=clink->header->start;
		clink2->flags|=CACHE_FLAG_DIRTY;
		clink->flags|=CACHE_FLAG_DIRTY;
		cacheFlushAllDirty(device);
		cacheAdd(clink2);
	}
	return clink;
}
예제 #11
0
파일: apa.c 프로젝트: EvertonSilva/ps2sdk
int apaRemove(u32 device, char *id)
{
	int			i;
	u32			nsub;
	apa_cache	*clink;
	apa_cache	*clink2;
	int			rv;

	for(i=0;i<maxOpen;i++)	// look to see if open
	{
		if(fileSlots[i].f!=0) {
			if(memcmp(fileSlots[i].id, id, APA_IDMAX)==0)
				return -EBUSY;
		}
	}
	if(id[0]=='_' && id[1]=='_')
		return -EACCES;
	if((clink=apaFindPartition(device, id, &rv))==NULL)
		return rv;
	if(passcmp(clink->header->fpwd, NULL))
	{
		cacheAdd(clink);
		return -EACCES;
	}
	// remove all subs frist...
	nsub=clink->header->nsub;
	clink->header->nsub=0;
	clink->flags|=CACHE_FLAG_DIRTY;
	cacheFlushAllDirty(device);
	for(i=nsub-1;i!=-1;i--)
	{
		if((clink2=cacheGetHeader(device, clink->header->subs[i].start, 0, &rv))){
			if((rv=apaDelete(clink2))){
				cacheAdd(clink);
				return rv;
			}
		}
	}
	if(rv==0)
		return apaDelete(clink);

	cacheAdd(clink);
	return rv;
}
예제 #12
0
파일: apa.c 프로젝트: EvertonSilva/ps2sdk
apa_cache *apaGetNextHeader(apa_cache *clink, int *err)
{
	u32 start=clink->header->start;

	cacheAdd(clink);
	if(!clink->header->next)
		return NULL;

	if(!(clink=cacheGetHeader(clink->device, clink->header->next, 0, err)))
		return NULL;

	if(start!=clink->header->prev) {
		dprintf1("ps2hdd: Warning: Invalid partition information. start != prev\n");
		clink->header->prev=start;
		clink->flags|=CACHE_FLAG_DIRTY;
		cacheFlushAllDirty(clink->device);
	}
	return clink;

}
예제 #13
0
파일: cache.c 프로젝트: AzagraMac/PS2_SDK
pfs_cache_t *cacheAlloc(pfs_mount_t *pfsMount, u16 sub, u32 scale,
					int flags, int *result) 
{
	pfs_cache_t *allocated;

	if (cacheBuf->prev==cacheBuf && cacheBuf->prev->next==cacheBuf->prev) {
		printf("ps2fs: Error: Free buffer list is empty\n");
		*result=-ENOMEM;
		return NULL;
	}
	allocated=cacheBuf->next;
	if (cacheBuf->next==NULL)
		printf("ps2fs: Panic: Null pointer allocated\n");
	if (allocated->pfsMount && (allocated->flags & CACHE_FLAG_DIRTY))
		cacheFlushAllDirty(allocated->pfsMount);
	allocated->flags 	= flags & CACHE_FLAG_MASKTYPE;
	allocated->pfsMount	= pfsMount;
	allocated->sub		= sub;
	allocated->sector	= scale;
	allocated->nused	= 1;
	return cacheUnLink(allocated);
}
예제 #14
0
int devctlSwapTemp(u32 device, char *argp)
{
	int			rv;
	input_param	params;
	char		szBuf[APA_IDMAX];
	apa_cache	*partTemp;
	apa_cache	*partNew;


	if((rv=fioGetInput(argp, &params)) < 0)
		return rv;

	if(*(u16 *)(params.id)==(u16)0x5F5F)// test for '__' system partition
		return -EINVAL;

	memset(szBuf, 0, APA_IDMAX);
	strcpy(szBuf, "_tmp");
	if(!(partTemp=apaFindPartition(device, szBuf, &rv)))
		return rv;

	if((partNew=apaFindPartition(device, params.id, &rv))) {
		if((rv=passcmp(partNew->header->fpwd, NULL))==0) {
			memcpy(partTemp->header->id, partNew->header->id, APA_IDMAX);
			memcpy(partTemp->header->rpwd, partNew->header->rpwd, APA_PASSMAX);
			memcpy(partTemp->header->fpwd, partNew->header->fpwd, APA_PASSMAX);
			//memset(partNew->header->id, 0, 8);// BUG! can make it so can not open!!
			memset(partNew->header->id, 0, APA_IDMAX);
			strcpy(partNew->header->id, "_tmp");
			memset(partNew->header->rpwd, 0, APA_PASSMAX);
			memset(partNew->header->fpwd, 0, APA_PASSMAX);
			partTemp->flags|=CACHE_FLAG_DIRTY;
			partNew->flags|=CACHE_FLAG_DIRTY;
			cacheFlushAllDirty(device);
		}
		cacheAdd(partNew);
	}
	cacheAdd(partTemp);
	return rv;
}
예제 #15
0
파일: apa.c 프로젝트: EvertonSilva/ps2sdk
apa_cache *apaAddPartitionHere(u32 device, input_param *params, u32 *emptyBlocks,
				u32 sector, int *err)
{
	apa_cache	*clink_this;
	apa_cache	*clink_next;
	apa_cache	*clink_new;
	apa_header	*header;
	u32			i;
	u32			tmp, some_size, part_end;
	u32			tempSize;

	// walk empty blocks in case can use one :)
	for(i=0;i< 32;i++)
	{
		if((1 << i) >= params->size && emptyBlocks[i]!=0)
			return apaInsertPartition(device, params, emptyBlocks[i], err);
	}
	clink_this=cacheGetHeader(device, sector, 0, err);
	header=clink_this->header;
	part_end=header->start+header->length;
	some_size=(part_end%params->size);
	tmp = some_size ? params->size - some_size : 0;

	if(hddDeviceBuf[device].totalLBA < (part_end+params->size+tmp))
	{
		*err=-ENOSPC;
		cacheAdd(clink_this);
		return NULL;
	}

	if((clink_next=cacheGetHeader(device, 0, 0, err))==NULL){
		cacheAdd(clink_this);
		return NULL;
	}

	tempSize=params->size;
	while(part_end%params->size){
		tempSize=params->size>>1;
		while(0x3FFFF<tempSize){
			if(!(part_end%tempSize)) {
				clink_new=apaRemovePartition(device, part_end, 0,
					clink_this->header->start, tempSize);
				clink_this->header->next=part_end;
				clink_this->flags|=CACHE_FLAG_DIRTY;
				clink_next->header->prev=clink_new->header->start;
				part_end+=tempSize;
				clink_next->flags|=CACHE_FLAG_DIRTY;
				cacheFlushAllDirty(device);
				cacheAdd(clink_this);
				clink_this=clink_new;
				break;
			}
			tempSize>>=1;
		}
	}
	if((clink_new=apaFillHeader(device, params, part_end, 0, clink_this->header->start,
		params->size, err))!=NULL) {
			clink_this->header->next=part_end;
			clink_this->flags|=CACHE_FLAG_DIRTY;
			clink_next->header->prev=clink_new->header->start;
			clink_next->flags|=CACHE_FLAG_DIRTY;
			cacheFlushAllDirty(device);
		}
		cacheAdd(clink_this);
		cacheAdd(clink_next);
		return clink_new;
}