xfs : version 5 superblock, checksum header file
- Implemented version 5 superblock fields and necessary macros. - Checksum functions are implemented which will be used for crc verification and crc updates. - fssh_kernal_priv.h ROUNDDOWN macro definition is consistent with kernal.h definition. Change-Id: I49b7c939bfd3ea1bffc85b3db42bc678dcce75cd Reviewed-on: https://review.haiku-os.org/c/haiku/+/5350 Tested-by: Commit checker robot <[email protected]> Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
ac2215ca09
commit
9c4a46b318
@@ -45,7 +45,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1))
|
#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1))
|
||||||
#define ROUNDOWN(a, b) (((a) / (b)) * (b))
|
#define ROUNDDOWN(a, b) (((a) / (b)) * (b))
|
||||||
|
|
||||||
|
|
||||||
#define CHECK_BIT(a, b) ((a) & (1 << (b)))
|
#define CHECK_BIT(a, b) ((a) & (1 << (b)))
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ KernelAddon ext2 :
|
|||||||
Attribute.cpp
|
Attribute.cpp
|
||||||
BitmapBlock.cpp
|
BitmapBlock.cpp
|
||||||
BlockAllocator.cpp
|
BlockAllocator.cpp
|
||||||
crc32.c
|
crc32.cpp
|
||||||
CRCTable.cpp
|
CRCTable.cpp
|
||||||
DataStream.cpp
|
DataStream.cpp
|
||||||
DeviceOpener.cpp
|
DeviceOpener.cpp
|
||||||
@@ -34,7 +34,7 @@ KernelAddon ext2 :
|
|||||||
SEARCH on [ FGristFiles DeviceOpener.cpp ]
|
SEARCH on [ FGristFiles DeviceOpener.cpp ]
|
||||||
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
||||||
|
|
||||||
SEARCH on [ FGristFiles crc32.c ]
|
SEARCH on [ FGristFiles crc32.cpp ]
|
||||||
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
||||||
|
|
||||||
SEARCH on [ FGristFiles CRCTable.cpp ]
|
SEARCH on [ FGristFiles CRCTable.cpp ]
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
uint16 calculate_crc(uint16 crc, uint8 *data, uint16 length);
|
uint16 calculate_crc(uint16 crc, uint8 *data, uint16 length);
|
||||||
|
|
||||||
__BEGIN_DECLS
|
|
||||||
uint32 calculate_crc32c(uint32 crc32c, const unsigned char *buffer,
|
uint32 calculate_crc32c(uint32 crc32c, const unsigned char *buffer,
|
||||||
unsigned int length);
|
unsigned int length);
|
||||||
__END_DECLS
|
|
||||||
|
|
||||||
|
|||||||
+49
-37
@@ -42,18 +42,32 @@
|
|||||||
* CRC32 code derived from work by Gary S. Brown.
|
* CRC32 code derived from work by Gary S. Brown.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef FS_SHELL
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#ifdef __HAIKU__
|
#ifdef __HAIKU__
|
||||||
#define rounddown(x, y) (((x)/(y))*(y))
|
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
|
#include <kernel.h>
|
||||||
#include <size_t.h>
|
#include <size_t.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
uint32_t calculate_crc32c(uint32_t crc32c, const unsigned char *buffer,
|
uint32 calculate_crc32c(uint32 crc32c, const unsigned char *buffer,
|
||||||
unsigned int length);
|
unsigned int length);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const uint32_t crc32_tab[] = {
|
#else
|
||||||
|
|
||||||
|
#include "fssh_api_wrapper.h"
|
||||||
|
#include "fssh_auto_deleter.h"
|
||||||
|
#include "fssh_kernel_priv.h"
|
||||||
|
#include "Debug.h"
|
||||||
|
uint32 calculate_crc32c(uint32 crc32c, const unsigned char *buffer,
|
||||||
|
unsigned int length);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
const uint32 crc32_tab[] = {
|
||||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||||
@@ -105,11 +119,11 @@ const uint32_t crc32_tab[] = {
|
|||||||
* of this function that's actually used in the kernel can be found
|
* of this function that's actually used in the kernel can be found
|
||||||
* in sys/libkern.h, where it can be inlined.
|
* in sys/libkern.h, where it can be inlined.
|
||||||
*
|
*
|
||||||
* uint32_t
|
* uint32
|
||||||
* crc32(const void *buf, size_t size)
|
* crc32(const void *buf, size_t size)
|
||||||
* {
|
* {
|
||||||
* const uint8_t *p = buf;
|
* const uint8_t *p = buf;
|
||||||
* uint32_t crc;
|
* uint32 crc;
|
||||||
*
|
*
|
||||||
* crc = ~0U;
|
* crc = ~0U;
|
||||||
* while (size--)
|
* while (size--)
|
||||||
@@ -139,7 +153,7 @@ const uint32_t crc32_tab[] = {
|
|||||||
/* */
|
/* */
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
|
|
||||||
static const uint32_t crc32Table[256] = {
|
static const uint32 crc32Table[256] = {
|
||||||
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
|
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
|
||||||
0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
|
0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
|
||||||
0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
|
0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
|
||||||
@@ -206,10 +220,10 @@ static const uint32_t crc32Table[256] = {
|
|||||||
0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
|
0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint32_t
|
static uint32
|
||||||
singletable_crc32c(uint32_t crc, const void *buf, size_t size)
|
singletable_crc32c(uint32 crc, const void *buf, size_t size)
|
||||||
{
|
{
|
||||||
const uint8_t *p = buf;
|
const uint8_t *p = (const uint8_t *)buf;
|
||||||
|
|
||||||
|
|
||||||
while (size--)
|
while (size--)
|
||||||
@@ -245,7 +259,7 @@ singletable_crc32c(uint32_t crc, const void *buf, size_t size)
|
|||||||
* File Name = ............................ 8x256_tables.c
|
* File Name = ............................ 8x256_tables.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const uint32_t sctp_crc_tableil8_o32[256] =
|
static const uint32 sctp_crc_tableil8_o32[256] =
|
||||||
{
|
{
|
||||||
0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
|
0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
|
||||||
0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
|
0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
|
||||||
@@ -301,7 +315,7 @@ static const uint32_t sctp_crc_tableil8_o32[256] =
|
|||||||
* File Name = ............................ 8x256_tables.c
|
* File Name = ............................ 8x256_tables.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const uint32_t sctp_crc_tableil8_o40[256] =
|
static const uint32 sctp_crc_tableil8_o40[256] =
|
||||||
{
|
{
|
||||||
0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899, 0x4E8A61DC, 0x5D28F9AB, 0x69CF5132, 0x7A6DC945,
|
0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899, 0x4E8A61DC, 0x5D28F9AB, 0x69CF5132, 0x7A6DC945,
|
||||||
0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21, 0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD,
|
0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21, 0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD,
|
||||||
@@ -357,7 +371,7 @@ static const uint32_t sctp_crc_tableil8_o40[256] =
|
|||||||
* File Name = ............................ 8x256_tables.c
|
* File Name = ............................ 8x256_tables.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const uint32_t sctp_crc_tableil8_o48[256] =
|
static const uint32 sctp_crc_tableil8_o48[256] =
|
||||||
{
|
{
|
||||||
0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073, 0x9EDEA41A, 0x3B9F3664, 0xD1B1F617, 0x74F06469,
|
0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073, 0x9EDEA41A, 0x3B9F3664, 0xD1B1F617, 0x74F06469,
|
||||||
0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6, 0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC,
|
0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6, 0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC,
|
||||||
@@ -413,7 +427,7 @@ static const uint32_t sctp_crc_tableil8_o48[256] =
|
|||||||
* File Name = ............................ 8x256_tables.c
|
* File Name = ............................ 8x256_tables.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const uint32_t sctp_crc_tableil8_o56[256] =
|
static const uint32 sctp_crc_tableil8_o56[256] =
|
||||||
{
|
{
|
||||||
0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939, 0x7B2231F3, 0xA6679B4B, 0xC4451272, 0x1900B8CA,
|
0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939, 0x7B2231F3, 0xA6679B4B, 0xC4451272, 0x1900B8CA,
|
||||||
0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF, 0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C,
|
0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF, 0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C,
|
||||||
@@ -469,7 +483,7 @@ static const uint32_t sctp_crc_tableil8_o56[256] =
|
|||||||
* File Name = ............................ 8x256_tables.c
|
* File Name = ............................ 8x256_tables.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const uint32_t sctp_crc_tableil8_o64[256] =
|
static const uint32 sctp_crc_tableil8_o64[256] =
|
||||||
{
|
{
|
||||||
0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4, 0xE045BEB0, 0xD854D11C, 0x906761E8, 0xA8760E44,
|
0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4, 0xE045BEB0, 0xD854D11C, 0x906761E8, 0xA8760E44,
|
||||||
0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65, 0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5,
|
0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65, 0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5,
|
||||||
@@ -525,7 +539,7 @@ static const uint32_t sctp_crc_tableil8_o64[256] =
|
|||||||
* File Name = ............................ 8x256_tables.c
|
* File Name = ............................ 8x256_tables.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const uint32_t sctp_crc_tableil8_o72[256] =
|
static const uint32 sctp_crc_tableil8_o72[256] =
|
||||||
{
|
{
|
||||||
0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA, 0xB2F53777, 0x5DC55C6E, 0x697997B4, 0x8649FCAD,
|
0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA, 0xB2F53777, 0x5DC55C6E, 0x697997B4, 0x8649FCAD,
|
||||||
0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5, 0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2,
|
0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5, 0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2,
|
||||||
@@ -581,7 +595,7 @@ static const uint32_t sctp_crc_tableil8_o72[256] =
|
|||||||
* File Name = ............................ 8x256_tables.c
|
* File Name = ............................ 8x256_tables.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const uint32_t sctp_crc_tableil8_o80[256] =
|
static const uint32 sctp_crc_tableil8_o80[256] =
|
||||||
{
|
{
|
||||||
0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558, 0xA5E0C5D1, 0xCDE3E919, 0x75E69C41, 0x1DE5B089,
|
0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558, 0xA5E0C5D1, 0xCDE3E919, 0x75E69C41, 0x1DE5B089,
|
||||||
0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B, 0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA,
|
0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B, 0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA,
|
||||||
@@ -637,7 +651,7 @@ static const uint32_t sctp_crc_tableil8_o80[256] =
|
|||||||
* File Name = ............................ 8x256_tables.c
|
* File Name = ............................ 8x256_tables.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const uint32_t sctp_crc_tableil8_o88[256] =
|
static const uint32 sctp_crc_tableil8_o88[256] =
|
||||||
{
|
{
|
||||||
0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769, 0x211D826D, 0x6821FF4A, 0xB3657823, 0xFA590504,
|
0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769, 0x211D826D, 0x6821FF4A, 0xB3657823, 0xFA590504,
|
||||||
0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3, 0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE,
|
0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3, 0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE,
|
||||||
@@ -678,20 +692,19 @@ static const uint32_t sctp_crc_tableil8_o88[256] =
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static uint32_t
|
static uint32
|
||||||
crc32c_sb8_64_bit(uint32_t crc,
|
crc32c_sb8_64_bit(uint32 crc,
|
||||||
const unsigned char *p_buf,
|
const unsigned char *p_buf,
|
||||||
uint32_t length,
|
uint32 length,
|
||||||
uint32_t init_bytes)
|
uint32 init_bytes)
|
||||||
{
|
{
|
||||||
uint32_t li;
|
uint32 li;
|
||||||
uint32_t term1, term2;
|
uint32 term1, term2;
|
||||||
uint32_t running_length;
|
uint32 running_length;
|
||||||
uint32_t end_bytes;
|
uint32 end_bytes;
|
||||||
|
|
||||||
running_length = rounddown(length - init_bytes, 8);
|
running_length = ROUNDDOWN(length - init_bytes, 8);
|
||||||
end_bytes = length - init_bytes - running_length;
|
end_bytes = length - init_bytes - running_length;
|
||||||
|
|
||||||
for (li = 0; li < init_bytes; li++)
|
for (li = 0; li < init_bytes; li++)
|
||||||
crc = sctp_crc_tableil8_o32[(crc ^ *p_buf++) & 0x000000FF] ^
|
crc = sctp_crc_tableil8_o32[(crc ^ *p_buf++) & 0x000000FF] ^
|
||||||
(crc >> 8);
|
(crc >> 8);
|
||||||
@@ -702,7 +715,7 @@ crc32c_sb8_64_bit(uint32_t crc,
|
|||||||
crc ^= (*p_buf++) << 16;
|
crc ^= (*p_buf++) << 16;
|
||||||
crc ^= (*p_buf++) << 24;
|
crc ^= (*p_buf++) << 24;
|
||||||
#else
|
#else
|
||||||
crc ^= *(const uint32_t *) p_buf;
|
crc ^= *(const uint32 *) p_buf;
|
||||||
p_buf += 4;
|
p_buf += 4;
|
||||||
#endif
|
#endif
|
||||||
term1 = sctp_crc_tableil8_o88[crc & 0x000000FF] ^
|
term1 = sctp_crc_tableil8_o88[crc & 0x000000FF] ^
|
||||||
@@ -718,10 +731,9 @@ crc32c_sb8_64_bit(uint32_t crc,
|
|||||||
crc ^= sctp_crc_tableil8_o40[*p_buf++];
|
crc ^= sctp_crc_tableil8_o40[*p_buf++];
|
||||||
crc ^= sctp_crc_tableil8_o32[*p_buf++];
|
crc ^= sctp_crc_tableil8_o32[*p_buf++];
|
||||||
#else
|
#else
|
||||||
term1 = sctp_crc_tableil8_o56[(*(const uint32_t *) p_buf) & 0x000000FF] ^
|
term1 = sctp_crc_tableil8_o56[(*(const uint32 *) p_buf) & 0x000000FF] ^
|
||||||
sctp_crc_tableil8_o48[((*(const uint32_t *) p_buf) >> 8) & 0x000000FF];
|
sctp_crc_tableil8_o48[((*(const uint32 *) p_buf) >> 8) & 0x000000FF];
|
||||||
|
term2 = (*(const uint32 *) p_buf) >> 16;
|
||||||
term2 = (*(const uint32_t *) p_buf) >> 16;
|
|
||||||
crc = crc ^
|
crc = crc ^
|
||||||
term1 ^
|
term1 ^
|
||||||
sctp_crc_tableil8_o40[term2 & 0x000000FF] ^
|
sctp_crc_tableil8_o40[term2 & 0x000000FF] ^
|
||||||
@@ -735,12 +747,12 @@ crc32c_sb8_64_bit(uint32_t crc,
|
|||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32
|
||||||
multitable_crc32c(uint32_t crc32c,
|
multitable_crc32c(uint32 crc32c,
|
||||||
const unsigned char *buffer,
|
const unsigned char *buffer,
|
||||||
unsigned int length)
|
unsigned int length)
|
||||||
{
|
{
|
||||||
uint32_t to_even_word;
|
uint32 to_even_word;
|
||||||
|
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
return (crc32c);
|
return (crc32c);
|
||||||
@@ -749,8 +761,8 @@ multitable_crc32c(uint32_t crc32c,
|
|||||||
return (crc32c_sb8_64_bit(crc32c, buffer, length, to_even_word));
|
return (crc32c_sb8_64_bit(crc32c, buffer, length, to_even_word));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32
|
||||||
calculate_crc32c(uint32_t crc32c,
|
calculate_crc32c(uint32 crc32c,
|
||||||
const unsigned char *buffer,
|
const unsigned char *buffer,
|
||||||
unsigned int length)
|
unsigned int length)
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022, Raghav Sharma, [email protected]
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef _XFS_CKSUM_H
|
||||||
|
#define _XFS_CKSUM_H
|
||||||
|
|
||||||
|
#include "CRCTable.h"
|
||||||
|
#include "xfs_types.h"
|
||||||
|
#include "system_dependencies.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define XFS_CRC_SEED (~(uint32)0)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calculate the intermediate checksum for a buffer that has the CRC field
|
||||||
|
inside it. The offset of the 32bit crc fields is passed as the
|
||||||
|
cksum_offset parameter. We do not modify the buffer during verification,
|
||||||
|
hence we have to split the CRC calculation across the cksum_offset.
|
||||||
|
*/
|
||||||
|
static inline uint32
|
||||||
|
xfs_start_cksum_safe(const char *buffer, size_t length, uint32 cksum_offset)
|
||||||
|
{
|
||||||
|
uint32 zero = 0;
|
||||||
|
uint32 crc;
|
||||||
|
|
||||||
|
// Calculate CRC up to the checksum.
|
||||||
|
crc = calculate_crc32c(XFS_CRC_SEED, (uint8*)buffer, cksum_offset);
|
||||||
|
|
||||||
|
// Skip checksum field
|
||||||
|
crc = calculate_crc32c(crc, (uint8*)&zero, sizeof(uint32));
|
||||||
|
|
||||||
|
// Calculate the rest of the CRC.
|
||||||
|
return calculate_crc32c(crc, (uint8*)buffer + cksum_offset + sizeof(uint32),
|
||||||
|
length - (cksum_offset + sizeof(uint32)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fast CRC method where the buffer is modified. Callers must have exclusive
|
||||||
|
access to the buffer while the calculation takes place.
|
||||||
|
*/
|
||||||
|
static inline uint32
|
||||||
|
xfs_start_cksum_update(char *buffer, size_t length, uint32 cksum_offset)
|
||||||
|
{
|
||||||
|
// zero the CRC field
|
||||||
|
*(uint32 *)(buffer + cksum_offset) = 0;
|
||||||
|
|
||||||
|
// single pass CRC calculation for the entire buffer
|
||||||
|
return calculate_crc32c(XFS_CRC_SEED, (uint8*)buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Helper to generate the checksum for a buffer.
|
||||||
|
|
||||||
|
This modifies the buffer temporarily - callers must have exclusive
|
||||||
|
access to the buffer while the calculation takes place.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
xfs_update_cksum(char *buffer, size_t length, uint32 cksum_offset)
|
||||||
|
{
|
||||||
|
uint32 crc = xfs_start_cksum_update(buffer, length, cksum_offset);
|
||||||
|
|
||||||
|
*(uint32 *)(buffer + cksum_offset) = ~crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Helper to verify the checksum for a buffer.
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
xfs_verify_cksum(char *buffer, size_t length, uint32 cksum_offset)
|
||||||
|
{
|
||||||
|
uint32 crc = xfs_start_cksum_safe(buffer, length, cksum_offset);
|
||||||
|
|
||||||
|
TRACE("calculated crc: (%" B_PRIu32 ")\n", ~crc);
|
||||||
|
|
||||||
|
TRACE("buffer = %s, cksum_offset: (%" B_PRIu32 ")\n", buffer, cksum_offset);
|
||||||
|
|
||||||
|
return *(uint32 *)(buffer + cksum_offset) == (~crc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -543,7 +543,7 @@ Inode::GetFromDisk()
|
|||||||
xfs_fsblock_t blockToRead = FSBLOCKS_TO_BASICBLOCKS(fVolume->BlockLog(),
|
xfs_fsblock_t blockToRead = FSBLOCKS_TO_BASICBLOCKS(fVolume->BlockLog(),
|
||||||
((uint64)(agNo * numberOfBlocksInAg) + agBlock));
|
((uint64)(agNo * numberOfBlocksInAg) + agBlock));
|
||||||
|
|
||||||
xfs_daddr_t readPos = blockToRead * BASICBLOCKSIZE + offset * len;
|
xfs_daddr_t readPos = blockToRead * XFS_MIN_BLOCKSIZE + offset * len;
|
||||||
|
|
||||||
if (read_pos(fVolume->Device(), readPos, fBuffer, len) != len) {
|
if (read_pos(fVolume->Device(), readPos, fBuffer, len) != len) {
|
||||||
ERROR("Inode::Inode(): IO Error");
|
ERROR("Inode::Inode(): IO Error");
|
||||||
@@ -570,7 +570,7 @@ Inode::FileSystemBlockToAddr(uint64 block)
|
|||||||
((uint64)(agNo * numberOfBlocksInAg) + agBlockNo));
|
((uint64)(agNo * numberOfBlocksInAg) + agBlockNo));
|
||||||
TRACE("blockToRead:(%" B_PRIu64 ")\n", actualBlockToRead);
|
TRACE("blockToRead:(%" B_PRIu64 ")\n", actualBlockToRead);
|
||||||
|
|
||||||
uint64 readPos = actualBlockToRead * (BASICBLOCKSIZE);
|
uint64 readPos = actualBlockToRead * (XFS_MIN_BLOCKSIZE);
|
||||||
return readPos;
|
return readPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ UsePrivateKernelHeaders ;
|
|||||||
DEFINES += DEBUG_APP="\\\"xfs\\\"" ;
|
DEFINES += DEBUG_APP="\\\"xfs\\\"" ;
|
||||||
|
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src libs uuid ] : true ;
|
UseHeaders [ FDirName $(HAIKU_TOP) src libs uuid ] : true ;
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] : true ;
|
||||||
|
|
||||||
local xfsSources =
|
local xfsSources =
|
||||||
BPlusTree.cpp
|
BPlusTree.cpp
|
||||||
DeviceOpener.cpp
|
|
||||||
Directory.cpp
|
Directory.cpp
|
||||||
Extent.cpp
|
Extent.cpp
|
||||||
Inode.cpp
|
Inode.cpp
|
||||||
@@ -33,8 +33,14 @@ local xfsSources =
|
|||||||
Volume.cpp
|
Volume.cpp
|
||||||
xfs.cpp
|
xfs.cpp
|
||||||
;
|
;
|
||||||
|
local sharedSources =
|
||||||
|
crc32.cpp
|
||||||
|
CRCTable.cpp
|
||||||
|
DeviceOpener.cpp
|
||||||
|
;
|
||||||
KernelAddon xfs :
|
KernelAddon xfs :
|
||||||
$(xfsSources)
|
$(xfsSources)
|
||||||
|
$(sharedSources)
|
||||||
:
|
:
|
||||||
libuuid_kernel.a
|
libuuid_kernel.a
|
||||||
;
|
;
|
||||||
@@ -42,8 +48,10 @@ KernelAddon xfs :
|
|||||||
SEARCH on [ FGristFiles $(xfsSources) ]
|
SEARCH on [ FGristFiles $(xfsSources) ]
|
||||||
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems xfs ] ;
|
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems xfs ] ;
|
||||||
|
|
||||||
SEARCH on [ FGristFiles DeviceOpener.cpp ]
|
SEARCH on [ FGristFiles $(sharedSources) ]
|
||||||
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
||||||
|
|
||||||
SEARCH on [ FGristFiles kernel_cpp.cpp ]
|
SEARCH on [ FGristFiles kernel_cpp.cpp ]
|
||||||
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
|
= [ FDirName $(HAIKU_TOP) src system kernel util ] ;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "Volume.h"
|
#include "Volume.h"
|
||||||
|
|
||||||
|
#include "Checksum.h"
|
||||||
#include "Inode.h"
|
#include "Inode.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -39,9 +40,28 @@ Volume::Identify(int fd, XfsSuperBlock *superBlock)
|
|||||||
|
|
||||||
TRACE("Volume::Identify() : Identifying Volume in progress");
|
TRACE("Volume::Identify() : Identifying Volume in progress");
|
||||||
|
|
||||||
if (read_pos(fd, 0, superBlock, sizeof(XfsSuperBlock))
|
//Create a buffer of 512 bytes for Crc verification
|
||||||
!= sizeof(XfsSuperBlock))
|
char buf[512];
|
||||||
return B_IO_ERROR;
|
|
||||||
|
if(read_pos(fd, 0, buf, 512) != 512)
|
||||||
|
return B_IO_ERROR;
|
||||||
|
|
||||||
|
memcpy(superBlock, buf, sizeof(XfsSuperBlock));
|
||||||
|
|
||||||
|
int version = B_BENDIAN_TO_HOST_INT16(superBlock->Version()) & XFS_SB_VERSION_NUMBITS;
|
||||||
|
|
||||||
|
// if its V5 filesystem check for superblock checksum
|
||||||
|
if (superBlock->MagicNum() == B_HOST_TO_BENDIAN_INT32(XFS_SB_MAGIC)
|
||||||
|
&& (version == 5 || superBlock->Crc() != 0)) {
|
||||||
|
|
||||||
|
TRACE("Superblock Crc: (%" B_PRIu32 ")\n", superBlock->Crc());
|
||||||
|
|
||||||
|
if(!xfs_verify_cksum(buf, 512, offsetof(XfsSuperBlock, sb_crc))) {
|
||||||
|
ERROR("Filesystem is corrupted");
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
superBlock->SwapEndian();
|
superBlock->SwapEndian();
|
||||||
|
|
||||||
@@ -85,7 +105,11 @@ Volume::Mount(const char *deviceName, uint32 flags)
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("Volume::Mount(): Valid SuperBlock.\n");
|
if ((fSuperBlock.Version() & XFS_SB_VERSION_NUMBITS) == 5)
|
||||||
|
TRACE("Volume::Mount(): Valid Version 5 SuperBlock.\n");
|
||||||
|
else
|
||||||
|
TRACE("Volume::Mount(): Valid Version 4 SuperBlock.\n");
|
||||||
|
|
||||||
|
|
||||||
// check if the device size is large enough to hold the file system
|
// check if the device size is large enough to hold the file system
|
||||||
off_t diskSize;
|
off_t diskSize;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#include "xfs.h"
|
#include "xfs.h"
|
||||||
|
|
||||||
|
|
||||||
#define FSBLOCK_SHIFT(fsBlockLog) (fsBlockLog - BASICBLOCKLOG);
|
#define FSBLOCK_SHIFT(fsBlockLog) (fsBlockLog - XFS_MIN_BLOCKSIZE_LOG);
|
||||||
#define FSBLOCKS_TO_BASICBLOCKS(fsBlockLog, x) x << FSBLOCK_SHIFT(fsBlockLog);
|
#define FSBLOCKS_TO_BASICBLOCKS(fsBlockLog, x) x << FSBLOCK_SHIFT(fsBlockLog);
|
||||||
// Converting the FS Blocks to Basic Blocks
|
// Converting the FS Blocks to Basic Blocks
|
||||||
|
|
||||||
|
|||||||
@@ -13,23 +13,143 @@ XfsSuperBlock::Flags() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
XfsSuperBlock::IsValidVersion() const
|
||||||
|
{
|
||||||
|
// Version 5 is supported
|
||||||
|
if ((Version() & XFS_SB_VERSION_NUMBITS) == 5) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version below 4 are not supported
|
||||||
|
if ((Version() & XFS_SB_VERSION_NUMBITS) < 4) {
|
||||||
|
ERROR("xfs version below 4 is not supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// V4 filesystems need v2 directories and unwritten extents
|
||||||
|
if (!(Version() & XFS_SB_VERSION_DIRV2BIT)) {
|
||||||
|
ERROR("xfs version 4 uses version 2 directories");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(Version() & XFS_SB_VERSION_EXTFLGBIT)) {
|
||||||
|
ERROR("xfs version 4 uses unwritten extents");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// V4 should not have any unknown v4 feature bits set
|
||||||
|
if ((Version() & ~XFS_SB_VERSION_OKBITS) ||
|
||||||
|
((Version() & XFS_SB_VERSION_MOREBITSBIT) &&
|
||||||
|
(Features2() & ~XFS_SB_VERSION2_OKBITS))) {
|
||||||
|
ERROR("xfs version 4 unknown feature bit detected");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid V4 filesytem
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
XfsSuperBlock::IsValidFeatureMask() const
|
||||||
|
{
|
||||||
|
// Version 5 superblock feature mask validation
|
||||||
|
if(sb_features_compat & XFS_SB_FEAT_COMPAT_UNKNOWN) {
|
||||||
|
ERROR("Superblock has unknown compatible features enabled");
|
||||||
|
ERROR("Use more recent kernal");
|
||||||
|
}
|
||||||
|
|
||||||
|
// We cannot have write support if this is set
|
||||||
|
if(sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_UNKNOWN) {
|
||||||
|
ERROR("Superblock has unknown read-only compatible features enabled");
|
||||||
|
ERROR("Filesystem is read-only");
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for incompatible features
|
||||||
|
if(sb_features_incompat & XFS_SB_FEAT_INCOMPAT_UNKNOWN) {
|
||||||
|
ERROR("Superblock has unknown incompatible features enabled");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
XfsSuperBlock::IsValid() const
|
XfsSuperBlock::IsValid() const
|
||||||
{
|
{
|
||||||
if (sb_magicnum != XFS_SB_MAGIC)
|
if (sb_magicnum != XFS_SB_MAGIC) {
|
||||||
|
ERROR("Invalid Superblock");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (BASICBLOCKSIZE > sb_blocksize) {
|
// For version 4
|
||||||
|
if (XFS_MIN_BLOCKSIZE > sb_blocksize) {
|
||||||
ERROR("Basic block is less than 512 bytes!");
|
ERROR("Basic block is less than 512 bytes!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checking version 4 file system
|
// Checking correct version of filesystem
|
||||||
if ((Version() & 0x000f) > 4) {
|
if(!(IsValidVersion())) {
|
||||||
ERROR("XFS version 5 or later is not yet supported");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((Version() & XFS_SB_VERSION_NUMBITS) == 4) {
|
||||||
|
|
||||||
|
if(sb_qflags & (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD |
|
||||||
|
XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD)) {
|
||||||
|
ERROR("V4 Superblock has XFS_{P|G}QUOTA_{ENFD|CHKD} bits");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(IsValidFeatureMask())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For V5
|
||||||
|
if (XFS_MIN_CRC_BLOCKSIZE > sb_blocksize) {
|
||||||
|
ERROR("Basic block is less than 1024 bytes!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// V5 has a separate project quota inode
|
||||||
|
if (sb_qflags & (XFS_OQUOTA_ENFD | XFS_OQUOTA_CHKD)) {
|
||||||
|
ERROR("Version 5 of Super block has XFS_OQUOTA bits");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*TODO: check if full Inode chunks are aligned to
|
||||||
|
inode chunk size when sparse inodes are
|
||||||
|
enabled to support the sparse chunk allocation
|
||||||
|
algorithm and prevent overlapping inode record.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Sanity Checking
|
||||||
|
if( sb_agcount <= 0 ||
|
||||||
|
sb_sectsize < XFS_MIN_SECTORSIZE ||
|
||||||
|
sb_sectsize > XFS_MAX_SECTORSIZE ||
|
||||||
|
sb_sectlog < XFS_MIN_SECTORSIZE_LOG ||
|
||||||
|
sb_sectlog > XFS_MAX_SECTORSIZE_LOG ||
|
||||||
|
sb_sectsize != (1 << sb_sectlog) ||
|
||||||
|
sb_blocksize < XFS_MIN_BLOCKSIZE ||
|
||||||
|
sb_blocksize > XFS_MAX_BLOCKSIZE ||
|
||||||
|
sb_blocklog < XFS_MIN_BLOCKSIZE_LOG ||
|
||||||
|
sb_blocklog > XFS_MAX_BLOCKSIZE_LOG ||
|
||||||
|
sb_blocksize != (uint32)(1 << sb_blocklog) ||
|
||||||
|
sb_dirblklog + sb_blocklog > XFS_MAX_BLOCKSIZE_LOG ||
|
||||||
|
sb_inodesize < XFS_DINODE_MIN_SIZE ||
|
||||||
|
sb_inodesize > XFS_DINODE_MAX_SIZE ||
|
||||||
|
sb_inodelog < XFS_DINODE_MIN_LOG ||
|
||||||
|
sb_inodelog > XFS_DINODE_MAX_LOG ||
|
||||||
|
sb_inodesize != (1 << sb_inodelog) ) {
|
||||||
|
|
||||||
|
ERROR("Sanity checking failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid V5 Superblock
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,38 +287,61 @@ XfsSuperBlock::AgBlocks() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32
|
||||||
|
XfsSuperBlock::Crc() const
|
||||||
|
{
|
||||||
|
return sb_crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
XfsSuperBlock::MagicNum() const
|
||||||
|
{
|
||||||
|
return sb_magicnum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
XfsSuperBlock::SwapEndian()
|
XfsSuperBlock::SwapEndian()
|
||||||
{
|
{
|
||||||
sb_magicnum = B_BENDIAN_TO_HOST_INT32(sb_magicnum);
|
sb_magicnum = B_BENDIAN_TO_HOST_INT32(sb_magicnum);
|
||||||
sb_blocksize = B_BENDIAN_TO_HOST_INT32(sb_blocksize);
|
sb_blocksize = B_BENDIAN_TO_HOST_INT32(sb_blocksize);
|
||||||
sb_dblocks = B_BENDIAN_TO_HOST_INT64(sb_dblocks);
|
sb_dblocks = B_BENDIAN_TO_HOST_INT64(sb_dblocks);
|
||||||
sb_rblocks = B_BENDIAN_TO_HOST_INT64(sb_rblocks);
|
sb_rblocks = B_BENDIAN_TO_HOST_INT64(sb_rblocks);
|
||||||
sb_rextents = B_BENDIAN_TO_HOST_INT64(sb_rextents);
|
sb_rextents = B_BENDIAN_TO_HOST_INT64(sb_rextents);
|
||||||
sb_logstart = B_BENDIAN_TO_HOST_INT64(sb_logstart);
|
sb_logstart = B_BENDIAN_TO_HOST_INT64(sb_logstart);
|
||||||
sb_rootino = B_BENDIAN_TO_HOST_INT64(sb_rootino);
|
sb_rootino = B_BENDIAN_TO_HOST_INT64(sb_rootino);
|
||||||
sb_rbmino = B_BENDIAN_TO_HOST_INT64(sb_rbmino);
|
sb_rbmino = B_BENDIAN_TO_HOST_INT64(sb_rbmino);
|
||||||
sb_rsumino = B_BENDIAN_TO_HOST_INT64(sb_rsumino);
|
sb_rsumino = B_BENDIAN_TO_HOST_INT64(sb_rsumino);
|
||||||
sb_rextsize = B_BENDIAN_TO_HOST_INT32(sb_rextsize);
|
sb_rextsize = B_BENDIAN_TO_HOST_INT32(sb_rextsize);
|
||||||
sb_agblocks = B_BENDIAN_TO_HOST_INT32(sb_agblocks);
|
sb_agblocks = B_BENDIAN_TO_HOST_INT32(sb_agblocks);
|
||||||
sb_agcount = B_BENDIAN_TO_HOST_INT32(sb_agcount);
|
sb_agcount = B_BENDIAN_TO_HOST_INT32(sb_agcount);
|
||||||
sb_rbmblocks = B_BENDIAN_TO_HOST_INT32(sb_rbmblocks);
|
sb_rbmblocks = B_BENDIAN_TO_HOST_INT32(sb_rbmblocks);
|
||||||
sb_logblocks = B_BENDIAN_TO_HOST_INT32(sb_logblocks);
|
sb_logblocks = B_BENDIAN_TO_HOST_INT32(sb_logblocks);
|
||||||
sb_versionnum = B_BENDIAN_TO_HOST_INT16(sb_versionnum);
|
sb_versionnum = B_BENDIAN_TO_HOST_INT16(sb_versionnum);
|
||||||
sb_sectsize = B_BENDIAN_TO_HOST_INT16(sb_sectsize);
|
sb_sectsize = B_BENDIAN_TO_HOST_INT16(sb_sectsize);
|
||||||
sb_inodesize = B_BENDIAN_TO_HOST_INT16(sb_inodesize);
|
sb_inodesize = B_BENDIAN_TO_HOST_INT16(sb_inodesize);
|
||||||
sb_inopblock = B_BENDIAN_TO_HOST_INT16(sb_inopblock);
|
sb_inopblock = B_BENDIAN_TO_HOST_INT16(sb_inopblock);
|
||||||
sb_icount = B_BENDIAN_TO_HOST_INT64(sb_icount);
|
sb_icount = B_BENDIAN_TO_HOST_INT64(sb_icount);
|
||||||
sb_ifree = B_BENDIAN_TO_HOST_INT64(sb_ifree);
|
sb_ifree = B_BENDIAN_TO_HOST_INT64(sb_ifree);
|
||||||
sb_fdblocks = B_BENDIAN_TO_HOST_INT64(sb_fdblocks);
|
sb_fdblocks = B_BENDIAN_TO_HOST_INT64(sb_fdblocks);
|
||||||
sb_frextents = B_BENDIAN_TO_HOST_INT64(sb_frextents);
|
sb_frextents = B_BENDIAN_TO_HOST_INT64(sb_frextents);
|
||||||
sb_uquotino = B_BENDIAN_TO_HOST_INT64(sb_uquotino);
|
sb_uquotino = B_BENDIAN_TO_HOST_INT64(sb_uquotino);
|
||||||
sb_gquotino = B_BENDIAN_TO_HOST_INT64(sb_gquotino);
|
sb_gquotino = B_BENDIAN_TO_HOST_INT64(sb_gquotino);
|
||||||
sb_qflags = B_BENDIAN_TO_HOST_INT16(sb_qflags);
|
sb_qflags = B_BENDIAN_TO_HOST_INT16(sb_qflags);
|
||||||
sb_inoalignmt = B_BENDIAN_TO_HOST_INT32(sb_inoalignmt);
|
sb_inoalignmt = B_BENDIAN_TO_HOST_INT32(sb_inoalignmt);
|
||||||
sb_unit = B_BENDIAN_TO_HOST_INT32(sb_unit);
|
sb_unit = B_BENDIAN_TO_HOST_INT32(sb_unit);
|
||||||
sb_width = B_BENDIAN_TO_HOST_INT32(sb_width);
|
sb_width = B_BENDIAN_TO_HOST_INT32(sb_width);
|
||||||
sb_logsectsize = B_BENDIAN_TO_HOST_INT16(sb_logsectsize);
|
sb_logsectsize = B_BENDIAN_TO_HOST_INT16(sb_logsectsize);
|
||||||
sb_logsunit = B_BENDIAN_TO_HOST_INT32(sb_logsunit);
|
sb_logsunit = B_BENDIAN_TO_HOST_INT32(sb_logsunit);
|
||||||
sb_features2 = B_BENDIAN_TO_HOST_INT32(sb_features2);
|
sb_features2 = B_BENDIAN_TO_HOST_INT32(sb_features2);
|
||||||
|
sb_bad_features2 = B_BENDIAN_TO_HOST_INT32(sb_bad_features2);
|
||||||
|
sb_features_compat = B_BENDIAN_TO_HOST_INT32(sb_features_compat);
|
||||||
|
sb_features_ro_compat = B_BENDIAN_TO_HOST_INT32(sb_features_ro_compat);
|
||||||
|
sb_features_incompat = B_BENDIAN_TO_HOST_INT32(sb_features_incompat);
|
||||||
|
sb_features_log_incompat = B_BENDIAN_TO_HOST_INT32(sb_features_log_incompat);
|
||||||
|
// crc is only used on disk, not in memory; just init to 0 here
|
||||||
|
sb_crc = 0;
|
||||||
|
sb_spino_align = B_BENDIAN_TO_HOST_INT32(sb_spino_align);
|
||||||
|
sb_pquotino = B_BENDIAN_TO_HOST_INT64(sb_pquotino);
|
||||||
|
sb_lsn = B_BENDIAN_TO_HOST_INT64(sb_lsn);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,13 +24,30 @@ extern fs_volume_ops gxfsVolumeOps;
|
|||||||
|
|
||||||
|
|
||||||
#define XFS_SB_MAGIC 0x58465342
|
#define XFS_SB_MAGIC 0x58465342
|
||||||
// Identifies XFS. "XFSB"
|
#define XFS_MIN_BLOCKSIZE_LOG 9
|
||||||
|
#define XFS_MAX_BLOCKSIZE_LOG 16
|
||||||
|
#define XFS_MIN_BLOCKSIZE (1 << XFS_MIN_BLOCKSIZE_LOG)
|
||||||
|
#define XFS_MAX_BLOCKSIZE (1 << XFS_MAX_BLOCKSIZE_LOG)
|
||||||
|
#define XFS_MIN_CRC_BLOCKSIZE (1 << (XFS_MIN_BLOCKSIZE_LOG + 1))
|
||||||
|
#define XFS_MIN_SECTORSIZE_LOG 9
|
||||||
|
#define XFS_MAX_SECTORSIZE_LOG 15
|
||||||
|
#define XFS_MIN_SECTORSIZE (1 << XFS_MIN_SECTORSIZE_LOG)
|
||||||
|
#define XFS_MAX_SECTORSIZE (1 << XFS_MAX_SECTORSIZE_LOG)
|
||||||
#define XFS_SB_MAXSIZE 512
|
#define XFS_SB_MAXSIZE 512
|
||||||
#define BASICBLOCKLOG 9
|
|
||||||
// Log of block size should be 9
|
|
||||||
#define BASICBLOCKSIZE (1 << BASICBLOCKLOG)
|
|
||||||
// The size of a basic block should be 512
|
|
||||||
#define XFS_OPEN_MODE_USER_MASK 0x7fffffff
|
#define XFS_OPEN_MODE_USER_MASK 0x7fffffff
|
||||||
|
#define XFS_SB_VERSION_NUMBITS 0x000f
|
||||||
|
#define XFS_SB_VERSION_ALLFBITS 0xfff0
|
||||||
|
#define XFS_SB_VERSION_NUM(sb) ((sb)->sb_versionnum & XFS_SB_VERSION_NUMBITS)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inode minimum and maximum sizes.
|
||||||
|
*/
|
||||||
|
#define XFS_DINODE_MIN_LOG 8
|
||||||
|
#define XFS_DINODE_MAX_LOG 11
|
||||||
|
#define XFS_DINODE_MIN_SIZE (1 << XFS_DINODE_MIN_LOG)
|
||||||
|
#define XFS_DINODE_MAX_SIZE (1 << XFS_DINODE_MAX_LOG)
|
||||||
|
|
||||||
/* B+Tree related macros
|
/* B+Tree related macros
|
||||||
*/
|
*/
|
||||||
@@ -50,11 +67,12 @@ struct file_cookie {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Version 4 superblock definition */
|
|
||||||
class XfsSuperBlock {
|
class XfsSuperBlock {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
|
bool IsValidVersion() const;
|
||||||
|
bool IsValidFeatureMask() const;
|
||||||
const char* Name() const;
|
const char* Name() const;
|
||||||
uint32 BlockSize() const;
|
uint32 BlockSize() const;
|
||||||
uint8 BlockLog() const;
|
uint8 BlockLog() const;
|
||||||
@@ -77,6 +95,8 @@ public:
|
|||||||
uint8 Flags() const;
|
uint8 Flags() const;
|
||||||
uint16 Version() const;
|
uint16 Version() const;
|
||||||
uint32 Features2() const;
|
uint32 Features2() const;
|
||||||
|
uint32 Crc() const;
|
||||||
|
uint32 MagicNum() const;
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint32 sb_magicnum;
|
uint32 sb_magicnum;
|
||||||
@@ -124,6 +144,22 @@ private:
|
|||||||
uint16 sb_logsectsize;
|
uint16 sb_logsectsize;
|
||||||
uint32 sb_logsunit;
|
uint32 sb_logsunit;
|
||||||
uint32 sb_features2;
|
uint32 sb_features2;
|
||||||
|
uint32 sb_bad_features2;
|
||||||
|
|
||||||
|
// version 5
|
||||||
|
|
||||||
|
uint32 sb_features_compat;
|
||||||
|
uint32 sb_features_ro_compat;
|
||||||
|
uint32 sb_features_incompat;
|
||||||
|
uint32 sb_features_log_incompat;
|
||||||
|
public:
|
||||||
|
uint32 sb_crc;
|
||||||
|
private:
|
||||||
|
xfs_extlen_t sb_spino_align;
|
||||||
|
|
||||||
|
xfs_ino_t sb_pquotino;
|
||||||
|
xfs_lsn_t sb_lsn;
|
||||||
|
uuid_t sb_meta_uuid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -146,6 +182,9 @@ private:
|
|||||||
#define XFS_SB_VERSION_DIRV2BIT 0x2000
|
#define XFS_SB_VERSION_DIRV2BIT 0x2000
|
||||||
#define XFS_SB_VERSION_MOREBITSBIT 0x4000
|
#define XFS_SB_VERSION_MOREBITSBIT 0x4000
|
||||||
|
|
||||||
|
#define XFS_SB_VERSION_OKBITS \
|
||||||
|
((XFS_SB_VERSION_NUMBITS | XFS_SB_VERSION_ALLFBITS) & \
|
||||||
|
~XFS_SB_VERSION_SHAREDBIT)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Superblock quota flags - sb_qflags
|
Superblock quota flags - sb_qflags
|
||||||
@@ -182,4 +221,51 @@ Superblock quota flags - sb_qflags
|
|||||||
#define XFS_SB_VERSION2_CRCBIT 0x00000100 /* Metadata checksumming */
|
#define XFS_SB_VERSION2_CRCBIT 0x00000100 /* Metadata checksumming */
|
||||||
#define XFS_SB_VERSION2_FTYPE 0x00000200
|
#define XFS_SB_VERSION2_FTYPE 0x00000200
|
||||||
|
|
||||||
|
#define XFS_SB_VERSION2_OKBITS \
|
||||||
|
(XFS_SB_VERSION2_LAZYSBCOUNTBIT | \
|
||||||
|
XFS_SB_VERSION2_ATTR2BIT | \
|
||||||
|
XFS_SB_VERSION2_PROJID32BIT | \
|
||||||
|
XFS_SB_VERSION2_FTYPE)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Extended Version 5 Superblock Read-Only compatibility flags
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define XFS_SB_FEAT_RO_COMPAT_FINOBT (1 << 0) /* free inode btree */
|
||||||
|
#define XFS_SB_FEAT_RO_COMPAT_RMAPBT (1 << 1) /* reverse map btree */
|
||||||
|
#define XFS_SB_FEAT_RO_COMPAT_REFLINK (1 << 2) /* reflinked files */
|
||||||
|
#define XFS_SB_FEAT_RO_COMPAT_INOBTCNT (1 << 3) /* inobt block counts */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Extended Version 5 Superblock Read-Write incompatibility flags
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
|
||||||
|
#define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */
|
||||||
|
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
|
||||||
|
#define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Extended v5 superblock feature masks. These are to be used for new v5
|
||||||
|
superblock features only.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define XFS_SB_FEAT_COMPAT_ALL 0
|
||||||
|
#define XFS_SB_FEAT_COMPAT_UNKNOWN ~XFS_SB_FEAT_COMPAT_ALL
|
||||||
|
|
||||||
|
#define XFS_SB_FEAT_RO_COMPAT_ALL \
|
||||||
|
(XFS_SB_FEAT_RO_COMPAT_FINOBT | \
|
||||||
|
XFS_SB_FEAT_RO_COMPAT_RMAPBT | \
|
||||||
|
XFS_SB_FEAT_RO_COMPAT_REFLINK| \
|
||||||
|
XFS_SB_FEAT_RO_COMPAT_INOBTCNT)
|
||||||
|
#define XFS_SB_FEAT_RO_COMPAT_UNKNOWN ~XFS_SB_FEAT_RO_COMPAT_ALL
|
||||||
|
|
||||||
|
#define XFS_SB_FEAT_INCOMPAT_ALL \
|
||||||
|
(XFS_SB_FEAT_INCOMPAT_FTYPE| \
|
||||||
|
XFS_SB_FEAT_INCOMPAT_SPINODES| \
|
||||||
|
XFS_SB_FEAT_INCOMPAT_META_UUID| \
|
||||||
|
XFS_SB_FEAT_INCOMPAT_BIGTIME)
|
||||||
|
|
||||||
|
#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ typedef uint64 xfs_rtblock_t; // extent number in the real-time sub-volume
|
|||||||
typedef uint64 xfs_fileoff_t; // block offset into a file
|
typedef uint64 xfs_fileoff_t; // block offset into a file
|
||||||
typedef uint64 xfs_filblks_t; // block count for a file
|
typedef uint64 xfs_filblks_t; // block count for a file
|
||||||
typedef int64 xfs_fsize_t; // byte size of a file
|
typedef int64 xfs_fsize_t; // byte size of a file
|
||||||
|
typedef int64 xfs_lsn_t; // log sequence number
|
||||||
typedef xfs_fileoff_t TreeKey;
|
typedef xfs_fileoff_t TreeKey;
|
||||||
typedef xfs_fsblock_t TreePointer;
|
typedef xfs_fsblock_t TreePointer;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
SubDir HAIKU_TOP src tests add-ons kernel file_systems xfs xfs_shell ;
|
SubDir HAIKU_TOP src tests add-ons kernel file_systems xfs xfs_shell ;
|
||||||
|
|
||||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems xfs ] ;
|
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems xfs ] ;
|
||||||
|
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
||||||
|
|
||||||
# prevent inclusion of HaikuBuildCompatibility.h and _BSD_SOURCE headers
|
# prevent inclusion of HaikuBuildCompatibility.h and _BSD_SOURCE headers
|
||||||
DEFINES += HAIKU_BUILD_COMPATIBILITY_H __STRICT_ANSI__ ;
|
DEFINES += HAIKU_BUILD_COMPATIBILITY_H __STRICT_ANSI__ ;
|
||||||
@@ -37,10 +38,10 @@ UsePrivateHeaders fs_shell ;
|
|||||||
UsePrivateHeaders file_systems ;
|
UsePrivateHeaders file_systems ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) headers private ] : true ;
|
UseHeaders [ FDirName $(HAIKU_TOP) headers private ] : true ;
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
|
UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] : true ;
|
||||||
|
|
||||||
local xfsSource =
|
local xfsSource =
|
||||||
BPlusTree.cpp
|
BPlusTree.cpp
|
||||||
DeviceOpener.cpp
|
|
||||||
Directory.cpp
|
Directory.cpp
|
||||||
Extent.cpp
|
Extent.cpp
|
||||||
Inode.cpp
|
Inode.cpp
|
||||||
@@ -51,8 +52,13 @@ local xfsSource =
|
|||||||
Volume.cpp
|
Volume.cpp
|
||||||
xfs.cpp
|
xfs.cpp
|
||||||
;
|
;
|
||||||
|
local sharedSources =
|
||||||
|
crc32.cpp
|
||||||
|
CRCTable.cpp
|
||||||
|
DeviceOpener.cpp
|
||||||
|
;
|
||||||
|
|
||||||
BuildPlatformMergeObject <build>xfs_shell.o : $(xfsSource) ;
|
BuildPlatformMergeObject <build>xfs_shell.o : $(xfsSource) $(sharedSources) ;
|
||||||
|
|
||||||
BuildPlatformMain <build>xfs_shell
|
BuildPlatformMain <build>xfs_shell
|
||||||
:
|
:
|
||||||
@@ -74,5 +80,3 @@ BuildPlatformMain <build>xfs_fuse
|
|||||||
SEARCH on [ FGristFiles QueryParserUtils.cpp ]
|
SEARCH on [ FGristFiles QueryParserUtils.cpp ]
|
||||||
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
||||||
|
|
||||||
SEARCH on [ FGristFiles DeviceOpener.cpp ]
|
|
||||||
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
|
||||||
|
|||||||
Reference in New Issue
Block a user