/*************************************************************************** fs_afs.cpp - AtheOS File System Support ------------------- begin : Mon May 22 2000 copyright : (C) 2000 by François Dupoux email : fdupoux@partimage.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "fs_afs.h" #include "partimage.h" #include "imagefile.h" // ======================================================= CAfsPart::CAfsPart(char *szDevice, FILE *fDeviceFile, QWORD qwPartSize): CFSBase(szDevice, fDeviceFile, qwPartSize) { BEGIN; RETURN; } // ======================================================= CAfsPart::~CAfsPart() { BEGIN; RETURN; } // ======================================================= void CAfsPart::fsck() { BEGIN; RETURN; } // ======================================================= void CAfsPart::readBitmap(COptions *options) { BEGIN; //DWORD i, j, k; int nRes; //char cBuffer[8192]; DWORD dwWordsPerBlock; DWORD dwBlocksPerGroup; QWORD qwCurBlock; // init dwWordsPerBlock = m_header.qwBlockSize/4; qwCurBlock = 0LL; dwBlocksPerGroup = m_info.dwBlockPerGroup / (m_header.qwBlockSize * 8); // init bitmap size nRes = m_bitmap.init(m_header.qwBitmapSize); if (nRes == -1) goto error_readBitmap; // init to false: because real code not implemented //for (i=0; i < m_header.qwBlocksCount; i++) // m_bitmap.setBit(i, true); // ****************************************************************************** /*for (i=0; i < m_header.qwBlocksCount; ++i) { int nGroup = nBlock / psVolume->av_psSuperBlock->as_nBlockPerGroup; int nStart = nBlock % psVolume->av_psSuperBlock->as_nBlockPerGroup; bool bFree; panBlock = afs_alloc_block_buffer( psVolume ); if ( panBlock == NULL ) { printk( "Error: afs_is_block_free() no memory for bitmap block\n" ); return( false ); } if ( afs_logged_read( psVolume, panBlock, psVolume->av_nBitmapStart + nGroup ) < 0 ) { printk( "Panic: afs_is_block_free() failed to load bitmap block\n" ); return( false ); } if ( panBlock[ nStart / 32 ] & (1 << (nStart % 32)) ) { bFree = false; } else { bFree = true; } }*/ // ****************************************************************************** /*for ( i = 0 ; i < m_info.dwAllocGroupCount * dwBlocksPerGroup ; ++i ) { nRes = readData(cBuffer, (m_info.qwBitmapStart+i)*m_header.qwBlockSize, m_header.qwBlockSize); memcpy(m_bitmap.data()+(i*m_header.qwBlockSize), cBuffer, m_header.qwBlockSize); for ( j = 0 ; j < dwWordsPerBlock ; ++j ) { for ( k = 0 ; k < 32 ; ++k ) { if ( (cBuffer[j] & (1L << k)) != 0 ) { //nCount++; m_bitmap.setBit(qwCurBlock++, true); } else m_bitmap.setBit(qwCurBlock++, false); } } }*/ // ****************************************************************************** nRes = readData(m_bitmap.data(), m_info.qwBitmapStart, m_header.qwBitmapSize); if (nRes == -1) goto error_readBitmap; calculateSpaceFromBitmap(); showDebug(1, "end success\n"); RETURN; // auccess error_readBitmap: showDebug(1, "end error\n"); g_interface->msgBoxError(i18n("There was an error while reading the bitmap")); THROW(ERR_READ_BITMAP); } /* // ======================================================= bool afs_is_block_free(QWORD nBlock) { uint32* panBlock; int nGroup = nBlock / psVolume->av_psSuperBlock->as_nBlockPerGroup; int nStart = nBlock % psVolume->av_psSuperBlock->as_nBlockPerGroup; bool bFree; panBlock = afs_alloc_block_buffer( psVolume ); if ( panBlock == NULL ) { printk( "Error: afs_is_block_free() no memory for bitmap block\n" ); return( false ); } if ( afs_logged_read( psVolume, panBlock, psVolume->av_nBitmapStart + nGroup ) < 0 ) { printk( "Panic: afs_is_block_free() failed to load bitmap block\n" ); return( false ); } if ( panBlock[ nStart / 32 ] & (1 << (nStart % 32)) ) { bFree = false; } else { bFree = true; } afs_free_block_buffer( psVolume, panBlock ); return( bFree ); }*/ // ======================================================= /*off_t afs_count_used_blocks( AfsVolume_s* psVolume ) // code from AFS kernel { AfsSuperBlock_s* psSuperBlock = psVolume->av_psSuperBlock; const int nBlockSize = psSuperBlock->as_nBlockSize; const int nBlocksPerGroup = psSuperBlock->as_nBlockPerGroup / (nBlockSize * 8); const int nWordsPerBlock = nBlockSize / 4; uint32* panBlock; off_t nCount = 0; int i; panBlock = afs_alloc_block_buffer( psVolume ); for ( i = 0 ; i < psSuperBlock->as_nAllocGroupCount * nBlocksPerGroup ; ++i ) { int j; int nError; nError = afs_logged_read( psVolume, panBlock, psVolume->av_nBitmapStart + i ); for ( j = 0 ; j < nWordsPerBlock ; ++j ) { int k; if ( panBlock[j] == 0 ) { continue; } if ( panBlock[j] == ~0 && i * nWordsPerBlock * 32 + j*32 + 32 < psSuperBlock->as_nNumBlocks ) { nCount += 32; continue; } for ( k = 0 ; k < 32 ; ++k ) { if ( i * nWordsPerBlock * 32 + j*32 + k >= psSuperBlock->as_nNumBlocks ) { if ( (panBlock[j] & (1L << k)) == 0 ) { printk( "Panic: afs_count_used_blocks() block past the partition-end are marked as free\n" ); } // break; } else { if ( (panBlock[j] & (1L << k)) != 0 ) { nCount++; } } } } } afs_free_block_buffer( psVolume, panBlock ); return( nCount ); }*/ // ======================================================= void CAfsPart::readSuperBlock() { BEGIN; QWORD qwFreeBlocks; CAfsSuper sb; int nRes; // init memset(&m_info, 0, sizeof(CInfoAfsHeader)); // 0. go to the beginning of the super block nRes = readData(&sb, AFS_SUPERBLOCK_OFFSET, sizeof(sb)); if (nRes == -1) goto error_readSuperBlock; if (CpuToLe32(sb.as_nMagic1) != SUPER_BLOCK_MAGIC1) goto error_readSuperBlock; if (CpuToLe32(sb.as_nMagic2) != SUPER_BLOCK_MAGIC2) goto error_readSuperBlock; // take infos from superblock m_info.dwByteOrder = sb.as_nByteOrder; m_info.dwBlockShift = sb.as_nBlockShift; m_info.dwBlockPerGroup = sb.as_nBlockPerGroup; m_info.dwAllocGrpShift = sb.as_nAllocGrpShift; m_info.dwAllocGroupCount = sb.as_nAllocGroupCount; m_info.dwFlags = sb.as_nFlags; m_info.dwBootLoaderSize = sb.as_nBootLoaderSize; // virtual blocks used in the abstract CFSBase m_header.qwBlocksCount = (DWORD)sb.as_nNumBlocks; showDebug(1, "qwBlocksCount=%llu\n", m_header.qwBlocksCount); m_header.qwBlockSize = (DWORD)sb.as_nBlockSize; showDebug(1, "qwBlockSize=%llu\n", m_header.qwBlockSize); m_header.qwBitmapSize = ((m_header.qwBlocksCount+7)/ 8)+1024; m_header.qwUsedBlocks = sb.as_nUsedBlocks; showDebug(1, "qwUsedBlocks%llu\n", m_header.qwUsedBlocks); // get bitmap position /*DWORD a, b, c; a = (m_info.dwBootLoaderSize*m_header.qwBlockSize + AFS_SUPERBLOCK_SIZE + 1024 + m_header.qwBlockSize - 1) / m_header.qwBlockSize; b = (m_info.dwBootLoaderSize*m_header.qwBlockSize + AFS_SUPERBLOCK_SIZE + 1024 + m_header.qwBlockSize) / m_header.qwBlockSize; c = (m_info.dwBootLoaderSize*m_header.qwBlockSize + AFS_SUPERBLOCK_SIZE + 1024 + m_header.qwBlockSize + 1) / m_header.qwBlockSize; showDebug(1, "a=%lu\n", a); showDebug(1, "b=%lu\n", b); showDebug(1, "c=%lu\n", c); */ m_info.qwBitmapStart = (m_info.dwBootLoaderSize*m_header.qwBlockSize + AFS_SUPERBLOCK_SIZE + 1024 + m_header.qwBlockSize - 1) / m_header.qwBlockSize; qwFreeBlocks = m_header.qwBlocksCount-m_header.qwUsedBlocks; setSuperBlockInfos(false, false, m_header.qwUsedBlocks*m_header.qwBlockSize, qwFreeBlocks * m_header.qwBlockSize); showDebug(1, "end success\n"); RETURN; error_readSuperBlock: g_interface -> ErrorReadingSuperblock(errno); THROW(ERR_WRONG_FS); } // ======================================================= void CAfsPart::printfInformations() { char szFullText[8192]; char szText[8192]; *(szText) = '\0'; getStdInfos(szText, sizeof(szText), false); SNPRINTF(szFullText, i18n("%s" // standard infos "Allocation groups count:......%u\n" "Byte order:...................%u\n" "Blocks per group:.............%u\n" "Boot loader size:.............%u blocks\n"), szText, m_info.dwAllocGroupCount, m_info.dwByteOrder, m_info.dwBlockPerGroup, m_info.dwBootLoaderSize); g_interface->msgBoxOk(i18n("AFS informations"), szFullText); }