* added flex group, dirnlink and gdtchecksum features for ext4.
* I reused crc_table.cpp from the UDF filesystem and switched it to have the reversed algorithm, then generated the table in CRCTable.cpp * added a binary search for extent tree leaves. * fixed a check in InodeAllocator::New(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40129 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2001-2010, Haiku Inc. All rights reserved.
|
* Copyright 2001-2011, Haiku Inc. All rights reserved.
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -36,7 +36,6 @@ public:
|
|||||||
status_t Initialize(Volume* volume, uint32 blockGroup,
|
status_t Initialize(Volume* volume, uint32 blockGroup,
|
||||||
uint32 numBits);
|
uint32 numBits);
|
||||||
|
|
||||||
status_t ScanFreeRanges();
|
|
||||||
bool IsFull() const;
|
bool IsFull() const;
|
||||||
|
|
||||||
status_t Allocate(Transaction& transaction, fsblock_t start,
|
status_t Allocate(Transaction& transaction, fsblock_t start,
|
||||||
@@ -58,9 +57,12 @@ public:
|
|||||||
void RemovedFromTransaction();
|
void RemovedFromTransaction();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
status_t _ScanFreeRanges();
|
||||||
void _AddFreeRange(uint32 start, uint32 length);
|
void _AddFreeRange(uint32 start, uint32 length);
|
||||||
void _LockInTransaction(Transaction& transaction);
|
void _LockInTransaction(Transaction& transaction);
|
||||||
|
status_t _InitGroup(Transaction& transaction);
|
||||||
|
bool _IsSparse();
|
||||||
|
uint32 _FirstFreeBlock();
|
||||||
|
|
||||||
Volume* fVolume;
|
Volume* fVolume;
|
||||||
uint32 fBlockGroup;
|
uint32 fBlockGroup;
|
||||||
@@ -130,7 +132,17 @@ AllocationBlockGroup::Initialize(Volume* volume, uint32 blockGroup,
|
|||||||
|
|
||||||
fBitmapBlock = fGroupDescriptor->BlockBitmap(fVolume->Has64bitFeature());
|
fBitmapBlock = fGroupDescriptor->BlockBitmap(fVolume->Has64bitFeature());
|
||||||
|
|
||||||
status = ScanFreeRanges();
|
if (fGroupDescriptor->Flags() & EXT2_BLOCK_GROUP_BLOCK_UNINIT) {
|
||||||
|
fFreeBits = fGroupDescriptor->FreeBlocks(fVolume->Has64bitFeature());
|
||||||
|
fLargestLength = fFreeBits;
|
||||||
|
fLargestStart = _FirstFreeBlock();
|
||||||
|
TRACE("Group %ld is uninit\n", fBlockGroup);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = _ScanFreeRanges();
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
if (fGroupDescriptor->FreeBlocks(fVolume->Has64bitFeature())
|
if (fGroupDescriptor->FreeBlocks(fVolume->Has64bitFeature())
|
||||||
!= fFreeBits) {
|
!= fFreeBits) {
|
||||||
@@ -152,14 +164,16 @@ AllocationBlockGroup::Initialize(Volume* volume, uint32 blockGroup,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
AllocationBlockGroup::ScanFreeRanges()
|
AllocationBlockGroup::_ScanFreeRanges()
|
||||||
{
|
{
|
||||||
TRACE("AllocationBlockGroup::ScanFreeRanges()\n");
|
TRACE("AllocationBlockGroup::_ScanFreeRanges() for group %ld\n",
|
||||||
|
fBlockGroup);
|
||||||
BitmapBlock block(fVolume, fNumBits);
|
BitmapBlock block(fVolume, fNumBits);
|
||||||
|
|
||||||
if (!block.SetTo(fBitmapBlock))
|
if (!block.SetTo(fBitmapBlock))
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
|
fFreeBits = 0;
|
||||||
uint32 start = 0;
|
uint32 start = 0;
|
||||||
uint32 end = 0;
|
uint32 end = 0;
|
||||||
|
|
||||||
@@ -201,6 +215,7 @@ AllocationBlockGroup::Allocate(Transaction& transaction, fsblock_t _start,
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
_LockInTransaction(transaction);
|
_LockInTransaction(transaction);
|
||||||
|
_InitGroup(transaction);
|
||||||
|
|
||||||
BitmapBlock block(fVolume, fNumBits);
|
BitmapBlock block(fVolume, fNumBits);
|
||||||
|
|
||||||
@@ -252,6 +267,7 @@ AllocationBlockGroup::Allocate(Transaction& transaction, fsblock_t _start,
|
|||||||
|
|
||||||
if (fLargestLength < fNumBits / 2)
|
if (fLargestLength < fNumBits / 2)
|
||||||
block.FindLargestUnmarkedRange(fLargestStart, fLargestLength);
|
block.FindLargestUnmarkedRange(fLargestStart, fLargestLength);
|
||||||
|
ASSERT(block.CheckUnmarked(fLargestStart, fLargestLength));
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -272,6 +288,8 @@ AllocationBlockGroup::Free(Transaction& transaction, uint32 start,
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
_LockInTransaction(transaction);
|
_LockInTransaction(transaction);
|
||||||
|
if (fGroupDescriptor->Flags() & EXT2_BLOCK_GROUP_BLOCK_UNINIT)
|
||||||
|
panic("AllocationBlockGroup::Free() can't free blocks if uninit\n");
|
||||||
|
|
||||||
BitmapBlock block(fVolume, fNumBits);
|
BitmapBlock block(fVolume, fNumBits);
|
||||||
|
|
||||||
@@ -402,6 +420,89 @@ AllocationBlockGroup::_LockInTransaction(Transaction& transaction)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
AllocationBlockGroup::_InitGroup(Transaction& transaction)
|
||||||
|
{
|
||||||
|
TRACE("AllocationBlockGroup::_InitGroup()\n");
|
||||||
|
uint16 flags = fGroupDescriptor->Flags();
|
||||||
|
if ((flags & EXT2_BLOCK_GROUP_BLOCK_UNINIT) == 0)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
TRACE("AllocationBlockGroup::_InitGroup() initing\n");
|
||||||
|
|
||||||
|
BitmapBlock blockBitmap(fVolume, fNumBits);
|
||||||
|
if (!blockBitmap.SetToWritable(transaction, fBitmapBlock))
|
||||||
|
return B_ERROR;
|
||||||
|
blockBitmap.Mark(0, _FirstFreeBlock(), true);
|
||||||
|
blockBitmap.Unmark(0, fNumBits, true);
|
||||||
|
|
||||||
|
fGroupDescriptor->SetFlags(flags & ~EXT2_BLOCK_GROUP_BLOCK_UNINIT);
|
||||||
|
fVolume->WriteBlockGroup(transaction, fBlockGroup);
|
||||||
|
|
||||||
|
status_t status = _ScanFreeRanges();
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
if (fGroupDescriptor->FreeBlocks(fVolume->Has64bitFeature())
|
||||||
|
!= fFreeBits) {
|
||||||
|
ERROR("AllocationBlockGroup(%lu,%lld)::_InitGroup(): Mismatch between "
|
||||||
|
"counted free blocks (%lu/%lu) and what is set on the group "
|
||||||
|
"descriptor (%lu)\n", fBlockGroup, fBitmapBlock, fFreeBits,
|
||||||
|
fNumBits, fGroupDescriptor->FreeBlocks(
|
||||||
|
fVolume->Has64bitFeature()));
|
||||||
|
return B_BAD_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("AllocationBlockGroup::_InitGroup() init OK\n");
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
AllocationBlockGroup::_IsSparse()
|
||||||
|
{
|
||||||
|
if (fBlockGroup <= 1)
|
||||||
|
return true;
|
||||||
|
if (fBlockGroup & 0x1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32 i = fBlockGroup;
|
||||||
|
while (i % 7 == 0)
|
||||||
|
i /= 7;
|
||||||
|
if (i == 1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
i = fBlockGroup;
|
||||||
|
while (i % 5 == 0)
|
||||||
|
i /= 5;
|
||||||
|
if (i == 1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
i = fBlockGroup;
|
||||||
|
while (i % 3 == 0)
|
||||||
|
i /= 3;
|
||||||
|
if (i == 1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
AllocationBlockGroup::_FirstFreeBlock()
|
||||||
|
{
|
||||||
|
uint32 first = 1;
|
||||||
|
if (_IsSparse())
|
||||||
|
first = 0;
|
||||||
|
else if (!fVolume->HasMetaGroupFeature()) {
|
||||||
|
first += fVolume->SuperBlock().ReservedGDTBlocks();
|
||||||
|
first += fVolume->NumGroups();
|
||||||
|
}
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AllocationBlockGroup::TransactionDone(bool success)
|
AllocationBlockGroup::TransactionDone(bool success)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011, Haiku Inc. All rights reserved.
|
||||||
|
* This file may be used under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Jérôme Duval
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
|
//! CRC 0120001 table, as generated by crc_table.cpp
|
||||||
|
static uint16 kCrcTable[256] = {
|
||||||
|
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
|
||||||
|
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
|
||||||
|
0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
|
||||||
|
0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
|
||||||
|
0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
|
||||||
|
0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
|
||||||
|
0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
|
||||||
|
0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
|
||||||
|
0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
|
||||||
|
0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
|
||||||
|
0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
|
||||||
|
0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
|
||||||
|
0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
|
||||||
|
0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
|
||||||
|
0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
|
||||||
|
0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
|
||||||
|
0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
|
||||||
|
0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
|
||||||
|
0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
|
||||||
|
0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
|
||||||
|
0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
|
||||||
|
0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
|
||||||
|
0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
|
||||||
|
0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
|
||||||
|
0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
|
||||||
|
0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
|
||||||
|
0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
|
||||||
|
0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
|
||||||
|
0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
|
||||||
|
0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
|
||||||
|
0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
|
||||||
|
0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Calculates the UDF crc checksum for the given byte stream.
|
||||||
|
|
||||||
|
Based on crc code from UDF-2.50 6.5, as permitted.
|
||||||
|
This is reversed.
|
||||||
|
|
||||||
|
\param data Pointer to the byte stream.
|
||||||
|
\param length Length of the byte stream in bytes.
|
||||||
|
|
||||||
|
\return The crc checksum, or 0 if an error occurred.
|
||||||
|
*/
|
||||||
|
uint16
|
||||||
|
calculate_crc(uint16 crc, uint8 *data, uint16 length)
|
||||||
|
{
|
||||||
|
if (data) {
|
||||||
|
for ( ; length > 0; length--, data++)
|
||||||
|
crc = kCrcTable[(crc ^ *data) & 0xff] ^ (crc >> 8);
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011, Haiku Inc. All rights reserved.
|
||||||
|
* This file may be used under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Jérôme Duval
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint16 calculate_crc(uint16 crc, uint8 *data, uint16 length);
|
||||||
|
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2001-2010, Haiku Inc. All rights reserved.
|
* Copyright 2001-2011, Haiku Inc. All rights reserved.
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -77,6 +77,41 @@ ExtentStream::FindBlock(off_t offset, fsblock_t& block, uint32 *_count)
|
|||||||
panic("ExtentStream::FindBlock() invalid header\n");
|
panic("ExtentStream::FindBlock() invalid header\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stream->extent_header.NumEntries() > 7) {
|
||||||
|
// binary search when enough entries
|
||||||
|
int32 low = 0;
|
||||||
|
int32 high = stream->extent_header.NumEntries() - 1;
|
||||||
|
int32 middle = 0;
|
||||||
|
while (low <= high) {
|
||||||
|
middle = (high + low) / 2;
|
||||||
|
if (stream->extent_entries[middle].LogicalBlock() == index)
|
||||||
|
break;
|
||||||
|
if (stream->extent_entries[middle].LogicalBlock() < index)
|
||||||
|
low = middle + 1;
|
||||||
|
else
|
||||||
|
high = middle - 1;
|
||||||
|
}
|
||||||
|
if (stream->extent_entries[middle].LogicalBlock() > index)
|
||||||
|
middle--;
|
||||||
|
if (stream->extent_entries[middle].LogicalBlock()
|
||||||
|
+ stream->extent_entries[middle].Length() > index) {
|
||||||
|
// sparse block
|
||||||
|
TRACE("FindBlock() sparse block index %lld at %ld\n", index,
|
||||||
|
stream->extent_entries[middle].LogicalBlock());
|
||||||
|
block = 0xffffffff;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileblock_t diff = index
|
||||||
|
- stream->extent_entries[middle].LogicalBlock();
|
||||||
|
block = stream->extent_entries[middle].PhysicalBlock() + diff;
|
||||||
|
if (_count)
|
||||||
|
*_count = stream->extent_entries[middle].Length() - diff;
|
||||||
|
TRACE("FindBlock(offset %lld): %lld %ld\n", offset,
|
||||||
|
block, _count != NULL ? *_count : 1);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
for (int32 i = 0; i < stream->extent_header.NumEntries(); i++) {
|
for (int32 i = 0; i < stream->extent_header.NumEntries(); i++) {
|
||||||
if (stream->extent_entries[i].LogicalBlock() > index) {
|
if (stream->extent_entries[i].LogicalBlock() > index) {
|
||||||
// sparse block
|
// sparse block
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2001-2010, Haiku Inc. All rights reserved.
|
* Copyright 2001-2011, Haiku Inc. All rights reserved.
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
#ifndef EXTENTSTREAM_H
|
#ifndef EXTENTSTREAM_H
|
||||||
#define EXTENTSTREAM_H
|
#define EXTENTSTREAM_H
|
||||||
|
|
||||||
|
|
||||||
#include "ext2.h"
|
#include "ext2.h"
|
||||||
#include "Transaction.h"
|
#include "Transaction.h"
|
||||||
|
|
||||||
|
|||||||
@@ -54,8 +54,7 @@ HTree::HTree(Volume* volume, Inode* directory)
|
|||||||
fRootEntry(NULL)
|
fRootEntry(NULL)
|
||||||
{
|
{
|
||||||
fBlockSize = volume->BlockSize();
|
fBlockSize = volume->BlockSize();
|
||||||
fIndexed = volume->IndexedDirectories()
|
fIndexed = directory->IsIndexed();
|
||||||
&& (directory->Flags() & EXT2_INODE_INDEXED) != 0;
|
|
||||||
|
|
||||||
ext2_super_block superBlock = volume->SuperBlock();
|
ext2_super_block superBlock = volume->SuperBlock();
|
||||||
fHashSeed[0] = superBlock.HashSeed(0);
|
fHashSeed[0] = superBlock.HashSeed(0);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2011, Jérôme Duval, [email protected].
|
||||||
* Copyright 2008, Axel Dörfler, [email protected].
|
* Copyright 2008, Axel Dörfler, [email protected].
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
@@ -440,7 +441,7 @@ Inode::InitDirectory(Transaction& transaction, Inode* parent)
|
|||||||
root->dotdot_entry_name[0] = '.';
|
root->dotdot_entry_name[0] = '.';
|
||||||
root->dotdot_entry_name[1] = '.';
|
root->dotdot_entry_name[1] = '.';
|
||||||
|
|
||||||
parent->Node().SetNumLinks(parent->Node().NumLinks() + 1);
|
parent->IncrementNumLinks(transaction);
|
||||||
|
|
||||||
return parent->WriteBack(transaction);
|
return parent->WriteBack(transaction);
|
||||||
}
|
}
|
||||||
@@ -911,3 +912,15 @@ Inode::_SetNumBlocks(uint64 numBlocks)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Inode::IncrementNumLinks(Transaction& transaction)
|
||||||
|
{
|
||||||
|
fNode.SetNumLinks(fNode.NumLinks() + 1);
|
||||||
|
if (IsIndexed() && (fNode.NumLinks() >= EXT2_INODE_MAX_LINKS
|
||||||
|
|| fNode.NumLinks() == 2)) {
|
||||||
|
fNode.SetNumLinks(1);
|
||||||
|
fVolume->ActivateDirNLink(transaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2011, Jérôme Duval, [email protected].
|
||||||
* Copyright 2008, Axel Dörfler, [email protected].
|
* Copyright 2008, Axel Dörfler, [email protected].
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
@@ -50,6 +51,9 @@ public:
|
|||||||
bool IsDeleted() const { return fUnlinked; }
|
bool IsDeleted() const { return fUnlinked; }
|
||||||
bool HasExtraAttributes() const
|
bool HasExtraAttributes() const
|
||||||
{ return fHasExtraAttributes; }
|
{ return fHasExtraAttributes; }
|
||||||
|
bool IsIndexed() const
|
||||||
|
{ return fVolume->IndexedDirectories()
|
||||||
|
&& (Flags() & EXT2_INODE_INDEXED) != 0; }
|
||||||
|
|
||||||
mode_t Mode() const { return fNode.Mode(); }
|
mode_t Mode() const { return fNode.Mode(); }
|
||||||
int32 Flags() const { return fNode.Flags(); }
|
int32 Flags() const { return fNode.Flags(); }
|
||||||
@@ -75,6 +79,7 @@ public:
|
|||||||
fHasExtraAttributes); }
|
fHasExtraAttributes); }
|
||||||
void SetAccessTime(const struct timespec *timespec)
|
void SetAccessTime(const struct timespec *timespec)
|
||||||
{ fNode.SetAccessTime(timespec, fHasExtraAttributes); }
|
{ fNode.SetAccessTime(timespec, fHasExtraAttributes); }
|
||||||
|
void IncrementNumLinks(Transaction& transaction);
|
||||||
|
|
||||||
//::Volume* _Volume() const { return fVolume; }
|
//::Volume* _Volume() const { return fVolume; }
|
||||||
Volume* GetVolume() const { return fVolume; }
|
Volume* GetVolume() const { return fVolume; }
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2001-2010, Haiku Inc. All rights reserved.
|
* Copyright 2001-2011, Haiku Inc. All rights reserved.
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
|
* Jérôme Duval
|
||||||
* Janito V. Ferreira Filho
|
* Janito V. Ferreira Filho
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -44,7 +45,7 @@ InodeAllocator::New(Transaction& transaction, Inode* parent, int32 mode,
|
|||||||
ino_t& id)
|
ino_t& id)
|
||||||
{
|
{
|
||||||
// Apply allocation policy
|
// Apply allocation policy
|
||||||
uint32 preferredBlockGroup = parent == NULL ? parent->ID()
|
uint32 preferredBlockGroup = parent != NULL ? (parent->ID() - 1)
|
||||||
/ parent->GetVolume()->InodesPerGroup() : 0;
|
/ parent->GetVolume()->InodesPerGroup() : 0;
|
||||||
|
|
||||||
return _Allocate(transaction, preferredBlockGroup, S_ISDIR(mode), id);
|
return _Allocate(transaction, preferredBlockGroup, S_ISDIR(mode), id);
|
||||||
@@ -65,16 +66,20 @@ InodeAllocator::Free(Transaction& transaction, ino_t id, bool isDirectory)
|
|||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
if (group->Flags() & EXT2_BLOCK_GROUP_INODE_UNINIT)
|
||||||
|
panic("InodeAllocator::Free() can't free inodes if uninit\n");
|
||||||
|
|
||||||
if (blockGroup == fVolume->NumGroups() - 1)
|
if (blockGroup == fVolume->NumGroups() - 1)
|
||||||
numInodes = fVolume->NumInodes() - blockGroup * numInodes;
|
numInodes = fVolume->NumInodes() - blockGroup * numInodes;
|
||||||
|
|
||||||
TRACE("InodeAllocator::Free(): Updating block group data\n");
|
TRACE("InodeAllocator::Free(): Updating block group data\n");
|
||||||
group->SetFreeInodes(group->FreeInodes(fVolume->Has64bitFeature()) + 1,
|
group->SetFreeInodes(group->FreeInodes(fVolume->Has64bitFeature()) + 1,
|
||||||
fVolume->Has64bitFeature());
|
fVolume->Has64bitFeature());
|
||||||
if (isDirectory)
|
if (isDirectory) {
|
||||||
group->SetUsedDirectories(
|
group->SetUsedDirectories(
|
||||||
group->UsedDirectories(fVolume->Has64bitFeature()) - 1,
|
group->UsedDirectories(fVolume->Has64bitFeature()) - 1,
|
||||||
fVolume->Has64bitFeature());
|
fVolume->Has64bitFeature());
|
||||||
|
}
|
||||||
|
|
||||||
status = fVolume->WriteBlockGroup(transaction, blockGroup);
|
status = fVolume->WriteBlockGroup(transaction, blockGroup);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
@@ -104,6 +109,8 @@ InodeAllocator::_Allocate(Transaction& transaction, uint32 preferredBlockGroup,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fsblock_t block = group->InodeBitmap(fVolume->Has64bitFeature());
|
||||||
|
_InitGroup(transaction, group, block, fVolume->InodesPerGroup());
|
||||||
uint32 freeInodes = group->FreeInodes(fVolume->Has64bitFeature());
|
uint32 freeInodes = group->FreeInodes(fVolume->Has64bitFeature());
|
||||||
if (freeInodes != 0) {
|
if (freeInodes != 0) {
|
||||||
TRACE("InodeAllocator::_Allocate() freeInodes %ld bitmap %lld\n",
|
TRACE("InodeAllocator::_Allocate() freeInodes %ld bitmap %lld\n",
|
||||||
@@ -118,8 +125,7 @@ InodeAllocator::_Allocate(Transaction& transaction, uint32 preferredBlockGroup,
|
|||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
return _MarkInBitmap(transaction,
|
return _MarkInBitmap(transaction, block,
|
||||||
group->InodeBitmap(fVolume->Has64bitFeature()),
|
|
||||||
blockGroup, fVolume->InodesPerGroup(), id);
|
blockGroup, fVolume->InodesPerGroup(), id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,16 +139,27 @@ InodeAllocator::_Allocate(Transaction& transaction, uint32 preferredBlockGroup,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 numInodes = fVolume->NumInodes()
|
||||||
|
- blockGroup * fVolume->InodesPerGroup();
|
||||||
|
fsblock_t block = group->InodeBitmap(fVolume->Has64bitFeature());
|
||||||
|
_InitGroup(transaction, group, block, numInodes);
|
||||||
uint32 freeInodes = group->FreeInodes(fVolume->Has64bitFeature());
|
uint32 freeInodes = group->FreeInodes(fVolume->Has64bitFeature());
|
||||||
if (freeInodes != 0) {
|
if (freeInodes != 0) {
|
||||||
TRACE("InodeAllocator::_Allocate() freeInodes %ld\n", freeInodes);
|
TRACE("InodeAllocator::_Allocate() freeInodes %ld\n", freeInodes);
|
||||||
group->SetFreeInodes(freeInodes - 1,
|
group->SetFreeInodes(freeInodes - 1,
|
||||||
fVolume->Has64bitFeature());
|
fVolume->Has64bitFeature());
|
||||||
|
if (isDirectory) {
|
||||||
|
group->SetUsedDirectories(group->UsedDirectories(
|
||||||
|
fVolume->Has64bitFeature()) + 1,
|
||||||
|
fVolume->Has64bitFeature());
|
||||||
|
}
|
||||||
|
|
||||||
return _MarkInBitmap(transaction,
|
status = fVolume->WriteBlockGroup(transaction, blockGroup);
|
||||||
group->InodeBitmap(fVolume->Has64bitFeature()),
|
if (status != B_OK)
|
||||||
blockGroup, fVolume->NumInodes()
|
return status;
|
||||||
- blockGroup * fVolume->InodesPerGroup(), id);
|
|
||||||
|
return _MarkInBitmap(transaction, block,
|
||||||
|
blockGroup, numInodes, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,3 +226,23 @@ InodeAllocator::_UnmarkInBitmap(Transaction& transaction, fsblock_t bitmapBlock,
|
|||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
InodeAllocator::_InitGroup(Transaction& transaction, ext2_block_group* group,
|
||||||
|
fsblock_t bitmapBlock, uint32 numInodes)
|
||||||
|
{
|
||||||
|
uint16 flags = group->Flags();
|
||||||
|
if ((flags & EXT2_BLOCK_GROUP_INODE_UNINIT) == 0)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
TRACE("InodeAllocator::_InitGroup() initing group\n");
|
||||||
|
BitmapBlock inodeBitmap(fVolume, numInodes);
|
||||||
|
if (!inodeBitmap.SetToWritable(transaction, bitmapBlock))
|
||||||
|
return B_ERROR;
|
||||||
|
inodeBitmap.Unmark(0, numInodes, true);
|
||||||
|
group->SetFlags(flags & ~EXT2_BLOCK_GROUP_INODE_UNINIT);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ private:
|
|||||||
uint32 numInodes, ino_t& id);
|
uint32 numInodes, ino_t& id);
|
||||||
status_t _UnmarkInBitmap(Transaction& transaction,
|
status_t _UnmarkInBitmap(Transaction& transaction,
|
||||||
fsblock_t bitmapBlock, uint32 numInodes, ino_t id);
|
fsblock_t bitmapBlock, uint32 numInodes, ino_t id);
|
||||||
|
status_t _InitGroup(Transaction& transaction,
|
||||||
|
ext2_block_group* group, fsblock_t bitmapBlock,
|
||||||
|
uint32 numInodes);
|
||||||
|
|
||||||
|
|
||||||
Volume* fVolume;
|
Volume* fVolume;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ KernelAddon ext2 :
|
|||||||
BitmapBlock.cpp
|
BitmapBlock.cpp
|
||||||
BlockAllocator.cpp
|
BlockAllocator.cpp
|
||||||
InodeAllocator.cpp
|
InodeAllocator.cpp
|
||||||
|
CRCTable.cpp
|
||||||
|
|
||||||
kernel_interface.cpp
|
kernel_interface.cpp
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2011, Jérôme Duval, korli@users.berlios.de.
|
||||||
* Copyright 2008-2010, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2008-2010, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
@@ -21,6 +22,7 @@
|
|||||||
#include <util/AutoLock.h>
|
#include <util/AutoLock.h>
|
||||||
|
|
||||||
#include "CachedBlock.h"
|
#include "CachedBlock.h"
|
||||||
|
#include "CRCTable.h"
|
||||||
#include "Inode.h"
|
#include "Inode.h"
|
||||||
#include "InodeJournal.h"
|
#include "InodeJournal.h"
|
||||||
#include "NoJournal.h"
|
#include "NoJournal.h"
|
||||||
@@ -507,7 +509,8 @@ Volume::_UnsupportedIncompatibleFeatures(ext2_super_block& superBlock)
|
|||||||
uint32 supportedIncompatible = EXT2_INCOMPATIBLE_FEATURE_FILE_TYPE
|
uint32 supportedIncompatible = EXT2_INCOMPATIBLE_FEATURE_FILE_TYPE
|
||||||
| EXT2_INCOMPATIBLE_FEATURE_RECOVER
|
| EXT2_INCOMPATIBLE_FEATURE_RECOVER
|
||||||
| EXT2_INCOMPATIBLE_FEATURE_JOURNAL
|
| EXT2_INCOMPATIBLE_FEATURE_JOURNAL
|
||||||
| EXT2_INCOMPATIBLE_FEATURE_EXTENTS;
|
| EXT2_INCOMPATIBLE_FEATURE_EXTENTS
|
||||||
|
| EXT2_INCOMPATIBLE_FEATURE_FLEX_GROUP;
|
||||||
/*| EXT2_INCOMPATIBLE_FEATURE_META_GROUP*/;
|
/*| EXT2_INCOMPATIBLE_FEATURE_META_GROUP*/;
|
||||||
uint32 unsupported = superBlock.IncompatibleFeatures()
|
uint32 unsupported = superBlock.IncompatibleFeatures()
|
||||||
& ~supportedIncompatible;
|
& ~supportedIncompatible;
|
||||||
@@ -527,7 +530,9 @@ Volume::_UnsupportedReadOnlyFeatures(ext2_super_block& superBlock)
|
|||||||
uint32 supportedReadOnly = EXT2_READ_ONLY_FEATURE_SPARSE_SUPER
|
uint32 supportedReadOnly = EXT2_READ_ONLY_FEATURE_SPARSE_SUPER
|
||||||
| EXT2_READ_ONLY_FEATURE_LARGE_FILE
|
| EXT2_READ_ONLY_FEATURE_LARGE_FILE
|
||||||
| EXT2_READ_ONLY_FEATURE_HUGE_FILE
|
| EXT2_READ_ONLY_FEATURE_HUGE_FILE
|
||||||
| EXT2_READ_ONLY_FEATURE_EXTRA_ISIZE;
|
| EXT2_READ_ONLY_FEATURE_EXTRA_ISIZE
|
||||||
|
| EXT2_READ_ONLY_FEATURE_DIR_NLINK
|
||||||
|
| EXT2_READ_ONLY_FEATURE_GDT_CSUM;
|
||||||
// TODO actually implement EXT2_READ_ONLY_FEATURE_SPARSE_SUPER when
|
// TODO actually implement EXT2_READ_ONLY_FEATURE_SPARSE_SUPER when
|
||||||
// implementing superblock backup copies
|
// implementing superblock backup copies
|
||||||
|
|
||||||
@@ -553,6 +558,25 @@ Volume::_GroupDescriptorBlock(uint32 blockIndex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16
|
||||||
|
Volume::_GroupCheckSum(ext2_block_group *group, int32 index)
|
||||||
|
{
|
||||||
|
uint16 checksum = 0;
|
||||||
|
if (HasChecksumFeature()) {
|
||||||
|
int32 number = B_HOST_TO_LENDIAN_INT32(index);
|
||||||
|
checksum = calculate_crc(0xffff, fSuperBlock.uuid,
|
||||||
|
sizeof(fSuperBlock.uuid));
|
||||||
|
checksum = calculate_crc(checksum, (uint8*)&number, sizeof(number));
|
||||||
|
checksum = calculate_crc(checksum, (uint8*)group, 30);
|
||||||
|
if (Has64bitFeature()) {
|
||||||
|
checksum = calculate_crc(checksum, (uint8*)group + 34,
|
||||||
|
fGroupDescriptorSize - 34);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! Makes the requested block group available.
|
/*! Makes the requested block group available.
|
||||||
The block groups are loaded on demand, but are kept in memory until the
|
The block groups are loaded on demand, but are kept in memory until the
|
||||||
volume is unmounted; therefore we don't use the block cache.
|
volume is unmounted; therefore we don't use the block cache.
|
||||||
@@ -564,6 +588,7 @@ Volume::GetBlockGroup(int32 index, ext2_block_group** _group)
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
int32 blockIndex = index / fGroupsPerBlock;
|
int32 blockIndex = index / fGroupsPerBlock;
|
||||||
|
int32 blockOffset = index % fGroupsPerBlock;
|
||||||
|
|
||||||
MutexLocker _(fLock);
|
MutexLocker _(fLock);
|
||||||
|
|
||||||
@@ -580,12 +605,16 @@ Volume::GetBlockGroup(int32 index, ext2_block_group** _group)
|
|||||||
memcpy(fGroupBlocks[blockIndex], block, fBlockSize);
|
memcpy(fGroupBlocks[blockIndex], block, fBlockSize);
|
||||||
|
|
||||||
TRACE("group [%ld]: inode table %lld\n", index, ((ext2_block_group*)
|
TRACE("group [%ld]: inode table %lld\n", index, ((ext2_block_group*)
|
||||||
(fGroupBlocks[blockIndex] + (index % fGroupsPerBlock)
|
(fGroupBlocks[blockIndex] + blockOffset
|
||||||
* fGroupDescriptorSize))->InodeTable(Has64bitFeature()));
|
* fGroupDescriptorSize))->InodeTable(Has64bitFeature()));
|
||||||
}
|
}
|
||||||
|
|
||||||
*_group = (ext2_block_group*)(fGroupBlocks[blockIndex]
|
*_group = (ext2_block_group*)(fGroupBlocks[blockIndex]
|
||||||
+ (index % fGroupsPerBlock) * fGroupDescriptorSize);
|
+ blockOffset * fGroupDescriptorSize);
|
||||||
|
if (HasChecksumFeature()
|
||||||
|
&& (*_group)->checksum != _GroupCheckSum(*_group, index)) {
|
||||||
|
return B_BAD_DATA;
|
||||||
|
}
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,12 +628,20 @@ Volume::WriteBlockGroup(Transaction& transaction, int32 index)
|
|||||||
TRACE("Volume::WriteBlockGroup()\n");
|
TRACE("Volume::WriteBlockGroup()\n");
|
||||||
|
|
||||||
int32 blockIndex = index / fGroupsPerBlock;
|
int32 blockIndex = index / fGroupsPerBlock;
|
||||||
|
int32 blockOffset = index % fGroupsPerBlock;
|
||||||
|
|
||||||
MutexLocker _(fLock);
|
MutexLocker _(fLock);
|
||||||
|
|
||||||
if (fGroupBlocks[blockIndex] == NULL)
|
if (fGroupBlocks[blockIndex] == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
ext2_block_group *group = (ext2_block_group*)(fGroupBlocks[blockIndex]
|
||||||
|
+ blockOffset * fGroupDescriptorSize);
|
||||||
|
|
||||||
|
group->checksum = _GroupCheckSum(group, index);
|
||||||
|
TRACE("Volume::WriteBlockGroup() checksum 0x%x for group %ld\n",
|
||||||
|
group->checksum, index);
|
||||||
|
|
||||||
CachedBlock cached(this);
|
CachedBlock cached(this);
|
||||||
uint8* block = cached.SetToWritable(transaction,
|
uint8* block = cached.SetToWritable(transaction,
|
||||||
_GroupDescriptorBlock(blockIndex));
|
_GroupDescriptorBlock(blockIndex));
|
||||||
@@ -633,6 +670,20 @@ Volume::ActivateLargeFiles(Transaction& transaction)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Volume::ActivateDirNLink(Transaction& transaction)
|
||||||
|
{
|
||||||
|
if ((fSuperBlock.ReadOnlyFeatures()
|
||||||
|
& EXT2_READ_ONLY_FEATURE_DIR_NLINK) != 0)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
fSuperBlock.SetReadOnlyFeatures(fSuperBlock.ReadOnlyFeatures()
|
||||||
|
| EXT2_READ_ONLY_FEATURE_DIR_NLINK);
|
||||||
|
|
||||||
|
return WriteSuperBlock(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Volume::SaveOrphan(Transaction& transaction, ino_t newID, ino_t& oldID)
|
Volume::SaveOrphan(Transaction& transaction, ino_t newID, ino_t& oldID)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2011, Jérôme Duval, korli@users.berlios.de.
|
||||||
* Copyright 2008-2010, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2008-2010, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
@@ -76,20 +77,29 @@ public:
|
|||||||
Journal* GetJournal() { return fJournal; }
|
Journal* GetJournal() { return fJournal; }
|
||||||
|
|
||||||
bool IndexedDirectories() const
|
bool IndexedDirectories() const
|
||||||
{ return (fSuperBlock.CompatibleFeatures()
|
{ return (fSuperBlock.CompatibleFeatures()
|
||||||
& EXT2_FEATURE_DIRECTORY_INDEX) != 0; }
|
& EXT2_FEATURE_DIRECTORY_INDEX) != 0; }
|
||||||
bool Has64bitFeature() const
|
bool Has64bitFeature() const
|
||||||
{ return (fSuperBlock.CompatibleFeatures()
|
{ return (fSuperBlock.CompatibleFeatures()
|
||||||
& EXT2_INCOMPATIBLE_FEATURE_64BIT) != 0; }
|
& EXT2_INCOMPATIBLE_FEATURE_64BIT) != 0; }
|
||||||
bool HasExtentsFeature() const
|
bool HasExtentsFeature() const
|
||||||
{ return (fSuperBlock.IncompatibleFeatures()
|
{ return (fSuperBlock.IncompatibleFeatures()
|
||||||
& EXT2_INCOMPATIBLE_FEATURE_EXTENTS) != 0; }
|
& EXT2_INCOMPATIBLE_FEATURE_EXTENTS)
|
||||||
|
!= 0; }
|
||||||
|
bool HasChecksumFeature() const
|
||||||
|
{ return (fSuperBlock.ReadOnlyFeatures()
|
||||||
|
& EXT2_READ_ONLY_FEATURE_GDT_CSUM) != 0; }
|
||||||
|
bool HasMetaGroupFeature() const
|
||||||
|
{ return (fSuperBlock.IncompatibleFeatures()
|
||||||
|
& EXT2_INCOMPATIBLE_FEATURE_META_GROUP)
|
||||||
|
!= 0; }
|
||||||
uint8 DefaultHashVersion() const
|
uint8 DefaultHashVersion() const
|
||||||
{ return fSuperBlock.default_hash_version; }
|
{ return fSuperBlock.default_hash_version; }
|
||||||
bool HugeFiles() const
|
bool HugeFiles() const
|
||||||
{ return (fSuperBlock.ReadOnlyFeatures()
|
{ return (fSuperBlock.ReadOnlyFeatures()
|
||||||
& EXT2_READ_ONLY_FEATURE_HUGE_FILE) != 0; }
|
& EXT2_READ_ONLY_FEATURE_HUGE_FILE) != 0; }
|
||||||
status_t ActivateLargeFiles(Transaction& transaction);
|
status_t ActivateLargeFiles(Transaction& transaction);
|
||||||
|
status_t ActivateDirNLink(Transaction& transaction);
|
||||||
|
|
||||||
status_t SaveOrphan(Transaction& transaction,
|
status_t SaveOrphan(Transaction& transaction,
|
||||||
ino_t newID, ino_t &oldID);
|
ino_t newID, ino_t &oldID);
|
||||||
@@ -131,6 +141,8 @@ private:
|
|||||||
uint32 _GroupDescriptorBlock(uint32 blockIndex);
|
uint32 _GroupDescriptorBlock(uint32 blockIndex);
|
||||||
uint16 _GroupDescriptorSize()
|
uint16 _GroupDescriptorSize()
|
||||||
{ return fGroupDescriptorSize; }
|
{ return fGroupDescriptorSize; }
|
||||||
|
uint16 _GroupCheckSum(ext2_block_group *group,
|
||||||
|
int32 index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutex fLock;
|
mutex fLock;
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003 Tyler Dauwalder, [email protected]
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*! \file crc_table.cpp
|
||||||
|
|
||||||
|
Standalone program to generate the CRC table used for calculating
|
||||||
|
UDF tag id CRC values.
|
||||||
|
|
||||||
|
This code based off of crc code in UDF-2.50 specs, as permitted.
|
||||||
|
See UDF-2.50 6.5 for more information.
|
||||||
|
|
||||||
|
Reversed version by Jérôme Duval
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[]) {
|
||||||
|
ulong crc, poly;
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "USAGE: crc_table <octal polynomial=120001 for ext2>\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sscanf(argv[1], "%lo", &poly);
|
||||||
|
if (poly & 0xffff0000) {
|
||||||
|
fprintf(stderr, "ERROR: polynomial is too large, sucka.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("//! CRC 0%o table, as generated by crc_table.cpp\n", poly);
|
||||||
|
printf("static uint16 crc_table[256] = { \n");
|
||||||
|
for (int n = 0; n < 256; n++) {
|
||||||
|
if (n%8 == 0)
|
||||||
|
printf(" ");
|
||||||
|
crc = n;
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
if (crc & 0x0001)
|
||||||
|
crc = (crc >> 1) ^ poly;
|
||||||
|
else
|
||||||
|
crc >>= 1;
|
||||||
|
}
|
||||||
|
printf("0x%04x%s ", crc, (n != 255 ? "," : ""));
|
||||||
|
if (n%8 == 7)
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
printf("};\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -60,7 +60,7 @@ struct ext2_super_block {
|
|||||||
uint32 algorithm_usage_bitmap;
|
uint32 algorithm_usage_bitmap;
|
||||||
uint8 preallocated_blocks;
|
uint8 preallocated_blocks;
|
||||||
uint8 preallocated_directory_blocks;
|
uint8 preallocated_directory_blocks;
|
||||||
uint16 _padding;
|
uint16 reserved_gdt_blocks;
|
||||||
|
|
||||||
// journaling ext3 support
|
// journaling ext3 support
|
||||||
uint8 journal_uuid[16];
|
uint8 journal_uuid[16];
|
||||||
@@ -127,6 +127,8 @@ struct ext2_super_block {
|
|||||||
{ return B_LENDIAN_TO_HOST_INT32(read_only_features); }
|
{ return B_LENDIAN_TO_HOST_INT32(read_only_features); }
|
||||||
uint32 IncompatibleFeatures() const
|
uint32 IncompatibleFeatures() const
|
||||||
{ return B_LENDIAN_TO_HOST_INT32(incompatible_features); }
|
{ return B_LENDIAN_TO_HOST_INT32(incompatible_features); }
|
||||||
|
uint16 ReservedGDTBlocks() const
|
||||||
|
{ return B_LENDIAN_TO_HOST_INT16(reserved_gdt_blocks); }
|
||||||
ino_t JournalInode() const
|
ino_t JournalInode() const
|
||||||
{ return B_LENDIAN_TO_HOST_INT32(journal_inode); }
|
{ return B_LENDIAN_TO_HOST_INT32(journal_inode); }
|
||||||
ino_t LastOrphan() const
|
ino_t LastOrphan() const
|
||||||
@@ -383,6 +385,7 @@ struct ext2_extent_stream {
|
|||||||
} _PACKED;
|
} _PACKED;
|
||||||
|
|
||||||
#define EXT2_INODE_NORMAL_SIZE 128
|
#define EXT2_INODE_NORMAL_SIZE 128
|
||||||
|
#define EXT2_INODE_MAX_LINKS 65000
|
||||||
|
|
||||||
struct ext2_inode {
|
struct ext2_inode {
|
||||||
uint16 mode;
|
uint16 mode;
|
||||||
|
|||||||
Reference in New Issue
Block a user