2#include "pedigree/kernel/process/FilesystemAccess.h"
3#include "pedigree/kernel/syscallError.h"
5#include "MountView-internal.h"
9 if (!parent || parent->provider() != view || !parent->node()->
isDirectory()) {
10 SYSCALL_ERROR(NotADirectory);
13 if (!name.length() || name ==
"." || name ==
"..") {
14 SYSCALL_ERROR(InvalidArgument);
17 for (
size_t i = 0; i < name.length(); ++i) {
19 SYSCALL_ERROR(InvalidArgument);
24 SYSCALL_ERROR(DoesNotExist);
27 if (!view->writable(parent)) {
35 if (status == Directory::LookupStatus::NotFound)
37 syscallError(status == Directory::LookupStatus::Found ? Error::FileExists
38 : status ==
Directory::LookupStatus::Retry ? Error::NoMoreProcesses
44bool VfsMountView::isMountpoint(
File* node)
const {
45 if (!m_State || !node)
48 for (
auto* row = m_State->attachments; row; row = row->next)
49 if (row->covered && row->covered->get() == node)
55 auto* owner = fromPath(parent);
56 if (owner && owner !=
this) {
57 return owner->createFile(parent, name, mask);
60 return validParent(parent, name,
this) &&
61 checkFilesystemAccess(parent, FilesystemAccess::MakeReg, &writer) &&
62 absent(parent, name) &&
63 parent->node()->getFilesystem()->
createFile(parent->node(), name, mask);
67 auto* owner = fromPath(parent);
68 if (owner && owner !=
this) {
69 return owner->createDirectory(parent, name, mask);
72 return validParent(parent, name,
this) &&
73 checkFilesystemAccess(parent, FilesystemAccess::MakeDir, &writer) &&
74 absent(parent, name) &&
75 parent->node()->getFilesystem()->
createDirectory(parent->node(), name, mask);
79 auto* owner = fromPath(parent);
80 if (owner && owner !=
this) {
81 return owner->createSymlink(parent, name, value);
84 return validParent(parent, name,
this) &&
85 checkFilesystemAccess(parent, FilesystemAccess::MakeSym, &writer) &&
86 absent(parent, name) &&
87 parent->node()->getFilesystem()->
createSymlink(parent->node(), name, value);
91 auto* owner = fromPath(parent);
92 if (owner && owner !=
this) {
93 return owner->createLink(parent, name, target);
96 if (!validParent(parent, name,
this))
98 auto* source = m_State->path(target);
99 auto* destination = m_State->path(parent);
100 if (!source || source->attachment.get() != destination->attachment.get()) {
101 SYSCALL_ERROR(CrossDeviceLink);
106 SYSCALL_ERROR(NotEnoughPermissions);
110 SYSCALL_ERROR(OperationNotSupported);
113 if (!authorizeLink(parent, target, writer)) {
116 return absent(parent, name) &&
117 parent->node()->getFilesystem()->
createLink(parent->node(), name, target->node());
120 auto* owner = fromPath(parent);
121 if (owner && owner !=
this) {
122 return owner->remove(parent, name, expected);
124 return validParent(parent, name,
this) &&
125 parent->node()->getFilesystem()->
removeChild(parent->node(), name, expected, &parent);
129 bool sourceMustBeDirectory) {
130 auto* owner = fromPath(oldParent);
131 if (owner && owner !=
this) {
132 return owner->rename(oldParent, oldName, newParent, newName, noReplace, sourceMustBeDirectory);
134 if (!validParent(oldParent, oldName,
this) || !validParent(newParent, newName,
this))
136 if (m_State->path(oldParent)->attachment.
get() != m_State->path(newParent)->attachment.
get()) {
137 SYSCALL_ERROR(CrossDeviceLink);
140 return oldParent->node()->getFilesystem()->renameChildren(
141 oldParent->node(), oldName, newParent->node(), newName, noReplace, sourceMustBeDirectory,
142 &oldParent, &newParent);
147 auto* owner = fromPath(parent);
148 if (owner && owner !=
this) {
149 return owner->createEphemeral(parent, node, access);
152 if (!node || !validParent(parent, node->getName(),
this) ||
153 !checkFilesystemAccess(parent, access, &writer)) {
154 return Directory::AddStatus::IoError;
static Directory * fromFile(File *pF)
AddStatus addEphemeralFile(File *pFile)
Add an ephemeral file to the directory.
MUST_USE_RESULT LookupStatus lookupChild(const HashedStringView &s, ChildLease &child) const
virtual bool isSocket() const
virtual bool isDirectory()
virtual bool isFifo() const
virtual bool isPipe() const
bool removeChild(File *parent, const String &filename, File *expected, const FilesystemPathRef *parentPath=nullptr)
bool createSymlink(const StringView &path, const String &value, File *pStartNode=0)
bool createDirectory(const StringView &path, uint32_t mask, File *pStartNode=0)
bool createLink(const StringView &path, File *target, File *pStartNode=0)
bool createFile(const StringView &path, uint32_t mask, File *pStartNode=0)
static bool checkAccess(File *pFile, bool bRead, bool bWrite, bool bExecute)