xref: /haiku/src/add-ons/kernel/file_systems/nfs4/ReplyBuilder.cpp (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
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 	if (fReply == NULL)
50 		return NULL;
51 
52 	fReply->Stream().InsertUInt(fStatusPosition, _HaikuErrorToNFS4(fStatus));
53 	fReply->Stream().InsertUInt(fOpCountPosition, fOpCount);
54 
55 	if (fReply->Stream().Error() == B_OK)
56 		return fReply;
57 	else
58 		return NULL;
59 }
60 
61 
62 status_t
63 ReplyBuilder::GetAttr(status_t status, int mask, uint64 size, uint64 change)
64 {
65 	if (fStatus != B_OK)
66 		return B_ERROR;
67 
68 	fReply->Stream().AddUInt(OpCallbackGetAttr);
69 	fReply->Stream().AddUInt(_HaikuErrorToNFS4(fStatus));
70 	fStatus = status;
71 
72 	if (status == B_OK) {
73 		uint32 bitmap = 0;
74 		if ((mask & CallbackAttrChange) != 0)
75 			bitmap |= 1 << FATTR4_CHANGE;
76 		if ((mask & CallbackAttrSize) != 0)
77 			bitmap |= 1 << FATTR4_SIZE;
78 		fReply->Stream().AddUInt(1);
79 		fReply->Stream().AddUInt(bitmap);
80 
81 		XDR::WriteStream str;
82 		if ((mask & CallbackAttrChange) != 0)
83 			str.AddUHyper(change);
84 
85 		if ((mask & CallbackAttrSize) != 0)
86 			str.AddUHyper(size);
87 		fReply->Stream().AddOpaque(str);
88 	}
89 
90 	fOpCount++;
91 
92 	return B_OK;
93 }
94 
95 
96 status_t
97 ReplyBuilder::Recall(status_t status)
98 {
99 	if (fStatus != B_OK)
100 		return B_ERROR;
101 
102 	fReply->Stream().AddUInt(OpCallbackRecall);
103 	fReply->Stream().AddUInt(_HaikuErrorToNFS4(fStatus));
104 	fStatus = status;
105 
106 	fOpCount++;
107 
108 	return B_OK;
109 }
110 
111 
112 uint32
113 ReplyBuilder::_HaikuErrorToNFS4(status_t error)
114 {
115 	switch (error) {
116 		case B_OK:				return NFS4_OK;
117 		case B_ENTRY_NOT_FOUND:	return NFS4ERR_BADHANDLE;
118 		case B_NOT_SUPPORTED:	return NFS4ERR_OP_ILLEGAL;
119 		default:				return NFS4ERR_RESOURCE;
120 	}
121 }
122 
123