static 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 = pfsCacheGetData(clink->pfsMount, clink->sub, clink->block + 1, PFS_CACHE_FLAG_NOTHING, &rv)) == NULL) return rv; switch (cmd) { case PIOCATTRADD: rv = ioctl2AttrAdd(flink, arg); break; case PIOCATTRDEL: rv = ioctl2AttrDelete(flink, arg); break; case PIOCATTRLOOKUP: rv = ioctl2AttrLookUp(flink, arg, outbuf); break; case PIOCATTRREAD: rv = ioctl2AttrRead(flink, outbuf, offset); break; } pfsCacheFree(flink); return rv; }
pfs_cache_t *pfsBlockGetLastSegmentDescriptorInode(pfs_cache_t *clink, int *result) { return pfsCacheGetData(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 *pfsGetDentriesChunk(pfs_blockpos_t *position, int *result) { pfs_blockinfo_t *bi; pfs_mount_t *pfsMount=position->inode->pfsMount; bi = &position->inode->u.inode->data[pfsFixIndex(position->block_segment)]; return pfsCacheGetData(pfsMount, bi->subpart, ((bi->number + position->block_offset) << pfsMount->inode_scale) + position->byte_offset / pfsMetaSize, PFS_CACHE_FLAG_NOTHING, result); }
// Returns the next block descriptor inode pfs_cache_t *pfsBlockGetNextSegment(pfs_cache_t *clink, int *result) { pfsCacheFree(clink); if (clink->u.inode->next_segment.number) return pfsCacheGetData(clink->pfsMount, clink->u.inode->next_segment.subpart, clink->u.inode->next_segment.number << clink->pfsMount->inode_scale, PFS_CACHE_FLAG_SEGI, result); PFS_PRINTF(PFS_DRV_NAME": Error: There is no next segment descriptor\n"); *result=-EINVAL; return NULL; }
pfs_cache_t *pfsInodeGetData(pfs_mount_t *pfsMount, u16 sub, u32 inode, int *result) { return pfsCacheGetData(pfsMount, sub, inode << pfsMount->inode_scale, PFS_CACHE_FLAG_SEGD, result); }
// Attempts to allocate 'blocks' new blocks for an inode int pfsBlockAllocNewSegment(pfs_cache_t *clink, pfs_blockpos_t *blockpos, u32 blocks) { pfs_blockinfo_t bi, *bi2; int result=0; pfs_mount_t *pfsMount=clink->pfsMount; u32 i, old_blocks = blocks; if (pfsCacheIsFull()) return -ENOMEM; // create "indirect segment descriptor" if necessary if (pfsFixIndex(clink->u.inode->number_data) == 0) { pfs_cache_t *clink2; bi2 = &blockpos->inode->u.inode->data[pfsFixIndex(blockpos->block_segment)]; bi.subpart=bi2->subpart; bi.count=1; bi.number=bi2->number+bi2->count; result=pfsBitmapSearchFreeZone(pfsMount, &bi, clink->u.inode->number_blocks); if (result<0) { PFS_PRINTF(PFS_DRV_NAME": Error: Couldnt allocate zone! (1)\n"); return result; } clink2=pfsCacheGetData(pfsMount, bi.subpart, bi.number << pfsMount->inode_scale, PFS_CACHE_FLAG_SEGI | PFS_CACHE_FLAG_NOLOAD, &result); memset(clink2->u.inode, 0, sizeof(pfs_inode_t)); clink2->u.inode->magic=PFS_SEGI_MAGIC; memcpy(&clink2->u.inode->inode_block, &clink->u.inode->inode_block, sizeof(pfs_blockinfo_t)); memcpy(&clink2->u.inode->last_segment, blockpos->inode->u.inode->data, sizeof(pfs_blockinfo_t)); memcpy(clink2->u.inode->data, &bi, sizeof(pfs_blockinfo_t)); clink2->flags |= PFS_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_t)); clink->u.inode->number_segdesg++; clink->flags |= PFS_CACHE_FLAG_DIRTY; blockpos->block_segment++; blockpos->block_offset=0; memcpy(&blockpos->inode->u.inode->next_segment, &bi, sizeof(pfs_blockinfo_t)); blockpos->inode->flags |= PFS_CACHE_FLAG_DIRTY; pfsCacheFree(blockpos->inode); blockpos->inode=clink2; } bi2 = &blockpos->inode->u.inode->data[pfsFixIndex(blockpos->block_segment)]; bi.subpart = bi2->subpart; bi.count = blocks; bi.number = bi2->number + bi2->count; result = pfsBitmapSearchFreeZone(pfsMount, &bi, clink->u.inode->number_blocks); if(result < 0) { PFS_PRINTF(PFS_DRV_NAME": Error: Couldnt allocate zone! (2)\n"); return result; } clink->u.inode->number_blocks += bi.count; clink->u.inode->number_data++; clink->flags |= PFS_CACHE_FLAG_DIRTY; blockpos->block_offset=0; blockpos->block_segment++; i = pfsFixIndex(clink->u.inode->number_data-1); memcpy(&blockpos->inode->u.inode->data[i], &bi, sizeof(pfs_blockinfo_t)); blockpos->inode->flags |= PFS_CACHE_FLAG_DIRTY; blocks -= bi.count; if (blocks) blocks -= pfsBlockExpandSegment(clink, blockpos, blocks); return old_blocks - blocks; }