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)
|
#define UFS2_ROOT ((ino_t)2)
|
||||||
|
|
||||||
|
|
||||||
|
struct timeval32
|
||||||
|
{
|
||||||
|
int tv_sec, tv_usec;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ufs2_inode {
|
struct ufs2_inode {
|
||||||
u_int16_t fileMode;
|
u_int16_t fileMode;
|
||||||
int16_t linkCount;
|
int16_t linkCount;
|
||||||
@ -20,10 +27,10 @@ struct ufs2_inode {
|
|||||||
int32_t inodeBlockSize;
|
int32_t inodeBlockSize;
|
||||||
int64_t size;
|
int64_t size;
|
||||||
int64_t byteHeld;
|
int64_t byteHeld;
|
||||||
int64_t accessTime;
|
struct timeval32 accessTime;
|
||||||
int64_t modifiedTime;
|
struct timeval32 modifiedTime;
|
||||||
int64_t changeTime;
|
struct timeval32 changeTime;
|
||||||
int64_t createTime;
|
struct timeval32 createTime;
|
||||||
/* time in nano seconds */
|
/* time in nano seconds */
|
||||||
int32_t nsModifiedTime;
|
int32_t nsModifiedTime;
|
||||||
int32_t nsAccessTime;
|
int32_t nsAccessTime;
|
||||||
@ -57,6 +64,20 @@ struct ufs2_inode {
|
|||||||
int64_t unused2;
|
int64_t unused2;
|
||||||
int64_t unused3;
|
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 {
|
class Inode {
|
||||||
@ -86,14 +107,14 @@ class Inode {
|
|||||||
off_t Size() const { return fNode.size; }
|
off_t Size() const { return fNode.size; }
|
||||||
uid_t UserID() const { return fNode.userId; }
|
uid_t UserID() const { return fNode.userId; }
|
||||||
gid_t GroupID() const { return fNode.groupId; }
|
gid_t GroupID() const { return fNode.groupId; }
|
||||||
/*void GetChangeTime(struct timespec& timespec) const
|
void GetChangeTime(struct timespec& timespec) const
|
||||||
{ fNode.GetChangeTime(timespec); }
|
{ fNode.GetChangeTime(timespec); }
|
||||||
void GetModificationTime(struct timespec& timespec) const
|
void GetModificationTime(struct timespec& timespec) const
|
||||||
{ fNode.GetModificationTime(timespec); }
|
{ fNode.GetModificationTime(timespec); }
|
||||||
void GetCreationTime(struct timespec& timespec) const
|
void GetCreationTime(struct timespec& timespec) const
|
||||||
{ fNode.GetCreationTime(timespec); }
|
{ fNode.GetCreationTime(timespec); }
|
||||||
void GetAccessTime(struct timespec& timespec) const
|
void GetAccessTime(struct timespec& timespec) const
|
||||||
{ fNode.GetCreationTime(timespec); }*/
|
{ fNode.GetAccessTime(timespec); }
|
||||||
|
|
||||||
Volume* GetVolume() const { return fVolume; }
|
Volume* GetVolume() const { return fVolume; }
|
||||||
|
|
||||||
@ -119,6 +140,7 @@ private:
|
|||||||
::Volume* fVolume;
|
::Volume* fVolume;
|
||||||
ino_t fID;
|
ino_t fID;
|
||||||
void* fCache;
|
void* fCache;
|
||||||
|
bool fHasNanoTime;
|
||||||
void* fMap;
|
void* fMap;
|
||||||
status_t fInitStatus;
|
status_t fInitStatus;
|
||||||
ufs2_inode fNode;
|
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
|
bool
|
||||||
Volume::IsValidSuperBlock()
|
Volume::IsValidSuperBlock()
|
||||||
{
|
{
|
||||||
|
@ -18,31 +18,34 @@ class Inode;
|
|||||||
|
|
||||||
class Volume {
|
class Volume {
|
||||||
public:
|
public:
|
||||||
Volume(fs_volume* volume);
|
Volume(fs_volume* volume);
|
||||||
~Volume();
|
~Volume();
|
||||||
|
|
||||||
status_t Mount(const char* device, uint32 flags);
|
status_t Mount(const char* device, uint32 flags);
|
||||||
status_t Unmount();
|
status_t Unmount();
|
||||||
status_t Initialize(int fd, const char* name,
|
status_t Initialize(int fd, const char* name,
|
||||||
uint32 blockSize, uint32 flags);
|
uint32 blockSize, uint32 flags);
|
||||||
|
|
||||||
bool IsValidSuperBlock();
|
bool IsValidSuperBlock();
|
||||||
bool IsValidInodeBlock(off_t block) const;
|
bool IsValidInodeBlock(off_t block) const;
|
||||||
bool IsReadOnly() const;
|
bool IsReadOnly() const
|
||||||
fs_volume* FSVolume() const { return fFSVolume; }
|
{ return (fFlags & VOLUME_READ_ONLY) != 0; }
|
||||||
dev_t ID() const
|
const char* Name() const;
|
||||||
{ return fFSVolume ? fFSVolume->id : -1; }
|
fs_volume* FSVolume() const { return fFSVolume; }
|
||||||
ufs2_super_block& SuperBlock() { return fSuperBlock; }
|
dev_t ID() const
|
||||||
status_t LoadSuperBlock();
|
{ return fFSVolume ? fFSVolume->id : -1; }
|
||||||
static status_t Identify(int fd, ufs2_super_block* superBlock);
|
ufs2_super_block& SuperBlock() { return fSuperBlock; }
|
||||||
|
status_t LoadSuperBlock();
|
||||||
|
static status_t Identify(int fd, ufs2_super_block* superBlock);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
fs_volume* fFSVolume;
|
fs_volume* fFSVolume;
|
||||||
int fDevice;
|
int fDevice;
|
||||||
ufs2_super_block fSuperBlock;
|
ufs2_super_block fSuperBlock;
|
||||||
mutex fLock;
|
mutex fLock;
|
||||||
uint32 fFlags;
|
uint32 fFlags;
|
||||||
Inode* fRootNode;
|
Inode* fRootNode;
|
||||||
|
char fName[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VOLUME_H
|
#endif // VOLUME_H
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
#include "Volume.h"
|
#include "Volume.h"
|
||||||
#include "Inode.h"
|
#include "Inode.h"
|
||||||
|
|
||||||
#ifdef TRACE_ufs2
|
|
||||||
|
#define TRACE_UFS2
|
||||||
|
#ifdef TRACE_UFS2
|
||||||
#define TRACE(x...) dprintf("\33[34mufs2:\33[0m " x)
|
#define TRACE(x...) dprintf("\33[34mufs2:\33[0m " x)
|
||||||
#else
|
#else
|
||||||
#define TRACE(x...) ;
|
#define TRACE(x...) ;
|
||||||
@ -107,7 +109,18 @@ ufs2_unmount(fs_volume *_volume)
|
|||||||
static status_t
|
static status_t
|
||||||
ufs2_read_fs_info(fs_volume *_volume, struct fs_info *info)
|
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
|
static status_t
|
||||||
ufs2_read_stat(fs_volume *_volume, fs_vnode *_node, struct stat *stat)
|
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_ronly; /* mounted read-only flag */
|
||||||
int8_t fs_old_flags; /* old FS_ flags */
|
int8_t fs_old_flags; /* old FS_ flags */
|
||||||
u_char fs_fsmnt[MAXMNTLEN]; /* name mounted on */
|
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 */
|
u_int64_t fs_swuid; /* system-wide uid */
|
||||||
int32_t fs_pad; /* due to alignment of fs_swuid */
|
int32_t fs_pad; /* due to alignment of fs_swuid */
|
||||||
/* these fields retain the current block allocation info */
|
/* these fields retain the current block allocation info */
|
||||||
|
Loading…
Reference in New Issue
Block a user