// Allocate block for metadata // flags is BLOCKGROUP's flags status_t ExtentAllocator::AllocateTreeBlock(uint64& found, uint64 start, uint64 flags) { // TODO: implement more features here with flags, e.g DUP, RAID, etc BlockGroup blockGroup(fVolume->ExtentTree()); status_t status = blockGroup.Initialize(flags); if (status != B_OK) return status; if (start == (uint64)-1) start = blockGroup.Start(); // normalize inputs uint64 remainder = start % fVolume->BlockSize(); if (remainder != 0) start += fVolume->BlockSize() - remainder; status = _Allocate(found, start, fVolume->BlockSize(), BTRFS_EXTENT_FLAG_TREE_BLOCK); if (status != B_OK) return status; // check here because tree block locate in 2 blockgroups (system and // metadata), and there might be a case one can get over the limit. if (found >= blockGroup.End()) return B_BAD_DATA; return B_OK; }
status_t ExtentAllocator::_LoadExtentTree(uint64 flags) { TRACE("ExtentAllocator::_LoadExtentTree() flags: %" B_PRIu64 "\n", flags); BlockGroup blockGroup(fVolume->ExtentTree()); status_t status = blockGroup.Initialize(flags); if (status != B_OK) return status; for (int i = 0; i < BTRFS_NUM_ROOT_BACKUPS; i++) { uint64 extentRootAddr = fVolume->SuperBlock().backup_roots[i].ExtentRoot(); if (extentRootAddr == 0) continue; // new device has 0 root address status = blockGroup.SetExtentTree(extentRootAddr); if (status != B_OK) return status; status = blockGroup.LoadExtent(fTree, false); if (status != B_OK) return status; } if (fTree->IsEmpty()) // 4 backup roots is 0 return B_OK; uint64 lowerBound = blockGroup.Start(); uint64 upperBound = blockGroup.End(); status = fTree->FillFreeExtents(lowerBound, upperBound); if (status != B_OK) { ERROR("ExtentAllocator::_LoadExtentTree() could not fill free extents" "start %" B_PRIu64 " end %" B_PRIu64 "\n", lowerBound, upperBound); return status; } if (fStart > lowerBound) fStart = lowerBound; if (fEnd < upperBound) fEnd = upperBound; return B_OK; }
void rootGroup::load(string dir) { int nDir=0; nDir = DIR.listDir(dir); //you can now iterate through the files as you like for(int i = 0; i < nDir; i++){ vector<string> spl= ofSplitString(DIR.getPath(i), "/"); vector<string> spl2= ofSplitString(spl.back(), "."); if(spl2.size()==1){ //if(atoi(spl2[0].substr(0,3).c_str())) bool found=0; for (unsigned int j=0; j<cfg().levelFolders.size(); j++) { if(cfg().levelFolders[j]==spl2[0]) found=true; } if(found){ if(cfg().verbose) cout << "Programming level " << set.size()+1 << " is " << spl2[0] << endl; set.push_back(blockGroup(DIR.getPath(i))); } } } }
// Allocate block for file data status_t ExtentAllocator::AllocateDataBlock(uint64& found, uint64 size, uint64 start, uint64 flags) { // TODO: implement more features here with flags, e.g DUP, RAID, etc if (start == (uint64)-1) { BlockGroup blockGroup(fVolume->ExtentTree()); status_t status = blockGroup.Initialize(flags); if (status != B_OK) return status; start = blockGroup.Start(); } // normalize inputs uint64 remainder = start % fVolume->SectorSize(); if (remainder != 0) start += fVolume->SectorSize() - remainder; size = size / fVolume->SectorSize() * fVolume->SectorSize(); return _Allocate(found, start, size, BTRFS_EXTENT_FLAG_DATA); }