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