* Copyright 2017, ChαΊΏ VΕ© Gia Hy, cvghy116@gmail.com.
* Copyright 2011, JΓ©rΓ΄me Duval, korli@users.berlios.de.
* Copyright 2008, Axel DΓΆrfler, axeld@pinc-software.de.
* This file may be used under the terms of the MIT License.
*/
#ifndef INODE_H
#define INODE_H
#include "btrfs.h"
#include "Volume.h"
#include "Journal.h"
#include "BTree.h"
#ifdef TRACE_BTRFS
# define TRACEI(x...) dprintf("\33[34mbtrfs:\33[0m " x)
#else
# define TRACEI(x...) ;
#endif
class Inode {
public:
Inode(Volume* volume, ino_t id);
Inode(Volume* volume, ino_t id,
const btrfs_inode& item);
~Inode();
status_t InitCheck();
ino_t ID() const { return fID; }
rw_lock* Lock() { return& fLock; }
status_t UpdateNodeFromDisk();
bool IsDirectory() const
{ return S_ISDIR(Mode()); }
bool IsFile() const
{ return S_ISREG(Mode()); }
bool IsSymLink() const
{ return S_ISLNK(Mode()); }
status_t CheckPermissions(int accessMode) const;
btrfs_inode& Node() { return fNode; }
mode_t Mode() const { return fNode.Mode(); }
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
{ 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); }
Volume* GetVolume() const { return fVolume; }
status_t FindBlock(off_t logical, off_t& physical,
off_t* _length = NULL);
status_t ReadAt(off_t pos, uint8* buffer, size_t* length);
status_t FillGapWithZeros(off_t start, off_t end);
void* FileCache() const { return fCache; }
void* Map() const { return fMap; }
status_t FindParent(ino_t* id);
uint64 FindNextIndex(BTree::Path* path) const;
static Inode* Create(Transaction& transaction, ino_t id,
Inode* parent, int32 mode, uint64 size = 0,
uint64 flags = 0);
status_t Insert(Transaction& transaction, BTree::Path* path);
status_t Remove(Transaction& transaction, BTree::Path* path);
status_t MakeReference(Transaction& transaction, BTree::Path* path,
Inode* parent, const char* name, int32 mode);
status_t Dereference(Transaction& transaction, BTree::Path* path,
ino_t parentID, const char* name);
private:
Inode(Volume* volume);
Inode(const Inode&);
Inode& operator=(const Inode&);
uint64 _NumBlocks();
private:
rw_lock fLock;
::Volume* fVolume;
ino_t fID;
void* fCache;
void* fMap;
status_t fInitStatus;
btrfs_inode fNode;
};
* you don't have to call put_vnode() anymore, which may make code more
* readable in some cases
*/
class Vnode {
public:
Vnode(Volume* volume, ino_t id)
:
fInode(NULL)
{
SetTo(volume, id);
}
Vnode()
:
fStatus(B_NO_INIT),
fInode(NULL)
{
}
~Vnode()
{
Unset();
}
status_t InitCheck()
{
return fStatus;
}
void Unset()
{
if (fInode != NULL) {
put_vnode(fInode->GetVolume()->FSVolume(), fInode->ID());
fInode = NULL;
fStatus = B_NO_INIT;
}
}
status_t SetTo(Volume* volume, ino_t id)
{
Unset();
return fStatus = get_vnode(volume->FSVolume(), id, (void**)&fInode);
}
status_t Get(Inode** _inode)
{
*_inode = fInode;
return fStatus;
}
void Keep()
{
TRACEI("Vnode::Keep()\n");
fInode = NULL;
}
private:
status_t fStatus;
Inode* fInode;
};
#endif