Exemple #1
0
unsigned LFS::countDeadBlocksForSegmentAtIndex(unsigned index) {
    Segment* segment = segments[index];
    unsigned deadCount = 0;
    for (unsigned i = 0; i < 1024 - 8; i++) {
        unsigned currentBlockAddress = (index << 10) + i;

        unsigned blockIndexInINode = segment->getBlockStatusForBlockAtIndex(i);
        unsigned iNodeIndexInInIMap = segment->getINodeStatusForBlockAtIndex(i);
        if (blockIndexInINode == std::numeric_limits<unsigned>::max()
                && iNodeIndexInInIMap == std::numeric_limits<unsigned>::max()) {
            // block is empty
            deadCount++;
            continue;
        } else if (iNodeIndexInInIMap == 10 * 1024) {
            // block is imap
            unsigned iMapAddress = iMapAddresses[blockIndexInINode];

            if (currentBlockAddress != iMapAddress) {
                deadCount++;
            }
        } else if (blockIndexInINode == 128) {
            // block is inode
            unsigned iMapIndex = iNodeIndexInInIMap % iMapAddresses.size();
            unsigned iMapAddress = iMapAddresses[iMapIndex]; 
            unsigned iMapSegmentIdx = getSegmentIndexFromAddress(iMapAddress);
            unsigned iMapBlockIdx = getBlockIndexFromAddress(iMapAddress);

            IMap iMap(segments[iMapSegmentIdx]->blocks[iMapBlockIdx]);
            unsigned iNodeAddress = iMap.iNodeAddresses[iNodeIndexInInIMap];

            if (currentBlockAddress != iNodeAddress) {
                deadCount++;
            }
        } else {
            // block is data
            unsigned iMapIndex = iNodeIndexInInIMap % iMapAddresses.size();
            unsigned iMapAddress = iMapAddresses[iMapIndex];
            unsigned iMapSegmentIdx = getSegmentIndexFromAddress(iMapAddress);
            unsigned iMapBlockIdx = getBlockIndexFromAddress(iMapAddress);

            IMap iMap(segments[iMapSegmentIdx]->blocks[iMapBlockIdx]);
            unsigned iNodeAddress = iMap.iNodeAddresses[iNodeIndexInInIMap];
            unsigned iNodeSegmentIdx = getSegmentIndexFromAddress(iNodeAddress);
            unsigned iNodeBlockIdx = getBlockIndexFromAddress(iNodeAddress);

            INode iNode(segments[iNodeSegmentIdx]->blocks[iNodeBlockIdx]);
            unsigned blockAddress = iNode.blockAddresses[blockIndexInINode];

            if (currentBlockAddress != blockAddress) {
                deadCount++;
            }
        }

    }
    return deadCount;
}
Exemple #2
0
LFS::LFS()
    : checkpointFile("DRIVE/CHECKPOINT_REGION",
            std::ios::binary | std::ios::in | std::ios::out),
    isClean(32, true),
    iMapAddresses(40, 0),
    currentIMapIdx{0},
    currentSegmentIdx{0},
    currentBlockIdx{0},
    numCleanSegments{32} {
        // read or create segments
        for (int i = 0; i < 32; i++) {
            segments.push_back(new Segment("DRIVE/SEGMENT" + std::to_string(i + 1)));
        }
        // read or create checkpoint region
        if (!checkpointFile) {
            checkpointFile.close();
            checkpointFile.open("DRIVE/CHECKPOINT_REGION",
                    std::ios::binary | std::ios::in | std::ios::out | std::ios::trunc); 
        } else {
            for (unsigned i = 0; i < isClean.size() && checkpointFile; i++) {
                bool clean = isClean[i];
                checkpointFile.read((char*)&clean, sizeof(clean));
                isClean[i] = clean;
                if (!isClean[i]) {
                    numCleanSegments--;
                }
            }
            for (unsigned i = 0; i < iMapAddresses.size() && checkpointFile; i++) {
                unsigned address = 0;
                checkpointFile.read((char*)&address, sizeof(address));
                iMapAddresses[i] = address;
                if (iMapAddresses[i] != 0) {
                    currentIMapIdx = i;
                }
            }
            checkpointFile.clear();
            checkpointFile.seekg(0, std::ios::beg);
            // read filenames
            for (unsigned i = 0; i <= currentIMapIdx; i++) {
                unsigned iMapAddress = iMapAddresses[currentIMapIdx];
                unsigned iMapSegmentIdx = getSegmentIndexFromAddress(iMapAddress);
                unsigned iMapBlockIdx = getBlockIndexFromAddress(iMapAddress);
                IMap iMap(segments[iMapSegmentIdx]->blocks[iMapBlockIdx]);
                for (unsigned i = 0; i < iMap.iNodeAddresses.size(); i++) {
                    unsigned iNodeAddress = iMap.iNodeAddresses[i];
                    if (iNodeAddress != 0) {
                        unsigned iNodeSegmentIdx = getSegmentIndexFromAddress(iNodeAddress);
                        unsigned iNodeBlockIdx = getBlockIndexFromAddress(iNodeAddress);
                        INode iNode(segments[iNodeSegmentIdx]->blocks[iNodeBlockIdx]);
                        files[iNode.fileName] = iNodeAddress;
                    }
                }
            }
            // find a clean segment
        }
    }
Exemple #3
0
void LFS::import(std::string& lfsFileName, std::istream& data) {
    unsigned iMapAddress = iMapAddresses[currentIMapIdx];
    unsigned iMapSegmentIdx = getSegmentIndexFromAddress(iMapAddress);
    unsigned iMapBlockIdx = getBlockIndexFromAddress(iMapAddress);
    IMap iMap(segments[iMapSegmentIdx]->blocks[iMapBlockIdx]);
    if (iMapAddress == 0) {
        iMap = IMap();
    }
    if (!iMap.hasFree()) {
        iMap = IMap();
        currentIMapIdx++; // may go out of bounds.
    }
    INode iNode(lfsFileName);

    while (data) {
        Block dataBlock;
        data >> dataBlock;
        unsigned blockOffset = 
            segments[currentSegmentIdx]->addBlock(
                    dataBlock, iNode.fileSize, iMap.getNextINodeIndex());
        if (blockOffset == 0) {
            selectNewCleanSegment();
            blockOffset = segments[currentSegmentIdx]->addBlock(
                    dataBlock, iNode.fileSize, iMap.getNextINodeIndex());
        }
        unsigned blockAddress = (currentSegmentIdx << 10) + blockOffset;
        iNode.addBlockAddress(blockAddress);
        if (iNode.fileSize == 128) {
            data.setstate(std::ios::badbit);
            break;
        }
    }

    unsigned iNodeOffset =segments[currentSegmentIdx]->addBlock(
            iNode, iMap.getNextINodeIndex());
    if (iNodeOffset == 0) {
        selectNewCleanSegment();
        iNodeOffset = segments[currentSegmentIdx]->addBlock(
                iNode, iMap.getNextINodeIndex());
    }
    unsigned iNodeAddress = (currentSegmentIdx << 10) + iNodeOffset;
    iMap.addINodeWithAddress(iNodeAddress);

    unsigned iMapOffset = segments[currentSegmentIdx]->addBlock(iMap, currentIMapIdx);
    if (iMapOffset == 0) {
        selectNewCleanSegment();
        iMapOffset = segments[currentSegmentIdx]->addBlock(iMap, currentIMapIdx);
    }
    iMapAddress = (currentSegmentIdx << 10) + iMapOffset;
    iMapAddresses[currentIMapIdx] = iMapAddress;

    files[lfsFileName] = iNodeAddress;
}
Exemple #4
0
std::string LFS::list() {
    std::stringstream fNames;
    for (auto file: files) {
        unsigned iNodeAddress = file.second;
        unsigned int segmentIdx = getSegmentIndexFromAddress(iNodeAddress);
        unsigned int blockIdx = getBlockIndexFromAddress(iNodeAddress);
        INode iNode(segments[segmentIdx]->blocks[blockIdx]);
        fNames << file.first << " ";
        fNames << iNode.fileSize;
        fNames << std::endl;
    }
    return fNames.str();
}
Exemple #5
0
std::string LFS::cat(std::string lfsFileName) {
    std::stringstream data;
    unsigned iNodeAddress = findFile(lfsFileName);
    unsigned segmentIdx = getSegmentIndexFromAddress(iNodeAddress);
    unsigned blockIdx = getBlockIndexFromAddress(iNodeAddress);
    INode iNode(segments[segmentIdx]->blocks[blockIdx]);
    unsigned i = 0;
    while(iNode.data[i++] != '\0') ;
    unsigned numBlocks = iNode.data[i++];
    for(unsigned j = 0; j < numBlocks; j++) {
        unsigned dataBlockAdd = 0; 
        for(int k = 6; k >= 0; k -= 2) {
            dataBlockAdd += (iNode.data[i++] << k);
        }
        unsigned dataSegIdx = getSegmentIndexFromAddress(dataBlockAdd);
        unsigned dataBlockIdx = getBlockIndexFromAddress(dataBlockAdd);
        data << segments[dataSegIdx]->blocks[dataBlockIdx];
    }
    return data.str();
}
Exemple #6
0
std::string LFS::display(std::string lfsFileName, int howMany, int start) {
    std::stringstream result;
    if (files.find(lfsFileName) != files.end()) {
        unsigned iNodeAddress = findFile(lfsFileName);
        unsigned iNodeSegmentIdx = getSegmentIndexFromAddress(iNodeAddress);
        unsigned iNodeBlockIdx = getBlockIndexFromAddress(iNodeAddress);
        INode iNode(segments[iNodeSegmentIdx]->blocks[iNodeBlockIdx]);
        for (auto blockAddress: iNode.blockAddresses) {
            if (blockAddress == 0 || howMany < 1) {
                break;
            }

            unsigned blockSegmentIdx = getSegmentIndexFromAddress(blockAddress);
            unsigned blockIdx = getBlockIndexFromAddress(blockAddress);
            unsigned numToPrint = 1024;
            if(howMany < 1024) numToPrint = howMany;
            howMany -= numToPrint;
            result << segments[blockSegmentIdx]->blocks[blockIdx].getFormattedBytesOfLength(numToPrint);
        }
    } else {
        result << "File " << lfsFileName << " does not exitst.";
    }
    return result.str();
}
Exemple #7
0
MayaMeshWriter::MayaMeshWriter(MDagPath & iDag,
    Alembic::Abc::OObject & iParent, Alembic::Util::uint32_t iTimeIndex,
    const JobArgs & iArgs, GetMembersMap& gmMap)
  : mNoNormals(iArgs.noNormals),
    mWriteUVs(iArgs.writeUVs),
    mWriteColorSets(iArgs.writeColorSets),
    mWriteUVSets(iArgs.writeUVSets),
    mIsGeometryAnimated(false),
    mDagPath(iDag)
{
    MStatus status = MS::kSuccess;
    MFnMesh lMesh( mDagPath, &status );
    if ( !status )
    {
        MGlobal::displayError( "MFnMesh() failed for MayaMeshWriter" );
    }

    // intermediate objects aren't translated
    MObject surface = iDag.node();

    if (iTimeIndex != 0 && util::isAnimated(surface))
    {
        mIsGeometryAnimated = true;
    }
    else
    {
        iTimeIndex = 0;
    }

    std::vector<float> uvs;
    std::vector<Alembic::Util::uint32_t> indices;
    std::string uvSetName;

    MString name = lMesh.name();
    name = util::stripNamespaces(name, iArgs.stripNamespace);

    // check to see if this poly has been tagged as a SubD
    MPlug plug = lMesh.findPlug("SubDivisionMesh");
    if ( !plug.isNull() && plug.asBool() )
    {
        Alembic::AbcGeom::OSubD obj(iParent, name.asChar(), iTimeIndex);
        mSubDSchema = obj.getSchema();

        Alembic::AbcGeom::OV2fGeomParam::Sample uvSamp;
        if (mWriteUVs || mWriteUVSets)
        {
            getUVs(uvs, indices, uvSetName);

            if (!uvs.empty())
            {
                if (!uvSetName.empty())
                {
                    mSubDSchema.setUVSourceName(uvSetName);
                }

                uvSamp.setScope( Alembic::AbcGeom::kFacevaryingScope );
                uvSamp.setVals(Alembic::AbcGeom::V2fArraySample(
                    (const Imath::V2f *) &uvs.front(), uvs.size() / 2));
                if (!indices.empty())
                {
                    uvSamp.setIndices(Alembic::Abc::UInt32ArraySample(
                        &indices.front(), indices.size()));
                }
            }
        }

        Alembic::Abc::OCompoundProperty cp;
        Alembic::Abc::OCompoundProperty up;
        if (AttributesWriter::hasAnyAttr(lMesh, iArgs))
        {
            cp = mSubDSchema.getArbGeomParams();
            up = mSubDSchema.getUserProperties();
        }
        mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, lMesh,
            iTimeIndex, iArgs));

        writeSubD(uvSamp);
    }
    else
    {
        Alembic::AbcGeom::OPolyMesh obj(iParent, name.asChar(), iTimeIndex);
        mPolySchema = obj.getSchema();

        Alembic::AbcGeom::OV2fGeomParam::Sample uvSamp;

        if (mWriteUVs || mWriteUVSets)
        {
            getUVs(uvs, indices, uvSetName);

            if (!uvs.empty())
            {
                if (!uvSetName.empty())
                {
                    mPolySchema.setUVSourceName(uvSetName);
                }
                uvSamp.setScope( Alembic::AbcGeom::kFacevaryingScope );
                uvSamp.setVals(Alembic::AbcGeom::V2fArraySample(
                    (const Imath::V2f *) &uvs.front(), uvs.size() / 2));
                if (!indices.empty())
                {
                    uvSamp.setIndices(Alembic::Abc::UInt32ArraySample(
                        &indices.front(), indices.size()));
                }
            }
        }

        Alembic::Abc::OCompoundProperty cp;
        Alembic::Abc::OCompoundProperty up;
        if (AttributesWriter::hasAnyAttr(lMesh, iArgs))
        {
            cp = mPolySchema.getArbGeomParams();
            up = mPolySchema.getUserProperties();
        }

        // set the rest of the props and write to the writer node
        mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, lMesh,
            iTimeIndex, iArgs));

        writePoly(uvSamp);
    }

    if (mWriteColorSets)
    {
        MStringArray colorSetNames;
        lMesh.getColorSetNames(colorSetNames);

        if (colorSetNames.length() > 0)
        {

            // Create the color sets compound prop
            Alembic::Abc::OCompoundProperty arbParams;
            if (mPolySchema.valid())
            {
                arbParams =  mPolySchema.getArbGeomParams();
            }
            else
            {
                arbParams =  mSubDSchema.getArbGeomParams();
            }

            std::string currentColorSet = lMesh.currentColorSetName().asChar();
            for (unsigned int i=0; i < colorSetNames.length(); ++i)
            {
                // Create an array property for each color set
                std::string colorSetPropName = colorSetNames[i].asChar();

                Alembic::AbcCoreAbstract::MetaData md;
                if (currentColorSet == colorSetPropName)
                {
                    md.set("mayaColorSet", "1");
                }
                else
                {
                    md.set("mayaColorSet", "0");
                }

                if (lMesh.getColorRepresentation(colorSetNames[i]) ==
                    MFnMesh::kRGB)
                {
                    Alembic::AbcGeom::OC3fGeomParam colorProp(arbParams,
                        colorSetPropName, true,
                        Alembic::AbcGeom::kFacevaryingScope, 1, iTimeIndex, md);
                    mRGBParams.push_back(colorProp);
                }
                else
                {
                    Alembic::AbcGeom::OC4fGeomParam colorProp(arbParams,
                        colorSetPropName, true,
                        Alembic::AbcGeom::kFacevaryingScope, 1, iTimeIndex, md);
                    mRGBAParams.push_back(colorProp);
                }
            }
            writeColor();
        }
    }

    if (mWriteUVSets)
    {
        MStringArray uvSetNames;
        lMesh.getUVSetNames(uvSetNames);
        unsigned int uvSetNamesLen = uvSetNames.length();

        if (uvSetNamesLen > 1)
        {
            // Create the uv sets compound prop
            Alembic::Abc::OCompoundProperty arbParams;
            if (mPolySchema.valid())
            {
                arbParams =  mPolySchema.getArbGeomParams();
            }
            else
            {
                arbParams =  mSubDSchema.getArbGeomParams();
            }

            MString currentUV = lMesh.currentUVSetName();

            for (unsigned int i = 0; i < uvSetNamesLen; ++i)
            {
                // Create an array property for each uv set
                MString uvSetPropName = uvSetNames[i];

                // the current UV set gets mapped to the primary UVs
                if (currentUV == uvSetPropName)
                {
                    continue;
                }

                if (uvSetPropName.length() > 0 &&
                    lMesh.numUVs(uvSetPropName) > 0)
                {
                    mUVparams.push_back(Alembic::AbcGeom::OV2fGeomParam(
                        arbParams, uvSetPropName.asChar(), true,
                        Alembic::AbcGeom::kFacevaryingScope, 1, iTimeIndex));
                }
            }
            writeUVSets();
        }
    }

    // write out facesets
    if(!iArgs.writeFaceSets)
        return;

    // get the connected shading engines
    MObjectArray connSGObjs (getOutConnectedSG(mDagPath));
    const unsigned int sgCount = connSGObjs.length();

    for (unsigned int i = 0; i < sgCount; ++i)
    {
        MObject connSGObj, compObj;

        connSGObj = connSGObjs[i];

        MFnDependencyNode fnDepNode(connSGObj);
        MString connSgObjName = fnDepNode.name();

        // retrive the component MObject
        status = getSetComponents(mDagPath, connSGObj, gmMap, compObj);

        if (status != MS::kSuccess)
        {
            // for some reason the shading group doesn't represent a face set
            continue;
        }

        // retrieve the face indices
        MIntArray indices;
        MFnSingleIndexedComponent compFn;
        compFn.setObject(compObj);
        compFn.getElements(indices);
        const unsigned int numData = indices.length();

        // encountered the whole object mapping. skip it.
        if (numData == 0)
            continue;

        std::vector<Alembic::Util::int32_t> faceIndices(numData);
        for (unsigned int j = 0; j < numData; ++j)
        {
            faceIndices[j] = indices[j];
        }

        connSgObjName = util::stripNamespaces(connSgObjName,
                                              iArgs.stripNamespace);

        Alembic::AbcGeom::OFaceSet faceSet;
        std::string faceSetName(connSgObjName.asChar());

        MPlug abcFacesetNamePlug = fnDepNode.findPlug("AbcFacesetName", true);
        if (!abcFacesetNamePlug.isNull())
        {
            faceSetName = abcFacesetNamePlug.asString().asChar();
        }

        if (mPolySchema.valid())
        {
            if (mPolySchema.hasFaceSet(faceSetName))
            {
                faceSet = mPolySchema.getFaceSet(faceSetName);
            }
            else
            {
                faceSet = mPolySchema.createFaceSet(faceSetName);
            }
        }
        else
        {
            if (mSubDSchema.hasFaceSet(faceSetName))
            {
                faceSet = mSubDSchema.getFaceSet(faceSetName);
            }
            else
            {
                faceSet = mSubDSchema.createFaceSet(faceSetName);
            }
        }
        Alembic::AbcGeom::OFaceSetSchema::Sample samp;
        samp.setFaces(Alembic::Abc::Int32ArraySample(faceIndices));

        Alembic::AbcGeom::OFaceSetSchema faceSetSchema = faceSet.getSchema();

        faceSetSchema.set(samp);
        faceSetSchema.setFaceExclusivity(Alembic::AbcGeom::kFaceSetExclusive);

        MFnDependencyNode iNode(connSGObj);

        Alembic::Abc::OCompoundProperty cp;
        Alembic::Abc::OCompoundProperty up;
        if (AttributesWriter::hasAnyAttr(iNode, iArgs))
        {
            cp = faceSetSchema.getArbGeomParams();
            up = faceSetSchema.getUserProperties();
        }

        AttributesWriter attrWriter(cp, up, faceSet, iNode, iTimeIndex, iArgs);
        attrWriter.write();
    }
}
Exemple #8
0
void LFS::overwrite(std::string lfsFileName, int howMany, int start, char c) {
    unsigned iNodeAddress = findFile(lfsFileName);
    unsigned iNodeSegmentIdx = getSegmentIndexFromAddress(iNodeAddress);
    unsigned iNodeBlockIdx = getBlockIndexFromAddress(iNodeAddress);
    INode iNode(segments[iNodeSegmentIdx]->blocks[iNodeBlockIdx]);

    unsigned iMapIndex = getImapIndexFromINodeAddress(iNodeAddress);
    unsigned iMapAddress = iMapAddresses[iMapIndex];
    unsigned iMapSegmentIndex = getSegmentIndexFromAddress(iMapAddress);
    unsigned iMapBlockIndex = getBlockIndexFromAddress(iMapAddress);
    IMap iMap(segments[iMapSegmentIndex]->blocks[iMapBlockIndex]);

    unsigned iNodeIndex = 0;
    for(unsigned i = 0; i < iMap.iNodeAddresses.size(); i++) {
        if(iMap.iNodeAddresses[i] == iNodeAddress)
            iNodeIndex = i;
    }

    unsigned i = 0;
    while(iNode.data[i++] != '\0') ; //Scanning past filename
    unsigned numBlocks = iNode.data[i++];

    int numBlocksRem = numBlocks;
    int howManyRem = howMany;
    int remStart = start;
    int workingBlockIndex = 0;

    //Don't need to create new data block or update INode
    while(remStart > 1023 && numBlocksRem > 0) {
        remStart -= 1024;
        numBlocksRem--;
        workingBlockIndex++;
    }

    //Create new data blocks until start point is within next block
    while(remStart > 1023) {
        Block dataBlock;
        unsigned blockOffset = segments[currentSegmentIdx]->addBlock(
                dataBlock, iNode.fileSize, iMap.getNextINodeIndex());
        if (blockOffset == 0) {
            selectNewCleanSegment();
            blockOffset = segments[currentSegmentIdx]->addBlock(
                    dataBlock, iNode.fileSize, iMap.getNextINodeIndex());
        }
        unsigned blockAddress = (currentSegmentIdx << 10) + blockOffset;
        if((unsigned)workingBlockIndex <= numBlocks) 
            iNode.addBlockAddress(blockAddress);
        else
            iNode.updateBlockAddressAtIndex(blockAddress, workingBlockIndex); 
        remStart -= 1024;
        workingBlockIndex++;
    }

    while(howManyRem > 0) {
        unsigned workingBitIndex = 0;
        Block newDataBlock;

        unsigned oldDataBlockAdd = 0;
        for(int j = 6; j >= 0; j -= 2) {
            oldDataBlockAdd += (iNode.data[i++] << j);
        }
        unsigned oldDataSegIdx = 
            getSegmentIndexFromAddress(oldDataBlockAdd);
        unsigned oldDataBlockIdx =
            getBlockIndexFromAddress(oldDataBlockAdd);

        while(remStart > 0) {
            if((unsigned)workingBlockIndex <= numBlocks)
                newDataBlock.data[workingBitIndex] = 
                    segments[oldDataSegIdx]->blocks[oldDataBlockIdx].
                    data[workingBitIndex];
            else 
                newDataBlock.data[workingBitIndex] = '\0';
            workingBitIndex++;
            remStart--;
        }
        while(workingBitIndex <= 1024 && howManyRem >= 0) {
            newDataBlock.data[workingBitIndex++] = c;
            howManyRem--;
        }
        while(workingBitIndex <= 1024) {
            if((unsigned)workingBlockIndex <= numBlocks)
                newDataBlock.data[workingBitIndex] = 
                    segments[oldDataSegIdx]->blocks[oldDataBlockIdx].
                    data[workingBitIndex];
            else 
                newDataBlock.data[workingBitIndex] = '\0';
            workingBitIndex++;
            remStart--;    
        }
        unsigned blockOffset = segments[currentSegmentIdx]->addBlock(
                newDataBlock, iNode.fileSize, iMap.getNextINodeIndex());
        if (blockOffset == 0) {
            selectNewCleanSegment();
            blockOffset = segments[currentSegmentIdx]->addBlock(
                    newDataBlock, iNode.fileSize, iMap.getNextINodeIndex());
        }
        unsigned blockAddress = (currentSegmentIdx << 10) + blockOffset;
        if((unsigned)workingBlockIndex < numBlocks) {
            iNode.updateBlockAddressAtIndex(blockAddress, workingBlockIndex);
        } else iNode.addBlockAddress(blockAddress);        
        numBlocksRem--;
        workingBlockIndex++;
    }

    unsigned iNodeOffset = segments[currentSegmentIdx]->addBlock(
            iNode, iMap.getNextINodeIndex());
    if (iNodeOffset == 0) {
        selectNewCleanSegment();
        iNodeOffset = segments[currentSegmentIdx]->addBlock(
                iNode, iMap.getNextINodeIndex());
    }
    iNodeAddress = (currentSegmentIdx << 10) + iNodeOffset;
    iMap.updateINodeAddressAtIndex(iNodeAddress, iNodeIndex);

    unsigned iMapOffset = segments[currentSegmentIdx]->addBlock(iMap, currentIMapIdx);
    if (iMapOffset == 0) {
        selectNewCleanSegment();
        iMapOffset = segments[currentSegmentIdx]->addBlock(iMap, currentIMapIdx);
    }
    iMapAddress = (currentSegmentIdx << 10) + iMapOffset;
    iMapAddresses[currentIMapIdx] = iMapAddress;

    files[lfsFileName] = iNodeAddress;
}