xref: /haiku/src/tests/system/kernel/file_corruption/fs/SymLink.cpp (revision 8794d8c48f3c595cf42a9ae36fe661e38c019f34)
1 /*
2  * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "SymLink.h"
8 
9 #include <string.h>
10 
11 #include "Block.h"
12 #include "DebugSupport.h"
13 
14 
15 static const size_t kSymLinkDataOffset	= sizeof(checksumfs_node);
16 static const size_t kMaxSymLinkSize		= B_PAGE_SIZE - kSymLinkDataOffset;
17 
18 
SymLink(Volume * volume,uint64 blockIndex,const checksumfs_node & nodeData)19 SymLink::SymLink(Volume* volume, uint64 blockIndex,
20 	const checksumfs_node& nodeData)
21 	:
22 	Node(volume, blockIndex, nodeData)
23 {
24 }
25 
26 
SymLink(Volume * volume,mode_t mode)27 SymLink::SymLink(Volume* volume, mode_t mode)
28 	:
29 	Node(volume, mode)
30 {
31 }
32 
33 
~SymLink()34 SymLink::~SymLink()
35 {
36 }
37 
38 
39 status_t
ReadSymLink(char * buffer,size_t toRead,size_t & _bytesRead)40 SymLink::ReadSymLink(char* buffer, size_t toRead, size_t& _bytesRead)
41 {
42 	uint64 size = Size();
43 	if (size > kMaxSymLinkSize)
44 		RETURN_ERROR(B_BAD_DATA);
45 
46 	if (toRead > size)
47 		toRead = size;
48 
49 	if (toRead == 0) {
50 		_bytesRead = 0;
51 		return B_OK;
52 	}
53 
54 	// get the block
55 	Block block;
56 	if (!block.GetReadable(GetVolume(), BlockIndex()))
57 		RETURN_ERROR(B_ERROR);
58 
59 	const char* data = (char*)block.Data() + kSymLinkDataOffset;
60 	memcpy(buffer, data, toRead);
61 
62 	_bytesRead = toRead;
63 	return B_OK;
64 }
65 
66 
67 status_t
WriteSymLink(const char * buffer,size_t toWrite,Transaction & transaction)68 SymLink::WriteSymLink(const char* buffer, size_t toWrite,
69 	Transaction& transaction)
70 {
71 	uint64 size = Size();
72 	if (size > kMaxSymLinkSize)
73 		RETURN_ERROR(B_BAD_DATA);
74 
75 	if (toWrite > kMaxSymLinkSize)
76 		RETURN_ERROR(B_NAME_TOO_LONG);
77 
78 	if (toWrite == 0) {
79 		SetSize(0);
80 		return B_OK;
81 	}
82 
83 	Block block;
84 	if (!block.GetWritable(GetVolume(), BlockIndex(), transaction))
85 		return B_ERROR;
86 
87 	char* data = (char*)block.Data() + kSymLinkDataOffset;
88 	memcpy(data, buffer, toWrite);
89 	SetSize(toWrite);
90 
91 	return B_OK;
92 }
93