22 #include "pedigree/kernel/Log.h" 23 #include "pedigree/kernel/syscallError.h" 24 #include "pedigree/kernel/utilities/Iterator.h" 25 #include "pedigree/kernel/utilities/StaticString.h" 26 #include "pedigree/kernel/utilities/StringView.h" 27 #include "pedigree/kernel/utilities/Vector.h" 28 #include "pedigree/kernel/utilities/utility.h" 30 #ifndef VFS_STANDALONE 31 #include "modules/Module.h" 32 #include "pedigree/kernel/process/Process.h" 33 #include "pedigree/kernel/process/Thread.h" 34 #include "pedigree/kernel/processor/Processor.h" 35 #include "pedigree/kernel/processor/ProcessorInformation.h" 47 static void splitPathOnColon(
51 size_t afterColon = path.nextCharacter(colonPosition);
52 right = path.
substring(afterColon, path.length());
61 VFS::VFS() : m_Aliases(), m_ProbeCallbacks(), m_MountCallbacks()
68 for (
auto it = m_ProbeCallbacks.
begin(); it != m_ProbeCallbacks.
end(); ++it)
74 for (
auto it = m_Mounts.
begin(); it != m_Mounts.
end(); ++it)
77 auto aliases = it.value();
78 for (
auto it2 = aliases->begin(); it2 != aliases->end(); ++it2)
91 m_ProbeCallbacks.
begin();
92 it != m_ProbeCallbacks.
end(); it++)
98 if (alias.length() == 0)
105 if (m_Mounts.
lookup(pFs) == 0)
111 it2 != m_MountCallbacks.
end(); it2++)
129 m_Aliases.
insert(alias, pFs);
131 if (m_Mounts.
lookup(pFs) == 0)
140 if (result.hasValue())
144 m_Aliases.
insert(newAlias, pFs);
146 if (m_Mounts.
lookup(pFs) == 0)
164 tmpAlias +=
static_cast<const char *
>(alias);
165 tmpAlias.append(index);
167 String s(static_cast<const char *>(tmpAlias));
190 for (AliasTable::Iterator it = m_Aliases.begin(); it != m_Aliases.end();)
194 it = m_Aliases.
erase(it);
201 if (m_Mounts.
lookup(pFs) != 0)
224 #if VFS_WITH_LRU_CACHES 225 if (!m_AliasCache.
get(alias, fs))
229 #if VFS_WITH_LRU_CACHES 232 m_AliasCache.
store(alias, fs);
240 return result.hasValue() ? result.value() :
nullptr;
252 ssize_t colon = findColon(path);
258 pResult = pStartNode->getFilesystem()->
find(pathView, pStartNode);
264 #if VFS_WITH_LRU_CACHES 265 if (m_FindCache.
get(path, pResult))
267 m_FindCache.
store(path, pResult);
274 splitPathOnColon(colon, pathView, left, right);
280 pResult = pFs->
find(right);
281 #if VFS_WITH_LRU_CACHES 284 m_FindCache.
store(path, pResult);
289 #if VFS_WITH_LRU_CACHES 315 ssize_t colon = findColon(path);
322 return pStartNode->getFilesystem()->
createFile(
323 path, mask, pStartNode);
328 splitPathOnColon(colon, path, left, right);
341 ssize_t colon = findColon(path);
352 path, mask, pStartNode);
358 splitPathOnColon(colon, path, left, right);
374 ssize_t colon = findColon(path);
382 path, value, pStartNode);
387 splitPathOnColon(colon, path, left, right);
400 ssize_t colon = findColon(path);
407 return pStartNode->getFilesystem()->
createLink(
408 path, target, pStartNode);
413 splitPathOnColon(colon, path, left, right);
426 ssize_t colon = findColon(path);
433 return pStartNode->getFilesystem()->
remove(path, pStartNode);
438 splitPathOnColon(colon, path, left, right);
444 return pFs->
remove(right, 0);
452 #ifdef VFS_STANDALONE 465 int64_t fuid = pFile->getUid();
466 int64_t fgid = pFile->getGid();
468 int64_t processUid = pProcess->getEffectiveUserId();
474 int64_t processGid = pProcess->getEffectiveGroupId();
477 processGid = pProcess->getGroupId();
481 uint32_t permissions = pFile->getPermissions();
483 if (fuid == processUid)
485 check = (permissions >> FILE_UBITS) & 0x7;
487 else if (fgid == processGid)
489 check = (permissions >> FILE_GBITS) & 0x7;
494 pProcess->getSupplementalGroupIds(supplementalGroups);
496 for (
auto it : supplementalGroups)
500 check = (permissions >> FILE_GBITS) & 0x7;
507 check = (permissions >> FILE_OBITS) & 0x7;
514 "no permissions? perms=" <<
Oct << permissions
515 <<
", check=" << check);
520 uint32_t needed = (bRead ? FILE_UR : 0) | (bWrite ? FILE_UW : 0) |
521 (bExecute ? FILE_UX : 0);
522 if ((check & needed) != needed)
525 "VFS::checkAccess: needed " <<
Oct << needed <<
", check was " 527 SYSCALL_ERROR(PermissionDenied);
535 ssize_t VFS::findColon(
const String &path)
541 size_t len = path.length();
542 for (i = 0; i < len; i++, result++)
549 if (path[i + 1] ==
'\xbb')
562 return bColon ? result : -1;
565 #ifndef VFS_STANDALONE 566 static bool initVFS()
571 static void destroyVFS()
575 MODULE_INFO(
"vfs", &initVFS, &destroyVFS,
"users");
void store(const K &key, const T &object)
void removeAlias(const String &alias)
File * find(const String &path, File *pStartNode=0)
void pushBack(const T &value)
StringView substring(size_t start, size_t end, bool hashed=HASH_STRINGVIEWS_BY_DEFAULT) const
bool contains(const K &k) const
bool createLink(const String &path, File *target, File *pStartNode=0)
bool createLink(const StringView &path, File *target, File *pStartNode=0)
void addAlias(Filesystem *pFs, const String &alias)
virtual int64_t getUserId() const
bool createFile(const StringView &path, uint32_t mask, File *pStartNode=0)
void removeAllAliases(Filesystem *pFs, bool canDelete=true)
void addMountCallback(MountCallback callback)
Filesystem * lookupFilesystem(const String &alias)
void addProbeCallback(Filesystem::ProbeCallback callback)
static ProcessorInformation & information()
bool remove(const StringView &path, File *pStartNode=0)
Iterator erase(Iterator &at)
Filesystem *(* ProbeCallback)(Disk *)
bool aliasExists(const String &alias)
bool createSymlink(const String &path, const String &value, File *pStartNode=0)
virtual File * find(const StringView &path)
void insert(const K &key, const E &value)
::Iterator< T, node_t > Iterator
bool insert(const K &k, const V &v)
bool createDirectory(const String &path, uint32_t mask, File *pStartNode=0)
bool createDirectory(const StringView &path, uint32_t mask, File *pStartNode=0)
bool createFile(const String &path, uint32_t mask, File *pStartNode=0)
bool remove(const String &path, File *pStartNode=0)
LookupResult lookup(const K &k) const
String getUniqueAlias(const String &alias)
virtual String getVolumeLabel() const =0
bool mount(Disk *pDisk, String &alias)
void remove(const K &key)
bool get(const K &key, T &object)
bool createSymlink(const StringView &path, const String &value, File *pStartNode=0)
E lookup(const K &key) const
static bool checkAccess(File *pFile, bool bRead, bool bWrite, bool bExecute)