Skip to content

Commit

Permalink
fs: Implement O_APPEND for ext2
Browse files Browse the repository at this point in the history
  • Loading branch information
Dennisbonke committed Oct 7, 2023
1 parent f274d8d commit 83d2b21
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 18 deletions.
1 change: 1 addition & 0 deletions drivers/libblockfs/src/ext2fs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ struct OpenFile {
std::shared_ptr<Inode> inode;
uint64_t offset;
Flock flock;
bool append;
};

} } // namespace blockfs::ext2fs
Expand Down
6 changes: 5 additions & 1 deletion drivers/libblockfs/src/libblockfs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ async::result<frg::expected<protocols::fs::Error, size_t>> write(void *object, c
}

auto self = static_cast<ext2fs::OpenFile *>(object);
if(self->append) {
self->offset = self->inode->fileSize();
}
co_await self->inode->fs.write(self->inode.get(), self->offset, buffer, length);
self->offset += length;
co_return length;
Expand Down Expand Up @@ -330,10 +333,11 @@ getStats(std::shared_ptr<void> object) {
}

async::result<protocols::fs::OpenResult>
open(std::shared_ptr<void> object) {
open(std::shared_ptr<void> object, bool append) {
auto self = std::static_pointer_cast<ext2fs::Inode>(object);
auto file = smarter::make_shared<ext2fs::OpenFile>(self);
co_await self->readyJump.wait();
file->append = append;

helix::UniqueLane local_ctrl, remote_ctrl;
helix::UniqueLane local_pt, remote_pt;
Expand Down
31 changes: 22 additions & 9 deletions posix/subsystem/src/extern_fs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,9 @@ struct OpenFile final : File {

public:
OpenFile(helix::UniqueLane control, helix::UniqueLane lane,
std::shared_ptr<MountView> mount, std::shared_ptr<FsLink> link)
std::shared_ptr<MountView> mount, std::shared_ptr<FsLink> link, bool append)
: File{StructName::get("externfs.file"), std::move(mount), std::move(link)},
_control{std::move(control)}, _file{std::move(lane)} { }
_control{std::move(control)}, _file{std::move(lane)}, _append(append) { }

~OpenFile() {
// It's not necessary to do any cleanup here.
Expand Down Expand Up @@ -247,6 +247,7 @@ struct OpenFile final : File {
private:
helix::UniqueLane _control;
protocols::fs::File _file;
bool _append;
};

struct RegularNode final : Node {
Expand All @@ -261,10 +262,10 @@ struct RegularNode final : Node {
// Regular files do not support O_NONBLOCK.
semantic_flags &= ~semanticNonBlock;

if(semantic_flags & ~(semanticRead | semanticWrite)){
if(semantic_flags & ~(semanticRead | semanticWrite | semanticAppend)){
std::cout << "\e[31mposix: open() received illegal arguments:"
<< std::bitset<32>(semantic_flags)
<< "\nOnly semanticRead (0x2) and semanticWrite(0x4) are allowed.\e[39m"
<< "\nOnly semanticRead (0x2), semanticWrite (0x4) and semanticAppend (0x8) are allowed.\e[39m"
<< std::endl;
co_return Error::illegalArguments;
}
Expand All @@ -274,8 +275,14 @@ struct RegularNode final : Node {
helix::PullDescriptor pull_ctrl;
helix::PullDescriptor pull_passthrough;

bool append = false;
if(semantic_flags & semanticAppend) {
append = true;
}

managarm::fs::CntRequest req;
req.set_req_type(managarm::fs::CntReqType::NODE_OPEN);
req.set_append(append);

auto ser = req.SerializeAsString();
auto &&transmit = helix::submitAsync(getLane(), helix::Dispatcher::global(),
Expand All @@ -296,7 +303,7 @@ struct RegularNode final : Node {
assert(resp.error() == managarm::fs::Errors::SUCCESS);

auto file = smarter::make_shared<OpenFile>(pull_ctrl.descriptor(),
pull_passthrough.descriptor(), std::move(mount), std::move(link));
pull_passthrough.descriptor(), std::move(mount), std::move(link), append);
file->setupWeakFile(file);
co_return File::constructHandle(std::move(file));
}
Expand Down Expand Up @@ -742,10 +749,10 @@ struct DirectoryNode final : Node {
// Regular files do not support O_NONBLOCK.
semantic_flags &= ~semanticNonBlock;

if(semantic_flags & ~(semanticRead | semanticWrite)){
if(semantic_flags & ~(semanticRead | semanticWrite | semanticAppend)){
std::cout << "\e[31mposix: open() received illegal arguments:"
<< std::bitset<32>(semantic_flags)
<< "\nOnly semanticRead (0x2) and semanticWrite(0x4) are allowed.\e[39m"
<< "\nOnly semanticRead (0x2), semanticWrite (0x4) and semanticAppend (0x8) are allowed.\e[39m"
<< std::endl;
co_return Error::illegalArguments;
}
Expand All @@ -755,8 +762,14 @@ struct DirectoryNode final : Node {
helix::PullDescriptor pull_ctrl;
helix::PullDescriptor pull_passthrough;

bool append = false;
if(semantic_flags & semanticAppend) {
append = true;
}

managarm::fs::CntRequest req;
req.set_req_type(managarm::fs::CntReqType::NODE_OPEN);
req.set_append(append);

auto ser = req.SerializeAsString();
auto &&transmit = helix::submitAsync(getLane(), helix::Dispatcher::global(),
Expand All @@ -777,7 +790,7 @@ struct DirectoryNode final : Node {
assert(resp.error() == managarm::fs::Errors::SUCCESS);

auto file = smarter::make_shared<OpenFile>(pull_ctrl.descriptor(),
pull_passthrough.descriptor(), std::move(mount), std::move(link));
pull_passthrough.descriptor(), std::move(mount), std::move(link), append);
file->setupWeakFile(file);
co_return File::constructHandle(std::move(file));
}
Expand Down Expand Up @@ -951,7 +964,7 @@ std::shared_ptr<FsLink> createRoot(helix::UniqueLane sb_lane, helix::UniqueLane
smarter::shared_ptr<File, FileHandle>
createFile(helix::UniqueLane lane, std::shared_ptr<MountView> mount, std::shared_ptr<FsLink> link) {
auto file = smarter::make_shared<OpenFile>(helix::UniqueLane{},
std::move(lane), std::move(mount), std::move(link));
std::move(lane), std::move(mount), std::move(link), false);
file->setupWeakFile(file);
return File::constructHandle(std::move(file));
}
Expand Down
9 changes: 5 additions & 4 deletions posix/subsystem/src/file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,13 @@ struct File : private smarter::crtp_counter<File, DisposeFileHandle> {
return smarter::shared_ptr<File, FileHandle>{smarter::adopt_rc, file, file};
}

File(StructName struct_name, DefaultOps default_ops = 0)
: _structName{struct_name}, _defaultOps{default_ops}, _isOpen{true} { }
File(StructName struct_name, DefaultOps default_ops = 0, bool append = false)
: _structName{struct_name}, _defaultOps{default_ops}, _isOpen{true}, _append{append} { }

File(StructName struct_name, std::shared_ptr<MountView> mount, std::shared_ptr<FsLink> link,
DefaultOps default_ops = 0)
DefaultOps default_ops = 0, bool append = false)
: _structName{struct_name}, _mount{std::move(mount)}, _link{std::move(link)},
_defaultOps{default_ops}, _isOpen{true} { }
_defaultOps{default_ops}, _isOpen{true}, _append{append} { }

virtual ~File();

Expand Down Expand Up @@ -373,6 +373,7 @@ struct File : private smarter::crtp_counter<File, DisposeFileHandle> {
DefaultOps _defaultOps;

bool _isOpen;
bool _append;
};

struct DummyFile final : File {
Expand Down
1 change: 1 addition & 0 deletions posix/subsystem/src/fs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ using SemanticFlags = uint32_t;
inline constexpr SemanticFlags semanticNonBlock = 1;
inline constexpr SemanticFlags semanticRead = 2;
inline constexpr SemanticFlags semanticWrite = 4;
inline constexpr SemanticFlags semanticAppend = 8;

// Represents an inode on an actual file system (i.e. not in the VFS).
struct FsNode {
Expand Down
6 changes: 5 additions & 1 deletion posix/subsystem/src/requests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1534,7 +1534,8 @@ async::result<void> serveRequests(std::shared_ptr<Process> self,
| managarm::posix::OpenFlags::OF_WRONLY
| managarm::posix::OpenFlags::OF_RDWR
| managarm::posix::OpenFlags::OF_PATH
| managarm::posix::OpenFlags::OF_NOCTTY))) {
| managarm::posix::OpenFlags::OF_NOCTTY
| managarm::posix::OpenFlags::OF_APPEND))) {
std::cout << "posix: OPENAT flags not recognized: " << req->flags() << std::endl;
co_await sendErrorResponse(managarm::posix::Errors::ILLEGAL_ARGUMENTS);
continue;
Expand All @@ -1551,6 +1552,9 @@ async::result<void> serveRequests(std::shared_ptr<Process> self,
else if (req->flags() & managarm::posix::OpenFlags::OF_RDWR)
semantic_flags |= semanticRead | semanticWrite;

if(req->flags() & managarm::posix::OpenFlags::OF_APPEND)
semantic_flags |= semanticAppend;

ViewPath relative_to;
smarter::shared_ptr<File, FileHandle> file;
std::shared_ptr<FsLink> target_link;
Expand Down
2 changes: 2 additions & 0 deletions protocols/fs/fs.bragi
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ head(128):
tag(69) int64 pgid;

tag(84) int32 seals;

tag(85) byte append;
}
}

Expand Down
2 changes: 1 addition & 1 deletion protocols/fs/include/protocols/fs/server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ struct NodeOperations {
async::result<frg::expected<protocols::fs::Error>> (*unlink)(std::shared_ptr<void> object,
std::string name);

async::result<OpenResult> (*open)(std::shared_ptr<void> object);
async::result<OpenResult> (*open)(std::shared_ptr<void> object, bool append);

async::result<std::string> (*readSymlink)(std::shared_ptr<void> object);

Expand Down
2 changes: 1 addition & 1 deletion protocols/fs/src/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1532,7 +1532,7 @@ async::detached serveNode(helix::UniqueLane lane, std::shared_ptr<void> node,
);
HEL_CHECK(send_resp.error());
}else if(req.req_type() == managarm::fs::CntReqType::NODE_OPEN) {
auto result = co_await node_ops->open(node);
auto result = co_await node_ops->open(node, req.append());

managarm::fs::SvrResponse resp;
resp.set_error(managarm::fs::Errors::SUCCESS);
Expand Down
3 changes: 2 additions & 1 deletion protocols/posix/posix.bragi
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ consts OpenFlags uint32 {
OF_RDWR = 32,
OF_TRUNC = 64,
OF_PATH = 128,
OF_NOCTTY = 512
OF_NOCTTY = 512,
OF_APPEND = 1024
}

message CntRequest 1 {
Expand Down

0 comments on commit 83d2b21

Please sign in to comment.