diff --git a/src/add-ons/kernel/file_systems/btrfs/Inode.cpp b/src/add-ons/kernel/file_systems/btrfs/Inode.cpp index 173fe190ed..bb3b49c775 100644 --- a/src/add-ons/kernel/file_systems/btrfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/btrfs/Inode.cpp @@ -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 { diff --git a/src/add-ons/kernel/file_systems/btrfs/Inode.h b/src/add-ons/kernel/file_systems/btrfs/Inode.h index 003baf4322..29c106d1c0 100644 --- a/src/add-ons/kernel/file_systems/btrfs/Inode.h +++ b/src/add-ons/kernel/file_systems/btrfs/Inode.h @@ -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; diff --git a/src/add-ons/kernel/file_systems/btrfs/Volume.h b/src/add-ons/kernel/file_systems/btrfs/Volume.h index 11b4debc3a..6ed1d3c027 100644 --- a/src/add-ons/kernel/file_systems/btrfs/Volume.h +++ b/src/add-ons/kernel/file_systems/btrfs/Volume.h @@ -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; } diff --git a/src/add-ons/kernel/file_systems/btrfs/btrfs.h b/src/add-ons/kernel/file_systems/btrfs/btrfs.h index f8b3accf47..2567c3b61d 100644 --- a/src/add-ons/kernel/file_systems/btrfs/btrfs.h +++ b/src/add-ons/kernel/file_systems/btrfs/btrfs.h @@ -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;