ufs2: Implementing read_stat function and fs_info
Change-Id: I337c53c017f00f480af7ac94a5774b39eb5255db Reviewed-on: https://review.haiku-os.org/c/haiku/+/2773 Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
parent
69c8afc98e
commit
589de4799a
@ -12,6 +12,13 @@
|
||||
|
||||
#define UFS2_ROOT ((ino_t)2)
|
||||
|
||||
|
||||
struct timeval32
|
||||
{
|
||||
int tv_sec, tv_usec;
|
||||
};
|
||||
|
||||
|
||||
struct ufs2_inode {
|
||||
u_int16_t fileMode;
|
||||
int16_t linkCount;
|
||||
@ -20,10 +27,10 @@ struct ufs2_inode {
|
||||
int32_t inodeBlockSize;
|
||||
int64_t size;
|
||||
int64_t byteHeld;
|
||||
int64_t accessTime;
|
||||
int64_t modifiedTime;
|
||||
int64_t changeTime;
|
||||
int64_t createTime;
|
||||
struct timeval32 accessTime;
|
||||
struct timeval32 modifiedTime;
|
||||
struct timeval32 changeTime;
|
||||
struct timeval32 createTime;
|
||||
/* time in nano seconds */
|
||||
int32_t nsModifiedTime;
|
||||
int32_t nsAccessTime;
|
||||
@ -57,6 +64,20 @@ struct ufs2_inode {
|
||||
int64_t unused2;
|
||||
int64_t unused3;
|
||||
|
||||
|
||||
static void _DecodeTime(struct timespec& timespec, timeval32 time)
|
||||
{
|
||||
timespec.tv_sec = time.tv_sec;
|
||||
timespec.tv_nsec = time.tv_usec * 1000;
|
||||
}
|
||||
void GetAccessTime(struct timespec& timespec) const
|
||||
{ _DecodeTime(timespec, accessTime); }
|
||||
void GetChangeTime(struct timespec& timespec) const
|
||||
{ _DecodeTime(timespec, changeTime); }
|
||||
void GetModificationTime(struct timespec& timespec) const
|
||||
{ _DecodeTime(timespec, modifiedTime); }
|
||||
void GetCreationTime(struct timespec& timespec) const
|
||||
{ _DecodeTime(timespec, createTime); }
|
||||
};
|
||||
|
||||
class Inode {
|
||||
@ -86,14 +107,14 @@ class Inode {
|
||||
off_t Size() const { return fNode.size; }
|
||||
uid_t UserID() const { return fNode.userId; }
|
||||
gid_t GroupID() const { return fNode.groupId; }
|
||||
/*void GetChangeTime(struct timespec& timespec) const
|
||||
void GetChangeTime(struct timespec& timespec) const
|
||||
{ fNode.GetChangeTime(timespec); }
|
||||
void GetModificationTime(struct timespec& timespec) const
|
||||
{ fNode.GetModificationTime(timespec); }
|
||||
void GetCreationTime(struct timespec& timespec) const
|
||||
{ fNode.GetCreationTime(timespec); }
|
||||
void GetAccessTime(struct timespec& timespec) const
|
||||
{ fNode.GetCreationTime(timespec); }*/
|
||||
{ fNode.GetAccessTime(timespec); }
|
||||
|
||||
Volume* GetVolume() const { return fVolume; }
|
||||
|
||||
@ -119,6 +140,7 @@ private:
|
||||
::Volume* fVolume;
|
||||
ino_t fID;
|
||||
void* fCache;
|
||||
bool fHasNanoTime;
|
||||
void* fMap;
|
||||
status_t fInitStatus;
|
||||
ufs2_inode fNode;
|
||||
|
@ -27,6 +27,16 @@ ufs2_super_block::IsValid()
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
Volume::Name() const
|
||||
{
|
||||
if (fSuperBlock.fs_volname[0])
|
||||
return fSuperBlock.fs_volname;
|
||||
|
||||
return fName;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Volume::IsValidSuperBlock()
|
||||
{
|
||||
|
@ -18,31 +18,34 @@ class Inode;
|
||||
|
||||
class Volume {
|
||||
public:
|
||||
Volume(fs_volume* volume);
|
||||
~Volume();
|
||||
Volume(fs_volume* volume);
|
||||
~Volume();
|
||||
|
||||
status_t Mount(const char* device, uint32 flags);
|
||||
status_t Unmount();
|
||||
status_t Initialize(int fd, const char* name,
|
||||
uint32 blockSize, uint32 flags);
|
||||
status_t Mount(const char* device, uint32 flags);
|
||||
status_t Unmount();
|
||||
status_t Initialize(int fd, const char* name,
|
||||
uint32 blockSize, uint32 flags);
|
||||
|
||||
bool IsValidSuperBlock();
|
||||
bool IsValidInodeBlock(off_t block) const;
|
||||
bool IsReadOnly() const;
|
||||
fs_volume* FSVolume() const { return fFSVolume; }
|
||||
dev_t ID() const
|
||||
{ return fFSVolume ? fFSVolume->id : -1; }
|
||||
ufs2_super_block& SuperBlock() { return fSuperBlock; }
|
||||
status_t LoadSuperBlock();
|
||||
static status_t Identify(int fd, ufs2_super_block* superBlock);
|
||||
bool IsValidSuperBlock();
|
||||
bool IsValidInodeBlock(off_t block) const;
|
||||
bool IsReadOnly() const
|
||||
{ return (fFlags & VOLUME_READ_ONLY) != 0; }
|
||||
const char* Name() const;
|
||||
fs_volume* FSVolume() const { return fFSVolume; }
|
||||
dev_t ID() const
|
||||
{ return fFSVolume ? fFSVolume->id : -1; }
|
||||
ufs2_super_block& SuperBlock() { return fSuperBlock; }
|
||||
status_t LoadSuperBlock();
|
||||
static status_t Identify(int fd, ufs2_super_block* superBlock);
|
||||
|
||||
private:
|
||||
fs_volume* fFSVolume;
|
||||
int fDevice;
|
||||
ufs2_super_block fSuperBlock;
|
||||
mutex fLock;
|
||||
uint32 fFlags;
|
||||
Inode* fRootNode;
|
||||
fs_volume* fFSVolume;
|
||||
int fDevice;
|
||||
ufs2_super_block fSuperBlock;
|
||||
mutex fLock;
|
||||
uint32 fFlags;
|
||||
Inode* fRootNode;
|
||||
char fName[32];
|
||||
};
|
||||
|
||||
#endif // VOLUME_H
|
||||
|
@ -9,7 +9,9 @@
|
||||
#include "Volume.h"
|
||||
#include "Inode.h"
|
||||
|
||||
#ifdef TRACE_ufs2
|
||||
|
||||
#define TRACE_UFS2
|
||||
#ifdef TRACE_UFS2
|
||||
#define TRACE(x...) dprintf("\33[34mufs2:\33[0m " x)
|
||||
#else
|
||||
#define TRACE(x...) ;
|
||||
@ -107,7 +109,18 @@ ufs2_unmount(fs_volume *_volume)
|
||||
static status_t
|
||||
ufs2_read_fs_info(fs_volume *_volume, struct fs_info *info)
|
||||
{
|
||||
return B_NOT_SUPPORTED;
|
||||
Volume* volume = (Volume*)_volume->private_volume;
|
||||
|
||||
// File system flags
|
||||
info->flags = B_FS_IS_PERSISTENT
|
||||
| (volume->IsReadOnly() ? B_FS_IS_READONLY : 0);
|
||||
info->io_size = 65536;
|
||||
info->block_size = volume->SuperBlock().fs_sbsize;
|
||||
info->total_blocks = volume->SuperBlock().fs_size;
|
||||
|
||||
strlcpy(info->volume_name, volume->Name(), sizeof(info->volume_name));
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -198,7 +211,29 @@ ufs2_ioctl(fs_volume *_volume, fs_vnode *_node, void *_cookie, uint32 cmd,
|
||||
static status_t
|
||||
ufs2_read_stat(fs_volume *_volume, fs_vnode *_node, struct stat *stat)
|
||||
{
|
||||
return B_NOT_SUPPORTED;
|
||||
TRACE("Reading stat...\n");
|
||||
Inode* inode = (Inode*)_node->private_node;
|
||||
stat->st_dev = inode->GetVolume()->ID();
|
||||
stat->st_ino = inode->ID();
|
||||
// TODO handle hardlinks which will have nlink > 1. Maybe linkCount in inode
|
||||
// structure may help?
|
||||
stat->st_nlink = 1;
|
||||
stat->st_blksize = 65536;
|
||||
|
||||
stat->st_uid = inode->UserID();
|
||||
stat->st_gid = inode->GroupID();
|
||||
stat->st_mode = inode->Mode();
|
||||
stat->st_type = 0;
|
||||
|
||||
inode->GetAccessTime(stat->st_atim);
|
||||
/* inode->GetModificationTime(stat->st_mtim);*/
|
||||
inode->GetChangeTime(stat->st_ctim);
|
||||
inode->GetCreationTime(stat->st_crtim);
|
||||
|
||||
stat->st_size = inode->Size();
|
||||
stat->st_blocks = (inode->Size() + 511) / 512;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -301,7 +301,7 @@ struct ufs2_super_block {
|
||||
int8_t fs_ronly; /* mounted read-only flag */
|
||||
int8_t fs_old_flags; /* old FS_ flags */
|
||||
u_char fs_fsmnt[MAXMNTLEN]; /* name mounted on */
|
||||
u_char fs_volname[MAXVOLLEN]; /* volume name */
|
||||
char fs_volname[MAXVOLLEN]; /* volume name */
|
||||
u_int64_t fs_swuid; /* system-wide uid */
|
||||
int32_t fs_pad; /* due to alignment of fs_swuid */
|
||||
/* these fields retain the current block allocation info */
|
||||
|
Loading…
Reference in New Issue
Block a user