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 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 apaOpen(u32 device, hdd_file_slot_t *fileSlot, input_param *params, int mode) { int rv=0; u32 emptyBlocks[32]; apa_cache *clink; apa_cache *clink2; u32 sector=0; // walk all looking for any empty blocks & look for partition clink=cacheGetHeader(device, 0, 0, &rv); memset(&emptyBlocks, 0, sizeof(emptyBlocks)); while(clink) { sector=clink->sector; if(!(clink->header->flags & APA_FLAG_SUB)) { if(memcmp(clink->header->id, params->id, APA_IDMAX) == 0) break; // found :) } addEmptyBlock(clink->header, emptyBlocks); clink=apaGetNextHeader(clink, &rv); } if(rv!=0) return rv; rv=-ENOENT; if(clink==NULL && (mode & O_CREAT)) { if((rv=apaCheckPartitionMax(device, params->size))>=0) { if((clink=apaAddPartitionHere(device, params, emptyBlocks, sector, &rv))!=NULL) { sector=clink->header->start; clink2=cacheGetFree(); memset(clink2->header, 0, sizeof(apa_header)); atadDmaTransfer(device, clink2->header, sector+8 , 2, ATAD_MODE_WRITE); atadDmaTransfer(device, clink2->header, sector+0x2000, 2, ATAD_MODE_WRITE); cacheAdd(clink2); } } } if(clink==NULL) return rv; fileSlot->start=clink->header->start; fileSlot->length=clink->header->length; memcpy(&fileSlot->subs, &clink->header->subs, APA_MAXSUB*sizeof(apa_subs)); fileSlot->type=clink->header->type; fileSlot->nsub=clink->header->nsub; memcpy(&fileSlot->id, &clink->header->id, APA_IDMAX); cacheAdd(clink); rv=0; if(passcmp(clink->header->fpwd, NULL)!=0) rv=-EACCES; 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; }
pfs_cache_t *cacheGetData(pfs_mount_t *pfsMount, u16 sub, u32 sector, int flags, int *result) { u32 i; pfs_cache_t *clink; *result=0; for (i=1; i < numBuffers + 1; i++) if ( cacheBuf[i].pfsMount && (cacheBuf[i].pfsMount==pfsMount) && (cacheBuf[i].sector == sector)) if (cacheBuf[i].sub==sub){ cacheBuf[i].flags &= CACHE_FLAG_MASKSTATUS; cacheBuf[i].flags |= flags & CACHE_FLAG_MASKTYPE; if (cacheBuf[i].nused == 0) cacheUnLink(&cacheBuf[i]); cacheBuf[i].nused++; return &cacheBuf[i]; } clink=cacheAlloc(pfsMount, sub, sector, flags, result); if (clink){ if (flags & CACHE_FLAG_NOLOAD) return clink; if ((*result=cacheTransfer(clink, IOCTL2_TMODE_READ))>=0) return clink; clink->pfsMount=NULL; cacheAdd(clink); } return NULL; }
// 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; }
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 journalResetore(u32 device) { // copys apa headers from apal to apa system int i; u32 sector; apa_cache *clink; dprintf1("ps2hdd: checking log...\n"); if(atadDmaTransfer(device, &journalBuf, APA_SECTOR_APAL, sizeof(apa_journal_t)/512, ATAD_MODE_READ)){ journalReset(device); return -EIO; } if(journalBuf.magic==APAL_MAGIC) { if(journalBuf.num==0) return 0; clink=cacheGetFree(); for(i=0, sector=APA_SECTOR_APAL_HEADERS;i<journalBuf.num;i++, sector+=2) { if(atadDmaTransfer(device, clink->header, sector, 2, ATAD_MODE_READ)) break; if(atadDmaTransfer(device, clink->header, journalBuf.sectors[i], 2, ATAD_MODE_WRITE)) break; } cacheAdd(clink); return journalReset(device);// only do if journal.. } memset(&journalBuf, 0, sizeof(apa_journal_t));// safe e journalBuf.magic=APAL_MAGIC; return 0;//-EINVAL; }
int getPartErrorName(u32 device, char *name) { int lba; int rv=0; apa_cache *clink; if((rv=getPartErrorSector(device, APA_SECTOR_PART_ERROR, &lba)) <= 0) return rv; if(!(clink=cacheGetHeader(device, 0, THEADER_MODE_READ, &rv))) return rv; while(clink) { if(clink->header->type!=APA_TYPE_FREE && !(clink->header->flags & CACHE_FLAG_DIRTY) && clink->header->start==lba) { if(name) { strncpy(name, clink->header->id, APA_IDMAX - 1); name[APA_IDMAX - 1] = '\0'; } cacheAdd(clink); return 1; } clink=apaGetNextHeader(clink, &rv); } // clear error if no errors and partitions was not found... if(rv==0) setPartErrorSector(device, 0); return rv; }
void setPartErrorSector(u32 device, u32 lba) {// used to set the lba of a partition that has a error... apa_cache *clink; clink=cacheGetFree(); apaSaveError(device, clink->header, APA_SECTOR_PART_ERROR, lba); cacheAdd(clink); }
int apaGetFormat(u32 device, int *format) { apa_cache *clink; int rv=0;// u32 rv=0; u32 *pDW; int i; clink=cacheGetFree(); *format=0; if((rv=apaReadHeader(device, clink->header, 0))==0) { *format=clink->header->mbr.version; if(atadDmaTransfer(device, clink->header, APA_SECTOR_SECTOR_ERROR, 2, ATAD_MODE_READ)) rv=-EIO; // return -EIO; if(rv==0){ pDW=(u32 *)clink->header; for(i=0;i < 256; i++) { if((i & 0x7F) && pDW[i]!=0) rv=1; } } } cacheAdd(clink); return rv==0; }
int ioctl2Alloc(pfs_cache_t *clink, int msize, int mode) { pfs_blockpos_t blockpos; int result=0; u32 val; int zsize; zsize=clink->pfsMount->zsize; val=((msize-1 + zsize) & (-zsize)) / zsize; if(mode==0) if (((clink->u.inode->number_blocks-clink->u.inode->number_segdesg) *(u64)zsize) >= (clink->u.inode->size + msize)) return 0; if((blockpos.inode = blockGetLastSegmentDescriptorInode(clink, &result))) { blockpos.block_offset=blockpos.byte_offset=0; blockpos.block_segment=clink->u.inode->number_data-1; val-=blockExpandSegment(clink, &blockpos, val); while (val && ((result=blockAllocNewSegment(clink, &blockpos, val))>=0)){ val-=result; result=0; } cacheAdd(blockpos.inode); } return result; }
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=cacheGetData(clink->pfsMount, clink->sub, clink->sector+1 ,CACHE_FLAG_NOTHING, &rv))==NULL) return rv; switch(cmd) { case PFS_IOCTL2_ATTR_ADD: rv=ioctl2AttrAdd(flink, arg); break; case PFS_IOCTL2_ATTR_DEL: rv=ioctl2AttrDelete(flink, arg); break; case PFS_IOCTL2_ATTR_LOOKUP: rv=ioctl2AttrLoopUp(flink, arg, outbuf); break; case PFS_IOCTL2_ATTR_READ: rv=ioctl2AttrRead(flink, outbuf, offset); break; } cacheAdd(flink); 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; }
cacheEntry *cacheFind(ccache *c, sds key) { cacheEntry *ce = dictFetchValue(c->data,key); if(ce == NULL) { ce = cacheAdd(c,sdsdup(key),NULL); cacheSendMessage(c,ce,CACHE_REQUEST_NEW); } return ce; }
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; }
int devctlFsckStat(pfs_mount_t *pfsMount, int mode) { int rv; pfs_cache_t *clink; if((clink=cacheAllocClean(&rv))!=NULL){ rv=fsckStat(pfsMount, clink->u.superblock, FSCK_STAT_ERROR_0x02, mode); cacheAdd(clink); } return rv; }
int checkDirForFiles(pfs_cache_t *clink) { pfs_dentry *dentry; pfs_cache_t *dcache; u32 size; if((dcache=getDentry(clink, NULL, &dentry, &size, 2))){ cacheAdd(dcache); return 0; } return 1; }
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; }
int hddDread(iop_file_t *f, iox_dirent_t *dirent) { int rv; hdd_file_slot_t *fileSlot=f->privdata; apa_cache *clink; if(!(f->mode & O_DIROPEN)) return -ENOTDIR; if(fileSlot->start==-1) return 0;// end :) WaitSema(fioSema); if((clink=cacheGetHeader(f->unit, fileSlot->start, 0, &rv)) && clink->header->length) { if(clink->header->flags & APA_FLAG_SUB) { // if sub get id from main header... apa_cache *cmain=cacheGetHeader(f->unit, clink->header->main, 0, &rv); if(cmain!=NULL){ rv=strlen(cmain->header->id); strcpy(dirent->name, cmain->header->id); cacheAdd(cmain); } } else { rv=strlen(clink->header->id); strcpy(dirent->name, clink->header->id); } fioGetStatFiller(clink, &dirent->stat); if(clink->header->next==0) fileSlot->start=-1; // mark end else fileSlot->start=clink->header->next;// set next cacheAdd(clink); } SignalSema(fioSema); return rv; }
// Returns the next block descriptor inode pfs_cache_t *blockGetNextSegment(pfs_cache_t *clink, int *result) { cacheAdd(clink); if (clink->u.inode->next_segment.number) return cacheGetData(clink->pfsMount, clink->u.inode->next_segment.subpart, clink->u.inode->next_segment.number << clink->pfsMount->inode_scale, CACHE_FLAG_SEGI, result); printf( "ps2fs: Error: There is no next segment descriptor\n"); *result=-EINVAL; return NULL; }
pfs_cache_t *getDentriesAtPos(pfs_cache_t *clink, u64 position, int *offset, int *result) { pfs_blockpos_t blockpos; pfs_cache_t *r; *result=blockInitPos(clink, &blockpos, position); if (*result) return 0; *offset=blockpos.byte_offset % metaSize; r=getDentriesChunk(&blockpos, result); cacheAdd(blockpos.inode); return r; }
int journalResetore(pfs_mount_t *pfsMount) { int rv; int result; pfs_cache_t *clink; u32 i; // Read journal buffer from disk rv = pfsMount->blockDev->transfer(pfsMount->fd, &journalBuf, 0, (pfsMount->log.number << pfsMount->sector_scale), 2, IOCTL2_TMODE_READ); if(rv || (journalBuf.magic != PFS_JOUNRNAL_MAGIC) || (journalBuf.checksum != (u16)journalCheckSum(&journalBuf))) { printf("ps2fs: Error: cannot read log/invalid log\n"); return journalReset(pfsMount); } if(journalBuf.num == 0) { dprintf("ps2fs: System cleanly un-mounted, no journal restore needed\n"); return journalReset(pfsMount); } clink = cacheAllocClean(&result); if(!clink) return result; for(i = 0; i < journalBuf.num; i++) { printf("ps2fs: Log overwrite %d:%08lx\n", journalBuf.log[i].sub, journalBuf.log[i].sector); // Read data in from log section on disk into cache buffer rv = pfsMount->blockDev->transfer(pfsMount->fd, clink->u.data, 0, (pfsMount->log.number << pfsMount->sector_scale) + journalBuf.log[i].logSector, 2, IOCTL2_TMODE_READ); // Write from cache buffer into destination location on disk if(!rv) pfsMount->blockDev->transfer(pfsMount->fd, clink->u.data, journalBuf.log[i].sub, journalBuf.log[i].sector, 2, IOCTL2_TMODE_WRITE); } cacheAdd(clink); return journalReset(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; }
int hddGetStat(iop_file_t *f, const char *name, iox_stat_t *stat) { apa_cache *clink; input_param params; int rv; if((rv=fioGetInput(name, ¶ms))<0) return rv; WaitSema(fioSema); if((clink=apaFindPartition(f->unit, params.id, &rv))){ if((rv=passcmp(clink->header->rpwd, NULL))==0) fioGetStatFiller(clink, stat); cacheAdd(clink); } SignalSema(fioSema); return rv; }
int getPartErrorSector(u32 device, u32 lba, int *lba_out) { apa_cache *clink; int rv=0; if(!(clink=cacheGetFree())) return -ENOMEM; if(atadDmaTransfer(device, clink->header, lba, 1, ATAD_MODE_READ)) return -EIO; if(lba_out) *lba_out=((u32 *)(clink->header))[0]; if(((u32 *)(clink->header))[0]) rv=1;// error is set ;) 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; }
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; }
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 getNextDentry(pfs_cache_t *clink, pfs_blockpos_t *blockpos, u32 *position, char *name, pfs_blockinfo *bi) { int result; pfs_cache_t *dcache; pfs_dentry *dentry; u32 len=0; // loop until a non-empty entry is found or until the end of the dentry chunk is reached while((len == 0) && (*position < clink->u.inode->size)) { if (!(dcache=getDentriesChunk(blockpos, &result))) { dprintf("ps2fs: couldnt get dentries chunk for dread!\n"); break; } dentry = (pfs_dentry*)((u32)dcache->u.data + (blockpos->byte_offset % metaSize)); len = dentry->pLen; memcpy(name, dentry->path, len); name[len] = '\0'; bi->subpart = dentry->sub; bi->number = dentry->inode; cacheAdd(dcache); *position += dentry->aLen & 0xFFF; // update blockpos if (inodeSync(blockpos, dentry->aLen & 0xFFF, clink->u.inode->number_data)) break; } return len; }