54 enum class LookupStatus { Found, NotFound, IoError, Retry };
56 enum class ReadStatus { Complete, Stopped, IoError };
58 enum class AddStatus { Added, Exists, IoError, Detached };
60 enum class EntryType : uint8_t {
75 uint64_t currentCookie;
90 explicit operator bool()
const {
91 return m_pFile !=
nullptr;
108 void adopt(
File* file);
111#if THREADS && !defined(STANDALONE_MUTEXES)
123 explicit operator bool()
const {
124 return m_pDirectory !=
nullptr;
127 void complete(LookupStatus result);
141 bool m_OwnsNamespaceLock;
142#if THREADS && !defined(STANDALONE_MUTEXES)
150 FATAL(
"Casting non-directory File to Directory!");
164 Directory(
const String& name, Time::Timestamp accessedTime, Time::Timestamp modifiedTime,
165 Time::Timestamp creationTime, uintptr_t inode,
class Filesystem* pFs,
size_t size,
176 File* getChild(
size_t n);
180 return __atomic_load_n(&m_Detached, __ATOMIC_ACQUIRE);
184 size_t getNumChildren();
191 ReadStatus enumerate(uint64_t& cookie, DirectoryEntryEmitter emitter,
void* context);
194 ReadStatus isEmpty(
bool& empty);
197 virtual void cacheDirectoryContents();
200 virtual bool isCachePopulated()
const;
219 ChildLease& child)
const;
235 void setReparsePoint(
Directory* pTarget);
244 AddStatus addEphemeralFile(
File* pFile);
258#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
259 enum class RetainedLookupPhase { BeforeLookup, AfterRetain };
260 using RetainedLookupHook = void (*)(
Directory*,
File*, RetainedLookupPhase);
261 static void setRetainedLookupHookForHostedTest(RetainedLookupHook hook);
262 const void* cacheLockAddressForHostedTest()
const {
263 return static_cast<const void*
>(&m_CacheLock);
265 bool tryCacheLockForHostedTest()
const;
290 virtual LookupStatus resolveChild(
const StringView& name,
File*& child);
302 virtual LookupStatus resolveChildAt(uint64_t cookie,
const StringView& name,
File*& child);
305 virtual ReadStatus readDirectory(uint64_t& cookie, DirectoryEntryEmitter emitter,
void* context);
308 static File* evaluateEntry(
const DirectoryEntryMetadata& meta);
309 static void destroyEntry(
File* file);
352 uint64_t m_NextCacheGeneration;
378#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
379 static RetainedLookupHook m_RetainedLookupHook;
389 void markCachePopulated();
392 bool addDirectoryEntry(
const String& name,
File* pTarget);
395 bool addDirectoryEntry(
const String& name, DirectoryEntryMetadata&& meta);
398 bool reserveDirectoryEntry(
const HashedStringView& name, NameReservation& reservation);
401 bool addCachedDirectoryEntry(NameReservation& reservation,
File* pTarget);
411 return m_NamespaceMutationLock;
417 void preallocateDirectoryEntries(
size_t count);
420 virtual File* convertToFile(
const DirectoryEntryMetadata& meta);
424 bool reserveRenameEntry(
const String& name, NameReservation& reservation);
425 void moveReservedEntry(NameReservation& sourceReservation,
Directory* destination,
426 NameReservation& destinationReservation,
File* source);
428 static constexpr uint64_t ResidentCookie =
static_cast<uint64_t
>(1) << 62;
430 uint64_t nextCacheGeneration();
432 void finishNameReservation(NameReservation& reservation, LookupStatus result);
433 bool addResidentDirectoryEntry(NameReservation& reservation,
File* pTarget,
bool ephemeral);
434 bool addResidentDirectoryEntry(NameReservation& reservation, DirectoryEntry* entry,
435 bool ephemeral,
File* createdTarget =
nullptr);
438 static EntryType entryType(
File* file);
439 LookupStatus lookupChildInternal(
const HashedStringView& name, uint64_t cookie,
bool hasCookie,
440 ChildLease& child)
const;
441 struct EnumerationContext;
442 static bool emitBackingEntry(
void* context,
const DirectoryEntryView& entry);