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; }
pfs_cache_t *blockGetLastSegmentDescriptorInode(pfs_cache_t *clink, int *result) { return cacheGetData(clink->pfsMount, clink->u.inode->last_segment.subpart, clink->u.inode->last_segment.number<<clink->pfsMount->inode_scale, (clink->u.inode->last_segment.subpart== clink->u.inode->inode_block.subpart)&& (clink->u.inode->last_segment.number== clink->u.inode->inode_block.number) ? 16 : 32, result); }
pfs_cache_t *getDentriesChunk(pfs_blockpos_t *position, int *result) { pfs_blockinfo *bi; pfs_mount_t *pfsMount=position->inode->pfsMount; bi = &position->inode->u.inode->data[fixIndex(position->block_segment)]; return cacheGetData(pfsMount, bi->subpart, ((bi->number + position->block_offset) << pfsMount->inode_scale) + position->byte_offset / metaSize, CACHE_FLAG_NOTHING, result); }
// 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; }
// 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; }