BTRFS: Implement Create() that allocate new Inode object.

Signed-off-by: Augustin Cavalier <[email protected]>
This commit is contained in:
hyche
2017-12-10 11:03:01 -05:00
committed by Augustin Cavalier
parent 20185bb9c3
commit 36a24fb34e
4 changed files with 73 additions and 0 deletions
@@ -43,6 +43,22 @@ Inode::Inode(Volume* volume, ino_t id)
}
Inode::Inode(Volume* volume, ino_t id, const btrfs_inode& item)
:
fVolume(volume),
fID(id),
fCache(NULL),
fMap(NULL),
fInitStatus(B_OK),
fNode(item)
{
if (!IsDirectory() && !IsSymLink()) {
fCache = file_cache_create(fVolume->ID(), ID(), Size());
fMap = file_map_create(fVolume->ID(), ID(), Size());
}
}
Inode::Inode(Volume* volume)
:
fVolume(volume),
@@ -94,6 +110,49 @@ Inode::UpdateNodeFromDisk()
}
/*
* Create new Inode object with inode_item
*/
Inode*
Inode::Create(Transaction& transaction, ino_t id, Inode* parent, int32 mode,
uint64 size, uint64 flags)
{
TRACE("Inode::Create() id % " B_PRIu64 " mode %" B_PRId32 " flags %"
B_PRIu64"\n", id, flags, mode);
Volume* volume = parent->GetVolume();
uint64 nbytes = size; // allocated size
if (size > volume->MaxInlineSize())
nbytes = (size / volume->SectorSize() + 1) * volume->SectorSize();
btrfs_inode inode;
inode.generation = B_HOST_TO_LENDIAN_INT64(transaction.SystemID());
inode.transaction_id = B_HOST_TO_LENDIAN_INT64(transaction.SystemID());
inode.size = B_HOST_TO_LENDIAN_INT64(size);
inode.nbytes = B_HOST_TO_LENDIAN_INT64(nbytes);
inode.blockgroup = 0; // normal inode only
inode.num_links = B_HOST_TO_LENDIAN_INT32(1);
inode.uid = B_HOST_TO_LENDIAN_INT32(geteuid());
inode.gid = B_HOST_TO_LENDIAN_INT32(parent ? parent->GroupID() : getegid());
inode.mode = B_HOST_TO_LENDIAN_INT32(mode);;
inode.rdev = 0; // normal file only
inode.flags = B_HOST_TO_LENDIAN_INT64(flags);
inode.sequence = 0; // incremented each time mtime value is changed
uint64 now = real_time_clock_usecs();
struct timespec timespec;
timespec.tv_sec = now / 1000000;
timespec.tv_nsec = (now % 1000000) * 1000;
btrfs_inode::SetTime(inode.access_time, timespec);
btrfs_inode::SetTime(inode.creation_time, timespec);
btrfs_inode::SetTime(inode.change_time, timespec);
btrfs_inode::SetTime(inode.modification_time, timespec);
return new Inode(volume, id, inode);
}
status_t
Inode::CheckPermissions(int accessMode) const
{
@@ -9,6 +9,7 @@
#include "btrfs.h"
#include "Volume.h"
#include "Journal.h"
//#define TRACE_BTRFS
@@ -22,6 +23,8 @@
class Inode {
public:
Inode(Volume* volume, ino_t id);
Inode(Volume* volume, ino_t id,
const btrfs_inode& item);
~Inode();
status_t InitCheck();
@@ -64,6 +67,9 @@ public:
void* Map() const { return fMap; }
status_t FindParent(ino_t* id);
static Inode* Create(Transaction& transaction, ino_t id,
Inode* parent, int32 mode, uint64 size = 0,
uint64 flags = 0);
private:
Inode(Volume* volume);
Inode(const Inode&);
@@ -71,6 +77,7 @@ private:
// no implementation
uint64 _NumBlocks();
private:
rw_lock fLock;
::Volume* fVolume;
@@ -46,6 +46,8 @@ public:
BTree* RootTree() const { return fRootTree; }
uint32 SectorSize() const { return fSectorSize; }
uint32 MaxInlineSize() const
{ return fSectorSize / 2; }
uint32 BlockSize() const { return fBlockSize; }
Chunk* SystemChunk() const { return fChunk; }
Journal* GetJournal() const { return fJournal; }
@@ -303,6 +303,11 @@ struct btrfs_inode {
{ _DecodeTime(timespec, modification_time); }
void GetCreationTime(struct timespec& timespec) const
{ _DecodeTime(timespec, creation_time); }
static void SetTime(btrfs_timespec& time, const struct timespec& timespec)
{
time.seconds = B_HOST_TO_LENDIAN_INT64(timespec.tv_sec);
time.nanoseconds = B_HOST_TO_LENDIAN_INT64(timespec.tv_nsec);
}
} _PACKED;