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 */
63 /* Disable the nls stuff */
64 # undef bindtextdomain
65 # define bindtextdomain(Domain, Directory) /* empty */
67 # define textdomain(Domain) /* empty */
68 # define _(Text) (Text)
69 # define N_(Text) (Text)
71 #define MS_MGC_VAL 0xc0ed0000 /* Magic number indicatng "new" flags */
72 #define MS_RDONLY 1 /* Mount read-only */
73 #define MS_NOSUID 2 /* Ignore suid and sgid bits */
74 #define MS_NODEV 4 /* Disallow access to device special files */
75 #define MS_NOEXEC 8 /* Disallow program execution */
76 #define MS_SYNCHRONOUS 16 /* Writes are synced at once */
77 #define MS_REMOUNT 32 /* Alter flags of a mounted FS */
78 #define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
79 #define S_QUOTA 128 /* Quota initialized for file/directory/symlink */
80 #define S_APPEND 256 /* Append-only file */
81 #define S_IMMUTABLE 512 /* Immutable file */
82 #define MS_NOATIME 1024 /* Do not update access times. */
83 #define MS_NODIRATIME 2048 /* Do not update directory access times */
87 * We want to be able to compile mount on old kernels in such a way
88 * that the binary will work well on more recent kernels.
89 * Thus, if necessary we teach nfsmount.c the structure of new fields
90 * that will come later.
92 * Moreover, the new kernel includes conflict with glibc includes
93 * so it is easiest to ignore the kernel altogether (at compile time).
96 #define NFS_MOUNT_VERSION 4
103 unsigned char data[64];
106 struct nfs_mount_data {
109 struct nfs2_fh old_root; /* 1 */
115 int acregmin; /* 1 */
116 int acregmax; /* 1 */
117 int acdirmin; /* 1 */
118 int acdirmax; /* 1 */
119 struct sockaddr_in addr; /* 1 */
120 char hostname[256]; /* 1 */
122 unsigned int bsize; /* 3 */
123 struct nfs3_fh root; /* 4 */
126 /* bits in the flags field */
128 #define NFS_MOUNT_SOFT 0x0001 /* 1 */
129 #define NFS_MOUNT_INTR 0x0002 /* 1 */
130 #define NFS_MOUNT_SECURE 0x0004 /* 1 */
131 #define NFS_MOUNT_POSIX 0x0008 /* 1 */
132 #define NFS_MOUNT_NOCTO 0x0010 /* 1 */
133 #define NFS_MOUNT_NOAC 0x0020 /* 1 */
134 #define NFS_MOUNT_TCP 0x0040 /* 2 */
135 #define NFS_MOUNT_VER3 0x0080 /* 3 */
136 #define NFS_MOUNT_KERBEROS 0x0100 /* 3 */
137 #define NFS_MOUNT_NONLM 0x0200 /* 3 */
140 #define UTIL_LINUX_VERSION "2.10m"
141 #define util_linux_version "util-linux-2.10m"
143 #define HAVE_inet_aton
148 #define HAVE_locale_h
149 #define HAVE_libintl_h
151 #define HAVE_langinfo_h
152 #define HAVE_progname
154 #define HAVE_nanosleep
155 #define HAVE_personality
156 #define HAVE_tm_gmtoff
158 extern char *xstrdup (const char *s);
159 extern char *xstrndup (const char *s, int n);
160 static char *nfs_strerror(int stat);
162 #define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
163 #define MAX_NFSPROT ((nfs_mount_version >= 4) ? 3 : 2)
165 #define EX_FAIL 32 /* mount failure */
166 #define EX_BG 256 /* retry in background (internal only) */
170 * nfs_mount_version according to the sources seen at compile time.
172 int nfs_mount_version = NFS_MOUNT_VERSION;
175 * Unfortunately, the kernel prints annoying console messages
176 * in case of an unexpected nfs mount version (instead of
177 * just returning some error). Therefore we'll have to try
178 * and figure out what version the kernel expects.
181 * KERNEL_NFS_MOUNT_VERSION: kernel sources at compile time
182 * NFS_MOUNT_VERSION: these nfsmount sources at compile time
183 * nfs_mount_version: version this source and running kernel can handle
186 find_kernel_nfs_mount_version(void) {
187 static int kernel_version = 0;
192 kernel_version = get_kernel_revision();
194 if (kernel_version) {
195 if (kernel_version < MAKE_VERSION(2,1,32))
196 nfs_mount_version = 1;
197 else if (kernel_version < MAKE_VERSION(2,3,99))
198 nfs_mount_version = 3;
200 nfs_mount_version = 4; /* since 2.3.99pre4 */
202 if (nfs_mount_version > NFS_MOUNT_VERSION)
203 nfs_mount_version = NFS_MOUNT_VERSION;
207 get_mountport(struct sockaddr_in *server_addr,
209 long unsigned version,
213 struct pmaplist *pmap;
214 static struct pmap p = {0, 0, 0, 0};
216 server_addr->sin_port = PMAPPORT;
217 pmap = pmap_getmaps(server_addr);
219 if (version > MAX_NFSPROT)
220 version = MAX_NFSPROT;
229 if (pmap->pml_map.pm_prog != prog)
231 if (!version && p.pm_vers > pmap->pml_map.pm_vers)
233 if (version > 2 && pmap->pml_map.pm_vers != version)
235 if (version && version <= 2 && pmap->pml_map.pm_vers > 2)
237 if (pmap->pml_map.pm_vers > MAX_NFSPROT ||
238 (proto && p.pm_prot && pmap->pml_map.pm_prot != proto) ||
239 (port && pmap->pml_map.pm_port != port))
241 memcpy(&p, &pmap->pml_map, sizeof(p));
243 pmap = pmap->pml_next;
246 p.pm_vers = MOUNTVERS;
248 p.pm_port = MOUNTPORT;
250 p.pm_prot = IPPROTO_TCP;
254 int nfsmount(const char *spec, const char *node, int *flags,
255 char **extra_opts, char **mount_opts, int running_bg)
257 static char *prev_bg_host;
263 char *mounthost=NULL;
265 struct timeval total_timeout;
266 enum clnt_stat clnt_stat;
267 static struct nfs_mount_data data;
271 struct sockaddr_in server_addr;
272 struct sockaddr_in mount_server_addr;
275 struct timeval retry_timeout;
277 struct fhstatus nfsv2;
278 struct mountres3 nfsv3;
303 find_kernel_nfs_mount_version();
308 if (strlen(spec) >= sizeof(hostdir)) {
309 error_msg("excessively long host:dir argument\n");
312 strcpy(hostdir, spec);
313 if ((s = strchr(hostdir, ':'))) {
317 /* Ignore all but first hostname in replicated mounts
318 until they can be fully supported. (mack@sgi.com) */
319 if ((s = strchr(hostdir, ','))) {
321 error_msg("warning: multiple hostnames not supported\n");
324 error_msg("directory to mount not in host:dir format\n");
328 server_addr.sin_family = AF_INET;
329 #ifdef HAVE_inet_aton
330 if (!inet_aton(hostname, &server_addr.sin_addr))
333 if ((hp = gethostbyname(hostname)) == NULL) {
334 error_msg("can't get address for %s\n", hostname);
337 if (hp->h_length > sizeof(struct in_addr)) {
338 error_msg("got bad hp->h_length\n");
339 hp->h_length = sizeof(struct in_addr);
341 memcpy(&server_addr.sin_addr,
342 hp->h_addr, hp->h_length);
346 memcpy (&mount_server_addr, &server_addr, sizeof (mount_server_addr));
348 /* add IP address to mtab options for use when unmounting */
350 s = inet_ntoa(server_addr.sin_addr);
351 old_opts = *extra_opts;
354 if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
355 error_msg("excessively long option argument\n");
358 sprintf(new_opts, "%s%saddr=%s",
359 old_opts, *old_opts ? "," : "", s);
360 *extra_opts = xstrdup(new_opts);
362 /* Set default options.
363 * rsize/wsize (and bsize, for ver >= 3) are left 0 in order to
364 * let the kernel decide.
365 * timeo is filled in after we know whether it'll be TCP or UDP. */
366 memset(&data, 0, sizeof(data));
372 #if NFS_MOUNT_VERSION >= 2
373 data.namlen = NAME_MAX;
383 retry = 10000; /* 10000 minutes ~ 1 week */
386 mountprog = MOUNTPROG;
390 nfsprog = NFS_PROGRAM;
395 for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
396 if ((opteq = strchr(opt, '='))) {
397 val = atoi(opteq + 1);
399 if (!strcmp(opt, "rsize"))
401 else if (!strcmp(opt, "wsize"))
403 else if (!strcmp(opt, "timeo"))
405 else if (!strcmp(opt, "retrans"))
407 else if (!strcmp(opt, "acregmin"))
409 else if (!strcmp(opt, "acregmax"))
411 else if (!strcmp(opt, "acdirmin"))
413 else if (!strcmp(opt, "acdirmax"))
415 else if (!strcmp(opt, "actimeo")) {
421 else if (!strcmp(opt, "retry"))
423 else if (!strcmp(opt, "port"))
425 else if (!strcmp(opt, "mountport"))
427 else if (!strcmp(opt, "mounthost"))
428 mounthost=xstrndup(opteq+1,
429 strcspn(opteq+1," \t\n\r,"));
430 else if (!strcmp(opt, "mountprog"))
432 else if (!strcmp(opt, "mountvers"))
434 else if (!strcmp(opt, "nfsprog"))
436 else if (!strcmp(opt, "nfsvers") ||
437 !strcmp(opt, "vers"))
439 else if (!strcmp(opt, "proto")) {
440 if (!strncmp(opteq+1, "tcp", 3))
442 else if (!strncmp(opteq+1, "udp", 3))
445 printf(_("Warning: Unrecognized proto= option.\n"));
446 } else if (!strcmp(opt, "namlen")) {
447 #if NFS_MOUNT_VERSION >= 2
448 if (nfs_mount_version >= 2)
452 printf(_("Warning: Option namlen is not supported.\n"));
453 } else if (!strcmp(opt, "addr"))
456 printf(_("unknown nfs mount parameter: "
457 "%s=%d\n"), opt, val);
463 if (!strncmp(opt, "no", 2)) {
467 if (!strcmp(opt, "bg"))
469 else if (!strcmp(opt, "fg"))
471 else if (!strcmp(opt, "soft"))
473 else if (!strcmp(opt, "hard"))
475 else if (!strcmp(opt, "intr"))
477 else if (!strcmp(opt, "posix"))
479 else if (!strcmp(opt, "cto"))
481 else if (!strcmp(opt, "ac"))
483 else if (!strcmp(opt, "tcp"))
485 else if (!strcmp(opt, "udp"))
487 else if (!strcmp(opt, "lock")) {
488 if (nfs_mount_version >= 3)
491 printf(_("Warning: option nolock is not supported.\n"));
493 printf(_("unknown nfs mount option: "
494 "%s%s\n"), val ? "" : "no", opt);
499 proto = (tcp) ? IPPROTO_TCP : IPPROTO_UDP;
501 data.flags = (soft ? NFS_MOUNT_SOFT : 0)
502 | (intr ? NFS_MOUNT_INTR : 0)
503 | (posix ? NFS_MOUNT_POSIX : 0)
504 | (nocto ? NFS_MOUNT_NOCTO : 0)
505 | (noac ? NFS_MOUNT_NOAC : 0);
506 #if NFS_MOUNT_VERSION >= 2
507 if (nfs_mount_version >= 2)
508 data.flags |= (tcp ? NFS_MOUNT_TCP : 0);
510 #if NFS_MOUNT_VERSION >= 3
511 if (nfs_mount_version >= 3)
512 data.flags |= (nolock ? NFS_MOUNT_NONLM : 0);
514 if (nfsvers > MAX_NFSPROT) {
515 error_msg("NFSv%d not supported!\n", nfsvers);
518 if (mountvers > MAX_NFSPROT) {
519 error_msg("NFSv%d not supported!\n", nfsvers);
522 if (nfsvers && !mountvers)
523 mountvers = (nfsvers < 3) ? 1 : nfsvers;
524 if (nfsvers && nfsvers < mountvers) {
528 /* Adjust options if none specified */
530 data.timeo = tcp ? 70 : 7;
532 #ifdef NFS_MOUNT_DEBUG
533 printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
534 data.rsize, data.wsize, data.timeo, data.retrans);
535 printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
536 data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
537 printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
538 port, bg, retry, data.flags);
539 printf("mountprog = %d, mountvers = %d, nfsprog = %d, nfsvers = %d\n",
540 mountprog, mountvers, nfsprog, nfsvers);
541 printf("soft = %d, intr = %d, posix = %d, nocto = %d, noac = %d\n",
542 (data.flags & NFS_MOUNT_SOFT) != 0,
543 (data.flags & NFS_MOUNT_INTR) != 0,
544 (data.flags & NFS_MOUNT_POSIX) != 0,
545 (data.flags & NFS_MOUNT_NOCTO) != 0,
546 (data.flags & NFS_MOUNT_NOAC) != 0);
547 #if NFS_MOUNT_VERSION >= 2
549 (data.flags & NFS_MOUNT_TCP) != 0);
553 data.version = nfs_mount_version;
554 *mount_opts = (char *) &data;
556 if (*flags & MS_REMOUNT)
560 * If the previous mount operation on the same host was
561 * backgrounded, and the "bg" for this mount is also set,
562 * give up immediately, to avoid the initial timeout.
564 if (bg && !running_bg &&
565 prev_bg_host && strcmp(hostname, prev_bg_host) == 0) {
571 /* create mount deamon client */
572 /* See if the nfs host = mount host. */
574 if (mounthost[0] >= '0' && mounthost[0] <= '9') {
575 mount_server_addr.sin_family = AF_INET;
576 mount_server_addr.sin_addr.s_addr = inet_addr(hostname);
578 if ((hp = gethostbyname(mounthost)) == NULL) {
579 error_msg("can't get address for %s\n", hostname);
582 if (hp->h_length > sizeof(struct in_addr)) {
583 error_msg("got bad hp->h_length?\n");
584 hp->h_length = sizeof(struct in_addr);
586 mount_server_addr.sin_family = AF_INET;
587 memcpy(&mount_server_addr.sin_addr,
588 hp->h_addr, hp->h_length);
594 * The following loop implements the mount retries. On the first
595 * call, "running_bg" is 0. When the mount times out, and the
596 * "bg" option is set, the exit status EX_BG will be returned.
597 * For a backgrounded mount, there will be a second call by the
598 * child process with "running_bg" set to 1.
600 * The case where the mount point is not present and the "bg"
601 * option is set, is treated as a timeout. This is done to
602 * support nested mounts.
604 * The "retry" count specified by the user is the number of
605 * minutes to retry before giving up.
607 * Only the first error message will be displayed.
609 retry_timeout.tv_sec = 3;
610 retry_timeout.tv_usec = 0;
611 total_timeout.tv_sec = 20;
612 total_timeout.tv_usec = 0;
613 timeout = time(NULL) + 60 * retry;
618 if (bg && stat(node, &statbuf) == -1) {
620 sleep(val); /* 1, 2, 4, 8, 16, 30, ... */
626 /* be careful not to use too many CPU cycles */
630 pm_mnt = get_mountport(&mount_server_addr,
636 /* contact the mount daemon via TCP */
637 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
640 switch (pm_mnt->pm_prot) {
642 mclient = clntudp_create(&mount_server_addr,
649 mount_server_addr.sin_port = htons(pm_mnt->pm_port);
652 mclient = clnttcp_create(&mount_server_addr,
661 /* try to mount hostname:dirname */
662 mclient->cl_auth = authunix_create_default();
664 /* make pointers in xdr_mountres3 NULL so
665 * that xdr_array allocates memory for us
667 memset(&status, 0, sizeof(status));
669 if (pm_mnt->pm_vers == 3)
670 clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
671 (xdrproc_t) xdr_dirpath,
673 (xdrproc_t) xdr_mountres3,
677 clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
678 (xdrproc_t) xdr_dirpath,
680 (xdrproc_t) xdr_fhstatus,
684 if (clnt_stat == RPC_SUCCESS)
685 break; /* we're done */
686 if (errno != ECONNREFUSED) {
687 clnt_perror(mclient, "mount");
688 goto fail; /* don't retry */
690 if (!running_bg && prevt == 0)
691 clnt_perror(mclient, "mount");
692 auth_destroy(mclient->cl_auth);
693 clnt_destroy(mclient);
697 if (!running_bg && prevt == 0)
698 clnt_pcreateerror("mount");
705 prev_bg_host = xstrdup(hostname);
714 nfsvers = (pm_mnt->pm_vers < 2) ? 2 : pm_mnt->pm_vers;
717 if (status.nfsv2.fhs_status != 0) {
718 error_msg("%s:%s failed, reason given by server: %s\n",
720 nfs_strerror(status.nfsv2.fhs_status));
723 memcpy(data.root.data,
724 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
726 #if NFS_MOUNT_VERSION >= 4
727 data.root.size = NFS_FHSIZE;
728 memcpy(data.old_root.data,
729 (char *) status.nfsv2.fhstatus_u.fhs_fhandle,
733 #if NFS_MOUNT_VERSION >= 4
735 if (status.nfsv3.fhs_status != 0) {
736 error_msg("%s:%s failed, reason given by server: %s\n",
738 nfs_strerror(status.nfsv3.fhs_status));
741 fhandle = &status.nfsv3.mountres3_u.mountinfo.fhandle;
742 memset(data.old_root.data, 0, NFS_FHSIZE);
743 memset(&data.root, 0, sizeof(data.root));
744 data.root.size = fhandle->fhandle3_len;
745 memcpy(data.root.data,
746 (char *) fhandle->fhandle3_val,
747 fhandle->fhandle3_len);
749 data.flags |= NFS_MOUNT_VER3;
753 /* create nfs socket for kernel */
756 if (nfs_mount_version < 3) {
757 printf(_("NFS over TCP is not supported.\n"));
760 fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
762 fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
764 perror(_("nfs socket"));
767 if (bindresvport(fsock, 0) < 0) {
768 perror(_("nfs bindresvport"));
772 server_addr.sin_port = PMAPPORT;
773 port = pmap_getport(&server_addr, nfsprog, nfsvers,
774 tcp ? IPPROTO_TCP : IPPROTO_UDP);
777 #ifdef NFS_MOUNT_DEBUG
779 printf(_("used portmapper to find NFS port\n"));
782 #ifdef NFS_MOUNT_DEBUG
783 printf(_("using port %d for nfs deamon\n"), port);
785 server_addr.sin_port = htons(port);
787 * connect() the socket for kernels 1.3.10 and below only,
788 * to avoid problems with multihomed hosts.
791 if (get_kernel_revision() <= 66314
792 && connect(fsock, (struct sockaddr *) &server_addr,
793 sizeof (server_addr)) < 0) {
794 perror(_("nfs connect"));
798 /* prepare data structure for kernel */
801 memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
802 strncpy(data.hostname, hostname, sizeof(data.hostname));
806 auth_destroy(mclient->cl_auth);
807 clnt_destroy(mclient);
816 auth_destroy(mclient->cl_auth);
817 clnt_destroy(mclient);
827 * We need to translate between nfs status return values and
828 * the local errno values which may not be the same.
830 * Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>: change errno:
831 * "after #include <errno.h> the symbol errno is reserved for any use,
832 * it cannot even be used as a struct tag or field name".
836 #define EDQUOT ENOSPC
844 { NFSERR_PERM, EPERM },
845 { NFSERR_NOENT, ENOENT },
847 { NFSERR_NXIO, ENXIO },
848 { NFSERR_ACCES, EACCES },
849 { NFSERR_EXIST, EEXIST },
850 { NFSERR_NODEV, ENODEV },
851 { NFSERR_NOTDIR, ENOTDIR },
852 { NFSERR_ISDIR, EISDIR },
854 { NFSERR_INVAL, EINVAL }, /* that Sun forgot */
856 { NFSERR_FBIG, EFBIG },
857 { NFSERR_NOSPC, ENOSPC },
858 { NFSERR_ROFS, EROFS },
859 { NFSERR_NAMETOOLONG, ENAMETOOLONG },
860 { NFSERR_NOTEMPTY, ENOTEMPTY },
861 { NFSERR_DQUOT, EDQUOT },
862 { NFSERR_STALE, ESTALE },
864 { NFSERR_WFLUSH, EWFLUSH },
866 /* Throw in some NFSv3 values for even more fun (HP returns these) */
872 static char *nfs_strerror(int stat)
875 static char buf[256];
877 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
878 if (nfs_errtbl[i].stat == stat)
879 return strerror(nfs_errtbl[i].errnum);
881 sprintf(buf, _("unknown nfs status return value: %d"), stat);
886 xdr_fhandle (XDR *xdrs, fhandle objp)
888 //register int32_t *buf;
890 if (!xdr_opaque (xdrs, objp, FHSIZE))
896 xdr_fhstatus (XDR *xdrs, fhstatus *objp)
898 //register int32_t *buf;
900 if (!xdr_u_int (xdrs, &objp->fhs_status))
902 switch (objp->fhs_status) {
904 if (!xdr_fhandle (xdrs, objp->fhstatus_u.fhs_fhandle))
914 xdr_dirpath (XDR *xdrs, dirpath *objp)
916 //register int32_t *buf;
918 if (!xdr_string (xdrs, objp, MNTPATHLEN))
924 xdr_fhandle3 (XDR *xdrs, fhandle3 *objp)
926 //register int32_t *buf;
928 if (!xdr_bytes (xdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3))
934 xdr_mountres3_ok (XDR *xdrs, mountres3_ok *objp)
936 //register int32_t *buf;
938 if (!xdr_fhandle3 (xdrs, &objp->fhandle))
940 if (!xdr_array (xdrs, (char **)&objp->auth_flavours.auth_flavours_val, (u_int *) &objp->auth_flavours.auth_flavours_len, ~0,
941 sizeof (int), (xdrproc_t) xdr_int))
947 xdr_mountstat3 (XDR *xdrs, mountstat3 *objp)
949 //register int32_t *buf;
951 if (!xdr_enum (xdrs, (enum_t *) objp))
957 xdr_mountres3 (XDR *xdrs, mountres3 *objp)
959 //register int32_t *buf;
961 if (!xdr_mountstat3 (xdrs, &objp->fhs_status))
963 switch (objp->fhs_status) {
965 if (!xdr_mountres3_ok (xdrs, &objp->mountres3_u.mountinfo))