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 Inode { 26 public: 27 Inode(Volume* volume, ino_t id); 28 Inode(Volume* volume, ino_t id, 29 const btrfs_inode& item); 30 ~Inode(); 31 32 status_t InitCheck(); 33 34 ino_t ID() const { return fID; } 35 36 rw_lock* Lock() { return& fLock; } 37 38 status_t UpdateNodeFromDisk(); 39 40 bool IsDirectory() const 41 { return S_ISDIR(Mode()); } 42 bool IsFile() const 43 { return S_ISREG(Mode()); } 44 bool IsSymLink() const 45 { return S_ISLNK(Mode()); } 46 status_t CheckPermissions(int accessMode) const; 47 48 mode_t Mode() const { return fNode.Mode(); } 49 off_t Size() const { return fNode.Size(); } 50 uid_t UserID() const { return fNode.UserID(); } 51 gid_t GroupID() const { return fNode.GroupID(); } 52 void GetChangeTime(struct timespec& timespec) const 53 { fNode.GetChangeTime(timespec); } 54 void GetModificationTime(struct timespec& timespec) const 55 { fNode.GetModificationTime(timespec); } 56 void GetCreationTime(struct timespec& timespec) const 57 { fNode.GetCreationTime(timespec); } 58 void GetAccessTime(struct timespec& timespec) const 59 { fNode.GetCreationTime(timespec); } 60 61 Volume* GetVolume() const { return fVolume; } 62 63 status_t FindBlock(off_t logical, off_t& physical, 64 off_t* _length = NULL); 65 status_t ReadAt(off_t pos, uint8* buffer, size_t* length); 66 status_t FillGapWithZeros(off_t start, off_t end); 67 68 void* FileCache() const { return fCache; } 69 void* Map() const { return fMap; } 70 71 status_t FindParent(ino_t* id); 72 uint64 FindNextIndex(BTree::Path* path) const; 73 static Inode* Create(Transaction& transaction, ino_t id, 74 Inode* parent, int32 mode, uint64 size = 0, 75 uint64 flags = 0); 76 status_t Insert(Transaction& transaction, BTree::Path* path); 77 status_t Remove(Transaction& transaction, BTree::Path* path); 78 status_t MakeReference(Transaction& transaction, BTree::Path* path, 79 Inode* parent, const char* name, int32 mode); 80 status_t Dereference(Transaction& transaction, BTree::Path* path, 81 ino_t parentID, const char* name); 82 private: 83 Inode(Volume* volume); 84 Inode(const Inode&); 85 Inode& operator=(const Inode&); 86 // no implementation 87 88 uint64 _NumBlocks(); 89 private: 90 91 rw_lock fLock; 92 ::Volume* fVolume; 93 ino_t fID; 94 void* fCache; 95 void* fMap; 96 status_t fInitStatus; 97 btrfs_inode fNode; 98 }; 99 100 101 // The Vnode class provides a convenience layer upon get_vnode(), so that 102 // you don't have to call put_vnode() anymore, which may make code more 103 // readable in some cases 104 105 class Vnode { 106 public: 107 Vnode(Volume* volume, ino_t id) 108 : 109 fInode(NULL) 110 { 111 SetTo(volume, id); 112 } 113 114 Vnode() 115 : 116 fStatus(B_NO_INIT), 117 fInode(NULL) 118 { 119 } 120 121 ~Vnode() 122 { 123 Unset(); 124 } 125 126 status_t InitCheck() 127 { 128 return fStatus; 129 } 130 131 void Unset() 132 { 133 if (fInode != NULL) { 134 put_vnode(fInode->GetVolume()->FSVolume(), fInode->ID()); 135 fInode = NULL; 136 fStatus = B_NO_INIT; 137 } 138 } 139 140 status_t SetTo(Volume* volume, ino_t id) 141 { 142 Unset(); 143 144 return fStatus = get_vnode(volume->FSVolume(), id, (void**)&fInode); 145 } 146 147 status_t Get(Inode** _inode) 148 { 149 *_inode = fInode; 150 return fStatus; 151 } 152 153 void Keep() 154 { 155 TRACEI("Vnode::Keep()\n"); 156 fInode = NULL; 157 } 158 159 private: 160 status_t fStatus; 161 Inode* fInode; 162 }; 163 164 165 #endif // INODE_H 166