xref: /haiku/src/add-ons/kernel/file_systems/btrfs/Inode.h (revision 1a76488fc88584bf66b9751d7fb9b6527ac20d87)
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