apa_cache_t *apaInsertPartition(s32 device, const apa_params_t *params, u32 sector, int *err) { // Adds a new partition using an empty block. apa_cache_t *clink_empty; apa_cache_t *clink_this; apa_cache_t *clink_next; if ((clink_this = apaCacheGetHeader(device, sector, APA_IO_MODE_READ, err)) == 0) return 0; while (clink_this->header->length != params->size) { if ((clink_next = apaCacheGetHeader(device, clink_this->header->next, APA_IO_MODE_READ, err)) == NULL) { // Get next partition apaCacheFree(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 |= APA_CACHE_FLAG_DIRTY; clink_next->header->prev = clink_empty->header->start; clink_next->flags |= APA_CACHE_FLAG_DIRTY; apaCacheFlushAllDirty(device); apaCacheFree(clink_empty); apaCacheFree(clink_next); } apaCacheFree(clink_this); clink_this = apaFillHeader(device, params, clink_this->header->start, clink_this->header->next, clink_this->header->prev, params->size, err); apaCacheFlushAllDirty(device); return clink_this; }
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; }
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; }
apa_cache_t *hddAddPartitionHere(s32 device, const apa_params_t *params, u32 *emptyBlocks, u32 sector, int *err) { apa_cache_t *clink_this; apa_cache_t *clink_next; apa_cache_t *clink_new; apa_header_t *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 ((u32)(1 << i) >= params->size && emptyBlocks[i] != 0) return apaInsertPartition(device, params, emptyBlocks[i], err); } clink_this = apaCacheGetHeader(device, sector, APA_IO_MODE_READ, 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 (hddDevices[device].totalLBA < (part_end + params->size + tmp) //Non-SONY: when dealing with large disks, this check may overflow (therefore, check for overflows!). || (part_end < sector)) { *err = -ENOSPC; apaCacheFree(clink_this); return NULL; } if ((clink_next = apaCacheGetHeader(device, 0, APA_IO_MODE_READ, err)) == NULL) { apaCacheFree(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 |= APA_CACHE_FLAG_DIRTY; clink_next->header->prev = clink_new->header->start; part_end += tempSize; clink_next->flags |= APA_CACHE_FLAG_DIRTY; apaCacheFlushAllDirty(device); apaCacheFree(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 |= APA_CACHE_FLAG_DIRTY; clink_next->header->prev = clink_new->header->start; clink_next->flags |= APA_CACHE_FLAG_DIRTY; apaCacheFlushAllDirty(device); } apaCacheFree(clink_this); apaCacheFree(clink_next); return clink_new; }