xref: /haiku/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h (revision 48d27198d0c684ad918733a087ea94897d7d6a4f)
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 DIRECTORYCACHE_H
9 #define DIRECTORYCACHE_H
10 
11 
12 #include <lock.h>
13 #include <SupportDefs.h>
14 #include <util/DoublyLinkedList.h>
15 #include <util/KernelReferenceable.h>
16 #include <util/SinglyLinkedList.h>
17 
18 
19 class Inode;
20 
21 struct NameCacheEntry :
22 	public SinglyLinkedListLinkImpl<NameCacheEntry> {
23 			ino_t			fNode;
24 			const char*		fName;
25 
26 							NameCacheEntry(const char* name, ino_t node);
27 							NameCacheEntry(const NameCacheEntry& entry);
28 							~NameCacheEntry();
29 };
30 
31 struct DirectoryCacheSnapshot : public KernelReferenceable {
32 			SinglyLinkedList<NameCacheEntry>	fEntries;
33 	mutable	mutex			fLock;
34 
35 							DirectoryCacheSnapshot();
36 							DirectoryCacheSnapshot(
37 								const DirectoryCacheSnapshot& snapshot);
38 							~DirectoryCacheSnapshot();
39 };
40 
41 class DirectoryCache {
42 public:
43 							DirectoryCache(Inode* inode, bool attr = false);
44 							~DirectoryCache();
45 
46 	inline	void			Lock();
47 	inline	void			Unlock();
48 
49 			void			Reset();
50 			void			Trash();
51 	inline	bool			Valid();
52 
53 			status_t		AddEntry(const char* name, ino_t node,
54 								bool created = false);
55 			void			RemoveEntry(const char* name);
56 
57 	inline	status_t		GetSnapshot(DirectoryCacheSnapshot** snapshot);
58 
59 	inline	SinglyLinkedList<NameCacheEntry>&	EntriesList();
60 
61 			status_t		Revalidate();
62 
63 	inline  status_t		ValidateChangeInfo(uint64 change);
64 	inline  void			SetChangeInfo(uint64 change);
65 	inline	uint64			ChangeInfo();
66 
67 	inline	Inode*			GetInode();
68 
69 	const	bigtime_t		fExpirationTime;
70 protected:
71 			void			NotifyChanges(DirectoryCacheSnapshot* oldSnapshot,
72 								DirectoryCacheSnapshot* newSnapshot);
73 
74 private:
75 			void			_SetSnapshot(DirectoryCacheSnapshot* snapshot);
76 			status_t		_LoadSnapshot(bool trash);
77 
78 			SinglyLinkedList<NameCacheEntry>	fNameCache;
79 
80 			DirectoryCacheSnapshot*	fDirectoryCache;
81 
82 			Inode*			fInode;
83 
84 			bool			fAttrDir;
85 			bool			fTrashed;
86 			mutex			fLock;
87 
88 			uint64			fChange;
89 			bigtime_t		fExpireTime;
90 };
91 
92 
93 inline void
94 DirectoryCache::Lock()
95 {
96 	mutex_lock(&fLock);
97 }
98 
99 
100 inline void
101 DirectoryCache::Unlock()
102 {
103 	mutex_unlock(&fLock);
104 }
105 
106 
107 inline bool
108 DirectoryCache::Valid()
109 {
110 	return !fTrashed;
111 }
112 
113 
114 inline status_t
115 DirectoryCache::GetSnapshot(DirectoryCacheSnapshot** snapshot)
116 {
117 	ASSERT(snapshot != NULL);
118 
119 	status_t result = B_OK;
120 	if (fDirectoryCache == NULL)
121 		result = _LoadSnapshot(false);
122 	*snapshot = fDirectoryCache;
123 	return result;
124 }
125 
126 
127 inline SinglyLinkedList<NameCacheEntry>&
128 DirectoryCache::EntriesList()
129 {
130 	return fNameCache;
131 }
132 
133 
134 inline status_t
135 DirectoryCache::ValidateChangeInfo(uint64 change)
136 {
137 	if (fTrashed || change != fChange) {
138 		Trash();
139 		fChange = change;
140 		fExpireTime = system_time() + fExpirationTime;
141 		fTrashed = false;
142 
143 		return B_ERROR;
144 	}
145 
146 	return B_OK;
147 }
148 
149 
150 inline void
151 DirectoryCache::SetChangeInfo(uint64 change)
152 {
153 	fExpireTime = system_time() + fExpirationTime;
154 	fChange = change;
155 }
156 
157 
158 inline uint64
159 DirectoryCache::ChangeInfo()
160 {
161 	return fChange;
162 }
163 
164 
165 inline Inode*
166 DirectoryCache::GetInode()
167 {
168 	return fInode;
169 }
170 
171 
172 #endif	// DIRECTORYCACHE_H
173 
174