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; }
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; }
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(¶ms, 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, ¶ms, 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; }
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; }
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; }
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; }
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; }
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); } }
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; }
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; }
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; }
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; }
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); }
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, ¶ms)) < 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; }
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; }