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; }
// Attempts to allocate 'blocks' new blocks for an inode int blockAllocNewSegment(pfs_cache_t *clink, pfs_blockpos_t *blockpos, u32 blocks) { pfs_blockinfo bi, *bi2; int result=0; pfs_mount_t *pfsMount=clink->pfsMount; u32 i, old_blocks = blocks; dprintf2("ps2fs CALL: allocNewBlockSegment(, , %ld)\n", blocks); if (cacheIsFull()) return -ENOMEM; // create "indirect segment descriptor" if necessary if (fixIndex(clink->u.inode->number_data) == 0) { pfs_cache_t *clink2; bi2 = &blockpos->inode->u.inode->data[fixIndex(blockpos->block_segment)]; bi.subpart=bi2->subpart; bi.count=1; bi.number=bi2->number+bi2->count; result=searchFreeZone(pfsMount, &bi, clink->u.inode->number_blocks); if (result<0) { dprintf("ps2fs: Error: Couldnt allocate zone! (1)\n"); return result; } clink2=cacheGetData(pfsMount, bi.subpart, bi.number << pfsMount->inode_scale, CACHE_FLAG_SEGI | CACHE_FLAG_NOLOAD, &result); memset(clink2->u.inode, 0, sizeof(pfs_inode)); clink2->u.inode->magic=PFS_SEGI_MAGIC; memcpy(&clink2->u.inode->inode_block, &clink->u.inode->inode_block, sizeof(pfs_blockinfo)); memcpy(&clink2->u.inode->last_segment, &blockpos->inode->u.inode->data[0], sizeof(pfs_blockinfo)); memcpy(&clink2->u.inode->data[0], &bi, sizeof(pfs_blockinfo)); clink2->flags |= CACHE_FLAG_DIRTY; clink->u.inode->number_blocks+=bi.count; clink->u.inode->number_data++; memcpy(&clink->u.inode->last_segment, &bi, sizeof(pfs_blockinfo)); clink->u.inode->number_segdesg++; clink->flags |= CACHE_FLAG_DIRTY; blockpos->block_segment++; blockpos->block_offset=0; memcpy(&blockpos->inode->u.inode->next_segment, &bi, sizeof(pfs_blockinfo)); blockpos->inode->flags |= CACHE_FLAG_DIRTY; cacheAdd(blockpos->inode); blockpos->inode=clink2; } bi2 = &blockpos->inode->u.inode->data[fixIndex(blockpos->block_segment)]; bi.subpart = bi2->subpart; bi.count = blocks; bi.number = bi2->number + bi2->count; result = searchFreeZone(pfsMount, &bi, clink->u.inode->number_blocks); if(result < 0) { dprintf("ps2fs: Error: Couldnt allocate zone! (2)\n"); return result; } clink->u.inode->number_blocks += bi.count; clink->u.inode->number_data++; clink->flags |= CACHE_FLAG_DIRTY; blockpos->block_offset=0; blockpos->block_segment++; i = fixIndex(clink->u.inode->number_data-1); memcpy(&blockpos->inode->u.inode->data[i], &bi, sizeof(pfs_blockinfo)); blockpos->inode->flags |= CACHE_FLAG_DIRTY; blocks -= bi.count; if (blocks) blocks -= blockExpandSegment(clink, blockpos, blocks); return old_blocks - blocks; }