1 /* 2 * Copyright 2017, Chế Vũ Gia Hy, cvghy116@gmail.com. 3 * Copyright 2011, Jérôme Duval, korli@users.berlios.de. 4 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. 5 * This file may be used under the terms of the MIT License. 6 */ 7 #ifndef INODE_H 8 #define INODE_H 9 10 11 #include "btrfs.h" 12 #include "Volume.h" 13 #include "Journal.h" 14 #include "BTree.h" 15 16 17 //#define TRACE_BTRFS 18 #ifdef TRACE_BTRFS 19 # define TRACEI(x...) dprintf("\33[34mbtrfs:\33[0m " x) 20 #else 21 # define TRACEI(x...) ; 22 #endif 23 24 25 //! Class used for in-memory representation of inodes 26 class Inode { 27 public: 28 Inode(Volume* volume, ino_t id); 29 Inode(Volume* volume, ino_t id, 30 const btrfs_inode& item); 31 ~Inode(); 32 33 status_t InitCheck(); 34 35 ino_t ID() const { return fID; } 36 37 rw_lock* Lock() { return& fLock; } 38 39 status_t UpdateNodeFromDisk(); 40 41 bool IsDirectory() const 42 { return S_ISDIR(Mode()); } 43 bool IsFile() const 44 { return S_ISREG(Mode()); } 45 bool IsSymLink() const 46 { return S_ISLNK(Mode()); } 47 status_t CheckPermissions(int accessMode) const; 48 49 btrfs_inode& Node() { return fNode; } 50 mode_t Mode() const { return fNode.Mode(); } 51 off_t Size() const { return fNode.Size(); } 52 uid_t UserID() const { return fNode.UserID(); } 53 gid_t GroupID() const { return fNode.GroupID(); } 54 void GetChangeTime(struct timespec& timespec) const 55 { fNode.GetChangeTime(timespec); } 56 void GetModificationTime(struct timespec& timespec) const 57 { fNode.GetModificationTime(timespec); } 58 void GetCreationTime(struct timespec& timespec) const 59 { fNode.GetCreationTime(timespec); } 60 void GetAccessTime(struct timespec& timespec) const 61 { fNode.GetCreationTime(timespec); } 62 63 Volume* GetVolume() const { return fVolume; } 64 65 status_t FindBlock(off_t logical, off_t& physical, 66 off_t* _length = NULL); 67 status_t ReadAt(off_t pos, uint8* buffer, size_t* length); 68 status_t FillGapWithZeros(off_t start, off_t end); 69 70 void* FileCache() const { return fCache; } 71 void* Map() const { return fMap; } 72 73 status_t FindParent(ino_t* id); 74 uint64 FindNextIndex(BTree::Path* path) const; 75 static Inode* Create(Transaction& transaction, ino_t id, 76 Inode* parent, int32 mode, uint64 size = 0, 77 uint64 flags = 0); 78 status_t Insert(Transaction& transaction, BTree::Path* path); 79 status_t Remove(Transaction& transaction, BTree::Path* path); 80 status_t MakeReference(Transaction& transaction, BTree::Path* path, 81 Inode* parent, const char* name, int32 mode); 82 status_t Dereference(Transaction& transaction, BTree::Path* path, 83 ino_t parentID, const char* name); 84 private: 85 Inode(Volume* volume); 86 Inode(const Inode&); 87 Inode& operator=(const Inode&); 88 // no implementation 89 90 uint64 _NumBlocks(); 91 private: 92 93 rw_lock fLock; 94 ::Volume* fVolume; 95 ino_t fID; 96 void* fCache; 97 void* fMap; 98 status_t fInitStatus; 99 btrfs_inode fNode; 100 }; 101 102 /*!The Vnode class provides a convenience layer upon get_vnode(), so that 103 * you don't have to call put_vnode() anymore, which may make code more 104 * readable in some cases 105 */ 106 class Vnode { 107 public: 108 Vnode(Volume* volume, ino_t id) 109 : 110 fInode(NULL) 111 { 112 SetTo(volume, id); 113 } 114 115 Vnode() 116 : 117 fStatus(B_NO_INIT), 118 fInode(NULL) 119 { 120 } 121 122 ~Vnode() 123 { 124 Unset(); 125 } 126 127 status_t InitCheck() 128 { 129 return fStatus; 130 } 131 132 void Unset() 133 { 134 if (fInode != NULL) { 135 put_vnode(fInode->GetVolume()->FSVolume(), fInode->ID()); 136 fInode = NULL; 137 fStatus = B_NO_INIT; 138 } 139 } 140 141 status_t SetTo(Volume* volume, ino_t id) 142 { 143 Unset(); 144 145 return fStatus = get_vnode(volume->FSVolume(), id, (void**)&fInode); 146 } 147 148 status_t Get(Inode** _inode) 149 { 150 *_inode = fInode; 151 return fStatus; 152 } 153 154 void Keep() 155 { 156 TRACEI("Vnode::Keep()\n"); 157 fInode = NULL; 158 } 159 160 private: 161 status_t fStatus; 162 Inode* fInode; 163 }; 164 165 166 #endif // INODE_H 167