From e3e93916b77a8e495a1819c4458862b7b0c50dfc Mon Sep 17 00:00:00 2001 From: CruxBox Date: Mon, 1 Jun 2020 15:30:04 +0530 Subject: [PATCH] xfs: get_vnode and read_stat hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch aimed at implementing the get_vnode and read_stat hook. read_stat seems to work well, get_vnode can be checked after working on dir. Change-Id: I487915b7e8f6ee6f97349b0c638676d5389cd2df Reviewed-on: https://review.haiku-os.org/c/haiku/+/2859 Reviewed-by: Chế Vũ Gia Hy Reviewed-by: Adrien Destugues --- src/add-ons/kernel/file_systems/xfs/Inode.cpp | 85 +++++++++++++++++++ src/add-ons/kernel/file_systems/xfs/Inode.h | 44 ++++++---- .../file_systems/xfs/kernel_interface.cpp | 73 +++++++++++++--- 3 files changed, 173 insertions(+), 29 deletions(-) diff --git a/src/add-ons/kernel/file_systems/xfs/Inode.cpp b/src/add-ons/kernel/file_systems/xfs/Inode.cpp index 9f5ff1aebf..61823765fd 100644 --- a/src/add-ons/kernel/file_systems/xfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/xfs/Inode.cpp @@ -1,3 +1,8 @@ +/* +* Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com +* All rights reserved. Distributed under the terms of the MIT License. +*/ + #include "Inode.h" @@ -31,6 +36,20 @@ xfs_inode::SwapEndian() } +xfs_rfsblock_t +xfs_inode::NoOfBlocks() const +{ + return di_nblocks; +} + + +xfs_fsize_t +xfs_inode::Size() const +{ + return di_size; +} + + mode_t xfs_inode::Mode() { @@ -38,6 +57,72 @@ xfs_inode::Mode() } +uint32 +xfs_inode::UserId() +{ + return di_uid; +} + + +uint32 +xfs_inode::GroupId() +{ + return di_gid; +} + + +void +xfs_inode::GetModificationTime(struct timespec& stamp) +{ + stamp.tv_sec = di_mtime.t_sec; + stamp.tv_nsec = di_mtime.t_nsec; +} + + +void +xfs_inode::GetAccessTime(struct timespec& stamp) +{ + stamp.tv_sec = di_atime.t_sec; + stamp.tv_nsec = di_atime.t_nsec; +} + + +void +xfs_inode::GetChangeTime(struct timespec& stamp) +{ + stamp.tv_sec = di_ctime.t_sec; + stamp.tv_nsec = di_ctime.t_nsec; +} + + +uint32 +xfs_inode::NLink() +{ + return di_nlink; +} + + +int8 +xfs_inode::Version() +{ + return di_version; +} + + +uint16 +xfs_inode::Flags() +{ + return di_flags; +} + + +int8 +xfs_inode::Format() +{ + return di_format; +} + + Inode::Inode(Volume* volume, xfs_ino_t id) { fVolume = volume; diff --git a/src/add-ons/kernel/file_systems/xfs/Inode.h b/src/add-ons/kernel/file_systems/xfs/Inode.h index e6c3e848d4..5241c291ea 100644 --- a/src/add-ons/kernel/file_systems/xfs/Inode.h +++ b/src/add-ons/kernel/file_systems/xfs/Inode.h @@ -55,10 +55,18 @@ typedef enum xfs_dinode_fmt typedef struct xfs_inode { void SwapEndian(); - void DirIsV2(); //TODO + int8 Version(); //TODO mode_t Mode(); - void GetModificationTime(); + void GetModificationTime(struct timespec& timestamp); + void GetChangeTime(struct timespec& timestamp); + void GetAccessTime(struct timespec& timestamp); int8 Format(); // The format of the inode + xfs_fsize_t Size() const; // TODO + xfs_rfsblock_t NoOfBlocks() const; + uint32 NLink(); + uint16 Flags(); + uint32 UserId(); + uint32 GroupId(); uint16 di_magic; uint16 di_mode; // uses standard S_Ixxx @@ -97,6 +105,9 @@ class Inode Inode(Volume* volume, xfs_ino_t id); ~Inode(); bool InitCheck(); + + xfs_ino_t ID() const { return fId; } + bool IsDirectory() const { return S_ISDIR(Mode()); } @@ -114,27 +125,28 @@ class Inode bool IsLocal() { return Format() == XFS_DINODE_FMT_LOCAL; } - #if 0 - int32 Flags() const { return fNode->Flags(); } + uint32 NLink() { return fNode->NLink(); } - off_t Size() const { return fNode->Size(); } + int8 Version() { return fNode->Version(); } - void GetChangeTime(xfs_timestamp_t *stamp) const - { fNode.GetChangeTime(stamp, fHasExtraAttributes); } + xfs_fsize_t Size() const { return fNode->Size(); } - void GetModificationTime(xfs_timestamp_t *stamp) const - { fNode.GetModificationTime(stamp, - fHasExtraAttributes); } + xfs_rfsblock_t NoOfBlocks() const { return fNode->NoOfBlocks(); } - void GetCreationTime(xfs_timestamp_t *stamp) const - { fNode.GetCreationTime(stamp, - fHasExtraAttributes); } + int16 Flags() const { return fNode->Flags(); } - void GetAccessTime(xfs_timestamp_t *stamp) const - { fNode.GetAccessTime(stamp, fHasExtraAttributes); } - #endif + void GetChangeTime(struct timespec& timestamp) const + { fNode->GetChangeTime(timestamp); } + + void GetModificationTime(struct timespec& timestamp) const + { fNode->GetModificationTime(timestamp); } + + void GetAccessTime(struct timespec& timestamp) const + { fNode->GetAccessTime(timestamp); } private: + uint32 UserId() { return fNode->UserId(); } + uint32 GroupId() { return fNode->GroupId(); } status_t GetFromDisk(); xfs_inode_t* fNode; 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 94ac7912d6..fef7c6f4da 100644 --- a/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/xfs/kernel_interface.cpp @@ -1,9 +1,10 @@ /* - * Copyright 2001-2017, Axel Dörfler, axeld@pinc-software.de. - * Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com - * All rights reserved. Distributed under the terms of the MIT License. - */ +* Copyright 2001-2017, Axel Dörfler, axeld@pinc-software.de. +* Copyright 2020, Shubham Bhagat, shubhambhagat111@yahoo.com +* All rights reserved. Distributed under the terms of the MIT License. +*/ #include "system_dependencies.h" +#include "Inode.h" #include "Volume.h" @@ -12,8 +13,8 @@ struct identify_cookie { /* super_block_struct super_block; - * No structure yet implemented. - */ + * No structure yet implemented. + */ int cookie; }; @@ -85,11 +86,17 @@ xfs_mount(fs_volume *_volume, const char *device, uint32 flags, return status; } -/* Don't have Inodes yet */ -#if 0 - *_rootID = volume->Root()->ID(); -#endif + //publish the root inode + Inode* rootInode = new(std::nothrow) Inode(volume, volume->Root()); + if (rootInode != NULL) { + status = publish_vnode(volume->FSVolume(), volume->Root(), + (void*)rootInode, &gxfsVnodeOps, rootInode->Mode(), 0); + if (status!=B_OK) + return B_BAD_VALUE; + } + + *_rootID = volume->Root(); return B_OK; } @@ -101,7 +108,6 @@ xfs_unmount(fs_volume *_volume) status_t status = volume->Unmount(); delete volume; - TRACE("xfs_unmount(): Deleted volume"); return status; } @@ -134,7 +140,26 @@ static status_t xfs_get_vnode(fs_volume *_volume, ino_t id, fs_vnode *_node, int *_type, uint32 *_flags, bool reenter) { - return B_NOT_SUPPORTED; + Volume* volume = (Volume*)_volume->private_volume; + + Inode* inode = new(std::nothrow) Inode(volume, id); + + if (inode == NULL) + return B_NO_MEMORY; + + status_t status = inode->InitCheck(); + if (status == false) { + delete inode; + ERROR("get_vnode: InitCheck() failed. Error: %s\n", strerror(status)); + return B_NO_INIT; + } + + _node->private_node = inode; + _node->ops = &gxfsVnodeOps; + *_type = inode->Mode(); + *_flags = 0; + + return B_OK; } @@ -198,7 +223,29 @@ xfs_ioctl(fs_volume *_volume, fs_vnode *_node, void *_cookie, uint32 cmd, static status_t xfs_read_stat(fs_volume *_volume, fs_vnode *_node, struct stat *stat) { - return B_NOT_SUPPORTED; + Inode* inode = (Inode*)_node->private_node; + stat->st_dev = inode->GetVolume()->ID(); + stat->st_ino = inode->ID(); + stat->st_nlink = 1; + stat->st_blksize = XFS_IO_SIZE; + + stat->st_uid = inode->UserId(); + stat->st_gid = inode->GroupId(); + stat->st_mode = inode->Mode(); + stat->st_type = 0; // TODO + + stat->st_size = inode->GetVolume()->InodeSize(); + stat->st_blocks = inode->NoOfBlocks(); + + inode->GetAccessTime(stat->st_atim); + inode->GetModificationTime(stat->st_mtim); + inode->GetChangeTime(stat->st_ctim); + + /* TODO: Can we obtain the Creation Time in v4 system? */ + inode->GetChangeTime(stat->st_crtim); + + return B_OK; + }