Add a new option to make caching writethrough instead of writeback.
[bluesky.git] / nfs3 / rpc.c
1 /* Blue Sky: File Systems in the Cloud
2  *
3  * Copyright (C) 2009  The Regents of the University of California
4  * Written by Michael Vrable <mvrable@cs.ucsd.edu>
5  *
6  * TODO: Licensing
7  */
8
9 /* RPC handling: registration, marshalling and unmarshalling of messages.  For
10  * now this uses the standard Sun RPC mechanisms in the standard C library.
11  * Later, it might be changed to use something better.  Much of this code was
12  * generated with rpcgen from the XDR specifications, but has been hand-edited
13  * slightly. */
14
15 #include "mount_prot.h"
16 #include "nfs3_prot.h"
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <rpc/pmap_clnt.h>
20 #include <string.h>
21 #include <memory.h>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24
25 #include "bluesky.h"
26 extern BlueSkyFS *fs;
27
28 static void
29 mount_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
30 {
31     union {
32         dirpath mountproc3_mnt_3_arg;
33         dirpath mountproc3_umnt_3_arg;
34     } argument;
35     char *result;
36     xdrproc_t _xdr_argument, _xdr_result;
37     char *(*local)(char *, struct svc_req *);
38
39     switch (rqstp->rq_proc) {
40     case MOUNTPROC3_NULL:
41         _xdr_argument = (xdrproc_t) xdr_void;
42         _xdr_result = (xdrproc_t) xdr_void;
43         local = (char *(*)(char *, struct svc_req *)) mountproc3_null_3_svc;
44         break;
45
46     case MOUNTPROC3_MNT:
47         _xdr_argument = (xdrproc_t) xdr_dirpath;
48         _xdr_result = (xdrproc_t) xdr_mountres3;
49         local = (char *(*)(char *, struct svc_req *)) mountproc3_mnt_3_svc;
50         break;
51
52     case MOUNTPROC3_DUMP:
53         _xdr_argument = (xdrproc_t) xdr_void;
54         _xdr_result = (xdrproc_t) xdr_mountlist;
55         local = (char *(*)(char *, struct svc_req *)) mountproc3_dump_3_svc;
56         break;
57
58     case MOUNTPROC3_UMNT:
59         _xdr_argument = (xdrproc_t) xdr_dirpath;
60         _xdr_result = (xdrproc_t) xdr_void;
61         local = (char *(*)(char *, struct svc_req *)) mountproc3_umnt_3_svc;
62         break;
63
64     case MOUNTPROC3_UMNTALL:
65         _xdr_argument = (xdrproc_t) xdr_void;
66         _xdr_result = (xdrproc_t) xdr_void;
67         local = (char *(*)(char *, struct svc_req *)) mountproc3_umntall_3_svc;
68         break;
69
70     case MOUNTPROC3_EXPORT:
71         _xdr_argument = (xdrproc_t) xdr_void;
72         _xdr_result = (xdrproc_t) xdr_exports;
73         local = (char *(*)(char *, struct svc_req *)) mountproc3_export_3_svc;
74         break;
75
76     default:
77         svcerr_noproc (transp);
78         return;
79     }
80     memset ((char *)&argument, 0, sizeof (argument));
81     if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
82         svcerr_decode (transp);
83         return;
84     }
85     result = (*local)((char *)&argument, rqstp);
86     if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
87         svcerr_systemerr (transp);
88     }
89     if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
90         fprintf (stderr, "%s", "unable to free arguments");
91         exit (1);
92     }
93     return;
94 }
95
96 static void
97 nfs_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
98 {
99     union {
100         nfs_fh3 nfsproc3_getattr_3_arg;
101         setattr3args nfsproc3_setattr_3_arg;
102         diropargs3 nfsproc3_lookup_3_arg;
103         access3args nfsproc3_access_3_arg;
104         nfs_fh3 nfsproc3_readlink_3_arg;
105         read3args nfsproc3_read_3_arg;
106         write3args nfsproc3_write_3_arg;
107         create3args nfsproc3_create_3_arg;
108         mkdir3args nfsproc3_mkdir_3_arg;
109         symlink3args nfsproc3_symlink_3_arg;
110         mknod3args nfsproc3_mknod_3_arg;
111         diropargs3 nfsproc3_remove_3_arg;
112         diropargs3 nfsproc3_rmdir_3_arg;
113         rename3args nfsproc3_rename_3_arg;
114         link3args nfsproc3_link_3_arg;
115         readdir3args nfsproc3_readdir_3_arg;
116         readdirplus3args nfsproc3_readdirplus_3_arg;
117         nfs_fh3 nfsproc3_fsstat_3_arg;
118         nfs_fh3 nfsproc3_fsinfo_3_arg;
119         nfs_fh3 nfsproc3_pathconf_3_arg;
120         commit3args nfsproc3_commit_3_arg;
121     } argument;
122     char *result;
123     xdrproc_t _xdr_argument, _xdr_result;
124     char *(*local)(char *, struct svc_req *);
125
126     switch (rqstp->rq_proc) {
127     case NFSPROC3_NULL:
128         _xdr_argument = (xdrproc_t) xdr_void;
129         _xdr_result = (xdrproc_t) xdr_void;
130         local = (char *(*)(char *, struct svc_req *)) nfsproc3_null_3_svc;
131         break;
132
133     case NFSPROC3_GETATTR:
134         _xdr_argument = (xdrproc_t) xdr_nfs_fh3;
135         _xdr_result = (xdrproc_t) xdr_getattr3res;
136         local = (char *(*)(char *, struct svc_req *)) nfsproc3_getattr_3_svc;
137         break;
138
139     case NFSPROC3_SETATTR:
140         _xdr_argument = (xdrproc_t) xdr_setattr3args;
141         _xdr_result = (xdrproc_t) xdr_wccstat3;
142         local = (char *(*)(char *, struct svc_req *)) nfsproc3_setattr_3_svc;
143         break;
144
145     case NFSPROC3_LOOKUP:
146         _xdr_argument = (xdrproc_t) xdr_diropargs3;
147         _xdr_result = (xdrproc_t) xdr_lookup3res;
148         local = (char *(*)(char *, struct svc_req *)) nfsproc3_lookup_3_svc;
149         break;
150
151     case NFSPROC3_ACCESS:
152         _xdr_argument = (xdrproc_t) xdr_access3args;
153         _xdr_result = (xdrproc_t) xdr_access3res;
154         local = (char *(*)(char *, struct svc_req *)) nfsproc3_access_3_svc;
155         break;
156
157     case NFSPROC3_READLINK:
158         _xdr_argument = (xdrproc_t) xdr_nfs_fh3;
159         _xdr_result = (xdrproc_t) xdr_readlink3res;
160         local = (char *(*)(char *, struct svc_req *)) nfsproc3_readlink_3_svc;
161         break;
162
163     case NFSPROC3_READ:
164         _xdr_argument = (xdrproc_t) xdr_read3args;
165         _xdr_result = (xdrproc_t) xdr_read3res;
166         local = (char *(*)(char *, struct svc_req *)) nfsproc3_read_3_svc;
167         break;
168
169     case NFSPROC3_WRITE:
170         _xdr_argument = (xdrproc_t) xdr_write3args;
171         _xdr_result = (xdrproc_t) xdr_write3res;
172         local = (char *(*)(char *, struct svc_req *)) nfsproc3_write_3_svc;
173         break;
174
175     case NFSPROC3_CREATE:
176         _xdr_argument = (xdrproc_t) xdr_create3args;
177         _xdr_result = (xdrproc_t) xdr_diropres3;
178         local = (char *(*)(char *, struct svc_req *)) nfsproc3_create_3_svc;
179         break;
180
181     case NFSPROC3_MKDIR:
182         _xdr_argument = (xdrproc_t) xdr_mkdir3args;
183         _xdr_result = (xdrproc_t) xdr_diropres3;
184         local = (char *(*)(char *, struct svc_req *)) nfsproc3_mkdir_3_svc;
185         break;
186
187     case NFSPROC3_SYMLINK:
188         _xdr_argument = (xdrproc_t) xdr_symlink3args;
189         _xdr_result = (xdrproc_t) xdr_diropres3;
190         local = (char *(*)(char *, struct svc_req *)) nfsproc3_symlink_3_svc;
191         break;
192
193     case NFSPROC3_MKNOD:
194         _xdr_argument = (xdrproc_t) xdr_mknod3args;
195         _xdr_result = (xdrproc_t) xdr_diropres3;
196         local = (char *(*)(char *, struct svc_req *)) nfsproc3_mknod_3_svc;
197         break;
198
199     case NFSPROC3_REMOVE:
200         _xdr_argument = (xdrproc_t) xdr_diropargs3;
201         _xdr_result = (xdrproc_t) xdr_wccstat3;
202         local = (char *(*)(char *, struct svc_req *)) nfsproc3_remove_3_svc;
203         break;
204
205     case NFSPROC3_RMDIR:
206         _xdr_argument = (xdrproc_t) xdr_diropargs3;
207         _xdr_result = (xdrproc_t) xdr_wccstat3;
208         local = (char *(*)(char *, struct svc_req *)) nfsproc3_rmdir_3_svc;
209         break;
210
211     case NFSPROC3_RENAME:
212         _xdr_argument = (xdrproc_t) xdr_rename3args;
213         _xdr_result = (xdrproc_t) xdr_rename3res;
214         local = (char *(*)(char *, struct svc_req *)) nfsproc3_rename_3_svc;
215         break;
216
217     case NFSPROC3_LINK:
218         _xdr_argument = (xdrproc_t) xdr_link3args;
219         _xdr_result = (xdrproc_t) xdr_link3res;
220         local = (char *(*)(char *, struct svc_req *)) nfsproc3_link_3_svc;
221         break;
222
223     case NFSPROC3_READDIR:
224         _xdr_argument = (xdrproc_t) xdr_readdir3args;
225         _xdr_result = (xdrproc_t) xdr_readdir3res;
226         local = (char *(*)(char *, struct svc_req *)) nfsproc3_readdir_3_svc;
227         break;
228
229     case NFSPROC3_READDIRPLUS:
230         _xdr_argument = (xdrproc_t) xdr_readdirplus3args;
231         _xdr_result = (xdrproc_t) xdr_readdirplus3res;
232         local = (char *(*)(char *, struct svc_req *)) nfsproc3_readdirplus_3_svc;
233         break;
234
235     case NFSPROC3_FSSTAT:
236         _xdr_argument = (xdrproc_t) xdr_nfs_fh3;
237         _xdr_result = (xdrproc_t) xdr_fsstat3res;
238         local = (char *(*)(char *, struct svc_req *)) nfsproc3_fsstat_3_svc;
239         break;
240
241     case NFSPROC3_FSINFO:
242         _xdr_argument = (xdrproc_t) xdr_nfs_fh3;
243         _xdr_result = (xdrproc_t) xdr_fsinfo3res;
244         local = (char *(*)(char *, struct svc_req *)) nfsproc3_fsinfo_3_svc;
245         break;
246
247     case NFSPROC3_PATHCONF:
248         _xdr_argument = (xdrproc_t) xdr_nfs_fh3;
249         _xdr_result = (xdrproc_t) xdr_pathconf3res;
250         local = (char *(*)(char *, struct svc_req *)) nfsproc3_pathconf_3_svc;
251         break;
252
253     case NFSPROC3_COMMIT:
254         _xdr_argument = (xdrproc_t) xdr_commit3args;
255         _xdr_result = (xdrproc_t) xdr_commit3res;
256         local = (char *(*)(char *, struct svc_req *)) nfsproc3_commit_3_svc;
257         break;
258
259     default:
260         svcerr_noproc (transp);
261         return;
262     }
263     memset ((char *)&argument, 0, sizeof (argument));
264     if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
265         svcerr_decode (transp);
266         return;
267     }
268     result = (*local)((char *)&argument, rqstp);
269     if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
270         svcerr_systemerr (transp);
271     }
272     if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
273         fprintf (stderr, "%s", "unable to free arguments");
274         exit (1);
275     }
276
277     bluesky_flushd_invoke(fs);
278
279     return;
280 }
281
282 void register_rpc()
283 {
284     SVCXPRT *transp;
285
286     /* MOUNT protocol */
287     pmap_unset (MOUNT_PROGRAM, MOUNT_V3);
288
289     transp = svcudp_create(RPC_ANYSOCK);
290     if (transp == NULL) {
291         fprintf(stderr, "%s", "cannot create udp service.");
292         exit(1);
293     }
294     if (!svc_register(transp, MOUNT_PROGRAM, MOUNT_V3, mount_program_3, IPPROTO_UDP)) {
295         fprintf(stderr, "%s", "unable to register (MOUNT_PROGRAM, MOUNT_V3, udp).");
296         exit(1);
297     }
298
299     transp = svctcp_create(RPC_ANYSOCK, 0, 0);
300     if (transp == NULL) {
301         fprintf(stderr, "%s", "cannot create tcp service.");
302         exit(1);
303     }
304     if (!svc_register(transp, MOUNT_PROGRAM, MOUNT_V3, mount_program_3, IPPROTO_TCP)) {
305         fprintf(stderr, "%s", "unable to register (MOUNT_PROGRAM, MOUNT_V3, tcp).");
306         exit(1);
307     }
308
309     /* NFS protocol (version 3) */
310     pmap_unset (NFS_PROGRAM, NFS_V3);
311
312     transp = svcudp_create(RPC_ANYSOCK);
313     if (transp == NULL) {
314         fprintf (stderr, "%s", "cannot create udp service.");
315         exit(1);
316     }
317     if (!svc_register(transp, NFS_PROGRAM, NFS_V3, nfs_program_3, IPPROTO_UDP)) {
318         fprintf (stderr, "%s", "unable to register (NFS_PROGRAM, NFS_V3, udp).");
319         exit(1);
320     }
321
322     transp = svctcp_create(RPC_ANYSOCK, 0, 0);
323     if (transp == NULL) {
324         fprintf (stderr, "%s", "cannot create tcp service.");
325         exit(1);
326     }
327     if (!svc_register(transp, NFS_PROGRAM, NFS_V3, nfs_program_3, IPPROTO_TCP)) {
328         fprintf (stderr, "%s", "unable to register (NFS_PROGRAM, NFS_V3, tcp).");
329         exit(1);
330     }
331 }