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; }
// Sets 'blockpos' to point to the next block segment for the inode (and moves onto the // next block descriptor inode if necessary) int pfsBlockSeekNextSegment(pfs_cache_t *clink, pfs_blockpos_t *blockpos) { pfs_cache_t *nextSegment; int result=0; if (blockpos->byte_offset) { PFS_PRINTF(PFS_DRV_NAME": Panic: This is a bug!\n"); return -1; } // If we're at the end of the block descriptor array for the current // inode, then move onto the next inode if (pfsFixIndex(blockpos->block_segment+1)==0) { if ((nextSegment=pfsBlockGetNextSegment(pfsCacheUsedAdd(blockpos->inode), &result)) == NULL) return result; pfsCacheFree(blockpos->inode); blockpos->inode=nextSegment; if (clink->u.inode->number_data-1 == ++blockpos->block_segment) return -EINVAL; } blockpos->block_offset=0; blockpos->block_segment++; return result; }
static int devctlFsckStat(pfs_mount_t *pfsMount, int mode) { int rv; pfs_cache_t *clink; if ((clink = pfsCacheAllocClean(&rv)) != NULL) { rv = pfsFsckStat(pfsMount, clink->u.superblock, PFS_FSCK_STAT_ERRORS_FIXED, mode); pfsCacheFree(clink); } return rv; }
pfs_cache_t *pfsGetDentriesAtPos(pfs_cache_t *clink, u64 position, int *offset, int *result) { pfs_blockpos_t blockpos; pfs_cache_t *r; *result=pfsBlockInitPos(clink, &blockpos, position); if (*result) return 0; *offset=blockpos.byte_offset % pfsMetaSize; r=pfsGetDentriesChunk(&blockpos, result); pfsCacheFree(blockpos.inode); return r; }
// 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; }
// 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; }