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; }