accc7e7521
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
79 lines
1.5 KiB
C++
79 lines
1.5 KiB
C++
/*
|
|
* \brief Symlink file-system node
|
|
* \author Norman Feske
|
|
* \date 2012-04-11
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2012-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 _INCLUDE__RAM_FS__SYMLINK_H_
|
|
#define _INCLUDE__RAM_FS__SYMLINK_H_
|
|
|
|
/* local includes */
|
|
#include "node.h"
|
|
|
|
namespace Ram_fs { class Symlink; }
|
|
|
|
|
|
class Ram_fs::Symlink : public Node
|
|
{
|
|
private:
|
|
|
|
char _link_to[File_system::MAX_PATH_LEN];
|
|
size_t _len;
|
|
|
|
public:
|
|
|
|
Symlink(char const *name): _len(0) { Node::name(name); }
|
|
|
|
size_t read(char *dst, size_t len, seek_off_t seek_offset) override
|
|
{
|
|
size_t count = min(len, _len-seek_offset);
|
|
Genode::memcpy(dst, _link_to+seek_offset, count);
|
|
return count;
|
|
}
|
|
|
|
size_t write(char const *src, size_t len, seek_off_t seek_offset) override
|
|
{
|
|
size_t const consumed_len = len;
|
|
|
|
/* Ideal symlink operations are atomic. */
|
|
if (seek_offset) return 0;
|
|
|
|
for (size_t i = 0; i < len; ++i) {
|
|
if (src[i] == '\0') {
|
|
len = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* if the target is too long return a
|
|
* short result to indicate the error
|
|
*/
|
|
if (len > sizeof(_link_to))
|
|
return len >> 1;
|
|
|
|
Genode::memcpy(_link_to, src, len);
|
|
_len = len;
|
|
|
|
return consumed_len;
|
|
}
|
|
|
|
Status status() override
|
|
{
|
|
Status s;
|
|
s.inode = inode();
|
|
s.size = _len;
|
|
s.mode = File_system::Status::MODE_SYMLINK;
|
|
return s;
|
|
}
|
|
};
|
|
|
|
#endif /* _INCLUDE__RAM_FS__SYMLINK_H_ */
|