[haiku-commits] Change in haiku[master]: xfs: An attempt to read block directories

  • From: Gerrit <review@xxxxxxxxxxxxxxxxxxx>
  • To: waddlesplash <waddlesplash@xxxxxxxxx>, haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 3 Jul 2020 07:54:26 +0000

From Shubham Bhagat <shubhambhagat111@xxxxxxxxx>:

Shubham Bhagat has uploaded this change for review. ( 
https://review.haiku-os.org/c/haiku/+/2981 ;)


Change subject: xfs: An attempt to read block directories
......................................................................

xfs: An attempt to read block directories

Map entries can be read, most structures are in place. Next is to
actually work with the directory block.
---
M src/add-ons/kernel/file_systems/xfs/Debug.h
M src/add-ons/kernel/file_systems/xfs/Directory.cpp
M src/add-ons/kernel/file_systems/xfs/Directory.h
A src/add-ons/kernel/file_systems/xfs/Extent.cpp
A src/add-ons/kernel/file_systems/xfs/Extent.h
M src/add-ons/kernel/file_systems/xfs/Inode.cpp
M src/add-ons/kernel/file_systems/xfs/Inode.h
M src/add-ons/kernel/file_systems/xfs/Jamfile
M src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp
M src/add-ons/kernel/file_systems/xfs/xfs_types.h
M src/tests/add-ons/kernel/file_systems/xfs/xfs_shell/Jamfile
11 files changed, 253 insertions(+), 9 deletions(-)



  git pull ssh://git.haiku-os.org:22/haiku refs/changes/81/2981/1

diff --git a/src/add-ons/kernel/file_systems/xfs/Debug.h 
b/src/add-ons/kernel/file_systems/xfs/Debug.h
index ec5a36b..ac7413c 100644
--- a/src/add-ons/kernel/file_systems/xfs/Debug.h
+++ b/src/add-ons/kernel/file_systems/xfs/Debug.h
@@ -9,7 +9,7 @@
 #ifndef _DEBUG_H_
 #define _DEBUG_H_

-// #define TRACE_XFS
+#define TRACE_XFS
 #ifdef TRACE_XFS
 #define TRACE(x...) dprintf("\n\33[34mxfs:\33[0m " x)
 #define ASSERT(x) \
diff --git a/src/add-ons/kernel/file_systems/xfs/Directory.cpp 
b/src/add-ons/kernel/file_systems/xfs/Directory.cpp
index ad825ec..3f53817 100644
--- a/src/add-ons/kernel/file_systems/xfs/Directory.cpp
+++ b/src/add-ons/kernel/file_systems/xfs/Directory.cpp
@@ -30,6 +30,13 @@
                        return B_NO_MEMORY;
                return B_OK;
        }
+       if (fInode->Format() == XFS_DINODE_FMT_EXTENTS) {
+               fExtentDir = new(std::nothrow) Extent(fInode);
+               if (fExtentDir == NULL)
+                       return B_NO_MEMORY;
+               status_t status = fExtentDir->Init();
+               return status;
+       }

        /* Return B_OK so even if the shortform directory has an extent 
directory
         * we can atleast still list the shortform directory
@@ -87,6 +94,8 @@
        //TODO: Reading from extent based dirs
        if (fInode->Format() == XFS_DINODE_FMT_EXTENTS) {
                TRACE("Iterator:Lookup: EXTENTS");
+               // status_t status = fExtentDir->Lookup(name, length, ino);
+               // return status;
                return B_NOT_SUPPORTED;
        }

diff --git a/src/add-ons/kernel/file_systems/xfs/Directory.h 
b/src/add-ons/kernel/file_systems/xfs/Directory.h
index fd0e3be..29450d2 100644
--- a/src/add-ons/kernel/file_systems/xfs/Directory.h
+++ b/src/add-ons/kernel/file_systems/xfs/Directory.h
@@ -8,6 +8,7 @@

 #include "Inode.h"
 #include "ShortDirectory.h"
+#include "Extent.h"


 /*
@@ -28,6 +29,7 @@
 private:
                        Inode*                          fInode;
                        ShortDirectory*         fShortDir;
+                       Extent*                         fExtentDir;
                                // Short form Directory type
 };

diff --git a/src/add-ons/kernel/file_systems/xfs/Extent.cpp 
b/src/add-ons/kernel/file_systems/xfs/Extent.cpp
new file mode 100644
index 0000000..fd42e5b
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/xfs/Extent.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
+#include "Extent.h"
+
+
+uint32
+hashfunction(const char* name, int length)
+{
+       uint32 hashVal = 0;
+
+       int lengthCovered = 0;
+       int index = 0;
+       if (length >= 4) {
+               for (; index <= length; index+=4)
+               {
+                       lengthCovered = index;
+                       hashVal = (name[index] << 21) ^ (name[index+1] << 14) ^ 
(name[index+2] << 7)
+                               ^ (name[index+3] << 0) ^ ((hashVal << 28) | 
(hashVal >> (4)));
+               }
+       }
+
+       int leftToCover = length - lengthCovered;
+       if (leftToCover == 3) {
+               hashVal = (name[index] << 14) ^ (name[index+1] << 7) ^ 
(name[index+2] << 0)
+                       ^ ((hashVal << 21) | (hashVal >> (11)));
+       }
+       if (leftToCover == 2) {
+               hashVal = (name[index] << 7) ^ (name[index+1] << 0)
+                               ^ ((hashVal << 14) | (hashVal >> (32 - 14)));
+       }
+       if (leftToCover == 1) {
+               hashVal = (name[index] << 0) ^ ((hashVal << 7) | (hashVal >> 
(32 - 7)));
+       }
+
+       return hashVal;
+}
+
+
+Extent::Extent(Inode* inode)
+       :
+       fInode(inode)
+{
+}
+
+
+void
+Extent::FillMapEntry(void* pointerToMap)
+{
+       uint64 firstHalf = *((uint64*)pointerToMap);
+       uint64 secondHalf = *((uint64*)pointerToMap + 1);
+               //dividing the 128 bits into 2 parts.
+       firstHalf = B_BENDIAN_TO_HOST_INT64(firstHalf);
+       secondHalf = B_BENDIAN_TO_HOST_INT64(secondHalf);
+       fMap->br_state = (firstHalf >> 63);
+       fMap->br_startoff = (firstHalf & MASK(63)) >> 9;
+       fMap->br_startblock = ((firstHalf & MASK(9)) << 43) | (secondHalf >> 
21);
+       fMap->br_blockcount = (secondHalf & MASK(21));
+       TRACE("Extent::Init: startoff:(%ld), startblock:(%ld), 
blockcount:(%ld),"
+                       "state:(%d)\n",
+               fMap->br_startoff,
+               fMap->br_startblock,
+               fMap->br_blockcount,
+               fMap->br_state
+               );
+}
+
+
+status_t
+Extent::Init()
+{
+       fMap = new(std::nothrow) ExtentMapEntry;
+       if (fMap == NULL)
+               return B_NO_MEMORY;
+
+       ASSERT(BlockType() == true);
+       void* pointerToMap = DIR_DFORK_PTR(fInode->Buffer());
+       FillMapEntry(pointerToMap);
+
+       return B_NOT_SUPPORTED;
+}
+
+
+ExtentBlockTail*
+Extent::BlockTail(ExtentDataHeader* header)
+{
+       return (ExtentBlockTail*)
+               ((char*)header + fInode->DirBlockSize() - 
sizeof(ExtentBlockTail));
+}
+
+
+ExtentLeafEntry*
+Extent::BlockFirstLeaf(ExtentBlockTail* tail)
+{
+       return (ExtentLeafEntry*)tail - B_BENDIAN_TO_HOST_INT32(tail->count);
+}
+
+
+bool
+Extent::BlockType()
+{
+       bool status = true;
+       if (fInode->NoOfBlocks() != 1)
+               status = false;
+       if (fInode->Size() != fInode->DirBlockSize())
+               status = false;
+       return status;
+}
+
diff --git a/src/add-ons/kernel/file_systems/xfs/Extent.h 
b/src/add-ons/kernel/file_systems/xfs/Extent.h
new file mode 100644
index 0000000..9d1dde8
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/xfs/Extent.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+#ifndef _EXTENT_H_
+#define _EXTENT_H_
+
+
+#include "Inode.h"
+#include "system_dependencies.h"
+
+
+#define DIR2_BLOCK_HEADER_MAGIC 0x58443242
+       // for v4 system
+#define XFS_DIR2_DATA_FD_COUNT 3
+#define EXTENT_REC_SIZE                128
+#define MASK(n) ((1UL << n) - 1)
+
+
+// xfs_exntst_t
+enum ExtentState {
+       XFS_EXT_NORM,
+       XFS_EXT_UNWRITTEN,
+       XFS_EXT_INVALID
+};
+
+
+// xfs_dir2_data_free_t
+struct FreeRegion {
+                               uint16                  offset;
+                               uint16                  length;
+};
+
+
+// xfs_dir2_data_hdr_t
+struct ExtentDataHeader {
+                               uint32                  magic;
+                               FreeRegion              
bestfree[XFS_DIR2_DATA_FD_COUNT];
+};
+
+
+// xfs_dir2_data_entry_t
+struct ExtentDataEntry {
+                               xfs_ino_t               inumber;
+                               uint8                   namelen;
+                               uint8                   name[];
+
+// Followed by a file type (8bit) if applicable and a 16bit tag
+// tag is the offset from start of the block
+};
+
+
+// xfs_dir2_data_unused_t
+struct ExtentUnusedEntry {
+                               uint16                  freetag;
+                                       // takes the value 0xffff
+                               uint16                  length;
+                                       // freetag+length overrides the inumber 
of an entry
+                               uint16                  tag;
+};
+
+
+// xfs_dir2_leaf_entry_t
+struct ExtentLeafEntry {
+                               uint32                  hashval;
+                               uint32                  address;
+                                       // offset into block after >> 3
+};
+
+
+// xfs_dir2_block_tail_t
+struct ExtentBlockTail {
+                               uint32                  count;
+                                       // # of entries in leaf
+                               uint32          stale;
+                                       // # of free leaf entries
+};
+
+
+struct ExtentMapEntry {
+                       xfs_fileoff_t           br_startoff;
+                               // logical file block offset
+                       xfs_fsblock_t           br_startblock;
+                               // absolute block number
+                       xfs_filblks_t           br_blockcount;
+                               // # of blocks
+                       uint8                           br_state;
+                               // state of the extent
+};
+
+
+class Extent
+{
+public:
+                                                               Extent(Inode* 
inode);
+                                                               ~Extent();
+                       status_t                        Init();
+                       bool                            BlockType();
+                       void                            FillMapEntry(void* 
pointerToMap);
+                       ExtentDataHeader*       BlockHeader();
+                       ExtentBlockTail*        BlockTail(ExtentDataHeader* 
header);
+                       ExtentLeafEntry*        BlockFirstLeaf(ExtentBlockTail* 
tail);
+                       xfs_ino_t                       GetIno();
+                       status_t                        GetNext(char* name, 
size_t* length,
+                                                                       
xfs_ino_t* ino);
+                       status_t                        Lookup(const char* 
name, size_t length,
+                                                                       
xfs_ino_t* id);
+private:
+                       Inode*                          fInode;
+                       ExtentMapEntry*         fMap;
+                       char*                           fBlockBuffer;
+                               // This isn't inode data. It holds the 
directory block.
+};
+
+
+#endif
diff --git a/src/add-ons/kernel/file_systems/xfs/Inode.cpp 
b/src/add-ons/kernel/file_systems/xfs/Inode.cpp
index 787ccd6..670b819 100644
--- a/src/add-ons/kernel/file_systems/xfs/Inode.cpp
+++ b/src/add-ons/kernel/file_systems/xfs/Inode.cpp
@@ -175,7 +175,8 @@
                // Inode len to read (size of inode)

        TRACE("AgNumber: (%d), AgRelativeIno: (%d), AgRelativeBlockNum: (%d),"
-               "Offset: (%d), len: (%d)\n", agNo, agInodeNo, agBlock, offset, 
len);
+               "Offset: (%d), len: (%d)\n", agNo,
+               agRelativeInodeNo, agBlock, offset, len);

        if (agNo > fVolume->AgCount()) {
                ERROR("Inode::GetFromDisk : AG Number more than number of AGs");
diff --git a/src/add-ons/kernel/file_systems/xfs/Inode.h 
b/src/add-ons/kernel/file_systems/xfs/Inode.h
index d891c8e..9c41604 100644
--- a/src/add-ons/kernel/file_systems/xfs/Inode.h
+++ b/src/add-ons/kernel/file_systems/xfs/Inode.h
@@ -159,6 +159,9 @@

                        xfs_fsize_t                     Size() const { return 
fNode->Size(); }

+                       uint32                          DirBlockSize() const
+                                                                       { 
return fVolume->DirBlockSize(); }
+
                        void                            GetChangeTime(struct 
timespec& timestamp) const
                                                                { 
fNode->GetChangeTime(timestamp); }

diff --git a/src/add-ons/kernel/file_systems/xfs/Jamfile 
b/src/add-ons/kernel/file_systems/xfs/Jamfile
index 0509ce2..e1857d2 100644
--- a/src/add-ons/kernel/file_systems/xfs/Jamfile
+++ b/src/add-ons/kernel/file_systems/xfs/Jamfile
@@ -22,6 +22,7 @@
 local xfsSources =
        DeviceOpener.cpp
        Directory.cpp
+       Extent.cpp
        Inode.cpp
        kernel_cpp.cpp
        kernel_interface.cpp
@@ -42,4 +43,4 @@
        = [ FDirName  $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;

 SEARCH on [ FGristFiles kernel_cpp.cpp ]
-       = [ FDirName $(HAIKU_TOP) src system kernel util ] ;
\ No newline at end of file
+       = [ FDirName $(HAIKU_TOP) src system kernel util ] ;
diff --git a/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp 
b/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp
index 1eabf9e..c7e3fd8 100644
--- a/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp
+++ b/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp
@@ -152,7 +152,7 @@
        _node->ops = &gxfsVnodeOps;
        *_type = inode->Mode();
        *_flags = 0;
-       TRACE("(%d)\n", inode->ID());
+       TRACE("(%ld)\n", inode->ID());
        return B_OK;
 }

@@ -230,7 +230,7 @@
                return status;
        }

-       TRACE("XFS_LOOKUP: ID: (%d)\n", *_vnodeID);
+       TRACE("XFS_LOOKUP: ID: (%ld)\n", *_vnodeID);
        status = get_vnode(volume->FSVolume(), *_vnodeID, NULL);
        TRACE("get_vnode status: (%d)\n", status);
        return status;
@@ -249,7 +249,7 @@
 xfs_read_stat(fs_volume *_volume, fs_vnode *_node, struct stat *stat)
 {
        Inode* inode = (Inode*)_node->private_node;
-       TRACE("XFS_READ_STAT: id: (%d)\n", inode->ID());
+       TRACE("XFS_READ_STAT: id: (%ld)\n", inode->ID());
        stat->st_dev = inode->GetVolume()->ID();
        stat->st_ino = inode->ID();
        stat->st_nlink = 1;
@@ -351,7 +351,7 @@
 xfs_open_dir(fs_volume * /*_volume*/, fs_vnode *_node, void **_cookie)
 {
        Inode* inode = (Inode*)_node->private_node;
-       TRACE("XFS_OPEN_DIR: (%d)\n", inode->ID());
+       TRACE("XFS_OPEN_DIR: (%ld)\n", inode->ID());

        if (!inode->IsDirectory())
                return B_NOT_A_DIRECTORY;
diff --git a/src/add-ons/kernel/file_systems/xfs/xfs_types.h 
b/src/add-ons/kernel/file_systems/xfs/xfs_types.h
index 3b1fd6e..ae32585 100644
--- a/src/add-ons/kernel/file_systems/xfs/xfs_types.h
+++ b/src/add-ons/kernel/file_systems/xfs/xfs_types.h
@@ -29,10 +29,9 @@
 typedef uint32 xfs_dahash_t;   // hash of a directory file name
                                                                // or extended 
attribute name
 typedef uint64 xfs_fsblock_t;  // filesystem block number combining AG number
-                                                               // and block 
offset into the AG
 typedef uint64 xfs_rfsblock_t; // raw filesystem block number
 typedef uint64 xfs_rtblock_t;  // extent number in the real-time sub-volume
-typedef uint64 xfs_filoff_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 int64 xfs_fsize_t;             // byte size of a file

diff --git a/src/tests/add-ons/kernel/file_systems/xfs/xfs_shell/Jamfile 
b/src/tests/add-ons/kernel/file_systems/xfs/xfs_shell/Jamfile
index c9fe209..1f3f52b 100644
--- a/src/tests/add-ons/kernel/file_systems/xfs/xfs_shell/Jamfile
+++ b/src/tests/add-ons/kernel/file_systems/xfs/xfs_shell/Jamfile
@@ -41,6 +41,7 @@
 local xfsSource =
        DeviceOpener.cpp
        Directory.cpp
+       Extent.cpp
        Inode.cpp
        kernel_interface.cpp
        ShortDirectory.cpp

--
To view, visit https://review.haiku-os.org/c/haiku/+/2981
To unsubscribe, or for help writing mail filters, visit 
https://review.haiku-os.org/settings

Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: I700ee2e003bdef97838b1f06a95e53a5e4293658
Gerrit-Change-Number: 2981
Gerrit-PatchSet: 1
Gerrit-Owner: Shubham Bhagat <shubhambhagat111@xxxxxxxxx>
Gerrit-MessageType: newchange

Other related posts:

  • » [haiku-commits] Change in haiku[master]: xfs: An attempt to read block directories - Gerrit