1 /* vi: set sw=4 ts=4: */
3 * nfsmount.c -- Linux NFS mount
4 * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * Wed Feb 8 12:51:48 1995, biro@yggdrasil.com (Ross Biro): allow all port
17 * numbers to be specified on the command line.
19 * Fri, 8 Mar 1996 18:01:39, Swen Thuemmler <swen@uni-paderborn.de>:
20 * Omit the call to connect() for Linux version 1.3.11 or later.
22 * Wed Oct 1 23:55:28 1997: Dick Streefland <dick_streefland@tasking.com>
23 * Implemented the "bg", "fg" and "retry" mount options for NFS.
25 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
26 * - added Native Language Support
28 * Modified by Olaf Kirch and Trond Myklebust for new NFS code,
33 * nfsmount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
45 #include <rpc/pmap_prot.h>
46 #include <rpc/pmap_clnt.h>
47 #include <sys/socket.h>
49 #include <sys/utsname.h>
50 #include <netinet/in.h>
51 #include <arpa/inet.h>
54 #include <linux/nfs.h> /* For the kernels nfs stuff */
57 /* Disable the nls stuff */
58 # undef bindtextdomain
59 # define bindtextdomain(Domain, Directory) /* empty */
61 # define textdomain(Domain) /* empty */
62 # define _(Text) (Text)
63 # define N_(Text) (Text)
65 #define MS_MGC_VAL 0xc0ed0000 /* Magic number indicatng "new" flags */
66 #define MS_RDONLY 1 /* Mount read-only */
67 #define MS_NOSUID 2 /* Ignore suid and sgid bits */
68 #define MS_NODEV 4 /* Disallow access to device special files */
69 #define MS_NOEXEC 8 /* Disallow program execution */
70 #define MS_SYNCHRONOUS 16 /* Writes are synced at once */
71 #define MS_REMOUNT 32 /* Alter flags of a mounted FS */
72 #define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
73 #define S_QUOTA 128 /* Quota initialized for file/directory/symlink */
74 #define S_APPEND 256 /* Append-only file */
75 #define S_IMMUTABLE 512 /* Immutable file */
76 #define MS_NOATIME 1024 /* Do not update access times. */
77 #define MS_NODIRATIME 2048 /* Do not update directory access times */
81 * We want to be able to compile mount on old kernels in such a way
82 * that the binary will work well on more recent kernels.
83 * Thus, if necessary we teach nfsmount.c the structure of new fields
84 * that will come later.
86 * Moreover, the new kernel includes conflict with glibc includes
87 * so it is easiest to ignore the kernel altogether (at compile time).
90 #define NFS_MOUNT_VERSION 4
97 unsigned char data[64];
100 struct nfs_mount_data {
103 struct nfs2_fh old_root; /* 1 */
109 int acregmin; /* 1 */
110 int acregmax; /* 1 */
111 int acdirmin; /* 1 */
112 int acdirmax; /* 1 */
113 struct sockaddr_in addr; /* 1 */
114 char hostname[256]; /* 1 */
116 unsigned int bsize; /* 3 */
117 struct nfs3_fh root; /* 4 */
120 /* bits in the flags field */
122 #define NFS_MOUNT_SOFT 0x0001 /* 1 */
123 #define NFS_MOUNT_INTR 0x0002 /* 1 */
124 #define NFS_MOUNT_SECURE 0x0004 /* 1 */
125 #define NFS_MOUNT_POSIX 0x0008 /* 1 */
126 #define NFS_MOUNT_NOCTO 0x0010 /* 1 */
127 #define NFS_MOUNT_NOAC 0x0020 /* 1 */
128 #define NFS_MOUNT_TCP 0x0040 /* 2 */
129 #define NFS_MOUNT_VER3 0x0080 /* 3 */
130 #define NFS_MOUNT_KERBEROS 0x0100 /* 3 */
131 #define NFS_MOUNT_NONLM 0x0200 /* 3 */
134 #define UTIL_LINUX_VERSION "2.10m"
135 #define util_linux_version "util-linux-2.10m"
137 #define HAVE_inet_aton
142 #define HAVE_locale_h
143 #define HAVE_libintl_h
145 #define HAVE_langinfo_h
146 #define HAVE_progname
148 #define HAVE_nanosleep
149 #define HAVE_personality
150 #define HAVE_tm_gmtoff
152 extern char *xstrdup (const char *s);
153 extern char *xstrndup (const char *s, int n);
154 static char *nfs_strerror(int stat);
156 #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
157 #define MAX_NFSPROT ((nfs_mount_version >= 4) ? 3 : 2)
159 #define EX_FAIL 32 /* mount failure */
160 #define EX_BG 256 /* retry in background (internal only) */
164 * nfs_mount_version according to the sources seen at compile time.
166 int nfs_mount_version = NFS_MOUNT_VERSION;
169 * Unfortunately, the kernel prints annoying console messages
170 * in case of an unexpected nfs mount version (instead of
171 * just returning some error). Therefore we'll have to try
172 * and figure out what version the kernel expects.
175 * KERNEL_NFS_MOUNT_VERSION: kernel sources at compile time
176 * NFS_MOUNT_VERSION: these nfsmount sources at compile time
177 * nfs_mount_version: version this source and running kernel can handle
180 find_kernel_nfs_mount_version(void) {
181 static int kernel_version = 0;
186 kernel_version = get_kernel_revision();
188 if (kernel_version) {
189 if (kernel_version < MAKE_VERSION(2,1,32))
190 nfs_mount_version = 1;
191 else if (kernel_version < MAKE_VERSION(2,3,99))
192 nfs_mount_version = 3;
194 nfs_mount_version = 4; /* since 2.3.99pre4 */
196 if (nfs_mount_version > NFS_MOUNT_VERSION)
197 nfs_mount_version = NFS_MOUNT_VERSION;
201 get_mountport(struct sockaddr_in *server_addr,
203 long unsigned version,
207 struct pmaplist *pmap;
208 static struct pmap p = {0, 0, 0, 0};
210 server_addr->sin_port = PMAPPORT;
211 pmap = pmap_getmaps(server_addr);
213 if (version > MAX_NFSPROT)
214 version = MAX_NFSPROT;
223 if (pmap->pml_map.pm_prog != prog)
225 if (!version && p.pm_vers > pmap->pml_map.pm_vers)
227 if (version > 2 && pmap->pml_map.pm_vers != version)
229 if (version && version <= 2 && pmap->pml_map.pm_vers > 2)
231 if (pmap->pml_map.pm_vers > MAX_NFSPROT ||
232 (proto && p.pm_prot && pmap->pml_map.pm_prot != proto) ||
233 (port && pmap->pml_map.pm_port != port))
235 memcpy(&p, &pmap->pml_map, sizeof(p));
237 pmap = pmap->pml_next;
240 p.pm_vers = MOUNTVERS;
242 p.pm_port = MOUNTPORT;
244 p.pm_prot = IPPROTO_TCP;
248 int nfsmount(const char *spec, const char *node, int *flags,
249 char **extra_opts, char **mount_opts, int running_bg)
251 static char *prev_bg_host;
257 char *mounthost=NULL;
259 struct timeval total_timeout;
260 enum clnt_stat clnt_stat;
261 static struct nfs_mount_data data;
265 struct sockaddr_in server_addr;
266 struct sockaddr_in mount_server_addr;
269 struct timeval retry_timeout;
271 struct fhstatus nfsv2;
272 struct mountres3 nfsv3;
297 find_kernel_nfs_mount_version();
302 if (strlen(spec) >= sizeof(hostdir)) {
303 error_msg("excessively long host:dir argument\n");
306 strcpy(hostdir, spec);
307 if ((s = strchr(hostdir, ':'))) {
311 /* Ignore all but first hostname in replicated mounts
312 until they can be fully supported. (mack@sgi.com) */
313 if ((s = strchr(hostdir, ','))) {
315 error_msg("warning: multiple hostnames not supported\n");
318 error_msg("directory to mount not in host:dir format\n");
322 server_addr.sin_family = AF_INET;
323 #ifdef HAVE_inet_aton
324 if (!inet_aton(hostname, &server_addr.sin_addr))
327 if ((hp = gethostbyname(hostname)) == NULL) {
328 error_msg("can't get address for %s\n", hostname);
331 if (hp->h_length > sizeof(struct in_addr)) {
332 error_msg("got bad hp->h_length\n");
333 hp->h_length = sizeof(struct in_addr);
335 memcpy(&server_addr.sin_addr,
336 hp->h_addr, hp->h_length);
340 memcpy (&mount_server_addr, &server_addr, sizeof (mount_server_addr));
342 /* add IP address to mtab options for use when unmounting */
344 s = inet_ntoa(server_addr.sin_addr);
345 old_opts = *extra_opts;
348 if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
349 error_msg("excessively long option argument\n");
352 sprintf(new_opts, "%s%saddr=%s",
353 old_opts, *old_opts ? "," : "", s);
354 *extra_opts = xstrdup(new_opts);
356 /* Set default options.
357 * rsize/wsize (and bsize, for ver >= 3) are left 0 in order to
358 * let the kernel decide.
359 * timeo is filled in after we know whether it'll be TCP or UDP. */
360 memset(&data, 0, sizeof(data));
366 #if NFS_MOUNT_VERSION >= 2
367 data.namlen = NAME_MAX;
377 retry = 10000; /* 10000 minutes ~ 1 week */
380 mountprog = MOUNTPROG;
384 nfsprog = NFS_PROGRAM;
389 for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
390 if ((opteq = strchr(opt, '='))) {
391 val = atoi(opteq + 1);
393 if (!strcmp(opt, "rsize"))
395 else if (!strcmp(opt, "wsize"))
397 else if (!strcmp(opt, "timeo"))
399 else if (!strcmp(opt, "retrans"))
401 else if (!strcmp(opt, "acregmin"))
403 else if (!strcmp(opt, "acregmax"))
405 else if (!strcmp(opt, "acdirmin"))
407 else if (!strcmp(opt, "acdirmax"))
409 else if (!strcmp(opt, "actimeo")) {
415 else if (!strcmp(opt, "retry"))
417 else if (!strcmp(opt, "port"))
419 else if (!strcmp(opt, "mountport"))
421 else if (!strcmp(opt, "mounthost"))
422 mounthost=xstrndup(opteq+1,
423 strcspn(opteq+1," \t\n\r,"));
424 else if (!strcmp(opt, "mountprog"))
426 else if (!strcmp(opt, "mountvers"))
428 else if (!strcmp(opt, "nfsprog"))
430 else if (!strcmp(opt, "nfsvers") ||
431 !strcmp(opt, "vers"))
433 else if (!strcmp(opt, "proto")) {
434 if (!strncmp(opteq+1, "tcp", 3))
436 else if (!strncmp(opteq+1, "udp", 3))
439 printf(_("Warning: Unrecognized proto= option.\n"));
440 } else if (!strcmp(opt, "namlen")) {
441 #if NFS_MOUNT_VERSION >= 2
442 if (nfs_mount_version >= 2)
446 printf(_("Warning: Option namlen is not supported.\n"));
447 } else if (!strcmp(opt, "addr"))
450 printf(_("unknown nfs mount parameter: "
451 "%s=%d\n"), opt, val);
457 if (!strncmp(opt, "no", 2)) {
461 if (!strcmp(opt, "bg"))
463 else if (!strcmp(opt, "fg"))
465 else if (!strcmp(opt, "soft"))
467 else if (!strcmp(opt, "hard"))
469 else if (!strcmp(opt, "intr"))
471 else if (!strcmp(opt, "posix"))
473 else if (!strcmp(opt, "cto"))
475 else if (!strcmp(opt, "ac"))
477 else if (!strcmp(opt, "tcp"))
479 else if (!strcmp(opt, "udp"))
481 else if (!strcmp(opt, "lock")) {
482 if (nfs_mount_version >= 3)
485 printf(_("Warning: option nolock is not supported.\n"));
487 printf(_("unknown nfs mount option: "
488 "%s%s\n"), val ? "" : "no", opt);
493 proto = (tcp) ? IPPROTO_TCP : IPPROTO_UDP;
495 data.flags = (soft ? NFS_MOUNT_SOFT : 0)
496 | (intr ? NFS_MOUNT_INTR : 0)
497 | (posix ? NFS_MOUNT_POSIX : 0)
498 | (nocto ? NFS_MOUNT_NOCTO : 0)
499 | (noac ? NFS_MOUNT_NOAC : 0);
500 #if NFS_MOUNT_VERSION >= 2
501 if (nfs_mount_version >= 2)
502 data.flags |= (tcp ? NFS_MOUNT_TCP : 0);
504 #if NFS_MOUNT_VERSION >= 3
505 if (nfs_mount_version >= 3)
506 data.flags |= (nolock ? NFS_MOUNT_NONLM : 0);
508 if (nfsvers > MAX_NFSPROT) {
509 error_msg("NFSv%d not supported!\n", nfsvers);
512 if (mountvers > MAX_NFSPROT) {
513 error_msg("NFSv%d not supported!\n", nfsvers);
516 if (nfsvers && !mountvers)
517 mountvers = (nfsvers < 3) ? 1 : nfsvers;
518 if (nfsvers && nfsvers < mountvers) {
522 /* Adjust options if none specified */
524 data.timeo = tcp ? 70 : 7;
526 #ifdef NFS_MOUNT_DEBUG
527 printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
528 data.rsize, data.wsize, data.timeo, data.retrans);
529 printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
530 data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
531 printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
532 port, bg, retry, data.flags);
533 printf("mountprog = %d, mountvers = %d, nfsprog = %d, nfsvers = %d\n",
534 mountprog, mountvers, nfsprog, nfsvers);
535 printf("soft = %d, intr = %d, posix = %d, nocto = %d, noac = %d\n",
536 (data.flags & NFS_MOUNT_SOFT) != 0,
537 (data.flags & NFS_MOUNT_INTR) != 0,
538 (data.flags & NFS_MOUNT_POSIX) != 0,
539 (data.flags & NFS_MOUNT_NOCTO) != 0,
540 (data.flags & NFS_MOUNT_NOAC) != 0);
541 #if NFS_MOUNT_VERSION >= 2
543 (data.flags & NFS_MOUNT_TCP) != 0);
547 data.version = nfs_mount_version;
548 *mount_opts = (char *) &data;
550 if (*flags & MS_REMOUNT)
554 * If the previous mount operation on the same host was
555 * backgrounded, and the "bg" for this mount is also set,
556 * give up immediately, to avoid the initial timeout.
558 if (bg && !running_bg &&
559 prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
565 /* create mount deamon client */
566 /* See if the nfs host = mount host. */
568 if (mounthost[0] >= '0' && mounthost[0] <= '9') {
569 mount_server_addr.sin_family = AF_INET;
570 mount_server_addr.sin_addr.s_addr = inet_addr(hostname);
572 if ((hp = gethostbyname(mounthost)) == NULL) {
573 error_msg("can't get address for %s\n", hostname);
576 if (hp->h_length > sizeof(struct in_addr)) {
577 error_msg("got bad hp->h_length?\n");
578 hp->h_length = sizeof(struct in_addr);
580 mount_server_addr.sin_family = AF_INET;
581 memcpy(&mount_server_addr.sin_addr,
582 hp->h_addr, hp->h_length);
588 * The following loop implements the mount retries. On the first
589 * call, "running_bg" is 0. When the mount times out, and the
590 * "bg" option is set, the exit status EX_BG will be returned.
591 * For a backgrounded mount, there will be a second call by the
592 * child process with "running_bg" set to 1.
594 * The case where the mount point is not present and the "bg"
595 * option is set, is treated as a timeout. This is done to
596 * support nested mounts.
598 * The "retry" count specified by the user is the number of
599 * minutes to retry before giving up.
601 * Only the first error message will be displayed.
603 retry_timeout.tv_sec = 3;
604 retry_timeout.tv_usec = 0;
605 total_timeout.tv_sec = 20;
606 total_timeout.tv_usec = 0;
607 timeout = time(NULL) + 60 * retry;
612 if (bg && stat(node, &statbuf) == -1) {
614 sleep(val); /* 1, 2, 4, 8, 16, 30, ... */
620 /* be careful not to use too many CPU cycles */
624 pm_mnt = get_mountport(&mount_server_addr,
630 /* contact the mount daemon via TCP */
631 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
634 switch (pm_mnt->pm_prot) {
636 mclient = clntudp_create(&mount_server_addr,
643 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
646 mclient = clnttcp_create(&mount_server_addr,
655 /* try to mount hostname:dirname */
656 mclient->cl_auth = authunix_create_default();
658 /* make pointers in xdr_mountres3 NULL so
659 * that xdr_array allocates memory for us
661 memset(&status, 0, sizeof(status));
663 if (pm_mnt->pm_vers == 3)
664 clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
665 (xdrproc_t) xdr_dirpath,
667 (xdrproc_t) xdr_mountres3,
671 clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
672 (xdrproc_t) xdr_dirpath,
674 (xdrproc_t) xdr_fhstatus,
678 if (clnt_stat == RPC_SUCCESS)
679 break; /* we're done */
680 if (errno != ECONNREFUSED) {
681 clnt_perror(mclient, "mount");
682 goto fail; /* don't retry */
684 if (!running_bg && prevt == 0)
685 clnt_perror(mclient, "mount");
686 auth_destroy(mclient->cl_auth);
687 clnt_destroy(mclient);
691 if (!running_bg && prevt == 0)
692 clnt_pcreateerror("mount");
699 prev_bg_host = xstrdup(hostname);
708 nfsvers = (pm_mnt->pm_vers < 2) ? 2 : pm_mnt->pm_vers;
711 if (status.nfsv2.fhs_status != 0) {
712 error_msg("%s:%s failed, reason given by server: %s\n",
714 nfs_strerror(status.nfsv2.fhs_status));
717 memcpy(data.root.data,
718 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
720 #if NFS_MOUNT_VERSION >= 4
721 data.root.size = NFS_FHSIZE;
722 memcpy(data.old_root.data,
723 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
727 #if NFS_MOUNT_VERSION >= 4
729 if (status.nfsv3.fhs_status != 0) {
730 error_msg("%s:%s failed, reason given by server: %s\n",
732 nfs_strerror(status.nfsv3.fhs_status));
735 fhandle = &status.nfsv3.mountres3_u.mountinfo.fhandle;
736 memset(data.old_root.data, 0, NFS_FHSIZE);
737 memset(&data.root, 0, sizeof(data.root));
738 data.root.size = fhandle->fhandle3_len;
739 memcpy(data.root.data,
740 (char *) fhandle->fhandle3_val,
741 fhandle->fhandle3_len);
743 data.flags |= NFS_MOUNT_VER3;
747 /* create nfs socket for kernel */
750 if (nfs_mount_version < 3) {
751 printf(_("NFS over TCP is not supported.\n"));
754 fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
756 fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
758 perror(_("nfs socket"));
761 if (bindresvport(fsock, 0) < 0) {
762 perror(_("nfs bindresvport"));
766 server_addr.sin_port = PMAPPORT;
767 port = pmap_getport(&server_addr, nfsprog, nfsvers,
768 tcp ? IPPROTO_TCP : IPPROTO_UDP);
771 #ifdef NFS_MOUNT_DEBUG
773 printf(_("used portmapper to find NFS port\n"));
776 #ifdef NFS_MOUNT_DEBUG
777 printf(_("using port %d for nfs deamon\n"), port);
779 server_addr.sin_port = htons(port);
781 * connect() the socket for kernels 1.3.10 and below only,
782 * to avoid problems with multihomed hosts.
785 if (get_kernel_revision() <= 66314
786 && connect(fsock, (struct sockaddr *) &server_addr,
787 sizeof (server_addr)) < 0) {
788 perror(_("nfs connect"));
792 /* prepare data structure for kernel */
795 memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
796 strncpy(data.hostname, hostname, sizeof(data.hostname));
800 auth_destroy(mclient->cl_auth);
801 clnt_destroy(mclient);
810 auth_destroy(mclient->cl_auth);
811 clnt_destroy(mclient);
821 * We need to translate between nfs status return values and
822 * the local errno values which may not be the same.
824 * Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>: change errno:
825 * "after #include <errno.h> the symbol errno is reserved for any use,
826 * it cannot even be used as a struct tag or field name".
830 #define EDQUOT ENOSPC
838 { NFSERR_PERM, EPERM },
839 { NFSERR_NOENT, ENOENT },
841 { NFSERR_NXIO, ENXIO },
842 { NFSERR_ACCES, EACCES },
843 { NFSERR_EXIST, EEXIST },
844 { NFSERR_NODEV, ENODEV },
845 { NFSERR_NOTDIR, ENOTDIR },
846 { NFSERR_ISDIR, EISDIR },
848 { NFSERR_INVAL, EINVAL }, /* that Sun forgot */
850 { NFSERR_FBIG, EFBIG },
851 { NFSERR_NOSPC, ENOSPC },
852 { NFSERR_ROFS, EROFS },
853 { NFSERR_NAMETOOLONG, ENAMETOOLONG },
854 { NFSERR_NOTEMPTY, ENOTEMPTY },
855 { NFSERR_DQUOT, EDQUOT },
856 { NFSERR_STALE, ESTALE },
858 { NFSERR_WFLUSH, EWFLUSH },
860 /* Throw in some NFSv3 values for even more fun (HP returns these) */
866 static char *nfs_strerror(int stat)
869 static char buf[256];
871 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
872 if (nfs_errtbl[i].stat == stat)
873 return strerror(nfs_errtbl[i].errnum);
875 sprintf(buf, _("unknown nfs status return value: %d"), stat);
880 xdr_fhandle (XDR *xdrs, fhandle objp)
882 //register int32_t *buf;
884 if (!xdr_opaque (xdrs, objp, FHSIZE))
890 xdr_fhstatus (XDR *xdrs, fhstatus *objp)
892 //register int32_t *buf;
894 if (!xdr_u_int (xdrs, &objp->fhs_status))
896 switch (objp->fhs_status) {
898 if (!xdr_fhandle (xdrs, objp->fhstatus_u.fhs_fhandle))
908 xdr_dirpath (XDR *xdrs, dirpath *objp)
910 //register int32_t *buf;
912 if (!xdr_string (xdrs, objp, MNTPATHLEN))
918 xdr_fhandle3 (XDR *xdrs, fhandle3 *objp)
920 //register int32_t *buf;
922 if (!xdr_bytes (xdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3))
928 xdr_mountres3_ok (XDR *xdrs, mountres3_ok *objp)
930 //register int32_t *buf;
932 if (!xdr_fhandle3 (xdrs, &objp->fhandle))
934 if (!xdr_array (xdrs, (char **)&objp->auth_flavours.auth_flavours_val, (u_int *) &objp->auth_flavours.auth_flavours_len, ~0,
935 sizeof (int), (xdrproc_t) xdr_int))
941 xdr_mountstat3 (XDR *xdrs, mountstat3 *objp)
943 //register int32_t *buf;
945 if (!xdr_enum (xdrs, (enum_t *) objp))
951 xdr_mountres3 (XDR *xdrs, mountres3 *objp)
953 //register int32_t *buf;
955 if (!xdr_mountstat3 (xdrs, &objp->fhs_status))
957 switch (objp->fhs_status) {
959 if (!xdr_mountres3_ok (xdrs, &objp->mountres3_u.mountinfo))