diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp index 5e39a9a2a5..14d315bb6f 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/Kernel/FileSystem/VirtualFileSystem.cpp @@ -151,10 +151,16 @@ KResult VFS::stat(StringView path, int options, Custody& base, struct stat& stat KResultOr> VFS::open(StringView path, int options, mode_t mode, Custody& base) { - auto custody_or_error = resolve_path(path, base, nullptr, options); + RetainPtr parent_custody; + auto custody_or_error = resolve_path(path, base, &parent_custody, options); if (options & O_CREAT) { - if (custody_or_error.is_error()) - return create(path, options, mode, base); + if (!parent_custody) + return KResult(-ENOENT); + if (custody_or_error.is_error()) { + if (custody_or_error.error() != -ENOENT) + return custody_or_error.error(); + return create(path, options, mode, *parent_custody); + } if (options & O_EXCL) return KResult(-EEXIST); } @@ -224,7 +230,7 @@ KResult VFS::mknod(StringView path, mode_t mode, dev_t dev, Custody& base) return KSuccess; } -KResultOr> VFS::create(StringView path, int options, mode_t mode, Custody& base) +KResultOr> VFS::create(StringView path, int options, mode_t mode, Custody& parent_custody) { (void)options; @@ -233,18 +239,9 @@ KResultOr> VFS::create(StringView path, int options, m mode |= 0100000; } - RetainPtr parent_custody; - auto existing_custody_or_error = resolve_path(path, base, &parent_custody); - if (!existing_custody_or_error.is_error()) - return KResult(-EEXIST); - if (!parent_custody) - return KResult(-ENOENT); - auto& parent_inode = parent_custody->inode(); - if (existing_custody_or_error.error() != -ENOENT) - return existing_custody_or_error.error(); + auto& parent_inode = parent_custody.inode(); if (!parent_inode.metadata().may_write(current->process())) return KResult(-EACCES); - FileSystemPath p(path); dbgprintf("VFS::create_file: '%s' in %u:%u\n", p.basename().characters(), parent_inode.fsid(), parent_inode.index()); int error; @@ -252,7 +249,7 @@ KResultOr> VFS::create(StringView path, int options, m if (!new_file) return KResult(error); - auto new_custody = Custody::create(parent_custody, p.basename(), *new_file); + auto new_custody = Custody::create(&parent_custody, p.basename(), *new_file); return FileDescription::create(*new_custody); } diff --git a/Kernel/FileSystem/VirtualFileSystem.h b/Kernel/FileSystem/VirtualFileSystem.h index a6ff04c2af..c1f2e20860 100644 --- a/Kernel/FileSystem/VirtualFileSystem.h +++ b/Kernel/FileSystem/VirtualFileSystem.h @@ -61,7 +61,7 @@ public: KResultOr> open(RetainPtr&&, int options); KResultOr> open(StringView path, int options, mode_t mode, Custody& base); - KResultOr> create(StringView path, int options, mode_t mode, Custody& base); + KResultOr> create(StringView path, int options, mode_t mode, Custody& parent_custody); KResult mkdir(StringView path, mode_t mode, Custody& base); KResult link(StringView old_path, StringView new_path, Custody& base); KResult unlink(StringView path, Custody& base);