diff --git a/src/bin/bfs_tools/lib/Disk.cpp b/src/bin/bfs_tools/lib/Disk.cpp index 1e2af9db30..5571a29dfb 100644 --- a/src/bin/bfs_tools/lib/Disk.cpp +++ b/src/bin/bfs_tools/lib/Disk.cpp @@ -95,6 +95,7 @@ Cache::Cacheable *BlockRunCache::NewCacheable(block_run run) Disk::Disk(const char *deviceName, bool rawMode, off_t start, off_t stop) : + fBufferedFile(NULL), fRawDiskOffset(0), fSize(0LL), fCache(this), @@ -121,6 +122,7 @@ Disk::Disk(const char *deviceName, bool rawMode, off_t start, off_t stop) //fprintf(stderr,"Could not open file: %s\n",strerror(fFile.InitCheck())); return; } + fBufferedFile = new BBufferIO(&fFile, 1024 * 1024, false); int device = open(deviceName, O_RDONLY); if (device < B_OK) { @@ -153,7 +155,7 @@ Disk::Disk(const char *deviceName, bool rawMode, off_t start, off_t stop) return; } - if (fFile.ReadAt(512 + fRawDiskOffset, &fSuperBlock, + if (fBufferedFile->ReadAt(512 + fRawDiskOffset, &fSuperBlock, sizeof(disk_super_block)) < 1) fprintf(stderr,"Disk: Could not read super block\n"); @@ -163,6 +165,7 @@ Disk::Disk(const char *deviceName, bool rawMode, off_t start, off_t stop) Disk::~Disk() { + delete fBufferedFile; } @@ -171,7 +174,7 @@ status_t Disk::InitCheck() status_t status = fFile.InitCheck(); if (status == B_OK) return fSize == 0LL ? B_ERROR : B_OK; - + return status; } @@ -201,7 +204,7 @@ uint8 *Disk::ReadBlockRun(block_run run) CacheableBlockRun *entry = (CacheableBlockRun *)fCache.Get(run); if (entry) return entry->Data(); - + return NULL; } @@ -234,7 +237,7 @@ Disk::DumpBootBlockToFile() // #pragma mark - Superblock recovery methods -status_t +status_t Disk::ScanForSuperBlock(off_t start, off_t stop) { printf("Disk size %Ld bytes, %.2f GB\n", fSize, 1.0 * fSize / (1024*1024*1024)); @@ -256,7 +259,7 @@ Disk::ScanForSuperBlock(off_t start, off_t stop) if (((offset-start) % (blockSize * 100)) == 0) printf(" %12Ld, %.2f GB %s1A\n",offset,1.0 * offset / (1024*1024*1024),escape); - ssize_t bytes = fFile.ReadAt(offset, buffer, blockSize + 1024); + ssize_t bytes = fBufferedFile->ReadAt(offset, buffer, blockSize + 1024); if (bytes < B_OK) { fprintf(stderr,"Could not read from device: %s\n", strerror(bytes)); @@ -322,7 +325,7 @@ Disk::ScanForSuperBlock(off_t start, off_t stop) // ToDo: free the other disk infos fRawDiskOffset = info->offset; - fFile.Seek(fRawDiskOffset, SEEK_SET); + fBufferedFile->Seek(fRawDiskOffset, SEEK_SET); if (ValidateSuperBlock(info->super_block)) fSize = info->super_block.block_size * info->super_block.block_size; @@ -382,7 +385,7 @@ Disk::RecreateSuperBlock() printf("\tblock size = %ld\n",BlockSize()); - strcpy(fSuperBlock.name,"recovered"); + strcpy(fSuperBlock.name,"recovered"); fSuperBlock.magic1 = SUPER_BLOCK_MAGIC1; fSuperBlock.fs_byte_order = SUPER_BLOCK_FS_LENDIAN; fSuperBlock.block_shift = get_shift(BlockSize()); @@ -422,7 +425,7 @@ Disk::RecreateSuperBlock() GetNextSpecialInode(buffer,&offset,offset + 32LL * 65536 * BlockSize(),true); if (fValidOffset == 0LL) - { + { fprintf(stderr,"FATAL ERROR: Could not find valid inode!\n"); return B_ERROR; } @@ -439,7 +442,7 @@ Disk::RecreateSuperBlock() fSuperBlock.num_ags = divide_roundup(fSuperBlock.num_blocks,allocationGroupSize); // calculate rest of log area - + fSuperBlock.log_blocks.allocation_group = fLogStart / allocationGroupSize; fSuperBlock.log_blocks.start = fLogStart - fSuperBlock.log_blocks.allocation_group * allocationGroupSize; fSuperBlock.log_blocks.length = LogSize(); // assumed length of 2048 blocks @@ -488,7 +491,7 @@ Disk::DetermineBlockSize() // read a quarter of the drive at maximum for (; offset < (fSize >> 2); offset += 1024) { - if (fFile.ReadAt(offset, buffer, sizeof(buffer)) < B_OK) { + if (fBufferedFile->ReadAt(offset, buffer, sizeof(buffer)) < B_OK) { fprintf(stderr, "could not read from device (offset = %Ld, " "size = %ld)!\n", offset, sizeof(buffer)); status = B_IO_ERROR; @@ -547,7 +550,7 @@ Disk::GetNextSpecialInode(char *buffer, off_t *_offset, off_t end, bfs_inode *inode = (bfs_inode *)buffer; for (; offset < end; offset += BlockSize()) { - if (fFile.ReadAt(offset, buffer, 1024) < B_OK) { + if (fBufferedFile->ReadAt(offset, buffer, 1024) < B_OK) { fprintf(stderr,"could not read from device (offset = %Ld, size = %d)!\n",offset,1024); *_offset = offset; return B_IO_ERROR; @@ -565,7 +568,7 @@ Disk::GetNextSpecialInode(char *buffer, off_t *_offset, off_t end, && offset >= (BlockSize() * (fLogStart + LogSize()))) { fValidBlockRun = inode->inode_num; fValidOffset = offset; - + if (skipAfterValidInode) return B_OK; } @@ -653,31 +656,31 @@ Disk::ScanForIndexAndRoot(bfs_inode *indexDir,bfs_inode *rootDir) if (!root) { printf("WARNING: Could not find root node at common places!\n"); printf("\tScanning log area for root node\n"); - + off_t logOffset = ToOffset(fSuperBlock.log_blocks); if (GetNextSpecialInode(buffer,&logOffset,logOffset + LogSize() * BlockSize()) == B_OK) { SaveInode(inode,&indices,indexDir,&root,rootDir); - + printf("root node at: 0x%Lx (DiskProbe)\n",logOffset / 512); - //fFile.ReadAt(logOffset + BlockSize(),buffer,1024); + //fBufferedFile->ReadAt(logOffset + BlockSize(),buffer,1024); //if (*(uint32 *)buffer == BPLUSTREE_MAGIC) //{ // puts("\t\tnext block in log contains a bplustree!"); //} } } - + /*if (!root) { char txt[64]; printf("Should I perform a deeper search (that will take some time) (Y/N) [N]? "); gets(txt); - + if (!strcasecmp("y",txt)) { // search not so common places for the root node (all places) - + if (indices) offset += BlockSize(); // the block after the indices inode else @@ -700,28 +703,28 @@ Disk::ScanForIndexAndRoot(bfs_inode *indexDir,bfs_inode *rootDir) ssize_t Disk::Read(void *buffer, size_t size) { - return fFile.Read(buffer, size); + return fBufferedFile->Read(buffer, size); } ssize_t Disk::Write(const void *buffer, size_t size) { - return fFile.Write(buffer, size); + return fBufferedFile->Write(buffer, size); } ssize_t Disk::ReadAt(off_t pos, void *buffer, size_t size) { - return fFile.ReadAt(pos + fRawDiskOffset, buffer, size); + return fBufferedFile->ReadAt(pos + fRawDiskOffset, buffer, size); } ssize_t Disk::WriteAt(off_t pos, const void *buffer, size_t size) { - return fFile.WriteAt(pos + fRawDiskOffset, buffer, size); + return fBufferedFile->WriteAt(pos + fRawDiskOffset, buffer, size); } @@ -731,14 +734,14 @@ Disk::Seek(off_t position, uint32 seekMode) // ToDo: only correct for seekMode == SEEK_SET, right?? if (seekMode != SEEK_SET) puts("OH NO, I AM BROKEN!"); - return fFile.Seek(position + fRawDiskOffset, seekMode); + return fBufferedFile->Seek(position + fRawDiskOffset, seekMode); } off_t Disk::Position() const { - return fFile.Position() - fRawDiskOffset; + return fBufferedFile->Position() - fRawDiskOffset; } diff --git a/src/bin/bfs_tools/lib/Disk.h b/src/bin/bfs_tools/lib/Disk.h index d1e89979c1..890a14e5e7 100644 --- a/src/bin/bfs_tools/lib/Disk.h +++ b/src/bin/bfs_tools/lib/Disk.h @@ -6,6 +6,7 @@ */ +#include #include #include @@ -23,9 +24,9 @@ class BlockRunCache : public Cache public: BlockRunCache(Disk *disk); // ~BlockRunCache(); - + virtual Cacheable *NewCacheable(block_run run); - + protected: Disk *fDisk; }; @@ -91,7 +92,9 @@ class Disk : public BPositionIO status_t LoadBootBlock(); + protected: BFile fFile; + BBufferIO* fBufferedFile; BPath fPath; off_t fRawDiskOffset; off_t fSize; @@ -101,7 +104,7 @@ class Disk : public BPositionIO block_run fValidBlockRun; off_t fValidOffset; off_t fLogStart; - + BlockRunCache fCache; bool fRawMode;