1/*
2 * Copyright 2012 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Pawe�� Dziepak, pdziepak@quarnos.org
7 */
8#ifndef INODE_H
9#define INODE_H
10
11
12#include "DirectoryCache.h"
13#include "MetadataCache.h"
14#include "NFS4Inode.h"
15#include "OpenState.h"
16
17
18class Delegation;
19
20class Inode : public NFS4Inode {
21public:
22	static			status_t	CreateInode(FileSystem* fs, const FileInfo& fi,
23									Inode** inode);
24	virtual						~Inode();
25
26	inline			ino_t		ID() const;
27	inline			mode_t		Type() const;
28	virtual			const char*	Name() const;
29	inline			FileSystem*	GetFileSystem() const;
30
31	inline			void		SetOpenState(OpenState* state);
32
33	inline			void*		FileCache();
34					status_t	RevalidateFileCache();
35
36	inline			uint64		MaxFileSize();
37
38	inline			uint64		Change();
39	inline			bool		Dirty();
40
41	inline			OpenState*	GetOpenState();
42
43					void		SetDelegation(Delegation* delegation);
44					void		RecallDelegation(bool truncate = false);
45					void		RecallReadDelegation();
46
47					status_t	LookUp(const char* name, ino_t* id);
48
49					status_t	Access(int mode);
50
51					status_t	Commit();
52					status_t	SyncAndCommit(bool force = false);
53
54					status_t	CreateObject(const char* name, const char* path,
55									int mode, FileType type, ino_t* id);
56
57					status_t	CreateLink(const char* name, const char* path,
58									int mode, ino_t* id);
59
60					status_t	Link(Inode* dir, const char* name);
61					status_t	Remove(const char* name, FileType type,
62									ino_t* id = NULL);
63	static			status_t	Rename(Inode* from, Inode* to,
64									const char* fromName, const char* toName,
65									bool attribute = false, ino_t* id = NULL,
66									ino_t* oldID = NULL);
67
68					status_t	Stat(struct stat* st,
69									OpenAttrCookie* attr = NULL);
70					status_t	WriteStat(const struct stat* st, uint32 mask,
71									OpenAttrCookie* attr = NULL);
72
73					status_t	Create(const char* name, int mode, int perms,
74									OpenFileCookie* cookie,
75									OpenDelegationData* data, ino_t* id);
76					status_t	Open(int mode, OpenFileCookie* cookie);
77					status_t	Close(OpenFileCookie* cookie);
78
79					status_t	OpenAttr(const char* name,  int mode,
80									OpenAttrCookie* cookie, bool create,
81									int32 type = 0);
82					status_t	CloseAttr(OpenAttrCookie* cookie);
83
84					status_t	Read(OpenFileCookie* cookie, off_t pos,
85									void* buffer, size_t* length);
86					status_t	Write(OpenFileCookie* cookie, off_t pos,
87									const void* buffer, size_t* _length);
88
89					status_t	ReadDirect(OpenStateCookie* cookie, off_t pos,
90									void* buffer, size_t* length, bool* eof);
91					status_t	WriteDirect(OpenStateCookie* cookie, off_t pos,
92									const void* buffer, size_t* _length);
93
94					status_t	CreateDir(const char* name, int mode,
95									ino_t* id);
96					status_t	OpenDir(OpenDirCookie* cookie);
97					status_t	ReadDir(void* buffer, uint32 size,
98									uint32* count, OpenDirCookie* cookie);
99
100					status_t	OpenAttrDir(OpenDirCookie* cookie);
101
102					status_t	TestLock(OpenFileCookie* cookie,
103									struct flock* lock);
104					status_t	AcquireLock(OpenFileCookie* cookie,
105									const struct flock* lock, bool wait);
106					status_t	ReleaseLock(OpenFileCookie* cookie,
107									const struct flock* lock);
108					status_t	ReleaseAllLocks(OpenFileCookie* cookie);
109
110					status_t	GetDirSnapshot(DirectoryCacheSnapshot**
111									_snapshot, OpenDirCookie* cookie,
112									uint64* _change, bool attribute);
113
114					status_t	LoadAttrDirHandle();
115
116	static inline	ino_t		FileIdToInoT(uint64 fileid);
117
118					void		BeginAIOOp();
119					void		EndAIOOp();
120	inline			void		WaitAIOComplete();
121protected:
122								Inode();
123
124					void		ReleaseOpenState();
125
126					status_t	CreateState(const char* name, int mode,
127									int perms, OpenState* state,
128									OpenDelegationData* data);
129
130					void		ReturnDelegation(bool truncate);
131
132					status_t	ReadDirUp(struct dirent* de, uint32 pos,
133									uint32 size);
134					status_t	FillDirEntry(struct dirent* de, ino_t id,
135									const char* name, uint32 pos, uint32 size);
136
137					status_t	ChildAdded(const char* name, uint64 fileID,
138									const FileHandle& fileHandle);
139
140					status_t	GetStat(struct stat* st,
141									OpenAttrCookie* attr = NULL);
142
143					char*		AttrToFileName(const char* path);
144
145	static inline	status_t	CheckLockType(short ltype, uint32 mode);
146
147private:
148					uint32		fType;
149
150					MetadataCache	fMetaCache;
151					DirectoryCache*	fCache;
152					DirectoryCache*	fAttrCache;
153
154					rw_lock		fDelegationLock;
155					Delegation*	fDelegation;
156
157					uint64		fChange;
158					void*		fFileCache;
159					mutex		fFileCacheLock;
160					uint64		fMaxFileSize;
161
162					OpenState*	fOpenState;
163					mutex		fStateLock;
164
165					rw_lock		fWriteLock;
166					bool		fWriteDirty;
167
168					sem_id		fAIOWait;
169					uint32		fAIOCount;
170					mutex		fAIOLock;
171};
172
173
174inline void
175Inode::WaitAIOComplete()
176{
177	acquire_sem(fAIOWait);
178	release_sem(fAIOWait);
179}
180
181
182inline ino_t
183Inode::FileIdToInoT(uint64 fileid)
184{
185	if (sizeof(ino_t) >= sizeof(uint64))
186		return fileid;
187	else
188		return (ino_t)fileid ^ (fileid >>
189					(sizeof(uint64) - sizeof(ino_t)) * 8);
190}
191
192
193inline ino_t
194Inode::ID() const
195{
196	return FileIdToInoT(fInfo.fFileId);
197}
198
199
200inline mode_t
201Inode::Type() const
202{
203	return sNFSFileTypeToHaiku[fType];
204}
205
206
207inline FileSystem*
208Inode::GetFileSystem() const
209{
210	ASSERT(fFileSystem != NULL);
211	return fFileSystem;
212}
213
214
215inline void*
216Inode::FileCache()
217{
218	return fFileCache;
219}
220
221
222inline void
223Inode::SetOpenState(OpenState* state)
224{
225	ASSERT(state != NULL);
226	fOpenState = state;
227}
228
229
230inline uint64
231Inode::MaxFileSize()
232{
233	return fMaxFileSize;
234}
235
236
237inline uint64
238Inode::Change()
239{
240	return fChange;
241}
242
243
244inline bool
245Inode::Dirty()
246{
247	return fWriteDirty;
248}
249
250
251inline OpenState*
252Inode::GetOpenState()
253{
254	return fOpenState;
255}
256
257
258#endif	// INODE_H
259
260