[haiku-commits] haiku: hrev53956 - src/add-ons/kernel/file_systems/xfs

  • From: Adrien Destugues <pulkomandy@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 9 Mar 2020 04:52:57 -0400 (EDT)

hrev53956 adds 1 changeset to branch 'master'
old head: 0d2645e44f9e7f132df9a90e8f65153c6293e56a
new head: 2deffe2f3f3d5f6a48cdc67bf423ff6f2af4c092
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=2deffe2f3f3d+%5E0d2645e44f9e

----------------------------------------------------------------------------

2deffe2f3f3d: Adding superblock, types, xfs_mount and volume
  
  Superblock work is done. A valid superblock is now detected.
  xfs_shell will fail though, because the filesystem does not own it's
  root node.
  
  Change-Id: I78e3c21c4d0dd8e535fd24df4a0c107ed5fb201c
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/2286
  Reviewed-by: Adrien Destugues <pulkomandy@xxxxxxxxx>

                                    [ CruxBox <shubhambhagat111@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev53956
Commit:      2deffe2f3f3d5f6a48cdc67bf423ff6f2af4c092
URL:         https://git.haiku-os.org/haiku/commit/?id=2deffe2f3f3d
Author:      CruxBox <shubhambhagat111@xxxxxxxxx>
Date:        Thu Feb 27 17:39:19 2020 UTC
Committer:   Adrien Destugues <pulkomandy@xxxxxxxxx>
Commit-Date: Mon Mar  9 08:52:50 2020 UTC

----------------------------------------------------------------------------

10 files changed, 715 insertions(+), 84 deletions(-)
src/add-ons/kernel/file_systems/xfs/Debug.h      |  16 ++
src/add-ons/kernel/file_systems/xfs/Jamfile      |   2 +
src/add-ons/kernel/file_systems/xfs/Volume.cpp   | 267 +++++++++++++++++++
src/add-ons/kernel/file_systems/xfs/Volume.h     |  64 +++++
.../kernel/file_systems/xfs/kernel_interface.cpp | 181 ++++++++-----
.../file_systems/xfs/system_dependencies.h       |  18 +-
src/add-ons/kernel/file_systems/xfs/xfs.cpp      |  73 +++++
src/add-ons/kernel/file_systems/xfs/xfs.h        | 129 +++++++++
src/add-ons/kernel/file_systems/xfs/xfs_types.h  |  41 +++
.../kernel/file_systems/xfs/xfs_shell/Jamfile    |   8 +-

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/file_systems/xfs/Debug.h 
b/src/add-ons/kernel/file_systems/xfs/Debug.h
new file mode 100644
index 0000000000..6ab16012bc
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/xfs/Debug.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+#ifndef _DEBUG_H_
+#define _DEBUG_H_
+
+#define TRACE_XFS
+#ifdef TRACE_XFS
+#define TRACE(x...) dprintf("\n\33[34mxfs:\33[0m " x)
+#else
+#define TRACE(x...) ;
+#endif
+#define ERROR(x...) dprintf("\n\33[34mxfs:\33[0m " x)
+
+#endif
\ No newline at end of file
diff --git a/src/add-ons/kernel/file_systems/xfs/Jamfile 
b/src/add-ons/kernel/file_systems/xfs/Jamfile
index edf605bb98..79c72ddc19 100644
--- a/src/add-ons/kernel/file_systems/xfs/Jamfile
+++ b/src/add-ons/kernel/file_systems/xfs/Jamfile
@@ -20,6 +20,8 @@ DEFINES += DEBUG_APP="\\\"xfs\\\"" ;
 UseHeaders [ FDirName $(HAIKU_TOP) src libs uuid ] : true ;
 
 local xfsSources =
+    xfs.cpp
+    Volume.cpp
     kernel_cpp.cpp
     kernel_interface.cpp
     ;
diff --git a/src/add-ons/kernel/file_systems/xfs/Volume.cpp 
b/src/add-ons/kernel/file_systems/xfs/Volume.cpp
new file mode 100644
index 0000000000..0c24307d5e
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/xfs/Volume.cpp
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2001 - 2017, Axel Dörfler, axeld @pinc - software.de.
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+#include "Volume.h"
+
+
+class DeviceOpener
+{
+public:
+                                                       DeviceOpener(int fd, 
int mode);
+                                                       DeviceOpener(const char 
*device, int mode);
+                                                       ~DeviceOpener();
+
+                       int                             Open(const char 
*device, int mode);
+                       int                             Open(int fd, int mode);
+                       void*                   InitCache(off_t numBlocks, 
uint32 blockSize);
+                       void                    RemoveCache(bool allowWrites);
+
+                       void                    Keep();
+
+                       int                             Device() const { return 
fDevice; }
+                       int                             Mode() const { return 
fMode; }
+                       bool                    IsReadOnly() const
+                                                               { return 
_IsReadOnly(fMode); }
+
+                       status_t                GetSize(off_t* _size, uint32* 
_blockSize = NULL);
+
+private:
+       static  bool                    _IsReadOnly(int mode)
+                                                               { return (mode 
& O_RWMASK) == O_RDONLY; }
+       static  bool                    _IsReadWrite(int mode)
+                                                               { return (mode 
& O_RWMASK) == O_RDWR; }
+
+                       int                             fDevice;
+                       int                             fMode;
+                       void*                   fBlockCache;
+};
+
+
+DeviceOpener::DeviceOpener(const char *device, int mode)
+       : fBlockCache(NULL)
+{
+       Open(device, mode);
+}
+
+
+DeviceOpener::DeviceOpener(int fd, int mode)
+       : fBlockCache(NULL)
+{
+       Open(fd, mode);
+}
+
+
+DeviceOpener::~DeviceOpener()
+{
+       if (fDevice >= 0) {
+               RemoveCache(false);
+               close(fDevice);
+       }
+}
+
+
+int
+DeviceOpener::Open(const char *device, int mode)
+{
+       fDevice = open(device, mode | O_NOCACHE);
+       if (fDevice < 0)
+               fDevice = errno;
+
+       if (fDevice < 0 && _IsReadWrite(mode)){
+               // try again to open read-only (don't rely on a specific error 
code)
+               return Open(device, O_RDONLY | O_NOCACHE);
+       }
+
+       if (fDevice >= 0) {
+               // opening succeeded
+               fMode = mode;
+               if (_IsReadWrite(mode)) {
+                       // check out if the device really allows for read/write 
access
+                       device_geometry geometry;
+                       if (!ioctl(fDevice, B_GET_GEOMETRY, &geometry)) {
+
+                               if (geometry.read_only) {
+                                       // reopen device read-only
+                                       close(fDevice);
+                                       return Open(device, O_RDONLY | 
O_NOCACHE);
+                               }
+                       }
+               }
+       }
+
+       return fDevice;
+}
+
+
+int
+DeviceOpener::Open(int fd, int mode)
+{
+       fDevice = dup(fd);
+       if (fDevice < 0)
+               return errno;
+
+       fMode = mode;
+
+       return fDevice;
+}
+
+
+void*
+DeviceOpener::InitCache(off_t numBlocks, uint32 blockSize)
+{
+       return fBlockCache = block_cache_create(fDevice, numBlocks, blockSize,
+                                                                               
        IsReadOnly());
+}
+
+
+void
+DeviceOpener::RemoveCache(bool allowWrites)
+{
+       if (fBlockCache == NULL)
+               return;
+
+       block_cache_delete(fBlockCache, allowWrites);
+       fBlockCache = NULL;
+}
+
+
+void
+DeviceOpener::Keep()
+{
+       fDevice = -1;
+}
+
+
+/*!    Returns the size of the device in bytes. It uses B_GET_GEOMETRY
+       to compute the size, or fstat() if that failed.
+*/
+status_t
+DeviceOpener::GetSize(off_t *_size, uint32 *_blockSize)
+{
+       device_geometry geometry;
+       if (ioctl(fDevice, B_GET_GEOMETRY, &geometry) < 0) {
+               // maybe it's just a file
+               struct stat stat;
+               if (fstat(fDevice, &stat) < 0)
+                       return B_ERROR;
+
+               if (_size)
+                       *_size = stat.st_size;
+               if (_blockSize)                         // that shouldn't cause 
us any problems
+                       *_blockSize = 512;
+
+               return B_OK;
+       }
+
+       if (_size) {
+               *_size = 1LL * geometry.head_count * geometry.cylinder_count
+                                       * geometry.sectors_per_track * 
geometry.bytes_per_sector;
+       }
+       if (_blockSize)
+               *_blockSize = geometry.bytes_per_sector;
+
+       return B_OK;
+}
+
+
+Volume::Volume(fs_volume *volume)
+    : fFSVolume(volume)
+{
+       fFlags = 0;
+       mutex_init(&fLock, "xfs volume");
+       TRACE("Volume::Volume() : Initialising volume");
+}
+
+
+Volume::~Volume()
+{
+       mutex_destroy(&fLock);
+       TRACE("Volume::Destructor : Removing Volume");
+}
+
+
+bool
+Volume::IsValidSuperBlock()
+{
+       return fSuperBlock.IsValid();
+}
+
+
+status_t
+Volume::Identify(int fd, XfsSuperBlock *superBlock)
+{
+
+       TRACE("Volume::Identify() : Identifying Volume in progress");
+
+       if (read_pos(fd, 0, superBlock, sizeof(XfsSuperBlock))
+               != sizeof(XfsSuperBlock))
+                       return B_IO_ERROR;
+
+       superBlock->SwapEndian();
+
+       if (!superBlock->IsValid()) {
+               ERROR("Volume::Identify(): Invalid Superblock!\n");
+               return B_BAD_VALUE;
+       }
+       return B_OK;
+}
+
+
+status_t
+Volume::Mount(const char *deviceName, uint32 flags)
+{
+       TRACE("Volume::Mount() : Mounting in progress");
+
+       flags |= B_MOUNT_READ_ONLY;
+
+       if ((flags & B_MOUNT_READ_ONLY) != 0) {
+               TRACE("Volume::Mount(): Read only\n");
+       } else {
+               TRACE("Volume::Mount(): Read write\n");
+       }
+
+       DeviceOpener opener(deviceName, (flags & B_MOUNT_READ_ONLY) != 0
+                                                                               
? O_RDONLY
+                                                                               
: O_RDWR);
+       fDevice = opener.Device();
+       if (fDevice < B_OK) {
+               ERROR("Volume::Mount(): couldn't open device\n");
+               return fDevice;
+       }
+
+       if (opener.IsReadOnly())
+               fFlags |= VOLUME_READ_ONLY;
+
+       // read the superblock
+       status_t status = Identify(fDevice, &fSuperBlock);
+       if (status != B_OK) {
+               ERROR("Volume::Mount(): Invalid super block!\n");
+               return B_BAD_VALUE;
+       }
+
+       TRACE("Volume::Mount(): Valid SuperBlock.\n");
+
+       // check if the device size is large enough to hold the file system
+       off_t diskSize;
+       if (opener.GetSize(&diskSize) != B_OK) {
+               ERROR("Volume:Mount() Unable to get diskSize");
+               return B_ERROR;
+       }
+
+       opener.Keep();
+       return B_OK;
+}
+
+
+status_t
+Volume::Unmount()
+{
+       TRACE("Volume::Unmount(): Unmounting");
+
+       TRACE("Volume::Unmount(): Closing device");
+       close(fDevice);
+
+       return B_OK;
+}
diff --git a/src/add-ons/kernel/file_systems/xfs/Volume.h 
b/src/add-ons/kernel/file_systems/xfs/Volume.h
new file mode 100644
index 0000000000..748eb10329
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/xfs/Volume.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+#ifndef _VOLUME_H_
+#define _VOLUME_H_
+
+#include "xfs.h"
+
+extern fs_volume_ops gxfsVolumeOps;
+enum volume_flags {
+       VOLUME_READ_ONLY        = 0x0001
+};
+
+
+class Volume {
+public:
+                                                               
Volume(fs_volume *volume);
+                                                               ~Volume();
+
+                       status_t                        Mount(const char 
*device, uint32 flags);
+                       status_t                        Unmount();
+                       status_t                        Initialize(int fd, 
const char *label,
+                                                                       uint32 
blockSize, uint32 sectorSize);
+
+                       bool                            IsValidSuperBlock();
+                       bool                            IsReadOnly() const
+                                                                       { 
return (fFlags & VOLUME_READ_ONLY) != 0; }
+
+                       dev_t                           ID() const
+                                                                       { 
return fFSVolume ? fFSVolume->id : -1; }
+                       fs_volume*                      FSVolume() const
+                                                                       { 
return fFSVolume; }
+                       char*                           Name()
+                                                                       { 
return fSuperBlock.Name(); }
+
+                       XfsSuperBlock&          SuperBlock() { return 
fSuperBlock; }
+                       int                                     Device() const 
{ return fDevice; }
+
+       static  status_t                        Identify(int fd, XfsSuperBlock 
*superBlock);
+
+       #if 0
+                       off_t                           NumBlocks() const
+                                                                       { 
return fSuperBlock.NumBlocks(); }
+
+                       off_t                           Root() const { return 
fSuperBlock.rootino; }
+
+       static  status_t                        Identify(int fd, SuperBlock 
*superBlock);
+       #endif
+
+protected:
+                       fs_volume*                      fFSVolume;
+                       int                                     fDevice;
+                       XfsSuperBlock           fSuperBlock;
+                       char                            fName[32];      /* 
filesystem name */
+                       
+                       uint32                          fDeviceBlockSize;
+                       mutex                           fLock;
+
+                       uint32                          fFlags;
+};
+
+#endif
\ No newline at end of file
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 905ad2752d..012e0806ce 100644
--- a/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp
+++ b/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp
@@ -1,14 +1,10 @@
 /*
- * Copyright 2020 Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * Copyright 2001-2017, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
  * All rights reserved. Distributed under the terms of the MIT License.
  */
 #include "system_dependencies.h"
-
-#ifdef TRACE_XFS
-#define TRACE(x...) dprintf("\33[34mxfs:\33[0m " x)
-#else
-#define TRACE(x...) ;
-#endif
+#include "Volume.h"
 
 
 struct identify_cookie
@@ -23,7 +19,7 @@ struct identify_cookie
 //!    xfs_io() callback hook
 static status_t
 iterative_io_get_vecs_hook(void *cookie, io_request *request, off_t offset,
-                                               size_t size, struct file_io_vec 
*vecs, size_t *_count)
+       size_t size, struct file_io_vec *vecs, size_t *_count)
 {
        return B_NOT_SUPPORTED;
 }
@@ -32,13 +28,15 @@ iterative_io_get_vecs_hook(void *cookie, io_request 
*request, off_t offset,
 //!    xfs_io() callback hook
 static status_t
 iterative_io_finished_hook(void *cookie, io_request *request, status_t status,
-                                                  bool partialTransfer, size_t 
bytesTransferred)
+       bool partialTransfer, size_t bytesTransferred)
 {
        return B_NOT_SUPPORTED;
 }
 
 
 //     #pragma mark - Scanning
+
+
 static float
 xfs_identify_partition(int fd, partition_data *partition, void **_cookie)
 {
@@ -62,18 +60,48 @@ xfs_free_identify_partition_cookie(partition_data 
*partition, void *_cookie)
 
 
 //     #pragma mark -
+
+
 static status_t
 xfs_mount(fs_volume *_volume, const char *device, uint32 flags,
-                 const char *args, ino_t *_rootID)
+       const char *args, ino_t *_rootID)
 {
-       return B_NOT_SUPPORTED;
+       TRACE("xfs_mount(): Trying to mount\n");
+
+       Volume *volume = new (std::nothrow) Volume(_volume);
+       if (volume == NULL)
+               return B_NO_MEMORY;
+
+       _volume->private_volume = volume;
+       _volume->ops = &gxfsVolumeOps;
+
+       status_t status = volume->Mount(device, flags);
+       if (status != B_OK) {
+               ERROR("Failed mounting the volume. Error: %s\n", 
strerror(status));
+               delete volume;
+               _volume->private_volume = NULL;
+               return status;
+       }
+
+/* Don't have Inodes yet */
+#if 0
+        *_rootID = volume->Root()->ID();
+#endif
+
+       return B_OK;
 }
 
 
 static status_t
 xfs_unmount(fs_volume *_volume)
 {
-       return B_NOT_SUPPORTED;
+       Volume* volume = (Volume*) _volume->private_volume;
+
+       status_t status = volume->Unmount();
+       delete volume;
+       
+       TRACE("xfs_unmount(): Deleted volume");
+       return status;
 }
 
 
@@ -86,9 +114,10 @@ xfs_read_fs_info(fs_volume *_volume, struct fs_info *info)
 
 //     #pragma mark -
 
+
 static status_t
 xfs_get_vnode(fs_volume *_volume, ino_t id, fs_vnode *_node, int *_type,
-                         uint32 *_flags, bool reenter)
+       uint32 *_flags, bool reenter)
 {
        return B_NOT_SUPPORTED;
 }
@@ -110,7 +139,7 @@ xfs_can_page(fs_volume *_volume, fs_vnode *_node, void 
*_cookie)
 
 static status_t
 xfs_read_pages(fs_volume *_volume, fs_vnode *_node, void *_cookie,
-                          off_t pos, const iovec *vecs, size_t count, size_t 
*_numBytes)
+       off_t pos, const iovec *vecs, size_t count, size_t *_numBytes)
 {
        return B_NOT_SUPPORTED;
 }
@@ -118,7 +147,7 @@ xfs_read_pages(fs_volume *_volume, fs_vnode *_node, void 
*_cookie,
 
 static status_t
 xfs_io(fs_volume *_volume, fs_vnode *_node, void *_cookie,
-          io_request *request)
+       io_request *request)
 {
        return B_NOT_SUPPORTED;
 }
@@ -126,7 +155,7 @@ xfs_io(fs_volume *_volume, fs_vnode *_node, void *_cookie,
 
 static status_t
 xfs_get_file_map(fs_volume *_volume, fs_vnode *_node, off_t offset,
-                                size_t size, struct file_io_vec *vecs, size_t 
*_count)
+       size_t size, struct file_io_vec *vecs, size_t *_count)
 {
        return B_NOT_SUPPORTED;
 }
@@ -134,9 +163,10 @@ xfs_get_file_map(fs_volume *_volume, fs_vnode *_node, 
off_t offset,
 
 //     #pragma mark -
 
+
 static status_t
 xfs_lookup(fs_volume *_volume, fs_vnode *_directory, const char *name,
-                  ino_t *_vnodeID)
+       ino_t *_vnodeID)
 {
        return B_NOT_SUPPORTED;
 }
@@ -144,7 +174,7 @@ xfs_lookup(fs_volume *_volume, fs_vnode *_directory, const 
char *name,
 
 static status_t
 xfs_ioctl(fs_volume *_volume, fs_vnode *_node, void *_cookie, uint32 cmd,
-                 void *buffer, size_t bufferLength)
+       void *buffer, size_t bufferLength)
 {
        return B_NOT_SUPPORTED;
 }
@@ -159,7 +189,7 @@ xfs_read_stat(fs_volume *_volume, fs_vnode *_node, struct 
stat *stat)
 
 static status_t
 xfs_open(fs_volume * /*_volume*/, fs_vnode *_node, int openMode,
-                void **_cookie)
+       void **_cookie)
 {
        return B_NOT_SUPPORTED;
 }
@@ -167,7 +197,7 @@ xfs_open(fs_volume * /*_volume*/, fs_vnode *_node, int 
openMode,
 
 static status_t
 xfs_read(fs_volume *_volume, fs_vnode *_node, void *_cookie, off_t pos,
-                void *buffer, size_t *_length)
+       void *buffer, size_t *_length)
 {
        return B_NOT_SUPPORTED;
 }
@@ -186,6 +216,7 @@ xfs_free_cookie(fs_volume *_volume, fs_vnode *_node, void 
*_cookie)
        return B_NOT_SUPPORTED;
 }
 
+
 static status_t
 xfs_access(fs_volume *_volume, fs_vnode *_node, int accessMode)
 {
@@ -195,7 +226,7 @@ xfs_access(fs_volume *_volume, fs_vnode *_node, int 
accessMode)
 
 static status_t
 xfs_read_link(fs_volume *_volume, fs_vnode *_node, char *buffer,
-                         size_t *_bufferSize)
+       size_t *_bufferSize)
 {
        return B_NOT_SUPPORTED;
 }
@@ -210,9 +241,10 @@ xfs_unlink(fs_volume *_volume, fs_vnode *_directory, const 
char *name)
 
 //     #pragma mark - Directory functions
 
+
 static status_t
 xfs_create_dir(fs_volume *_volume, fs_vnode *_directory, const char *name,
-                          int mode)
+       int mode)
 {
        return B_NOT_SUPPORTED;
 }
@@ -234,7 +266,7 @@ xfs_open_dir(fs_volume * /*_volume*/, fs_vnode *_node, void 
**_cookie)
 
 static status_t
 xfs_read_dir(fs_volume *_volume, fs_vnode *_node, void *_cookie,
-                        struct dirent *dirent, size_t bufferSize, uint32 *_num)
+       struct dirent *dirent, size_t bufferSize, uint32 *_num)
 {
        return B_NOT_SUPPORTED;
 }
@@ -249,7 +281,7 @@ xfs_rewind_dir(fs_volume * /*_volume*/, fs_vnode * 
/*node*/, void *_cookie)
 
 static status_t
 xfs_close_dir(fs_volume * /*_volume*/, fs_vnode * /*node*/,
-                         void * /*_cookie*/)
+       void * /*_cookie*/)
 {
        return B_NOT_SUPPORTED;
 }
@@ -285,7 +317,7 @@ xfs_free_attr_dir_cookie(fs_volume *_volume, fs_vnode 
*_node, void *_cookie)
 
 static status_t
 xfs_read_attr_dir(fs_volume *_volume, fs_vnode *_node,
-                                 void *_cookie, struct dirent *dirent, size_t 
bufferSize, uint32 *_num)
+       void *_cookie, struct dirent *dirent, size_t bufferSize, uint32 *_num)
 {
        return B_NOT_SUPPORTED;
 }
@@ -301,7 +333,7 @@ xfs_rewind_attr_dir(fs_volume *_volume, fs_vnode *_node, 
void *_cookie)
 /* attribute operations */
 static status_t
 xfs_create_attr(fs_volume *_volume, fs_vnode *_node,
-                               const char *name, uint32 type, int openMode, 
void **_cookie)
+       const char *name, uint32 type, int openMode, void **_cookie)
 {
        return B_NOT_SUPPORTED;
 }
@@ -309,7 +341,7 @@ xfs_create_attr(fs_volume *_volume, fs_vnode *_node,
 
 static status_t
 xfs_open_attr(fs_volume *_volume, fs_vnode *_node, const char *name,
-                         int openMode, void **_cookie)
+       int openMode, void **_cookie)
 {
        return B_NOT_SUPPORTED;
 }
@@ -317,15 +349,14 @@ xfs_open_attr(fs_volume *_volume, fs_vnode *_node, const 
char *name,
 
 static status_t
 xfs_close_attr(fs_volume *_volume, fs_vnode *_node,
-                          void *cookie)
+       void *cookie)
 {
        return B_NOT_SUPPORTED;
 }
 
 
 static status_t
-xfs_free_attr_cookie(fs_volume *_volume, fs_vnode *_node,
-                                        void *cookie)
+xfs_free_attr_cookie(fs_volume *_volume, fs_vnode *_node, void *cookie)
 {
        return B_NOT_SUPPORTED;
 }
@@ -333,7 +364,7 @@ xfs_free_attr_cookie(fs_volume *_volume, fs_vnode *_node,
 
 static status_t
 xfs_read_attr(fs_volume *_volume, fs_vnode *_node, void *_cookie,
-                         off_t pos, void *buffer, size_t *_length)
+       off_t pos, void *buffer, size_t *_length)
 {
        return B_NOT_SUPPORTED;
 }
@@ -341,7 +372,7 @@ xfs_read_attr(fs_volume *_volume, fs_vnode *_node, void 
*_cookie,
 
 static status_t
 xfs_write_attr(fs_volume *_volume, fs_vnode *_node, void *cookie,
-                          off_t pos, const void *buffer, size_t *length)
+       off_t pos, const void *buffer, size_t *length)
 {
        return B_NOT_SUPPORTED;
 }
@@ -349,7 +380,7 @@ xfs_write_attr(fs_volume *_volume, fs_vnode *_node, void 
*cookie,
 
 static status_t
 xfs_read_attr_stat(fs_volume *_volume, fs_vnode *_node,
-                                  void *_cookie, struct stat *stat)
+       void *_cookie, struct stat *stat)
 {
        return B_NOT_SUPPORTED;
 }
@@ -357,7 +388,7 @@ xfs_read_attr_stat(fs_volume *_volume, fs_vnode *_node,
 
 static status_t
 xfs_write_attr_stat(fs_volume *_volume, fs_vnode *_node,
-                                       void *cookie, const struct stat *stat, 
int statMask)
+       void *cookie, const struct stat *stat, int statMask)
 {
        return B_NOT_SUPPORTED;
 }
@@ -365,7 +396,7 @@ xfs_write_attr_stat(fs_volume *_volume, fs_vnode *_node,
 
 static status_t
 xfs_rename_attr(fs_volume *_volume, fs_vnode *fromVnode,
-                               const char *fromName, fs_vnode *toVnode, const 
char *toName)
+       const char *fromName, fs_vnode *toVnode, const char *toName)
 {
        return B_NOT_SUPPORTED;
 }
@@ -373,7 +404,7 @@ xfs_rename_attr(fs_volume *_volume, fs_vnode *fromVnode,
 
 static status_t
 xfs_remove_attr(fs_volume *_volume, fs_vnode *vnode,
-                               const char *name)
+       const char *name)
 {
        return B_NOT_SUPPORTED;
 }
@@ -388,7 +419,7 @@ xfs_get_supported_operations(partition_data *partition, 
uint32 mask)
 
 static status_t
 xfs_initialize(int fd, partition_id partitionID, const char *name,
-                       const char *parameterString, off_t partitionSize, 
disk_job_id job)
+       const char *parameterString, off_t partitionSize, disk_job_id job)
 {
        return B_NOT_SUPPORTED;
 }
@@ -396,7 +427,7 @@ xfs_initialize(int fd, partition_id partitionID, const char 
*name,
 
 static status_t
 xfs_uninitialize(int fd, partition_id partitionID, off_t partitionSize,
-                                uint32 blockSize, disk_job_id job)
+       uint32 blockSize, disk_job_id job)
 {
        return B_NOT_SUPPORTED;
 }
@@ -404,6 +435,7 @@ xfs_uninitialize(int fd, partition_id partitionID, off_t 
partitionSize,
 
 //     #pragma mark -
 
+
 static status_t
 xfs_std_ops(int32 op, ...)
 {
@@ -427,57 +459,59 @@ xfs_std_ops(int32 op, ...)
        }
 }
 
+
 fs_volume_ops gxfsVolumeOps = {
        &xfs_unmount,
        &xfs_read_fs_info,
-       NULL, // write_fs_info()
-       NULL, // fs_sync,
+       NULL,                           // write_fs_info()
+       NULL,                           // fs_sync,
        &xfs_get_vnode,
 };
 
+
 fs_vnode_ops gxfsVnodeOps = {
        /* vnode operations */
        &xfs_lookup,
-       NULL, // xfs_get_vnode_name - optional, and we can't do better than the
-                 // fallback implementation, so leave as NULL.
+       NULL,                           // xfs_get_vnode_name- optional, and we 
can't do better
+                                               // than the fallback 
implementation, so leave as NULL.
        &xfs_put_vnode,
-       NULL, // xfs_remove_vnode,
+       NULL,                           // xfs_remove_vnode,
 
        /* VM file access */
        &xfs_can_page,
        &xfs_read_pages,
-       NULL, // xfs_write_pages,
+       NULL,                           // xfs_write_pages,
 
-       &xfs_io, // io()
-       NULL,   // cancel_io()
+       &xfs_io,                        // io()
+       NULL,                           // cancel_io()
 
        &xfs_get_file_map,
 
        &xfs_ioctl,
        NULL,
-       NULL, // fs_select
-       NULL, // fs_deselect
-       NULL, // fs_fsync,
+       NULL,                           // fs_select
+       NULL,                           // fs_deselect
+       NULL,                           // fs_fsync,
 
        &xfs_read_link,
-       NULL, // fs_create_symlink,
+       NULL,                           // fs_create_symlink,
 
-       NULL, // fs_link,
+       NULL,                           // fs_link,
        &xfs_unlink,
-       NULL, // fs_rename,
+       NULL,                           // fs_rename,
 
        &xfs_access,
        &xfs_read_stat,
-       NULL, // fs_write_stat,
-       NULL, // fs_preallocate
+       NULL,                           // fs_write_stat,
+       NULL,                           // fs_preallocate
 
        /* file operations */
-       NULL, // fs_create,
+       NULL,                           // fs_create,
        &xfs_open,
        &xfs_close,
        &xfs_free_cookie,
        &xfs_read,
-       NULL, //        fs_write,
+       NULL,                           // fs_write,
 
        /* directory operations */
        &xfs_create_dir,
@@ -509,18 +543,19 @@ fs_vnode_ops gxfsVnodeOps = {
 };
 
 
-static file_system_module_info sxfsFileSystem = {
+static
+file_system_module_info sxfsFileSystem = {
        {
                "file_systems/xfs" B_CURRENT_FS_API_VERSION,
                0,
                xfs_std_ops,
        },
 
-       "xfs",                     // short_name
-       "XFS File System", // pretty_name
+       "xfs",                          // short_name
+       "XFS File System",      // pretty_name
 
        // DDM flags
-       0| B_DISK_SYSTEM_SUPPORTS_INITIALIZING 
|B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME
+       0 |B_DISK_SYSTEM_SUPPORTS_INITIALIZING 
|B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME
        //      | B_DISK_SYSTEM_SUPPORTS_WRITING
        ,
 
@@ -528,29 +563,29 @@ static file_system_module_info sxfsFileSystem = {
        xfs_identify_partition,
        xfs_scan_partition,
        xfs_free_identify_partition_cookie,
-       NULL, // free_partition_content_cookie()
+       NULL,                           // free_partition_content_cookie()
 
        &xfs_mount,
 
        /* capability querying operations */
        &xfs_get_supported_operations,
 
-       NULL, // validate_resize
-       NULL, // validate_move
-       NULL, // validate_set_content_name
-       NULL, // validate_set_content_parameters
-       NULL, // validate_initialize,
+       NULL,                           // validate_resize
+       NULL,                           // validate_move
+       NULL,                           // validate_set_content_name
+       NULL,                           // validate_set_content_parameters
+       NULL,                           // validate_initialize,
 
        /* shadow partition modification */
-       NULL, // shadow_changed
+       NULL,                           // shadow_changed
 
        /* writing */
-       NULL, // defragment
-       NULL, // repair
-       NULL, // resize
-       NULL, // move
-       NULL, // set_content_name
-       NULL, // set_content_parameters
+       NULL,                           // defragment
+       NULL,                           // repair
+       NULL,                           // resize
+       NULL,                           // move
+       NULL,                           // set_content_name
+       NULL,                           // set_content_parameters
        xfs_initialize,
        xfs_uninitialize};
 
diff --git a/src/add-ons/kernel/file_systems/xfs/system_dependencies.h 
b/src/add-ons/kernel/file_systems/xfs/system_dependencies.h
index cb49f9f164..a42dc02a51 100644
--- a/src/add-ons/kernel/file_systems/xfs/system_dependencies.h
+++ b/src/add-ons/kernel/file_systems/xfs/system_dependencies.h
@@ -1,29 +1,30 @@
 /*
- * Copyright 2020 Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * Copyright 2007, Ingo Weinhold, bonefish@xxxxxxxxxxxxxxx.
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
  * All rights reserved. Distributed under the terms of the MIT License.
  */
 
-#ifndef _SYSTE_DEPENDENCIES_H
-#define _SYSTEM_DEPENDENCIES_H
+#ifndef _SYSTEM_DEPENDENCIES_H_
+#define _SYSTEM_DEPENDENCIES_H_
 
 #ifdef FS_SHELL
 // This needs to be included before the fs_shell wrapper
 
 #include "fssh_api_wrapper.h"
 #include "fssh_auto_deleter.h"
-#include <new>
+#include "Debug.h"
 
 #ifdef __cplusplus
-extern "C" {
+extern "C"
+{
 #endif
-typedef unsigned char uuid_t[16];
+       typedef unsigned char uuid_t[16];
 
-void uuid_generate(uuid_t out);        
+       void uuid_generate(uuid_t out);
 #ifdef __cplusplus
 }
 #endif
 
-
 #else // !FS_SHELL
 
 #include <AutoDeleter.h>
@@ -44,6 +45,7 @@ void uuid_generate(uuid_t out);
 #include <fs_interface.h>
 #include <fs_query.h>
 #include <fs_volume.h>
+#include "Debug.h"
 #include <Drivers.h>
 #include <KernelExport.h>
 #include <NodeMonitor.h>
diff --git a/src/add-ons/kernel/file_systems/xfs/xfs.cpp 
b/src/add-ons/kernel/file_systems/xfs/xfs.cpp
new file mode 100644
index 0000000000..616290c070
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/xfs/xfs.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+#include "xfs.h"
+
+
+bool
+XfsSuperBlock::IsValid()
+{
+       if (sb_magicnum != XFS_SB_MAGIC) return false;
+
+       return true;
+}
+
+
+uint32
+XfsSuperBlock::BlockSize()
+{
+       return sb_blocksize;
+}
+
+
+uint32
+XfsSuperBlock::Size()
+{
+       return XFS_SB_MAXSIZE;
+}
+
+
+char*
+XfsSuperBlock::Name()
+{
+       return sb_fname;
+}
+
+
+void
+XfsSuperBlock::SwapEndian()
+{
+       sb_magicnum             =       B_BENDIAN_TO_HOST_INT32(sb_magicnum);
+       sb_blocksize    =       B_BENDIAN_TO_HOST_INT32(sb_blocksize);
+       sb_dblocks              =       B_BENDIAN_TO_HOST_INT64(sb_dblocks);
+       sb_rblocks              =       B_BENDIAN_TO_HOST_INT64(sb_rblocks);
+       sb_rextents             =       B_BENDIAN_TO_HOST_INT64(sb_rextents);
+       sb_logstart             =       B_BENDIAN_TO_HOST_INT64(sb_logstart);
+       sb_rootino              =       B_BENDIAN_TO_HOST_INT64(sb_rootino);
+       sb_rbmino               =       B_BENDIAN_TO_HOST_INT64(sb_rbmino);
+       sb_rsumino              =       B_BENDIAN_TO_HOST_INT64(sb_rsumino);
+       sb_rextsize             =       B_BENDIAN_TO_HOST_INT32(sb_rextsize);
+       sb_agblocks             =       B_BENDIAN_TO_HOST_INT32(sb_agblocks);
+       sb_agcount              =       B_BENDIAN_TO_HOST_INT32(sb_agcount);
+       sb_rbmblocks    =       B_BENDIAN_TO_HOST_INT32(sb_rbmblocks);
+       sb_logblocks    =       B_BENDIAN_TO_HOST_INT32(sb_logblocks);
+       sb_versionnum   =       B_BENDIAN_TO_HOST_INT16(sb_versionnum);
+       sb_sectsize             =       B_BENDIAN_TO_HOST_INT16(sb_sectsize);
+       sb_inodesize    =       B_BENDIAN_TO_HOST_INT16(sb_inodesize);
+       sb_inopblock    =       B_BENDIAN_TO_HOST_INT16(sb_inopblock);
+       sb_icount               =       B_BENDIAN_TO_HOST_INT64(sb_icount);
+       sb_ifree                =       B_BENDIAN_TO_HOST_INT64(sb_ifree);
+       sb_fdblocks             =       B_BENDIAN_TO_HOST_INT64(sb_fdblocks);
+       sb_frextents    =       B_BENDIAN_TO_HOST_INT64(sb_frextents);
+       sb_uquotino             =       B_BENDIAN_TO_HOST_INT64(sb_uquotino);
+       sb_gquotino             =       B_BENDIAN_TO_HOST_INT64(sb_gquotino);
+       sb_qflags               =       B_BENDIAN_TO_HOST_INT16(sb_qflags);
+       sb_inoalignmt   =       B_BENDIAN_TO_HOST_INT32(sb_inoalignmt);
+       sb_unit                 =       B_BENDIAN_TO_HOST_INT32(sb_unit);
+       sb_width                =       B_BENDIAN_TO_HOST_INT32(sb_width);
+       sb_logsectsize  =       B_BENDIAN_TO_HOST_INT16(sb_logsectsize);
+       sb_logsunit             =       B_BENDIAN_TO_HOST_INT32(sb_logsunit);
+       sb_features2    =       B_BENDIAN_TO_HOST_INT32(sb_features2);
+}
diff --git a/src/add-ons/kernel/file_systems/xfs/xfs.h 
b/src/add-ons/kernel/file_systems/xfs/xfs.h
new file mode 100644
index 0000000000..a1d6e6fabc
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/xfs/xfs.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+#ifndef _XFS_SB_H_
+#define _XFS_SB_H_
+
+#include "system_dependencies.h"
+#include "xfs_types.h"
+
+#define XFS_SB_MAGIC 0x58465342 /* Identifies XFS. "XFSB" */
+#define XFS_SB_MAXSIZE 512
+
+
+
+/*     Version 4 superblock definition */
+class XfsSuperBlock
+{
+public:
+
+                       bool                    IsValid();
+                       char*                   Name();
+                       uint32                  BlockSize();
+                       uint32                  Size();
+                       void                    SwapEndian();
+
+private:
+
+                       uint32                  sb_magicnum;
+                       uint32                  sb_blocksize;
+                       xfs_rfsblock_t  sb_dblocks;
+                       xfs_rfsblock_t  sb_rblocks;
+                       xfs_rtblock_t   sb_rextents;
+                       uuid_t                  sb_uuid;
+                       xfs_fsblock_t   sb_logstart;
+                       xfs_ino_t               sb_rootino;
+                       xfs_ino_t               sb_rbmino;
+                       xfs_ino_t               sb_rsumino;
+                       xfs_agblock_t   sb_rextsize;
+                       xfs_agblock_t   sb_agblocks;
+                       xfs_agnumber_t  sb_agcount;
+                       xfs_extlen_t    sb_rbmblocks;
+                       xfs_extlen_t    sb_logblocks;
+                       uint16                  sb_versionnum;
+                       uint16                  sb_sectsize;
+                       uint16                  sb_inodesize;
+                       uint16                  sb_inopblock;
+                       char                    sb_fname[12];
+                       uint8                   sb_blocklog;
+                       uint8                   sb_sectlog;
+                       uint8                   sb_inodelog;
+                       uint8                   sb_inopblog;
+                       uint8                   sb_agblklog;
+                       uint8                   sb_rextslog;
+                       uint8                   sb_inprogress;
+                       uint8                   sb_imax_pct;
+                       uint64                  sb_icount;
+                       uint64                  sb_ifree;
+                       uint64                  sb_fdblocks;
+                       uint64                  sb_frextents;
+                       xfs_ino_t               sb_uquotino;
+                       xfs_ino_t               sb_gquotino;
+                       uint16                  sb_qflags;
+                       uint8                   sb_flags;
+                       uint8                   sb_shared_vn;
+                       xfs_extlen_t    sb_inoalignmt;
+                       uint32                  sb_unit;
+                       uint32                  sb_width;
+                       uint8                   sb_dirblklog;
+                       uint8                   sb_logsectlog;
+                       uint16                  sb_logsectsize;
+                       uint32                  sb_logsunit;
+                       uint32                  sb_features2;
+};
+
+/*
+ These flags indicate features introduced over time.
+
+ If the lower nibble of sb_versionnum >=4 then the following features are
+ checked. If it's equal to 5, it's version 5.
+*/
+
+#define XFS_SB_VERSION_ATTRBIT 0x0010
+#define XFS_SB_VERSION_NLINKBIT 0x0020
+#define XFS_SB_VERSION_QUOTABIT 0x0040
+#define XFS_SB_VERSION_ALIGNBIT 0x0080
+#define XFS_SB_VERSION_DALIGNBIT 0x0100
+#define XFS_SB_VERSION_SHAREDBIT 0x0200
+#define XFS_SB_VERSION_LOGV2BIT 0x0400
+#define XFS_SB_VERSION_SECTORBIT 0x0800
+#define XFS_SB_VERSION_EXTFLGBIT 0x1000
+#define XFS_SB_VERSION_DIRV2BIT 0x2000
+#define XFS_SB_VERSION_MOREBITSBIT 0x4000
+
+/*
+Superblock quota flags - sb_qflags
+*/
+#define XFS_UQUOTA_ACCT 0x0001
+#define XFS_UQUOTA_ENFD 0x0002
+#define XFS_UQUOTA_CHKD 0x0004
+#define XFS_PQUOTA_ACCT 0x0008
+#define XFS_OQUOTA_ENFD 0x0010
+#define XFS_OQUOTA_CHKD 0x0020
+#define XFS_GQUOTA_ACCT 0x0040
+#define XFS_GQUOTA_ENFD 0x0080
+#define XFS_GQUOTA_CHKD 0x0100
+#define XFS_PQUOTA_ENFD 0x0200
+#define XFS_PQUOTA_CHKD 0x0400
+
+/*
+       Superblock flags - sb_flags
+*/
+#define XFS_SBF_READONLY 0x1
+
+/*
+       Extended v4 Superblock flags - sb_features2
+*/
+
+#define XFS_SB_VERSION2_LAZYSBCOUNTBIT                                         
                                        \
+       0x0001  /*update global free space                                      
                                                \
+                       and inode on clean unmount*/
+#define XFS_SB_VERSION2_ATTR2BIT                                               
                                                \
+       0x0002  /* optimises the inode layout of ext-attr */
+#define XFS_SB_VERSION2_PARENTBIT 0x0004       /* Parent pointers */
+#define XFS_SB_VERSION2_PROJID32BIT 0x0008     /* 32-bit project id */
+#define XFS_SB_VERSION2_CRCBIT 0x0010          /* Metadata checksumming */
+#define XFS_SB_VERSION2_FTYPE 0x0020
+#endif
\ No newline at end of file
diff --git a/src/add-ons/kernel/file_systems/xfs/xfs_types.h 
b/src/add-ons/kernel/file_systems/xfs/xfs_types.h
new file mode 100644
index 0000000000..a2940bfcfc
--- /dev/null
+++ b/src/add-ons/kernel/file_systems/xfs/xfs_types.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2020, Shubham Bhagat, shubhambhagat111@xxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _XFS_TYPES_H_
+#define _XFS_TYPES_H_
+
+#include "system_dependencies.h"
+
+/*
+Reference documentation: 
+https://mirrors.edge.kernel.org/pub/linux/utils/fs/xfs/docs
+/xfs_filesystem_structure.pdf
+
+Chapter 5: Common XFS types            (Page 8)
+*/
+
+
+typedef uint64 xfs_ino_t;              // absolute inode number
+typedef int64 xfs_off_t;               // file offset
+typedef int64 xfs_daddr_t;             // device address
+typedef uint32 xfs_agnumber_t; // Allocation Group (AG) number
+typedef uint32 xfs_agblock_t;  // AG relative block number
+typedef uint32 xfs_extlen_t;   // extent length in blocks
+typedef int32 xfs_extnum_t;            // number of extends in a file
+typedef int16 xfs_aextnum_t;   // number of extents in an attribute fork
+typedef uint32 xfs_dablk_t;    // block number for directories
+                                                               // and extended 
attributes
+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_filblks_t;  // block count for a file
+typedef int64 xfs_fsize_t;             // byte size of a file
+
+// typedef unsigned char uuid_t[16];
+
+#endif
\ No newline at end of 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 cefcc77947..93db59e162 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
@@ -38,15 +38,17 @@ UseHeaders [ FDirName $(HAIKU_TOP) headers private ] : true 
;
 UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
 
 local xfsSource =
+       xfs.cpp
+       Volume.cpp
        kernel_interface.cpp
 ;
 
-BuildPlatformMergeObject <build>xfs.o : $(xfsSource) ;
+BuildPlatformMergeObject <build>xfs_shell.o : $(xfsSource) ;
 
 BuildPlatformMain <build>xfs_shell
        :
        :
-       <build>xfs.o
+       <build>xfs_shell.o
        <build>fs_shell.a $(HOST_LIBSUPC++) $(HOST_LIBSTDC++)
        $(HOST_LIBROOT) $(fsShellCommandLibs)
 ;
@@ -54,7 +56,7 @@ BuildPlatformMain <build>xfs_shell
 BuildPlatformMain <build>xfs_fuse
        :
        :
-       <build>xfs.o
+       <build>xfs_shell.o
        <build>fuse_module.a
        $(HOST_LIBSUPC++) $(HOST_LIBSTDC++)
        $(HOST_STATIC_LIBROOT) $(fsShellCommandLibs) fuse


Other related posts:

  • » [haiku-commits] haiku: hrev53956 - src/add-ons/kernel/file_systems/xfs - Adrien Destugues