genode/repos/dde_rump/src/server/rump_fs/symlink.h
Alexander Boettcher accc7e7521 fs servers: handle result propagation better
This patch removes the notion of partial writes from the file-system
servers. Since write operations are asynchronously submitted, they are
expected to succeed completely, except for I/O errors. I/O errors are
propagated with the write acknowledgement but those are usually handled
out of band at the client side. Partial writes must never occur because
they would go undetected by clients, which usually don't wait for the
completion of each single write operation.

Until now, most file-system servers returned the number of written bytes
in the acknowledgement packet. If a server managed to write a part of
the request only, it issued the acknowledgement immediately where it
should have cared about writing the remaining part first.

The patch detects such misbehaving server-side code. If partial writes
unexpectedly occur, it prints a message and leaves the corresponding
request unacknowdleged.

Issue #2672
2018-02-15 10:22:08 +01:00

87 lines
1.6 KiB
C++

/**
* \brief Rump symlink node
* \author Sebastian Sumpf
* \date 2014-01-20
*/
/*
* Copyright (C) 2014-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _SYMLINK_H_
#define _SYMLINK_H_
/* Genode includes */
#include <file_system/util.h>
#include <os/path.h>
#include "node.h"
namespace Rump_fs {
class Symlink;
}
class Rump_fs::Symlink : public Node
{
private:
typedef Genode::Path<MAX_PATH_LEN> Path;
Path _path;
bool _create;
public:
Symlink(char const *dir, char const *name, bool create)
: Node(0), _path(name, dir), _create(create)
{
Node::name(name);
}
Symlink(char const *path)
: Node(0), _path(path), _create(false)
{
Node::name(basename(path));
}
size_t write(char const *src, size_t const len, seek_off_t seek_offset) override
{
/* Ideal symlink operations are atomic. */
if (!_create || seek_offset)
return 0;
/* src may not be null-terminated */
Genode::String<MAX_PATH_LEN> target(Genode::Cstring(src, len));
int ret = rump_sys_symlink(target.string(), _path.base());
return ret == -1 ? 0 : len;
}
size_t read(char *dst, size_t len, seek_off_t seek_offset) override
{
int ret = rump_sys_readlink(_path.base(), dst, len);
return ret == -1 ? 0 : ret;
}
Status status() override
{
Status s;
s.inode = inode();
s.size = length();
s.mode = File_system::Status::MODE_SYMLINK;
return s;
}
file_size_t length()
{
char link_to[MAX_PATH_LEN];
return read(link_to, MAX_PATH_LEN, 0);
}
};
#endif /* _SYMLINK_H_ */