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:
Mashijams
2022-06-18 08:32:18 +00:00
committed by Adrien Destugues
parent ac2215ca09
commit 9c4a46b318
13 changed files with 460 additions and 97 deletions
+1 -1
View File
@@ -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)))
+2 -2
View File
@@ -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
@@ -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;
} }
+10 -2
View File
@@ -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 ] ;
+28 -4
View File
@@ -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;
+1 -1
View File
@@ -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
+179 -36
View File
@@ -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);
} }
+92 -6
View File
@@ -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 ] ;