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 Lock()94DirectoryCache::Lock() 95 { 96 mutex_lock(&fLock); 97 } 98 99 100 inline void Unlock()101DirectoryCache::Unlock() 102 { 103 mutex_unlock(&fLock); 104 } 105 106 107 inline bool Valid()108DirectoryCache::Valid() 109 { 110 return !fTrashed; 111 } 112 113 114 inline status_t GetSnapshot(DirectoryCacheSnapshot ** snapshot)115DirectoryCache::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>& EntriesList()128DirectoryCache::EntriesList() 129 { 130 return fNameCache; 131 } 132 133 134 inline status_t ValidateChangeInfo(uint64 change)135DirectoryCache::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 SetChangeInfo(uint64 change)151DirectoryCache::SetChangeInfo(uint64 change) 152 { 153 fExpireTime = system_time() + fExpirationTime; 154 fChange = change; 155 } 156 157 158 inline uint64 ChangeInfo()159DirectoryCache::ChangeInfo() 160 { 161 return fChange; 162 } 163 164 165 inline Inode* GetInode()166DirectoryCache::GetInode() 167 { 168 return fInode; 169 } 170 171 172 #endif // DIRECTORYCACHE_H 173 174