The Pedigree Project  0.1
Directory.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "Directory.h"
21 #include "Filesystem.h"
22 #include "pedigree/kernel/utilities/Iterator.h"
23 #include "pedigree/kernel/utilities/Pair.h"
24 #include "pedigree/kernel/utilities/Result.h"
25 #include "pedigree/kernel/utilities/StringView.h"
26 #include "pedigree/kernel/utilities/Vector.h"
27 
29 
30 Directory::Directory() : File(), m_Cache(nullptr), m_bCachePopulated(false)
31 {
32 }
33 
35  const String &name, Time::Timestamp accessedTime,
36  Time::Timestamp modifiedTime, Time::Timestamp creationTime, uintptr_t inode,
37  Filesystem *pFs, size_t size, File *pParent)
38  : File(
39  name, accessedTime, modifiedTime, creationTime, inode, pFs, size,
40  pParent),
41  m_Cache(nullptr), m_bCachePopulated(false)
42 {
43 }
44 
46 {
47  for (auto it : m_Cache)
48  {
49  delete it;
50  }
51 
52  m_Cache.clear();
53 }
54 
56 {
58  {
60  m_bCachePopulated = true;
61  }
62 
64  if (result.hasError())
65  {
66  return 0;
67  }
68  else
69  {
70  return result.value().second()->get();
71  }
72 }
73 
75 {
77  {
79  m_bCachePopulated = true;
80  }
81 
82  return m_Cache.count();
83 }
84 
86 {
87 }
88 
90 {
92  {
94  if (result.hasValue())
95  {
96  return result.value()->get();
97  }
98  }
99  return nullptr;
100 }
101 
103 {
105  if (result.hasValue())
106  {
107  DirectoryEntry *v = result.value();
109  m_Cache.remove(s.toString());
110  delete v;
111  }
112 }
113 
114 void Directory::addDirectoryEntry(const String &name, File *pTarget)
115 {
116  DirectoryEntry *entry = new DirectoryEntry(pTarget);
117 
118  if (!m_Cache.insert(name, entry))
119  {
120  ERROR(
121  "can't add directory entry for '" << name
122  << "' as it already exists.");
123  delete entry;
124  }
125  else
126  {
127  m_bCachePopulated = true;
128  }
129 }
130 
132  const String &name, DirectoryEntryMetadata &&meta)
133 {
134  DirectoryEntry *entry = new DirectoryEntry(pedigree_std::move(meta));
135 
136  if (!m_Cache.insert(name, entry))
137  {
138  ERROR(
139  "can't add directory entry for '" << name
140  << "' as it already exists.");
141  delete entry;
142  }
143  else
144  {
145  m_bCachePopulated = true;
146  }
147 }
148 
150 {
151  return m_ReparseTarget;
152 }
153 
155 {
156  m_ReparseTarget = pTarget;
157 }
158 
160 {
162  {
164  m_bCachePopulated = true;
165  }
166 
167  if (m_Cache.lookup(pFile->getName()).hasValue())
168  {
169  // already exists!
170  return false;
171  }
172 
174  DirectoryEntry *entry = new DirectoryEntry(pFile);
175  m_Cache.insert(pFile->getName(), entry);
176 
177  return true;
178 }
179 
181 {
182  // Need to make sure we can safely remove all nodes regardless of what
183  // happens to the directory cache while we empty
184  Vector<File *> entries;
185  for (auto it = m_Cache.begin(); it != m_Cache.end(); ++it)
186  {
187  entries.pushBack((*it)->get());
188  }
189 
190  for (auto it : entries)
191  {
192  if (!getFilesystem()->remove(this, it))
193  {
196  return false;
197  }
198  }
199 
200  m_Cache.clear();
201 
202  return true;
203 }
204 
205 File *Directory::evaluateEntry(const DirectoryEntryMetadata &meta)
206 {
207  if (!meta.pDirectory)
208  {
209  return nullptr;
210  }
211  return meta.pDirectory->convertToFile(meta);
212 }
213 
215 {
217  // Thinking maybe something on VFS that tracks File objects and once they
218  // hit zero references, they get culled (i.e. once no more file descriptors
219  // etc are present)
220 }
221 
223 {
224  return nullptr;
225 }
226 
228 {
229  m_Cache.reserve(count);
230 }
231 
232 Directory::DirectoryEntryMetadata::DirectoryEntryMetadata()
233  : pDirectory(nullptr), filename(), opaque()
234 {
235 }
236 Directory::DirectoryEntryMetadata::DirectoryEntryMetadata(
238  : pDirectory(pedigree_std::move(other.pDirectory)),
239  filename(pedigree_std::move(other.filename)),
240  opaque(pedigree_std::move(other.opaque))
241 {
242  other.pDirectory = nullptr;
243 }
244 
245 Directory::DirectoryEntryMetadata::~DirectoryEntryMetadata()
246 {
247  opaque.reset();
248 }
void pushBack(const T &value)
Definition: Vector.h:270
A vector / dynamic array.
void preallocateDirectoryEntries(size_t count)
Definition: Directory.cc:227
void setReparsePoint(Directory *pTarget)
Definition: Directory.cc:154
Definition: String.h:49
Definition: Result.h:36
bool empty()
Definition: Directory.cc:180
virtual File * convertToFile(const DirectoryEntryMetadata &meta)
Definition: Directory.cc:222
void clear()
Definition: HashTable.h:150
bool remove(const StringView &path, File *pStartNode=0)
Definition: Filesystem.cc:234
void addDirectoryEntry(const String &name, File *pTarget)
Definition: Directory.cc:114
void reserve(size_t numItems)
Definition: HashTable.h:373
bool insert(const K &k, const V &v)
Definition: HashTable.h:264
Directory * m_ReparseTarget
Definition: Directory.h:177
LookupResult lookup(const K &k) const
Definition: HashTable.h:200
void remove(const K &k)
Definition: HashTable.h:323
String getName() const
Definition: File.cc:411
void remove(const HashedStringView &s)
Definition: Directory.cc:102
PairLookupResult getNth(size_t n) const
Definition: HashTable.h:238
bool addEphemeralFile(File *pFile)
Add an ephemeral file to the directory.
Definition: Directory.cc:159
#define ERROR(text)
Definition: Log.h:82
bool m_bCachePopulated
Definition: Directory.h:174
size_t getNumChildren()
Definition: Directory.cc:74
File * getChild(size_t n)
Definition: Directory.cc:55
File * lookup(const HashedStringView &s) const
Definition: Directory.cc:89
Directory * getReparsePoint() const
Get the reparse point attached to this directory. Reparse points allow locations on the filesystem to...
Definition: Directory.cc:149
virtual void cacheDirectoryContents()
Definition: Directory.cc:85
Definition: File.h:66
virtual ~Directory()
Definition: Directory.cc:45
DirectoryEntryCache m_Cache
Definition: Directory.h:168
static void destroyEntry(File *file)
Definition: Directory.cc:214