xref: /haiku/src/add-ons/kernel/file_systems/btrfs/Inode.h (revision 69f814cded60c5f977a61a2ab747e4456323e6f2)
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 			mode_t		Mode() const { return fNode.Mode(); }
50 			off_t		Size() const { return fNode.Size(); }
51 			uid_t		UserID() const { return fNode.UserID(); }
52 			gid_t		GroupID() const { return fNode.GroupID(); }
53 			void		GetChangeTime(struct timespec& timespec) const
54 							{ fNode.GetChangeTime(timespec); }
55 			void		GetModificationTime(struct timespec& timespec) const
56 							{ fNode.GetModificationTime(timespec); }
57 			void		GetCreationTime(struct timespec& timespec) const
58 							{ fNode.GetCreationTime(timespec); }
59 			void		GetAccessTime(struct timespec& timespec) const
60 							{ fNode.GetCreationTime(timespec); }
61 
62 			Volume*		GetVolume() const { return fVolume; }
63 
64 			status_t	FindBlock(off_t logical, off_t& physical,
65 							off_t* _length = NULL);
66 			status_t	ReadAt(off_t pos, uint8* buffer, size_t* length);
67 			status_t	FillGapWithZeros(off_t start, off_t end);
68 
69 			void*		FileCache() const { return fCache; }
70 			void*		Map() const { return fMap; }
71 
72 			status_t	FindParent(ino_t* id);
73 			uint64		FindNextIndex(BTree::Path* path) const;
74 	static	Inode*		Create(Transaction& transaction, ino_t id,
75 							Inode* parent, int32 mode, uint64 size = 0,
76 							uint64 flags = 0);
77 			status_t	Insert(Transaction& transaction, BTree::Path* path);
78 			status_t	Remove(Transaction& transaction, BTree::Path* path);
79 			status_t	MakeReference(Transaction& transaction, BTree::Path* path,
80 							Inode* parent, const char* name, int32 mode);
81 			status_t	Dereference(Transaction& transaction, BTree::Path* path,
82 							ino_t parentID, const char* name);
83 private:
84 						Inode(Volume* volume);
85 						Inode(const Inode&);
86 						Inode& operator=(const Inode&);
87 							// no implementation
88 
89 			uint64		_NumBlocks();
90 private:
91 
92 			rw_lock		fLock;
93 			::Volume*	fVolume;
94 			ino_t		fID;
95 			void*		fCache;
96 			void*		fMap;
97 			status_t	fInitStatus;
98 			btrfs_inode fNode;
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