xref: /haiku/src/add-ons/kernel/file_systems/nfs4/ReplyBuilder.cpp (revision b617a7b410c05275effb95f4b2f5608359d9b7b9)
1 /*
2  * Copyright 2012 Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Paweł Dziepak, pdziepak@quarnos.org
7  */
8 
9 
10 #include "ReplyBuilder.h"
11 
12 #include "NFS4Defs.h"
13 #include "RPCCallbackReply.h"
14 
15 
16 ReplyBuilder::ReplyBuilder(uint32 xid)
17 	:
18 	fStatus(B_OK),
19 	fOpCount(0),
20 	fReply(RPC::CallbackReply::Create(xid))
21 {
22 	_InitHeader();
23 }
24 
25 
26 ReplyBuilder::~ReplyBuilder()
27 {
28 	delete fReply;
29 }
30 
31 
32 void
33 ReplyBuilder::_InitHeader()
34 {
35 	fStatusPosition = fReply->Stream().Current();
36 	fReply->Stream().AddUInt(0);
37 
38 	fReply->Stream().AddOpaque(NULL, 0);
39 
40 	fOpCountPosition = fReply->Stream().Current();
41 	fReply->Stream().AddUInt(0);
42 
43 }
44 
45 
46 RPC::CallbackReply*
47 ReplyBuilder::Reply()
48 {
49 	fReply->Stream().InsertUInt(fStatusPosition, _HaikuErrorToNFS4(fStatus));
50 	fReply->Stream().InsertUInt(fOpCountPosition, fOpCount);
51 
52 	if (fReply == NULL || fReply->Stream().Error() == B_OK)
53 		return fReply;
54 	else
55 		return NULL;
56 }
57 
58 
59 status_t
60 ReplyBuilder::GetAttr(status_t status, int mask, uint64 size, uint64 change)
61 {
62 	if (fStatus != B_OK)
63 		return B_ERROR;
64 
65 	fReply->Stream().AddUInt(OpCallbackGetAttr);
66 	fReply->Stream().AddUInt(_HaikuErrorToNFS4(fStatus));
67 	fStatus = status;
68 
69 	if (status == B_OK) {
70 		uint32 bitmap = 0;
71 		if ((mask & CallbackAttrChange) != 0)
72 			bitmap |= 1 << FATTR4_CHANGE;
73 		if ((mask & CallbackAttrSize) != 0)
74 			bitmap |= 1 << FATTR4_SIZE;
75 		fReply->Stream().AddUInt(1);
76 		fReply->Stream().AddUInt(bitmap);
77 
78 		XDR::WriteStream str;
79 		if ((mask & CallbackAttrChange) != 0)
80 			str.AddUHyper(change);
81 
82 		if ((mask & CallbackAttrSize) != 0)
83 			str.AddUHyper(size);
84 		fReply->Stream().AddOpaque(str);
85 	}
86 
87 	fOpCount++;
88 
89 	return B_OK;
90 }
91 
92 
93 status_t
94 ReplyBuilder::Recall(status_t status)
95 {
96 	if (fStatus != B_OK)
97 		return B_ERROR;
98 
99 	fReply->Stream().AddUInt(OpCallbackRecall);
100 	fReply->Stream().AddUInt(_HaikuErrorToNFS4(fStatus));
101 	fStatus = status;
102 
103 	fOpCount++;
104 
105 	return B_OK;
106 }
107 
108 
109 uint32
110 ReplyBuilder::_HaikuErrorToNFS4(status_t error)
111 {
112 	switch (error) {
113 		case B_OK:				return NFS4_OK;
114 		case B_FILE_NOT_FOUND:	return NFS4ERR_BADHANDLE;
115 		case B_NOT_SUPPORTED:	return NFS4ERR_OP_ILLEGAL;
116 		default:				return NFS4ERR_RESOURCE;
117 	}
118 }
119 
120