typedef int (*vumount_fs) (am_node *, mntfs *);
typedef am_node *(*vlookup_child) (am_node *, char *, int *, int);
typedef am_node *(*vmount_child) (am_node *, int *);
-typedef int (*vreaddir) (am_node *, nfscookie, nfsdirlist *, nfsentry *, u_int);
+typedef int (*vreaddir) (am_node *, voidp, voidp, voidp, u_int);
typedef am_node *(*vreadlink) (am_node *, int *);
typedef void (*vmounted) (mntfs *);
typedef void (*vumounted) (mntfs *);
typedef fserver *(*vffserver) (mntfs *);
typedef wchan_t (*vget_wchan) (mntfs *);
+/*
+ * NFS progran dispatcher
+ */
+typedef void (*dispatcher_t)(struct svc_req *rqstp, SVCXPRT *transp);
/*
int s_readdir; /* Count of readdirs */
int s_readlink; /* Count of readlinks */
int s_statfs; /* Count of statfs */
+ int s_fsinfo; /* Count of fsinfo */
+ int s_pathconf; /* Count of pathconf */
};
/*
* Global variables.
*/
extern SVCXPRT *current_transp; /* For nfs_quick_reply() */
+extern dispatcher_t nfs_dispatcher;
extern char *conf_tag;
#define SIZEOF_UID_STR 12
#define SIZEOF_GID_STR 12
*/
extern am_node *amfs_generic_lookup_child(am_node *mp, char *fname, int *error_return, int op);
extern am_node *amfs_generic_mount_child(am_node *ap, int *error_return);
-extern int amfs_generic_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count);
+extern int amfs_generic_readdir(am_node *mp, voidp cookie, voidp dp, voidp ep, u_int count);
extern int amfs_generic_umount(am_node *mp, mntfs *mf);
extern void amfs_generic_mounted(mntfs *mf);
extern char *amfs_generic_match(am_opts *fo);
extern am_ops amfs_error_ops; /* Error file system */
extern am_node *amfs_error_lookup_child(am_node *mp, char *fname, int *error_return, int op);
extern am_node *amfs_error_mount_child(am_node *ap, int *error_return);
-extern int amfs_error_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count);
+extern int amfs_error_readdir(am_node *mp, voidp cookie, voidp dp, voidp ep, u_int count);
+
#endif /* HAVE_AMU_FS_ERROR */
/*
* If we do then just give an error.
*/
int
-amfs_error_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count)
+amfs_error_readdir(am_node *mp, voidp cookie, voidp dp, voidp ep, u_int count)
{
return ESTALE;
}
/*
* Code for quick reply. If current_transp is set, then it's the
- * transp that's been passed down from nfs_program_2() or from
+ * transp that's been passed down from nfs_dispatcher() or from
* autofs_program_[123]().
* If new_mp->am_transp is not already set, set it by copying in
* current_transp. Once am_transp is set, nfs_quick_reply() and
mntent_t mnt;
MTYPE_TYPE type;
int forced_unmount = 0; /* are we using forced unmounts? */
+ u_long nfs_version = get_nfs_dispatcher_version(nfs_dispatcher);
- memset((voidp) &mnt, 0, sizeof(mnt));
+ memset(&mnt, 0, sizeof(mnt));
mnt.mnt_dir = dir;
mnt.mnt_fsname = pid_fsname;
mnt.mnt_opts = opts;
/*
* Create sockaddr to point to the local machine.
*/
- memset((voidp) &sin, 0, sizeof(sin));
+ memset(&sin, 0, sizeof(sin));
/* as per POSIX, sin_len need not be set (used internally by kernel) */
sin.sin_family = AF_INET;
sin.sin_addr = myipaddr;
genflags,
nfsncp,
NULL, /* remote host IP addr is set below */
- NFS_VERSION, /* version 2 */
+ nfs_version,
"udp",
&anh,
fs_hostname,
genflags,
NULL,
&sin,
- NFS_VERSION, /* version 2 */
+ nfs_version,
"udp",
&anh,
fs_hostname,
static int gopt_arch(const char *val);
static int gopt_auto_attrcache(const char *val);
static int gopt_auto_dir(const char *val);
+static int gopt_auto_nfs_version(const char *val);
static int gopt_autofs_use_lofs(const char *val);
static int gopt_browsable_dirs(const char *val);
static int gopt_cache_duration(const char *val);
{"arch", gopt_arch},
{"auto_attrcache", gopt_auto_attrcache},
{"auto_dir", gopt_auto_dir},
+ {"auto_nfs_version", gopt_auto_nfs_version},
{"autofs_use_lofs", gopt_autofs_use_lofs},
{"browsable_dirs", gopt_browsable_dirs},
{"cache_duration", gopt_cache_duration},
return 0;
}
+static int
+gopt_auto_nfs_version(const char *val)
+{
+ if (strcmp(val, "2") == 0)
+ nfs_dispatcher = nfs_program_2;
+ else if (strcmp(val, "3") == 0)
+ nfs_dispatcher = nfs_program_3;
+ else {
+ fprintf(stderr, "conf: bad auto nfs version : \"%s\"\n", val);
+ return 1;
+ }
+ return 0;
+}
static int
gopt_autofs_use_lofs(const char *val)
static am_nfs_fh nfh;
am_node *mp = get_root_ap(dir);
if (mp) {
- mp_to_fh(mp, &nfh);
+ if (nfs_dispatcher == nfs_program_2)
+ mp_to_fh(mp, &nfh);
+ else
+ mp_to_fh3(mp, &nfh);
return &nfh;
}
/* global variables */
SVCXPRT *current_transp;
+dispatcher_t nfs_dispatcher = nfs_program_2;
/* typedefs */
typedef char *(*nfssvcproc_t)(voidp, struct svc_req *);
going_down(1);
}
}
+
+void
+nfs_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
+{
+ union {
+ am_GETATTR3args am_nfs3_getattr_3_arg;
+ am_SETATTR3args am_nfs3_setattr_3_arg;
+ am_LOOKUP3args am_nfs3_lookup_3_arg;
+ am_ACCESS3args am_nfs3_access_3_arg;
+ am_READLINK3args am_nfs3_readlink_3_arg;
+ am_READ3args am_nfs3_read_3_arg;
+ am_WRITE3args am_nfs3_write_3_arg;
+ am_CREATE3args am_nfs3_create_3_arg;
+ am_MKDIR3args am_nfs3_mkdir_3_arg;
+ am_SYMLINK3args am_nfs3_symlink_3_arg;
+ am_MKNOD3args am_nfs3_mknod_3_arg;
+ am_REMOVE3args am_nfs3_remove_3_arg;
+ am_RMDIR3args am_nfs3_rmdir_3_arg;
+ am_RENAME3args am_nfs3_rename_3_arg;
+ am_LINK3args am_nfs3_link_3_arg;
+ am_READDIR3args am_nfs3_readdir_3_arg;
+ am_READDIRPLUS3args am_nfs3_readdirplus_3_arg;
+ am_FSSTAT3args am_nfs3_fsstat_3_arg;
+ am_FSINFO3args am_nfs3_fsinfo_3_arg;
+ am_PATHCONF3args am_nfs3_pathconf_3_arg;
+ am_COMMIT3args am_nfs3_commit_3_arg;
+ } argument;
+ char *result;
+ xdrproc_t _xdr_argument, _xdr_result;
+ nfssvcproc_t local;
+
+ switch (rqstp->rq_proc) {
+ case AM_NFS3_NULL:
+ _xdr_argument = (xdrproc_t) xdr_void;
+ _xdr_result = (xdrproc_t) xdr_void;
+ local = (nfssvcproc_t) am_nfs3_null_3_svc;
+ break;
+
+ case AM_NFS3_GETATTR:
+ _xdr_argument = (xdrproc_t) xdr_am_GETATTR3args;
+ _xdr_result = (xdrproc_t) xdr_am_GETATTR3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_getattr_3_svc;
+ break;
+
+ case AM_NFS3_SETATTR:
+ _xdr_argument = (xdrproc_t) xdr_am_SETATTR3args;
+ _xdr_result = (xdrproc_t) xdr_am_SETATTR3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_setattr_3_svc;
+ break;
+
+ case AM_NFS3_LOOKUP:
+ _xdr_argument = (xdrproc_t) xdr_am_LOOKUP3args;
+ _xdr_result = (xdrproc_t) xdr_am_LOOKUP3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_lookup_3_svc;
+ break;
+
+ case AM_NFS3_ACCESS:
+ _xdr_argument = (xdrproc_t) xdr_am_ACCESS3args;
+ _xdr_result = (xdrproc_t) xdr_am_ACCESS3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_access_3_svc;
+ break;
+
+ case AM_NFS3_READLINK:
+ _xdr_argument = (xdrproc_t) xdr_am_READLINK3args;
+ _xdr_result = (xdrproc_t) xdr_am_READLINK3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_readlink_3_svc;
+ break;
+
+ case AM_NFS3_READ:
+ _xdr_argument = (xdrproc_t) xdr_am_READ3args;
+ _xdr_result = (xdrproc_t) xdr_am_READ3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_read_3_svc;
+ break;
+
+ case AM_NFS3_WRITE:
+ _xdr_argument = (xdrproc_t) xdr_am_WRITE3args;
+ _xdr_result = (xdrproc_t) xdr_am_WRITE3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_write_3_svc;
+ break;
+
+ case AM_NFS3_CREATE:
+ _xdr_argument = (xdrproc_t) xdr_am_CREATE3args;
+ _xdr_result = (xdrproc_t) xdr_am_CREATE3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_create_3_svc;
+ break;
+
+ case AM_NFS3_MKDIR:
+ _xdr_argument = (xdrproc_t) xdr_am_MKDIR3args;
+ _xdr_result = (xdrproc_t) xdr_am_MKDIR3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_mkdir_3_svc;
+ break;
+
+ case AM_NFS3_SYMLINK:
+ _xdr_argument = (xdrproc_t) xdr_am_SYMLINK3args;
+ _xdr_result = (xdrproc_t) xdr_am_SYMLINK3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_symlink_3_svc;
+ break;
+
+ case AM_NFS3_MKNOD:
+ _xdr_argument = (xdrproc_t) xdr_am_MKNOD3args;
+ _xdr_result = (xdrproc_t) xdr_am_MKNOD3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_mknod_3_svc;
+ break;
+
+ case AM_NFS3_REMOVE:
+ _xdr_argument = (xdrproc_t) xdr_am_REMOVE3args;
+ _xdr_result = (xdrproc_t) xdr_am_REMOVE3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_remove_3_svc;
+ break;
+
+ case AM_NFS3_RMDIR:
+ _xdr_argument = (xdrproc_t) xdr_am_RMDIR3args;
+ _xdr_result = (xdrproc_t) xdr_am_RMDIR3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_rmdir_3_svc;
+ break;
+
+ case AM_NFS3_RENAME:
+ _xdr_argument = (xdrproc_t) xdr_am_RENAME3args;
+ _xdr_result = (xdrproc_t) xdr_am_RENAME3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_rename_3_svc;
+ break;
+
+ case AM_NFS3_LINK:
+ _xdr_argument = (xdrproc_t) xdr_am_LINK3args;
+ _xdr_result = (xdrproc_t) xdr_am_LINK3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_link_3_svc;
+ break;
+
+ case AM_NFS3_READDIR:
+ _xdr_argument = (xdrproc_t) xdr_am_READDIR3args;
+ _xdr_result = (xdrproc_t) xdr_am_READDIR3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_readdir_3_svc;
+ break;
+
+ case AM_NFS3_READDIRPLUS:
+ _xdr_argument = (xdrproc_t) xdr_am_READDIRPLUS3args;
+ _xdr_result = (xdrproc_t) xdr_am_READDIRPLUS3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_readdirplus_3_svc;
+ break;
+
+ case AM_NFS3_FSSTAT:
+ _xdr_argument = (xdrproc_t) xdr_am_FSSTAT3args;
+ _xdr_result = (xdrproc_t) xdr_am_FSSTAT3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_fsstat_3_svc;
+ break;
+
+ case AM_NFS3_FSINFO:
+ _xdr_argument = (xdrproc_t) xdr_am_FSINFO3args;
+ _xdr_result = (xdrproc_t) xdr_am_FSINFO3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_fsinfo_3_svc;
+ break;
+
+ case AM_NFS3_PATHCONF:
+ _xdr_argument = (xdrproc_t) xdr_am_PATHCONF3args;
+ _xdr_result = (xdrproc_t) xdr_am_PATHCONF3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_pathconf_3_svc;
+ break;
+
+ case AM_NFS3_COMMIT:
+ _xdr_argument = (xdrproc_t) xdr_am_COMMIT3args;
+ _xdr_result = (xdrproc_t) xdr_am_COMMIT3res;
+ local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_commit_3_svc;
+ break;
+
+ default:
+ svcerr_noproc (transp);
+ return;
+ }
+
+ memset ((char *)&argument, 0, sizeof (argument));
+
+ if (!svc_getargs(transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
+ plog(XLOG_ERROR,
+ "NFS xdr decode failed for %d %d %d",
+ (int) rqstp->rq_prog, (int) rqstp->rq_vers, (int) rqstp->rq_proc);
+ svcerr_decode(transp);
+ return;
+ }
+
+ result = (*local) (&argument, rqstp);
+ if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
+ svcerr_systemerr (transp);
+ }
+
+ if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
+ plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_3");
+ going_down(1);
+ }
+ return;
+}
* already created the service during restart_automounter_nodes().
*/
if (nfs_port == 0) {
- ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
+ ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_dispatcher,
+ get_nfs_dispatcher_version(nfs_dispatcher));
if (ret != 0)
return ret;
}
} u;
};
+struct am_fh3 {
+ u_int fhh_gen; /* generation number */
+ union {
+ struct {
+ int fhh_type; /* old or new am_fh */
+ pid_t fhh_pid; /* process id */
+ int fhh_id; /* map id */
+ } s;
+ char fhh_path[AM_FHSIZE3-sizeof(u_int)]; /* path to am_node */
+ } u;
+};
/* forward declarations */
/* converting am-filehandles to mount-points */
*out_bavail = bavail;
}
-
-/*
- * Convert from file handle to automount node.
- */
static am_node *
-fh_to_mp3(am_nfs_fh *fhp, int *rp, int vop)
+validate_ap(am_node *node, int *rp, u_int fhh_gen)
{
- struct am_fh *fp = (struct am_fh *) fhp;
- am_node *ap = NULL;
-
- if (fp->u.s.fhh_type != 0) {
- /* New filehandle type */
- int len = sizeof(*fhp) - sizeof(fp->fhh_gen);
- char *path = xmalloc(len+1);
- /*
- * Because fhp is treated as a filehandle we use memcpy
- * instead of xstrlcpy.
- */
- memcpy(path, (char *) fp->u.fhh_path, len);
- path[len] = '\0';
- /* dlog("fh_to_mp3: new filehandle: %s", path); */
-
- ap = path_to_exported_ap(path);
- XFREE(path);
- } else {
- /* dlog("fh_to_mp3: old filehandle: %d", fp->u.s.fhh_id); */
- /*
- * Check process id matches
- * If it doesn't then it is probably
- * from an old kernel-cached filehandle
- * which is now out of date.
- */
- if (fp->u.s.fhh_pid != get_server_pid()) {
- dlog("fh_to_mp3: wrong pid %ld != my pid %ld",
- (long) fp->u.s.fhh_pid, get_server_pid());
- goto drop;
- }
-
- /*
- * Get hold of the supposed mount node
- */
- ap = get_exported_ap(fp->u.s.fhh_id);
- }
-
+ am_node *ap = node;
/*
* Check the generation number in the node
* matches the one from the kernel. If not
* then the old node has been timed out and
* a new one allocated.
*/
- if (ap != NULL && ap->am_gen != fp->fhh_gen)
+ if (node != NULL && node->am_gen != fhh_gen)
ap = NULL;
/*
int error;
am_node *orig_ap = ap;
- dlog("fh_to_mp3: %s (%s) is hung: lookup alternative file server",
+ dlog("%s: %s (%s) is hung: lookup alternative file server", __func__,
orig_ap->am_path, orig_ap->am_al->al_mnt->mf_info);
/*
return ap;
}
+/*
+ * Convert from file handle to automount node.
+ */
+static am_node *
+fh_to_mp3(am_nfs_fh *fhp, int *rp, int vop)
+{
+ struct am_fh *fp = (struct am_fh *) fhp;
+ am_node *ap = NULL;
+
+ if (fp->u.s.fhh_type != 0) {
+ /* New filehandle type */
+ int len = sizeof(*fhp) - sizeof(fp->fhh_gen);
+ char *path = xmalloc(len+1);
+ /*
+ * Because fhp is treated as a filehandle we use memcpy
+ * instead of xstrlcpy.
+ */
+ memcpy(path, (char *) fp->u.fhh_path, len);
+ path[len] = '\0';
+ dlog("%s: new filehandle: %s", __func__, path);
+
+ ap = path_to_exported_ap(path);
+ XFREE(path);
+ } else {
+ dlog("%s: old filehandle: %d", __func__, fp->u.s.fhh_id);
+ /*
+ * Check process id matches
+ * If it doesn't then it is probably
+ * from an old kernel-cached filehandle
+ * which is now out of date.
+ */
+ if (fp->u.s.fhh_pid != get_server_pid()) {
+ dlog("%s: wrong pid %ld != my pid %ld", __func__,
+ (long) fp->u.s.fhh_pid, get_server_pid());
+ goto done;
+ }
+
+ /*
+ * Get hold of the supposed mount node
+ */
+ ap = get_exported_ap(fp->u.s.fhh_id);
+ }
+done:
+ return validate_ap(ap, rp, fp->fhh_gen);
+}
static am_node *
fh_to_mp(am_nfs_fh *fhp)
return fh_to_mp3(fhp, &dummy, VLOOK_CREATE);
}
+static am_node *
+fh3_to_mp3(am_nfs_fh3 *fhp, int *rp, int vop)
+{
+ struct am_fh3 *fp = (struct am_fh3 *) fhp->am_fh3_data;
+ am_node *ap = NULL;
+
+ if (fp->u.s.fhh_type != 0) {
+ /* New filehandle type */
+ int len = sizeof(*fp) - sizeof(fp->fhh_gen);
+ char *path = xmalloc(len+1);
+ /*
+ * Because fhp is treated as a filehandle we use memcpy
+ * instead of xstrlcpy.
+ */
+ memcpy(path, (char *) fp->u.fhh_path, len);
+ path[len] = '\0';
+ dlog("%s: new filehandle: %s", __func__, path);
+
+ ap = path_to_exported_ap(path);
+ XFREE(path);
+ } else {
+ dlog("%s: old filehandle: %d", __func__, fp->u.s.fhh_id);
+ /*
+ * Check process id matches
+ * If it doesn't then it is probably
+ * from an old kernel-cached filehandle
+ * which is now out of date.
+ */
+ if (fp->u.s.fhh_pid != get_server_pid()) {
+ dlog("%s: wrong pid %ld != my pid %ld", __func__,
+ (long) fp->u.s.fhh_pid, get_server_pid());
+ goto done;
+ }
+
+ /*
+ * Get hold of the supposed mount node
+ */
+ ap = get_exported_ap(fp->u.s.fhh_id);
+ }
+done:
+ return validate_ap(ap, rp, fp->fhh_gen);
+}
+
+static am_node *
+fh3_to_mp(am_nfs_fh3 *fhp)
+{
+ int dummy;
+
+ return fh3_to_mp3(fhp, &dummy, VLOOK_CREATE);
+}
/*
* Convert from automount node to file handle.
/* dlog("mp_to_fh: old filehandle: %d", fp->u.s.fhh_id); */
}
}
+void
+mp_to_fh3(am_node *mp, am_nfs_fh3 *fhp)
+{
+ u_int pathlen;
+ struct am_fh3 *fp = (struct am_fh3 *) fhp->am_fh3_data;
+
+ memset((char *) fhp, 0, sizeof(am_nfs_fh3));
+ fhp->am_fh3_length = AM_FHSIZE3;
+
+ /* Store the generation number */
+ fp->fhh_gen = mp->am_gen;
+
+ pathlen = strlen(mp->am_path);
+ if (pathlen <= sizeof(*fp) - sizeof(fp->fhh_gen)) {
+ /* dlog("mp_to_fh: new filehandle: %s", mp->am_path); */
+
+ /*
+ * Because fhp is treated as a filehandle we use memcpy instead of
+ * xstrlcpy.
+ */
+ memcpy(fp->u.fhh_path, mp->am_path, pathlen); /* making a filehandle */
+ } else {
+ /*
+ * Take the process id
+ */
+ fp->u.s.fhh_pid = get_server_pid();
+
+ /*
+ * ... the map number
+ */
+ fp->u.s.fhh_id = mp->am_mapno;
+
+ /*
+ * ... and the generation number (previously stored)
+ * to make a "unique" triple that will never
+ * be reallocated except across reboots (which doesn't matter)
+ * or if we are unlucky enough to be given the same
+ * pid as a previous amd (very unlikely).
+ */
+ /* dlog("mp_to_fh: old filehandle: %d", fp->u.s.fhh_id); */
+ }
+}
+
+#ifdef HAVE_FS_NFS3
+static am_ftype3 ftype_to_ftype3(nfsftype ftype)
+{
+ if (ftype == NFFIFO)
+ return AM_NF3FIFO;
+ else
+ return ftype;
+}
+
+static void nfstime_to_am_nfstime3(nfstime *time, am_nfstime3 *time3)
+{
+ time3->seconds = time->seconds;
+ time3->nseconds = time->useconds * 1000;
+}
+
+static void rdev_to_am_specdata3(u_int rdev, am_specdata3 *rdev3)
+{
+ /* No device node here */
+ rdev3->specdata1 = (u_int) -1;
+ rdev3->specdata2 = (u_int) -1;
+}
+
+static void fattr_to_fattr3(nfsfattr *fattr, am_fattr3 *fattr3)
+{
+ fattr3->type = ftype_to_ftype3(fattr->na_type);
+ fattr3->mode = (am_mode3) fattr->na_mode;
+ fattr3->nlink = fattr->na_nlink;
+ fattr3->uid = (am_uid3) fattr->na_uid;
+ fattr3->gid = (am_uid3) fattr->na_gid;
+ fattr3->size = (am_size3) fattr->na_size;
+ fattr3->used = (am_size3) fattr->na_size;
+ rdev_to_am_specdata3(fattr->na_rdev, &fattr3->rdev);
+ fattr3->fsid = (uint64) fattr->na_fsid;
+ fattr3->fileid = (uint64) fattr->na_fileid;
+ nfstime_to_am_nfstime3(&fattr->na_atime, &fattr3->atime);
+ nfstime_to_am_nfstime3(&fattr->na_mtime, &fattr3->mtime);
+ nfstime_to_am_nfstime3(&fattr->na_ctime, &fattr3->ctime);
+}
+
+static void fattr_to_wcc_attr(nfsfattr *fattr, am_wcc_attr *wcc_attr)
+{
+ wcc_attr->size = (am_size3) fattr->na_size;
+ nfstime_to_am_nfstime3(&fattr->na_mtime, &wcc_attr->mtime);
+ nfstime_to_am_nfstime3(&fattr->na_ctime, &wcc_attr->ctime);
+}
+
+static am_nfsstat3 return_estale_or_rofs(am_nfs_fh3 *fh,
+ am_pre_op_attr *pre_op,
+ am_post_op_attr *post_op)
+{
+ am_node *mp;
+
+ mp = fh3_to_mp(fh);
+ if (!mp) {
+ pre_op->attributes_follow = 0;
+ post_op->attributes_follow = 0;
+ return nfs_error(ESTALE);
+ } else {
+ am_fattr3 *fattr3 = &post_op->am_post_op_attr_u.attributes;
+ am_wcc_attr *wcc_attr = &pre_op->am_pre_op_attr_u.attributes;
+ nfsfattr *fattr = &mp->am_fattr;
+ pre_op->attributes_follow = 1;
+ fattr_to_wcc_attr(fattr, wcc_attr);
+ post_op->attributes_follow = 1;
+ fattr_to_fattr3(fattr, fattr3);
+ return nfs_error(EROFS);
+ }
+}
+
+static am_nfsstat3 unlink3_or_rmdir3(am_diropargs3 *argp,
+ am_wcc_data *wcc_data, int unlinkp)
+{
+ static am_nfsstat3 res;
+ am_nfs_fh3 *dir = &argp->dir;
+ am_filename3 name = argp->name;
+ am_pre_op_attr *pre_op_dir = &wcc_data->before;
+ am_post_op_attr *post_op_dir = &wcc_data->after;
+ nfsfattr *fattr;
+ am_wcc_attr *wcc_attr;
+ am_node *mp, *ap;
+ int retry;
+
+ post_op_dir->attributes_follow = 0;
+
+ mp = fh3_to_mp3(dir, &retry, VLOOK_DELETE);
+ if (!mp) {
+ pre_op_dir->attributes_follow = 0;
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ res = nfs_error(retry);
+ goto out;
+ }
+
+ pre_op_dir->attributes_follow = 1;
+ fattr = &mp->am_fattr;
+ wcc_attr = &pre_op_dir->am_pre_op_attr_u.attributes;
+ fattr_to_wcc_attr(fattr, wcc_attr);
+
+ if (mp->am_fattr.na_type != NFDIR) {
+ res = nfs_error(ENOTDIR);
+ goto out;
+ }
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\tremove(%s, %s)", mp->am_path, name);
+
+ ap = mp->am_al->al_mnt->mf_ops->lookup_child(mp, name, &retry, VLOOK_DELETE);
+ if (!ap) {
+ /*
+ * Ignore retries...
+ */
+ if (retry < 0)
+ retry = 0;
+ /*
+ * Usual NFS workaround...
+ */
+ else if (retry == ENOENT)
+ retry = 0;
+ res = nfs_error(retry);
+ } else {
+ forcibly_timeout_mp(mp);
+ res = AM_NFS3_OK;
+ }
+
+out:
+ return res;
+}
+
+voidp
+am_nfs3_null_3_svc(voidp argp, struct svc_req *rqstp)
+{
+ static char * result;
+
+ return (voidp) &result;
+}
+
+am_GETATTR3res *
+am_nfs3_getattr_3_svc(am_GETATTR3args *argp, struct svc_req *rqstp)
+{
+ static am_GETATTR3res result;
+ am_nfs_fh3 *fh = (am_nfs_fh3 *) &argp->object;
+ am_fattr3 *fattr3;
+ nfsfattr *fattr;
+ am_node *mp;
+ int retry = 0;
+ time_t now = clocktime(NULL);
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "getattr_3:");
+
+ mp = fh3_to_mp3(fh, &retry, VLOOK_CREATE);
+ if (!mp) {
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\tretry=%d", retry);
+
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ result.status = nfs_error(retry);
+ return &result;
+ }
+
+ fattr = &mp->am_fattr;
+ fattr3 = (am_fattr3 *) &result.res_u.ok.obj_attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ result.status = AM_NFS3_OK;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\tstat(%s), size = %lu, mtime=%d.%d",
+ mp->am_path,
+ (am_size3) fattr3->size,
+ (u_int) fattr3->mtime.seconds,
+ (u_int) fattr3->mtime.nseconds);
+
+ /* Delay unmount of what was looked up */
+ if (mp->am_timeo_w < 4 * gopt.am_timeo_w)
+ mp->am_timeo_w += gopt.am_timeo_w;
+ mp->am_ttl = now + mp->am_timeo_w;
+
+ mp->am_stats.s_getattr++;
+
+ return &result;
+}
+
+am_SETATTR3res *
+am_nfs3_setattr_3_svc(am_SETATTR3args *argp, struct svc_req *rqstp)
+{
+ static am_SETATTR3res result;
+ am_nfs_fh3 *fh = (am_nfs_fh3 *) &argp->object;
+ am_pre_op_attr *pre_op_obj = &result.res_u.fail.obj_wcc.before;
+ am_post_op_attr *post_op_obj = &result.res_u.fail.obj_wcc.after;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "setattr_3:");
+
+ result.status = return_estale_or_rofs(fh, pre_op_obj, post_op_obj);
+
+ return &result;
+}
+
+am_LOOKUP3res *
+am_nfs3_lookup_3_svc(am_LOOKUP3args *argp, struct svc_req *rqstp)
+{
+ static am_LOOKUP3res result;
+ am_nfs_fh3 *dir = &argp->what.dir;
+ am_post_op_attr *post_op_dir;
+ am_post_op_attr *post_op_obj;
+ am_node *mp;
+ int retry;
+ uid_t uid;
+ gid_t gid;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "lookup_3:");
+
+ /* finally, find the effective uid/gid from RPC request */
+ if (getcreds(rqstp, &uid, &gid, nfsxprt) < 0)
+ plog(XLOG_ERROR, "cannot get uid/gid from RPC credentials");
+ xsnprintf(opt_uid, sizeof(uid_str), "%d", (int) uid);
+ xsnprintf(opt_gid, sizeof(gid_str), "%d", (int) gid);
+
+ mp = fh3_to_mp3(dir, &retry, VLOOK_CREATE);
+ if (!mp) {
+ post_op_dir = &result.res_u.fail.dir_attributes;
+ post_op_dir->attributes_follow = 0;
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ result.status = nfs_error(retry);
+ } else {
+ post_op_dir = &result.res_u.ok.dir_attributes;
+ post_op_obj = &result.res_u.ok.obj_attributes;
+ am_filename3 name;
+ am_fattr3 *fattr3;
+ nfsfattr *fattr;
+ am_node *ap;
+ int error;
+
+ /* dir attributes */
+ post_op_dir->attributes_follow = 1;
+ fattr = &mp->am_fattr;
+ fattr3 = &post_op_dir->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ post_op_obj->attributes_follow = 0;
+
+ name = argp->what.name;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\tlookup_3(%s, %s)", mp->am_path, name);
+
+ ap = mp->am_al->al_mnt->mf_ops->lookup_child(mp, name, &error, VLOOK_CREATE);
+ if (ap && error < 0)
+ ap = mp->am_al->al_mnt->mf_ops->mount_child(ap, &error);
+ if (ap == 0) {
+ if (error < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ result.status = nfs_error(error);
+ } else {
+ /*
+ * XXX: EXPERIMENTAL! Delay unmount of what was looked up. This
+ * should reduce the chance for race condition between unmounting an
+ * entry synchronously, and re-mounting it asynchronously.
+ */
+ if (ap->am_ttl < mp->am_ttl)
+ ap->am_ttl = mp->am_ttl;
+
+ mp_to_fh3(ap, &result.res_u.ok.object);
+
+ /* mount attributes */
+ post_op_obj->attributes_follow = 1;
+ fattr = &ap->am_fattr;
+ fattr3 = &post_op_obj->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ result.status = AM_NFS3_OK;
+ }
+ mp->am_stats.s_lookup++;
+ }
+ return &result;
+}
+
+am_ACCESS3res *
+am_nfs3_access_3_svc(am_ACCESS3args *argp, struct svc_req *rqstp)
+{
+ static am_ACCESS3res result;
+
+ am_nfs_fh3 *obj = &argp->object;
+ u_int accessbits = argp->access;
+ u_int accessmask = AM_ACCESS3_LOOKUP;
+ am_post_op_attr *post_op_obj;
+ am_node *mp;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "access_3:");
+
+ mp = fh3_to_mp(obj);
+ if (!mp) {
+ post_op_obj = &result.res_u.fail.obj_attributes;
+ post_op_obj->attributes_follow = 0;
+ result.status = nfs_error(ENOENT);
+ } else {
+ nfsfattr *fattr = &mp->am_fattr;
+ am_fattr3 *fattr3;
+ post_op_obj = &result.res_u.ok.obj_attributes;
+ fattr3 = &post_op_obj->am_post_op_attr_u.attributes;
+ post_op_obj->attributes_follow = 1;
+ fattr_to_fattr3(fattr, fattr3);
+
+ result.res_u.ok.access = accessbits & accessmask;
+
+ result.status = AM_NFS3_OK;
+ }
+
+ return &result;
+}
+
+am_READLINK3res *
+am_nfs3_readlink_3_svc(am_READLINK3args *argp, struct svc_req *rqstp)
+{
+ static am_READLINK3res result;
+
+ am_nfs_fh3 *symlink = (am_nfs_fh3 *) &argp->symlink;
+ am_post_op_attr *post_op_sym;
+ am_node *mp;
+ int retry = 0;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "readlink_3:");
+
+ mp = fh3_to_mp3(symlink, &retry, VLOOK_CREATE);
+ if (!mp) {
+ readlink_retry:
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ post_op_sym = &result.res_u.fail.symlink_attributes;
+ post_op_sym->attributes_follow = 0;
+ result.status = nfs_error(retry);
+ } else {
+ nfsfattr *fattr;
+ am_fattr3 *fattr3;
+ char *ln;
+
+ ln = do_readlink(mp, &retry);
+ if (!ln)
+ goto readlink_retry;
+
+ if (amuDebug(D_TRACE) && ln)
+ plog(XLOG_DEBUG, "\treadlink_3(%s) = %s", mp->am_path, ln);
+
+ result.res_u.ok.data = ln;
+
+ post_op_sym = &result.res_u.ok.symlink_attributes;
+ post_op_sym->attributes_follow = 1;
+ fattr = &mp->am_fattr;
+ fattr3 = &post_op_sym->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ mp->am_stats.s_readlink++;
+ result.status = AM_NFS3_OK;
+ }
+
+ return &result;
+}
+
+am_READ3res *
+am_nfs3_read_3_svc(am_READ3args *argp, struct svc_req *rqstp)
+{
+ static am_READ3res result;
+
+ am_nfs_fh3 *file = (am_nfs_fh3 *) &argp->file;
+ am_post_op_attr *post_op_file;
+ am_node *mp;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "read_3:");
+
+ post_op_file = &result.res_u.fail.file_attributes;
+ result.status = nfs_error(EACCES);
+
+ mp = fh3_to_mp(file);
+ if (!mp)
+ post_op_file->attributes_follow = 0;
+ else {
+ nfsfattr *fattr = &mp->am_fattr;
+ am_fattr3 *fattr3 = &post_op_file->am_post_op_attr_u.attributes;
+ post_op_file->attributes_follow = 1;
+ fattr_to_fattr3(fattr, fattr3);
+ }
+
+ return &result;
+}
+
+am_WRITE3res *
+am_nfs3_write_3_svc(am_WRITE3args *argp, struct svc_req *rqstp)
+{
+ static am_WRITE3res result;
+
+ am_nfs_fh3 *file = (am_nfs_fh3 *) &argp->file;
+ am_pre_op_attr *pre_op_file = &result.res_u.fail.file_wcc.before;
+ am_post_op_attr *post_op_file = &result.res_u.fail.file_wcc.after;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "write_3:");
+
+ result.status = return_estale_or_rofs(file, pre_op_file, post_op_file);
+
+ return &result;
+}
+
+am_CREATE3res *
+am_nfs3_create_3_svc(am_CREATE3args *argp, struct svc_req *rqstp)
+{
+ static am_CREATE3res result;
+
+ am_nfs_fh3 *dir = (am_nfs_fh3 *) &argp->where.dir;
+ am_pre_op_attr *pre_op_dir = &result.res_u.fail.dir_wcc.before;
+ am_post_op_attr *post_op_dir = &result.res_u.fail.dir_wcc.after;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "create_3:");
+
+ result.status = return_estale_or_rofs(dir, pre_op_dir, post_op_dir);
+
+ return &result;
+}
+
+am_MKDIR3res *
+am_nfs3_mkdir_3_svc(am_MKDIR3args *argp, struct svc_req *rqstp)
+{
+ static am_MKDIR3res result;
+
+ am_nfs_fh3 *dir = (am_nfs_fh3 *) &argp->where.dir;
+ am_pre_op_attr *pre_op_dir = &result.res_u.fail.dir_wcc.before;
+ am_post_op_attr *post_op_dir = &result.res_u.fail.dir_wcc.after;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "mkdir_3:");
+
+ result.status = return_estale_or_rofs(dir, pre_op_dir, post_op_dir);
+
+ return &result;
+}
+
+am_SYMLINK3res *
+am_nfs3_symlink_3_svc(am_SYMLINK3args *argp, struct svc_req *rqstp)
+{
+ static am_SYMLINK3res result;
+
+ am_nfs_fh3 *dir = (am_nfs_fh3 *) &argp->where.dir;
+ am_pre_op_attr *pre_op_dir = &result.res_u.fail.dir_wcc.before;
+ am_post_op_attr *post_op_dir = &result.res_u.fail.dir_wcc.after;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "symlink_3:");
+
+ result.status = return_estale_or_rofs(dir, pre_op_dir, post_op_dir);
+
+ return &result;
+}
+
+am_MKNOD3res *
+am_nfs3_mknod_3_svc(am_MKNOD3args *argp, struct svc_req *rqstp)
+{
+ static am_MKNOD3res result;
+
+ am_nfs_fh3 *dir = (am_nfs_fh3 *) &argp->where.dir;
+ am_pre_op_attr *pre_op_dir = &result.res_u.fail.dir_wcc.before;
+ am_post_op_attr *post_op_dir = &result.res_u.fail.dir_wcc.after;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "mknod_3:");
+
+ result.status = return_estale_or_rofs(dir, pre_op_dir, post_op_dir);
+ return &result;
+}
+
+am_REMOVE3res *
+am_nfs3_remove_3_svc(am_REMOVE3args *argp, struct svc_req *rqstp)
+{
+ static am_REMOVE3res result;
+
+ am_diropargs3 *obj = &argp->object;
+ am_wcc_data dir_wcc;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "remove_3:");
+
+ result.status = unlink3_or_rmdir3(obj, &dir_wcc, TRUE);
+
+ result.res_u.ok.dir_wcc = dir_wcc;
+
+ return &result;
+}
+
+am_RMDIR3res *
+am_nfs3_rmdir_3_svc(am_RMDIR3args *argp, struct svc_req *rqstp)
+{
+ static am_RMDIR3res result;
+
+ am_diropargs3 *obj = &argp->object;
+ am_wcc_data dir_wcc;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "rmdir_3:");
+
+ result.status = unlink3_or_rmdir3(obj, &dir_wcc, TRUE);
+
+ result.res_u.ok.dir_wcc = dir_wcc;
+
+ return &result;
+}
+
+am_RENAME3res *
+am_nfs3_rename_3_svc(am_RENAME3args *argp, struct svc_req *rqstp)
+{
+ static am_RENAME3res result;
+
+ am_nfs_fh3 *fromdir = (am_nfs_fh3 *) &argp->from.dir;
+ am_nfs_fh3 *todir = (am_nfs_fh3 *) &argp->to.dir;
+ am_filename3 name = argp->to.name;
+ am_node *to_mp, *from_mp;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "rename_3:");
+
+ if (!(from_mp = fh3_to_mp(fromdir)) || !(to_mp = fh3_to_mp(todir)))
+ result.status = nfs_error(ESTALE);
+ /*
+ * If the kernel is doing clever things with referenced files
+ * then let it pretend...
+ */
+ else {
+ am_wcc_attr *wcc_attr;
+ am_fattr3 *fattr3;
+ am_wcc_data *to_wcc_data, *from_wcc_data;
+ am_pre_op_attr *pre_op_to, *pre_op_from;
+ am_post_op_attr *post_op_to, *post_op_from;
+ nfsfattr *fattr;
+
+ to_wcc_data = &result.res_u.ok.todir_wcc;
+
+ pre_op_to = &to_wcc_data->before;
+ post_op_to = &to_wcc_data->after;
+
+ pre_op_to->attributes_follow = 1;
+ fattr = &to_mp->am_fattr;
+ wcc_attr = &pre_op_to->am_pre_op_attr_u.attributes;
+ fattr_to_wcc_attr(fattr, wcc_attr);
+ post_op_to->attributes_follow = 1;
+ fattr3 = &post_op_to->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ from_wcc_data = &result.res_u.ok.fromdir_wcc;
+
+ pre_op_from = &from_wcc_data->before;
+ post_op_from = &from_wcc_data->after;
+
+ pre_op_from->attributes_follow = 1;
+ fattr = &from_mp->am_fattr;
+ wcc_attr = &pre_op_from->am_pre_op_attr_u.attributes;
+ fattr_to_wcc_attr(fattr, wcc_attr);
+ post_op_from->attributes_follow = 1;
+ fattr3 = &post_op_from->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ if (NSTREQ(name, ".nfs", 4))
+ result.status = AM_NFS3_OK;
+ /*
+ * otherwise a failure
+ */
+ else
+ result.status = nfs_error(EROFS);
+ }
+
+ return &result;
+}
+
+am_LINK3res *
+am_nfs3_link_3_svc(am_LINK3args *argp, struct svc_req *rqstp)
+{
+ static am_LINK3res result;
+
+ am_nfs_fh3 *file = (am_nfs_fh3 *) &argp->file;
+ am_nfs_fh3 *dir = (am_nfs_fh3 *) &argp->link.dir;
+ am_post_op_attr *post_op_file;
+ am_pre_op_attr *pre_op_dir;
+ am_post_op_attr *post_op_dir;
+ am_node *mp_file, *mp_dir;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "link_3:");
+
+ post_op_file = &result.res_u.fail.file_attributes;
+ post_op_file->attributes_follow = 0;
+
+ mp_file = fh3_to_mp(file);
+ if (mp_file) {
+ nfsfattr *fattr = &mp_file->am_fattr;
+ am_fattr3 *fattr3 = &post_op_file->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+ }
+
+ pre_op_dir = &result.res_u.fail.linkdir_wcc.before;
+ pre_op_dir->attributes_follow = 0;
+ post_op_dir = &result.res_u.fail.linkdir_wcc.after;
+ post_op_dir->attributes_follow = 0;
+
+ mp_dir = fh3_to_mp(dir);
+ if (mp_dir) {
+ nfsfattr *fattr = &mp_dir->am_fattr;
+ am_fattr3 *fattr3 = &post_op_dir->am_post_op_attr_u.attributes;
+ am_wcc_attr *wcc_attr = &pre_op_dir->am_pre_op_attr_u.attributes;
+
+ pre_op_dir->attributes_follow = 1;
+ fattr_to_wcc_attr(fattr, wcc_attr);
+ post_op_dir->attributes_follow = 1;
+ fattr_to_fattr3(fattr, fattr3);
+ }
+
+ if (!mp_file || !mp_dir)
+ result.status = nfs_error(ESTALE);
+ else
+ result.status = nfs_error(EROFS);
+
+ return &result;
+}
+
+am_READDIR3res *
+am_nfs3_readdir_3_svc(am_READDIR3args *argp, struct svc_req *rqstp)
+{
+ static am_READDIR3res result;
+ static am_entry3 entries[MAX_READDIR_ENTRIES];
+ am_nfs_fh3 *dir = (am_nfs_fh3 *) &argp->dir;
+ am_cookie3 cookie = argp->cookie;
+ am_cookieverf3 cookieverf;
+ am_count3 count = argp->count;
+ am_post_op_attr *post_op_dir;
+ am_node *mp;
+ int retry;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "readdir_3:");
+
+ memcpy(&cookieverf, &argp->cookieverf, sizeof(am_cookieverf3));
+
+ mp = fh3_to_mp3(dir, &retry, VLOOK_CREATE);
+ if (mp == NULL) {
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ post_op_dir = &result.res_u.fail.dir_attributes;
+ post_op_dir->attributes_follow = 0;
+ result.status = nfs_error(retry);
+ } else {
+ am_dirlist3 *list = &result.res_u.ok.reply;
+ am_nfsstat3 status;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\treaddir_3(%s)", mp->am_path);
+
+ status = mp->am_al->al_mnt->mf_ops->readdir(mp,
+ (voidp)&cookie, list, entries, count);
+ if (status == 0) {
+ post_op_dir = &result.res_u.ok.dir_attributes;
+ nfsfattr *fattr;
+ am_fattr3 *fattr3;
+
+ fattr = &mp->am_fattr;
+ fattr3 = &post_op_dir->am_post_op_attr_u.attributes;
+ post_op_dir->attributes_follow = 1;
+ fattr_to_fattr3(fattr, fattr3);
+ result.status = AM_NFS3_OK;
+ } else {
+ post_op_dir = &result.res_u.fail.dir_attributes;
+ post_op_dir->attributes_follow = 0;
+ result.status = nfs_error(status);
+ }
+
+ mp->am_stats.s_readdir++;
+ }
+
+ return &result;
+}
+
+am_READDIRPLUS3res *
+am_nfs3_readdirplus_3_svc(am_READDIRPLUS3args *argp, struct svc_req *rqstp)
+{
+ static am_READDIRPLUS3res result;
+ am_nfs_fh3 *dir = (am_nfs_fh3 *) &argp->dir;
+ am_post_op_attr *post_op_dir;
+ nfsfattr *fattr;
+ am_fattr3 *fattr3;
+ am_node *mp;
+ int retry;
+
+ mp = fh3_to_mp3(dir, &retry, VLOOK_CREATE);
+ if (mp == NULL) {
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ post_op_dir = &result.res_u.fail.dir_attributes;
+ post_op_dir->attributes_follow = 0;
+ result.status = nfs_error(retry);
+ } else {
+ post_op_dir = &result.res_u.ok.dir_attributes;
+ fattr = &mp->am_fattr;
+ fattr3 = &post_op_dir->am_post_op_attr_u.attributes;
+ post_op_dir->attributes_follow = 1;
+ fattr_to_fattr3(fattr, fattr3);
+ result.status = AM_NFS3ERR_NOTSUPP;
+ }
+
+ return &result;
+}
+
+am_FSSTAT3res *
+am_nfs3_fsstat_3_svc(am_FSSTAT3args *argp, struct svc_req *rqstp)
+{
+ static am_FSSTAT3res result;
+
+ am_nfs_fh3 *fsroot = (am_nfs_fh3 *) &argp->fsroot;
+ am_post_op_attr *post_op_fsroot;
+ am_node *mp;
+ int retry;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "fsstat_3:");
+
+ mp = fh3_to_mp3(fsroot, &retry, VLOOK_CREATE);
+ if (!mp) {
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ post_op_fsroot = &result.res_u.fail.obj_attributes;
+ post_op_fsroot->attributes_follow = 0;
+ result.status = nfs_error(retry);
+ } else {
+ am_FSSTAT3resok *ok = &result.res_u.ok;
+ u_int blocks, bfree, bavail;
+ nfsfattr *fattr;
+ am_fattr3 *fattr3;
+ mntent_t mnt;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\tfsstat_3(%s)", mp->am_path);
+
+ fattr = &mp->am_fattr;
+ post_op_fsroot = &ok->obj_attributes;
+ post_op_fsroot->attributes_follow = 1;
+ fattr3 = &post_op_fsroot->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ /*
+ * just return faked up file system information
+ */
+ ok->tbytes = 1024;
+ ok->invarsec = 0;
+
+ /* check if map is browsable and show_statfs_entries=yes */
+ if ((gopt.flags & CFM_SHOW_STATFS_ENTRIES) &&
+ mp->am_al->al_mnt && mp->am_al->al_mnt->mf_mopts) {
+ mnt.mnt_opts = mp->am_al->al_mnt->mf_mopts;
+ if (amu_hasmntopt(&mnt, "browsable")) {
+ count_map_entries(mp, &blocks, &bfree, &bavail);
+ }
+ ok->fbytes = bfree;
+ ok->abytes = bavail;
+ ok->ffiles = bfree;
+ ok->afiles = bavail;
+ ok->tfiles = blocks;
+ } else {
+ ok->fbytes = 0;
+ ok->abytes = 0;
+ ok->ffiles = 0;
+ ok->afiles = 0;
+ ok->tfiles = 0; /* set to 1 if you don't want empty automounts */
+ }
+
+ result.status = AM_NFS3_OK;
+ mp->am_stats.s_statfs++;
+ }
+
+ return &result;
+}
+
+#define FSF3_HOMOGENEOUS 0x0008
+
+am_FSINFO3res *
+am_nfs3_fsinfo_3_svc(am_FSINFO3args *argp, struct svc_req *rqstp)
+{
+ static am_FSINFO3res result;
+
+ am_nfs_fh3 *fsroot = (am_nfs_fh3 *) &argp->fsroot;
+ am_post_op_attr *post_op_fsroot;
+ am_node *mp;
+ int retry;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "fsinfo_3:");
+
+ mp = fh3_to_mp3(fsroot, &retry, VLOOK_CREATE);
+ if (!mp) {
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ post_op_fsroot = &result.res_u.fail.obj_attributes;
+ post_op_fsroot->attributes_follow = 0;
+ result.status = nfs_error(retry);
+ } else {
+ am_FSINFO3resok *ok = &result.res_u.ok;
+ nfsfattr *fattr;
+ am_fattr3 *fattr3;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\tfsinfo_3(%s)", mp->am_path);
+
+ fattr = &mp->am_fattr;
+ post_op_fsroot = &ok->obj_attributes;
+ post_op_fsroot->attributes_follow = 1;
+ fattr3 = &post_op_fsroot->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ /*
+ * just return faked up file system information
+ */
+ ok->rtmax = 0;
+ ok->rtpref = 0;
+ ok->rtmult = 0;
+ ok->wtmax = 0;
+ ok->wtpref = 0;
+ ok->wtmult = 0;
+ ok->dtpref = 1024;
+ ok->maxfilesize = 0;
+ ok->time_delta.seconds = 1;
+ ok->time_delta.nseconds = 0;
+ ok->properties = FSF3_HOMOGENEOUS;
+
+ result.status = AM_NFS3_OK;
+ mp->am_stats.s_fsinfo++;
+ }
+
+ return &result;
+}
+
+am_PATHCONF3res *
+am_nfs3_pathconf_3_svc(am_PATHCONF3args *argp, struct svc_req *rqstp)
+{
+ static am_PATHCONF3res result;
+
+ am_nfs_fh3 *obj = (am_nfs_fh3 *) &argp->object;
+ am_post_op_attr *post_op_obj;
+ am_node *mp;
+ int retry;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "pathconf_3:");
+
+ mp = fh3_to_mp3(obj, &retry, VLOOK_CREATE);
+ if (!mp) {
+ if (retry < 0) {
+ amd_stats.d_drops++;
+ return 0;
+ }
+ post_op_obj = &result.res_u.fail.obj_attributes;
+ post_op_obj->attributes_follow = 0;
+ result.status = nfs_error(retry);
+ } else {
+ am_PATHCONF3resok *ok = &result.res_u.ok;
+ nfsfattr *fattr;
+ am_fattr3 *fattr3;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "\tpathconf_3(%s)", mp->am_path);
+
+ fattr = &mp->am_fattr;
+ post_op_obj = &ok->obj_attributes;
+ post_op_obj->attributes_follow = 1;
+ fattr3 = &post_op_obj->am_post_op_attr_u.attributes;
+ fattr_to_fattr3(fattr, fattr3);
+
+ ok->linkmax = 0;
+ ok->name_max = NAME_MAX;
+ ok->no_trunc = 1;
+ ok->chown_restricted = 1;
+ ok->case_insensitive = 0;
+ ok->case_preserving = 1;
+
+ result.status = AM_NFS3_OK;
+ mp->am_stats.s_pathconf++;
+ }
+
+ return &result;
+}
+
+am_COMMIT3res *
+am_nfs3_commit_3_svc(am_COMMIT3args *argp, struct svc_req *rqstp)
+{
+ static am_COMMIT3res result;
+
+ am_nfs_fh3 *file = (am_nfs_fh3 *) &argp->file;
+ am_pre_op_attr *pre_op_file = &result.res_u.fail.file_wcc.before;
+ am_post_op_attr *post_op_file = &result.res_u.fail.file_wcc.after;
+
+ if (amuDebug(D_TRACE))
+ plog(XLOG_DEBUG, "commit_3:");
+
+ result.status = return_estale_or_rofs(file, pre_op_file, post_op_file);
+
+ return &result;
+}
+#endif /* HAVE_FS_NFS3 */
static int foofs_mount(am_node *mp, mntfs *mf);
static int foofs_umount(am_node *mp, mntfs *mf);
static am_node *foofs_lookuppn(am_node *mp, char *fname, int *error_return, int op);
-static int foofs_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count);
+static int foofs_readdir(am_node *mp, void cookie, voidp dp, voidp ep, u_int count);
static am_node *foofs_readlink(am_node *mp, int *error_return);
static void foofs_mounted(am_node *am, mntfs *mf);
static void foofs_umounted(am_node *mp, mntfs *mf);
* If OK, fills in ep with chain of directory entries.
*/
static int
-foofs_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count)
+foofs_readdir(am_node *mp, void cookie, voidp dp, voidp ep, u_int count)
{
int error = 0;
* to be returned in a single packet. If it isn't (which would be
* fairly unbelievable) then tough.
*/
- dlog("amfs_readdir_browsable: default search");
+ dlog("%s: default search", __func__);
/*
* Check for enough room. This is extremely approximate but is more
* than enough space. Really need 2 times:
return 0;
} /* end of "if (gen == 0)" statement */
- dlog("amfs_readdir_browsable: real child");
+ dlog("%s: real child", __func__);
if (gen == DOT_DOT_COOKIE) {
- dlog("amfs_readdir_browsable: End of readdir in %s", mp->am_path);
+ dlog("%s: End of readdir in %s", __func__, mp->am_path);
dp->dl_eof = TRUE;
dp->dl_entries = NULL;
return 0;
return 0;
}
-
-/*
- * This readdir function which call a special version of it that allows
- * browsing if browsable_dirs=yes was set on the map.
- */
-int
-amfs_generic_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count)
+static int
+amfs_readdir(am_node *mp, nfscookie cookie, nfsdirlist *dp, nfsentry *ep, u_int count)
{
u_int gen = *(u_int *) cookie;
am_node *xp;
- mntent_t mnt;
dp->dl_eof = FALSE; /* assume readdir not done */
- /* check if map is browsable */
- if (mp->am_al->al_mnt && mp->am_al->al_mnt->mf_mopts) {
- mnt.mnt_opts = mp->am_al->al_mnt->mf_mopts;
- if (amu_hasmntopt(&mnt, "fullybrowsable"))
- return amfs_readdir_browsable(mp, cookie, dp, ep, count, TRUE);
- if (amu_hasmntopt(&mnt, "browsable"))
- return amfs_readdir_browsable(mp, cookie, dp, ep, count, FALSE);
- }
-
/* when gen is 0, we start reading from the beginning of the directory */
if (gen == 0) {
/*
* to be returned in a single packet. If it isn't (which would be
* fairly unbelievable) then tough.
*/
- dlog("amfs_generic_readdir: default search");
+ dlog("%s: default search", __func__);
/*
* Check for enough room. This is extremely approximate but is more
* than enough space. Really need 2 times:
}
return 0;
}
- dlog("amfs_generic_readdir: real child");
+ dlog("%s: real child", __func__);
if (gen == DOT_DOT_COOKIE) {
- dlog("amfs_generic_readdir: End of readdir in %s", mp->am_path);
+ dlog("%s: End of readdir in %s", __func__, mp->am_path);
dp->dl_eof = TRUE;
dp->dl_entries = NULL;
if (amuDebug(D_READDIR))
}
return ESTALE;
}
+
+/*
+ * Search a chain for an entry with some name.
+ */
+static int
+key_already_in_chain3(char *keyname, const am_entry3 *chain)
+{
+ const am_entry3 *tmpchain = chain;
+
+ while (tmpchain) {
+ if (keyname && tmpchain->name && STREQ(keyname, tmpchain->name))
+ return 1;
+ tmpchain = tmpchain->nextentry;
+ }
+
+ return 0;
+}
+
+/*
+ * Create a chain of entries which are not linked.
+ */
+static am_entry3 *
+make_entry_chain3(am_node *mp, const am_entry3 *current_chain, int fully_browsable)
+{
+ static uint64 last_cookie = (uint64) 2; /* monotonically increasing */
+ static am_entry3 chain[MAX_CHAIN];
+ static int max_entries = MAX_CHAIN;
+ char *key;
+ int num_entries = 0, i;
+ u_int preflen = 0;
+ am_entry3 *retval = (am_entry3 *) NULL;
+ mntfs *mf;
+ mnt_map *mmp;
+
+ if (!mp) {
+ plog(XLOG_DEBUG, "make_entry_chain3: mp is (NULL)");
+ return retval;
+ }
+ mf = mp->am_al->al_mnt;
+ if (!mf) {
+ plog(XLOG_DEBUG, "make_entry_chain3: mp->am_al->al_mnt is (NULL)");
+ return retval;
+ }
+ mmp = (mnt_map *) mf->mf_private;
+ if (!mmp) {
+ plog(XLOG_DEBUG, "make_entry_chain3: mp->am_al->al_mnt->mf_private is (NULL)");
+ return retval;
+ }
+
+ if (mp->am_pref)
+ preflen = strlen(mp->am_pref);
+
+ /* iterate over keys */
+ for (i = 0; i < NKVHASH; i++) {
+ kv *k;
+ for (k = mmp->kvhash[i]; k ; k = k->next) {
+
+ /*
+ * Skip unwanted entries which are either not real entries or
+ * very difficult to interpret (wildcards...) This test needs
+ * lots of improvement. Any takers?
+ */
+ key = k->key;
+ if (!key)
+ continue;
+
+ /* Skip '/defaults' */
+ if (STREQ(key, "/defaults"))
+ continue;
+
+ /* Skip '*' */
+ if (!fully_browsable && strchr(key, '*'))
+ continue;
+
+ /*
+ * If the map has a prefix-string then check if the key starts with
+ * this string, and if it does, skip over this prefix. If it has a
+ * prefix and it doesn't match the start of the key, skip it.
+ */
+ if (preflen) {
+ if (preflen > strlen(key))
+ continue;
+ if (!NSTREQ(key, mp->am_pref, preflen))
+ continue;
+ key += preflen;
+ }
+
+ /* no more '/' are allowed, unless browsable_dirs=full was used */
+ if (!fully_browsable && strchr(key, '/'))
+ continue;
+
+ /* no duplicates allowed */
+ if (key_already_in_chain3(key, current_chain))
+ continue;
+
+ /* fill in a cell and link the entry */
+ if (num_entries >= max_entries) {
+ /* out of space */
+ plog(XLOG_DEBUG, "make_entry_chain3: no more space in chain");
+ if (num_entries > 0) {
+ chain[num_entries - 1].nextentry = NULL;
+ retval = &chain[0];
+ }
+ return retval;
+ }
+
+ /* we have space. put entry in next cell */
+ ++last_cookie;
+ chain[num_entries].fileid = last_cookie;
+ chain[num_entries].cookie = last_cookie;
+ chain[num_entries].name = key;
+ if (num_entries < max_entries - 1) { /* link to next one */
+ chain[num_entries].nextentry = &chain[num_entries + 1];
+ }
+ ++num_entries;
+ } /* end of "while (k)" */
+ } /* end of "for (i ... NKVHASH ..." */
+
+ /* terminate chain */
+ if (num_entries > 0) {
+ chain[num_entries - 1].nextentry = NULL;
+ retval = &chain[0];
+ }
+
+ return retval;
+}
+
+/* This one is called only if map is browsable */
+static int
+amfs_readdir3_browsable(am_node *mp, am_cookie3 cookie,
+ am_dirlist3 *dp, am_entry3 *ep, u_int count,
+ int fully_browsable)
+{
+ uint64 gen = *(uint64 *) cookie;
+ int chain_length, i;
+ static am_entry3 *te, *te_next;
+ static int j;
+
+ dp->eof = FALSE; /* assume readdir not done */
+
+ if (amuDebug(D_READDIR))
+ plog(XLOG_DEBUG, "amfs_readdir3_browsable gen=%lu, count=%d", gen, count);
+
+ if (gen == 0) {
+ /*
+ * In the default instance (which is used to start a search) we return
+ * "." and "..".
+ *
+ * This assumes that the count is big enough to allow both "." and ".."
+ * to be returned in a single packet. If it isn't (which would be
+ * fairly unbelievable) then tough.
+ */
+ dlog("%s: default search", __func__);
+ /*
+ * Check for enough room. This is extremely approximate but should
+ * be enough space. Really need 2 times:
+ * (8byte fileid
+ * 8byte cookie
+ * 8byte name pointer
+ * 8byte next entry addres) = sizeof(*ep)
+ * 2byte name + 1byte terminator
+ * plus the dirlist structure */
+ if (count < ((2 * ((sizeof(*ep) + sizeof("..") + 1))) + sizeof(*dp)));
+ return EINVAL;
+
+ /*
+ * compute # of entries to send in this chain.
+ * heuristics: 128 bytes per entry.
+ * This is too much probably, but it seems to work better because
+ * of the re-entrant nature of nfs_readdir, and esp. on systems
+ * like OpenBSD 2.2.
+ */
+ chain_length = count / 128;
+
+ /* reset static state counters */
+ te = te_next = NULL;
+
+ dp->entries = ep;
+
+ /* construct "." */
+ ep[0].fileid = mp->am_gen;
+ ep[0].name = ".";
+ ep[0].nextentry = &ep[1];
+ ep[0].cookie = 0;
+
+ /* construct ".." */
+ if (mp->am_parent)
+ ep[1].fileid = mp->am_parent->am_gen;
+ else
+ ep[1].fileid = mp->am_gen;
+
+ ep[1].name = "..";
+ ep[1].nextentry = NULL;
+ ep[1].cookie = dotdotcookie;
+
+ /*
+ * If map is browsable, call a function make_entry_chain() to construct
+ * a linked list of unmounted keys, and return it. Then link the chain
+ * to the regular list. Get the chain only once, but return
+ * chunks of it each time.
+ */
+ te = make_entry_chain3(mp, dp->entries, fully_browsable);
+ if (!te)
+ return 0;
+ if (amuDebug(D_READDIR)) {
+ am_entry3 *ne;
+ for (j = 0, ne = te; ne; ne = ne->ne_nextentry)
+ plog(XLOG_DEBUG, "gen1 key %4d \"%s\"", j++, ne->ne_name);
+ }
+
+ /* return only "chain_length" entries */
+ te_next = te;
+ for (i=1; i<chain_length; ++i) {
+ te_next = te_next->nextentry;
+ if (!te_next)
+ break;
+ }
+ if (te_next) {
+ am_entry3 *te_saved = te_next->nextentry;
+ te_next->nextentry = NULL; /* terminate "te" chain */
+ te_next = te_saved; /* save rest of "te" for next iteration */
+ dp->eof = FALSE; /* tell readdir there's more */
+ } else {
+ dp->eof = TRUE; /* tell readdir that's it */
+ }
+ ep[1].nextentry = te; /* append this chunk of "te" chain */
+ if (amuDebug(D_READDIR)) {
+ am_entry3 *ne;
+ for (j = 0, ne = te; ne; ne = ne->ne_nextentry)
+ plog(XLOG_DEBUG, "gen2 key %4d \"%s\"", j++, ne->name);
+ for (j = 0, ne = ep; ne; ne = ne->ne_nextentry) {
+ plog(XLOG_DEBUG, "gen2+ key %4d \"%s\" fi=%lu ck=%lu",
+ j++, ne->name, ne->fileid, ne->cookie);
+ }
+ plog(XLOG_DEBUG, "EOF is %d", dp->eof);
+ }
+ return 0;
+ } /* end of "if (gen == 0)" statement */
+
+ dlog("%s: real child", __func__);
+
+ if (gen == DOT_DOT_COOKIE) {
+ dlog("%s: End of readdir in %s", __func__, mp->am_path);
+ dp->eof = TRUE;
+ dp->entries = NULL;
+ return 0;
+ }
+
+ /*
+ * If browsable directories, then continue serving readdir() with another
+ * chunk of entries, starting from where we left off (when gen was equal
+ * to 0). Once again, assume last chunk served to readdir.
+ */
+ dp->eof = TRUE;
+ dp->entries = ep;
+
+ te = te_next; /* reset 'te' from last saved te_next */
+ if (!te) { /* another indicator of end of readdir */
+ dp->entries = NULL;
+ return 0;
+ }
+ /*
+ * compute # of entries to send in this chain.
+ * heuristics: 128 bytes per entry.
+ */
+ chain_length = count / 128;
+
+ /* return only "chain_length" entries */
+ for (i = 1; i < chain_length; ++i) {
+ te_next = te_next->nextentry;
+ if (!te_next)
+ break;
+ }
+ if (te_next) {
+ am_entry3 *te_saved = te_next->nextentry;
+ te_next->nextentry = NULL; /* terminate "te" chain */
+ te_next = te_saved; /* save rest of "te" for next iteration */
+ dp->eof = FALSE; /* tell readdir there's more */
+ }
+ ep = te; /* send next chunk of "te" chain */
+ dp->entries = ep;
+ if (amuDebug(D_READDIR)) {
+ am_entry3 *ne;
+ plog(XLOG_DEBUG,
+ "entries=%p, te_next=%p, eof=%d", dp->entries, te_next, dp->eof);
+ for (ne = te; ne; ne = ne->nextentry)
+ plog(XLOG_DEBUG, "gen3 key %4d \"%s\"", j++, ne->name);
+ }
+ return 0;
+}
+
+static int
+amfs_readdir3(am_node *mp, am_cookie3 cookie,
+ am_dirlist3 *dp, am_entry3 *ep, u_int count)
+{
+ uint64 gen = *(uint64 *) cookie;
+ am_node *xp;
+
+ if (amuDebug(D_READDIR))
+ plog(XLOG_DEBUG, "amfs_readdir3 gen=%lu, count=%d", gen, count);
+
+ dp->eof = FALSE; /* assume readdir not done */
+
+ /* when gen is 0, we start reading from the beginning of the directory */
+ if (gen == 0) {
+ /*
+ * In the default instance (which is used to start a search) we return
+ * "." and "..".
+ *
+ * This assumes that the count is big enough to allow both "." and ".."
+ * to be returned in a single packet. If it isn't (which would be
+ * fairly unbelievable) then tough.
+ */
+ dlog("%s: default search", __func__);
+ /*
+ * Check for enough room. This is extremely approximate but should
+ * be enough space. Really need 2 times:
+ * (8byte fileid
+ * 8byte cookie
+ * 8byte name pointer
+ * 8byte next entry addres) = sizeof(*ep)
+ * 2byte name + 1byte terminator
+ * plus the dirlist structure */
+ if (count < ((2 * ((sizeof(*ep) + sizeof("..") + 1))) + sizeof(*dp)));
+ return EINVAL;
+
+ xp = next_nonerror_node(mp->am_child);
+ dp->entries = ep;
+
+ /* construct "." */
+ ep[0].fileid = mp->am_gen;
+ ep[0].name = ".";
+ ep[0].cookie = 0;
+ ep[0].nextentry = &ep[1];
+
+ /* construct ".." */
+ if (mp->am_parent)
+ ep[1].fileid = mp->am_parent->am_gen;
+ else
+ ep[1].fileid = mp->am_gen;
+ ep[1].name = "..";
+ ep[1].nextentry = NULL;
+ ep[1].cookie = (xp ? xp->am_gen : dotdotcookie);
+
+ if (!xp)
+ dp->eof = TRUE; /* by default assume readdir done */
+
+ if (amuDebug(D_READDIR)) {
+ am_entry3 *ne;
+ int j;
+ for (j = 0, ne = ep; ne; ne = ne->nextentry) {
+ plog(XLOG_DEBUG, "gen1 key %4d \"%s\" fi=%lu ck=%lu",
+ j++, ne->name, ne->fileid, ne->cookie);
+ }
+ }
+ return 0;
+ }
+ dlog("%s: real child", __func__);
+
+ if (gen == (uint64) DOT_DOT_COOKIE) {
+ dlog("%s: End of readdir in %s", __func__, mp->am_path);
+ dp->eof = TRUE;
+ dp->entries = NULL;
+ if (amuDebug(D_READDIR))
+ plog(XLOG_DEBUG, "end of readdir eof=TRUE, dl_entries=0\n");
+ return 0;
+ }
+
+ /* non-browsable directories code */
+ xp = mp->am_child;
+ while (xp && xp->am_gen != gen)
+ xp = xp->am_osib;
+
+ if (xp) {
+ int nbytes = count / 2; /* conservative */
+ int todo = MAX_READDIR_ENTRIES;
+
+ dp->entries = ep;
+ do {
+ am_node *xp_next = next_nonerror_node(xp->am_osib);
+
+ if (xp_next) {
+ ep->cookie = xp_next->am_gen;
+ } else {
+ ep->cookie = (uint64) dotdotcookie;
+ dp->eof = TRUE;
+ }
+
+ ep->fileid = xp->am_gen;
+ ep->name = xp->am_name;
+ nbytes -= sizeof(*ep) + 1;
+ if (xp->am_name)
+ nbytes -= strlen(xp->am_name);
+
+ xp = xp_next;
+
+ if (nbytes > 0 && !dp->dl_eof && todo > 1) {
+ ep->nextentry = ep + 1;
+ ep++;
+ --todo;
+ } else {
+ todo = 0;
+ }
+ } while (todo > 0);
+
+ ep->nextentry = NULL;
+
+ if (amuDebug(D_READDIR)) {
+ am_entry3 *ne;
+ int j;
+ for (j = 0, ne = ep; ne; ne = ne->nextentry) {
+ plog(XLOG_DEBUG, "gen2 key %4d \"%s\" fi=%lu ck=%lu",
+ j++, ne->name, ne->fileid, ne->cookie);
+ }
+ }
+ return 0;
+ }
+ return ESTALE;
+}
+
+/*
+ * This readdir function which call a special version of it that allows
+ * browsing if browsable_dirs=yes was set on the map.
+ */
+int
+amfs_generic_readdir(am_node *mp, voidp cookie, voidp dp, voidp ep, u_int count)
+{
+ int browsable, full;
+
+ /* check if map is browsable */
+ browsable = 0;
+ if (mp->am_al->al_mnt && mp->am_al->al_mnt->mf_mopts) {
+ mntent_t mnt;
+ mnt.mnt_opts = mp->am_al->al_mnt->mf_mopts;
+ if (amu_hasmntopt(&mnt, "fullybrowsable"))
+ browsable = 2;
+ else if (amu_hasmntopt(&mnt, "browsable"))
+ browsable = 1;
+ }
+ full = (browsable == 2);
+
+ if (nfs_dispatcher == nfs_program_2) {
+ if (browsable)
+ return amfs_readdir_browsable(mp, cookie, dp, ep, count, full);
+ else
+ return amfs_readdir(mp, cookie, dp, ep, count);
+ } else {
+ if (browsable)
+ return amfs_readdir3_browsable(mp, (am_cookie3) cookie, dp, ep, count, full);
+ else
+ return amfs_readdir3(mp, (am_cookie3) cookie, dp, ep, count);
+ }
+}
if (old_ports[i] == 0) {
int soNFS;
SVCXPRT *nfsxprt;
- if (create_nfs_service(&soNFS, &port, &nfsxprt, nfs_program_2) != 0) {
+ if (create_nfs_service(&soNFS, &port, &nfsxprt, nfs_dispatcher,
+ get_nfs_dispatcher_version(nfs_dispatcher)) != 0) {
plog(XLOG_WARNING, "Can't bind to port %u", port);
goto give_up;
}
#define na_mode mode
#define na_mtime mtime
#define na_nlink nlink
+#define na_rdev rdev
#define na_size size
#define na_uid uid
#define na_type type
* Create the nfs service for amd
*/
int
-create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp))
+create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp), u_long nfs_version)
{
-
*soNFSp = socket(AF_INET, SOCK_DGRAM, 0);
if (*soNFSp < 0 || bind_resv_port(*soNFSp, nfs_portp) < 0) {
close(*soNFSp);
return 1;
}
- if (!svc_register(*nfs_xprtp, NFS_PROGRAM, NFS_VERSION, dispatch_fxn, 0)) {
- plog(XLOG_FATAL, "unable to register (%ld, %ld, 0)",
- (u_long) NFS_PROGRAM, (u_long) NFS_VERSION);
+ if (!svc_register(*nfs_xprtp, NFS_PROGRAM, nfs_version, dispatch_fxn, 0)) {
+ plog(XLOG_FATAL, "unable to register (%lu, %lu, 0)",
+ (u_long) NFS_PROGRAM, nfs_version);
svc_destroy(*nfs_xprtp);
close(*soNFSp);
return 3;
* return 0 (TRUE) if OK, 1 (FALSE) if failed.
*/
int
-create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp))
+create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp), u_long nfs_version)
{
char *nettype = "ticlts";
svc_destroy(*nfs_xprtp);
return 1;
}
- if (svc_reg(*nfs_xprtp, NFS_PROGRAM, NFS_VERSION, dispatch_fxn, NULL) != 1) {
+ if (svc_reg(*nfs_xprtp, NFS_PROGRAM, nfs_version, dispatch_fxn, NULL) != 1) {
plog(XLOG_ERROR, "could not register amd NFS service");
svc_destroy(*nfs_xprtp);
return 1;
/*
* Register hlfsd as an nfs service with the portmapper.
*/
-#ifdef HAVE_TRANSPORT_TYPE_TLI
- ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
-#else /* not HAVE_TRANSPORT_TYPE_TLI */
- ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
-#endif /* not HAVE_TRANSPORT_TYPE_TLI */
+ ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2,
+ NFS_VERSION);
if (ret != 0)
fatal("cannot create NFS service");
extern int mkdirs(char *, int);
extern int mount_fs(mntent_t *, int, caddr_t, int, MTYPE_TYPE, u_long, const char *, const char *, int);
extern void nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp);
+extern void nfs_program_3(struct svc_req *rqstp, SVCXPRT *transp);
+#define get_nfs_dispatcher_version(a) \
+ ((a) == nfs_program_2 ? NFS_VERSION : NFS_VERSION3)
extern int pickup_rpc_reply(voidp, int, voidp, XDRPROC_T_TYPE);
extern int switch_option(char *);
extern int switch_to_logfile(char *logfile, int orig_umask, int truncate_log);
extern void compute_nfs_args(void *nap, mntent_t *mntp, int genflags, struct netconfig *nfsncp, struct sockaddr_in *ip_addr, u_long nfs_version, char *nfs_proto, am_nfs_handle_t *fhp, char *host_name, char *fs_name);
extern void destroy_nfs_args(void *nap, u_long nfs_version);
extern int create_amq_service(int *udp_soAMQp, SVCXPRT **udp_amqpp, struct netconfig **udp_amqncpp, int *tcp_soAMQp, SVCXPRT **tcp_amqpp, struct netconfig **tcp_amqncpp, u_short preferred_amq_port);
-extern int create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp));
+extern int create_nfs_service(int *soNFSp, u_short *nfs_portp, SVCXPRT **nfs_xprtp, void (*dispatch_fxn)(struct svc_req *rqstp, SVCXPRT *transp), u_long nfs_version);
extern int amu_svc_register(SVCXPRT *, u_long, u_long, void (*)(struct svc_req *, SVCXPRT *), u_long, struct netconfig *);
#ifdef HAVE_TRANSPORT_TYPE_TLI
#ifdef HAVE_FS_NFS3
+#define AM_MOUNTVERS3 ((unsigned long)(3))
+
#define AM_FHSIZE3 64 /* size in bytes of a file handle (v3) */
-#define AM_MOUNTVERS3 ((unsigned long)(3))
+#define AM_NFS3_WRITEVERFSIZE 8
+#define AM_NFS3_CREATEVERFSIZE 8
+#define AM_NFS3_COOKIEVERFSIZE 8
+#define AM_ACCESS3_READ 0x0001
+#define AM_ACCESS3_LOOKUP 0x0002
+#define AM_ACCESS3_MODIFY 0x0004
+#define AM_ACCESS3_EXTEND 0x0008
+#define AM_ACCESS3_DELETE 0x0010
+#define AM_ACCESS3_EXECUTE 0x0020
+#define AM_FSF3_LINK 0x0001
+#define AM_FSF3_SYMLINK 0x0002
+#define AM_FSF3_HOMOGENEOUS 0x0008
+#define AM_FSF3_CANSETTIME 0x0010
+
+typedef char am_cookieverf3[AM_NFS3_COOKIEVERFSIZE];
+
+typedef u_quad_t uint64;
+
+typedef uint64 am_cookie3;
/* NFSv3 handle */
struct am_nfs_fh3 {
};
typedef struct am_diropargs3 am_diropargs3;
+enum am_ftype3 {
+ AM_NF3REG = 1,
+ AM_NF3DIR = 2,
+ AM_NF3BLK = 3,
+ AM_NF3CHR = 4,
+ AM_NF3LNK = 5,
+ AM_NF3SOCK = 6,
+ AM_NF3FIFO = 7,
+};
+typedef enum am_ftype3 am_ftype3;
+
+typedef u_int am_mode3;
+
+typedef u_int am_uid3;
+
+typedef u_int am_gid3;
+
+typedef uint64 am_size3;
+
+typedef uint64 am_fileid3;
+
+struct am_specdata3 {
+ u_int specdata1;
+ u_int specdata2;
+};
+typedef struct am_specdata3 am_specdata3;
+
+struct am_nfstime3 {
+ u_int seconds;
+ u_int nseconds;
+};
+typedef struct am_nfstime3 am_nfstime3;
+
+struct am_fattr3 {
+ am_ftype3 type;
+ am_mode3 mode;
+ u_int nlink;
+ am_uid3 uid;
+ am_gid3 gid;
+ am_size3 size;
+ am_size3 used;
+ am_specdata3 rdev;
+ uint64 fsid;
+ am_fileid3 fileid;
+ am_nfstime3 atime;
+ am_nfstime3 mtime;
+ am_nfstime3 ctime;
+};
+typedef struct am_fattr3 am_fattr3;
+
+struct am_post_op_attr {
+ bool_t attributes_follow;
+ union {
+ am_fattr3 attributes;
+ } am_post_op_attr_u;
+};
+typedef struct am_post_op_attr am_post_op_attr;
+
+enum am_stable_how {
+ AM_UNSTABLE = 0,
+ AM_DATA_SYNC = 1,
+ AM_FILE_SYNC = 2,
+};
+typedef enum am_stable_how am_stable_how;
+
+typedef uint64 am_offset3;
+
+typedef u_int am_count3;
+
+struct am_wcc_attr {
+ am_size3 size;
+ am_nfstime3 mtime;
+ am_nfstime3 ctime;
+};
+typedef struct am_wcc_attr am_wcc_attr;
+
+struct am_pre_op_attr {
+ bool_t attributes_follow;
+ union {
+ am_wcc_attr attributes;
+ } am_pre_op_attr_u;
+};
+typedef struct am_pre_op_attr am_pre_op_attr;
+
+struct am_wcc_data {
+ am_pre_op_attr before;
+ am_post_op_attr after;
+};
+typedef struct am_wcc_data am_wcc_data;
+
+struct am_WRITE3args {
+ am_nfs_fh3 file;
+ am_offset3 offset;
+ am_count3 count;
+ am_stable_how stable;
+ struct {
+ u_int data_len;
+ char *data_val;
+ } data;
+};
+typedef struct am_WRITE3args am_WRITE3args;
+
+typedef char am_writeverf3[AM_NFS3_WRITEVERFSIZE];
+
+struct am_WRITE3resok {
+ am_wcc_data file_wcc;
+ am_count3 count;
+ am_stable_how committed;
+ am_writeverf3 verf;
+};
+typedef struct am_WRITE3resok am_WRITE3resok;
+
+struct am_WRITE3resfail {
+ am_wcc_data file_wcc;
+};
+typedef struct am_WRITE3resfail am_WRITE3resfail;
+
+struct am_WRITE3res {
+ am_nfsstat3 status;
+ union {
+ am_WRITE3resok ok;
+ am_WRITE3resfail fail;
+ } res_u;
+};
+typedef struct am_WRITE3res am_WRITE3res;
+
struct am_LOOKUP3args {
- am_diropargs3 what;
+ am_diropargs3 what;
};
typedef struct am_LOOKUP3args am_LOOKUP3args;
struct am_LOOKUP3resok {
- am_nfs_fh3 object;
-#if 0
- post_op_attr obj_attributes;
- post_op_attr dir_attributes;
-#endif /* 0 */
+ am_nfs_fh3 object;
+ am_post_op_attr obj_attributes;
+ am_post_op_attr dir_attributes;
};
typedef struct am_LOOKUP3resok am_LOOKUP3resok;
struct am_LOOKUP3resfail {
-#if 0
- post_op_attr dir_attributes;
-#else /* !0 */
- char dummy; /* cannot have an empty declaration */
-#endif /* !0 */
+ am_post_op_attr dir_attributes;
};
typedef struct am_LOOKUP3resfail am_LOOKUP3resfail;
struct am_LOOKUP3res {
- am_nfsstat3 status;
- union {
- am_LOOKUP3resok ok;
- am_LOOKUP3resfail fail;
- } res_u;
+ am_nfsstat3 status;
+ union {
+ am_LOOKUP3resok ok;
+ am_LOOKUP3resfail fail;
+ } res_u;
};
typedef struct am_LOOKUP3res am_LOOKUP3res;
+
+struct am_COMMIT3args {
+ am_nfs_fh3 file;
+ am_offset3 offset;
+ am_count3 count;
+};
+typedef struct am_COMMIT3args am_COMMIT3args;
+
+struct am_COMMIT3resok {
+ am_wcc_data file_wcc;
+ am_writeverf3 verf;
+};
+typedef struct am_COMMIT3resok am_COMMIT3resok;
+
+struct am_COMMIT3resfail {
+ am_wcc_data file_wcc;
+};
+typedef struct am_COMMIT3resfail am_COMMIT3resfail;
+
+struct am_COMMIT3res {
+ am_nfsstat3 status;
+ union {
+ am_COMMIT3resok ok;
+ am_COMMIT3resfail fail;
+ } res_u;
+};
+typedef struct am_COMMIT3res am_COMMIT3res;
+
+struct am_ACCESS3args {
+ am_nfs_fh3 object;
+ u_int access;
+};
+typedef struct am_ACCESS3args am_ACCESS3args;
+
+struct am_ACCESS3resok {
+ am_post_op_attr obj_attributes;
+ u_int access;
+};
+typedef struct am_ACCESS3resok am_ACCESS3resok;
+
+struct am_ACCESS3resfail {
+ am_post_op_attr obj_attributes;
+};
+typedef struct am_ACCESS3resfail am_ACCESS3resfail;
+
+struct am_ACCESS3res {
+ am_nfsstat3 status;
+ union {
+ am_ACCESS3resok ok;
+ am_ACCESS3resfail fail;
+ } res_u;
+};
+typedef struct am_ACCESS3res am_ACCESS3res;
+
+struct am_GETATTR3args {
+ am_nfs_fh3 object;
+};
+typedef struct am_GETATTR3args am_GETATTR3args;
+
+struct am_GETATTR3resok {
+ am_fattr3 obj_attributes;
+};
+typedef struct am_GETATTR3resok am_GETATTR3resok;
+
+struct am_GETATTR3res {
+ am_nfsstat3 status;
+ union {
+ am_GETATTR3resok ok;
+ } res_u;
+};
+typedef struct am_GETATTR3res am_GETATTR3res;
+
+enum am_time_how {
+ AM_DONT_CHANGE = 0,
+ AM_SET_TO_SERVER_TIME = 1,
+ AM_SET_TO_CLIENT_TIME = 2,
+};
+typedef enum am_time_how am_time_how;
+
+struct am_set_mode3 {
+ bool_t set_it;
+ union {
+ am_mode3 mode;
+ } am_set_mode3_u;
+};
+typedef struct am_set_mode3 am_set_mode3;
+
+struct am_set_uid3 {
+ bool_t set_it;
+ union {
+ am_uid3 uid;
+ } am_set_uid3_u;
+};
+typedef struct am_set_uid3 am_set_uid3;
+
+struct am_set_gid3 {
+ bool_t set_it;
+ union {
+ am_gid3 gid;
+ } am_set_gid3_u;
+};
+typedef struct am_set_gid3 am_set_gid3;
+
+struct am_set_size3 {
+ bool_t set_it;
+ union {
+ am_size3 size;
+ } am_set_size3_u;
+};
+typedef struct am_set_size3 am_set_size3;
+
+struct am_set_atime {
+ am_time_how set_it;
+ union {
+ am_nfstime3 atime;
+ } am_set_atime_u;
+};
+typedef struct am_set_atime am_set_atime;
+
+struct am_set_mtime {
+ am_time_how set_it;
+ union {
+ am_nfstime3 mtime;
+ } am_set_mtime_u;
+};
+typedef struct am_set_mtime am_set_mtime;
+
+struct am_sattr3 {
+ am_set_mode3 mode;
+ am_set_uid3 uid;
+ am_set_gid3 gid;
+ am_set_size3 size;
+ am_set_atime atime;
+ am_set_mtime mtime;
+};
+typedef struct am_sattr3 am_sattr3;
+
+enum am_createmode3 {
+ AM_UNCHECKED = 0,
+ AM_GUARDED = 1,
+ AM_EXCLUSIVE = 2,
+};
+typedef enum am_createmode3 am_createmode3;
+
+typedef char am_createverf3[AM_NFS3_CREATEVERFSIZE];
+
+struct am_createhow3 {
+ am_createmode3 mode;
+ union {
+ am_sattr3 obj_attributes;
+ am_sattr3 g_obj_attributes;
+ am_createverf3 verf;
+ } am_createhow3_u;
+};
+typedef struct am_createhow3 am_createhow3;
+
+struct am_CREATE3args {
+ am_diropargs3 where;
+ am_createhow3 how;
+};
+typedef struct am_CREATE3args am_CREATE3args;
+
+struct am_post_op_fh3 {
+ bool_t handle_follows;
+ union {
+ am_nfs_fh3 handle;
+ } am_post_op_fh3_u;
+};
+typedef struct am_post_op_fh3 am_post_op_fh3;
+
+struct am_CREATE3resok {
+ am_post_op_fh3 obj;
+ am_post_op_attr obj_attributes;
+ am_wcc_data dir_wcc;
+};
+typedef struct am_CREATE3resok am_CREATE3resok;
+
+struct am_CREATE3resfail {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_CREATE3resfail am_CREATE3resfail;
+
+struct am_CREATE3res {
+ am_nfsstat3 status;
+ union {
+ am_CREATE3resok ok;
+ am_CREATE3resfail fail;
+ } res_u;
+};
+typedef struct am_CREATE3res am_CREATE3res;
+
+struct am_REMOVE3args {
+ am_diropargs3 object;
+};
+typedef struct am_REMOVE3args am_REMOVE3args;
+
+struct am_REMOVE3resok {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_REMOVE3resok am_REMOVE3resok;
+
+struct am_REMOVE3resfail {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_REMOVE3resfail am_REMOVE3resfail;
+
+struct am_REMOVE3res {
+ am_nfsstat3 status;
+ union {
+ am_REMOVE3resok ok;
+ am_REMOVE3resfail fail;
+ } res_u;
+};
+typedef struct am_REMOVE3res am_REMOVE3res;
+
+struct am_READ3args {
+ am_nfs_fh3 file;
+ am_offset3 offset;
+ am_count3 count;
+};
+typedef struct am_READ3args am_READ3args;
+
+struct am_READ3resok {
+ am_post_op_attr file_attributes;
+ am_count3 count;
+ bool_t eof;
+ struct {
+ u_int data_len;
+ char *data_val;
+ } data;
+};
+typedef struct am_READ3resok am_READ3resok;
+
+struct am_READ3resfail {
+ am_post_op_attr file_attributes;
+};
+typedef struct am_READ3resfail am_READ3resfail;
+
+struct am_READ3res {
+ am_nfsstat3 status;
+ union {
+ am_READ3resok ok;
+ am_READ3resfail fail;
+ } res_u;
+};
+typedef struct am_READ3res am_READ3res;
+
+struct am_FSINFO3args {
+ am_nfs_fh3 fsroot;
+};
+typedef struct am_FSINFO3args am_FSINFO3args;
+
+struct am_FSINFO3resok {
+ am_post_op_attr obj_attributes;
+ u_int rtmax;
+ u_int rtpref;
+ u_int rtmult;
+ u_int wtmax;
+ u_int wtpref;
+ u_int wtmult;
+ u_int dtpref;
+ am_size3 maxfilesize;
+ am_nfstime3 time_delta;
+ u_int properties;
+};
+typedef struct am_FSINFO3resok am_FSINFO3resok;
+
+struct am_FSINFO3resfail {
+ am_post_op_attr obj_attributes;
+};
+typedef struct am_FSINFO3resfail am_FSINFO3resfail;
+
+struct am_FSINFO3res {
+ am_nfsstat3 status;
+ union {
+ am_FSINFO3resok ok;
+ am_FSINFO3resfail fail;
+ } res_u;
+};
+typedef struct am_FSINFO3res am_FSINFO3res;
+
+struct am_FSSTAT3args {
+ am_nfs_fh3 fsroot;
+};
+typedef struct am_FSSTAT3args am_FSSTAT3args;
+
+struct am_FSSTAT3resok {
+ am_post_op_attr obj_attributes;
+ am_size3 tbytes;
+ am_size3 fbytes;
+ am_size3 abytes;
+ am_size3 tfiles;
+ am_size3 ffiles;
+ am_size3 afiles;
+ u_int invarsec;
+};
+typedef struct am_FSSTAT3resok am_FSSTAT3resok;
+
+struct am_FSSTAT3resfail {
+ am_post_op_attr obj_attributes;
+};
+typedef struct am_FSSTAT3resfail am_FSSTAT3resfail;
+
+struct am_FSSTAT3res {
+ am_nfsstat3 status;
+ union {
+ am_FSSTAT3resok ok;
+ am_FSSTAT3resfail fail;
+ } res_u;
+};
+typedef struct am_FSSTAT3res am_FSSTAT3res;
+
+struct am_PATHCONF3args {
+ am_nfs_fh3 object;
+};
+typedef struct am_PATHCONF3args am_PATHCONF3args;
+
+struct am_PATHCONF3resok {
+ am_post_op_attr obj_attributes;
+ u_int linkmax;
+ u_int name_max;
+ bool_t no_trunc;
+ bool_t chown_restricted;
+ bool_t case_insensitive;
+ bool_t case_preserving;
+};
+typedef struct am_PATHCONF3resok am_PATHCONF3resok;
+
+struct am_PATHCONF3resfail {
+ am_post_op_attr obj_attributes;
+};
+typedef struct am_PATHCONF3resfail am_PATHCONF3resfail;
+
+struct am_PATHCONF3res {
+ am_nfsstat3 status;
+ union {
+ am_PATHCONF3resok ok;
+ am_PATHCONF3resfail fail;
+ } res_u;
+};
+typedef struct am_PATHCONF3res am_PATHCONF3res;
+
+typedef char *am_nfspath3;
+
+struct am_symlinkdata3 {
+ am_sattr3 symlink_attributes;
+ am_nfspath3 symlink_data;
+};
+typedef struct am_symlinkdata3 am_symlinkdata3;
+
+struct am_SYMLINK3args {
+ am_diropargs3 where;
+ am_symlinkdata3 symlink;
+};
+typedef struct am_SYMLINK3args am_SYMLINK3args;
+
+struct am_SYMLINK3resok {
+ am_post_op_fh3 obj;
+ am_post_op_attr obj_attributes;
+ am_wcc_data dir_wcc;
+};
+typedef struct am_SYMLINK3resok am_SYMLINK3resok;
+
+struct am_SYMLINK3resfail {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_SYMLINK3resfail am_SYMLINK3resfail;
+
+struct am_SYMLINK3res {
+ am_nfsstat3 status;
+ union {
+ am_SYMLINK3resok ok;
+ am_SYMLINK3resfail fail;
+ } res_u;
+};
+typedef struct am_SYMLINK3res am_SYMLINK3res;
+
+struct am_READLINK3args {
+ am_nfs_fh3 symlink;
+};
+typedef struct am_READLINK3args am_READLINK3args;
+
+struct am_READLINK3resok {
+ am_post_op_attr symlink_attributes;
+ am_nfspath3 data;
+};
+typedef struct am_READLINK3resok am_READLINK3resok;
+
+struct am_READLINK3resfail {
+ am_post_op_attr symlink_attributes;
+};
+typedef struct am_READLINK3resfail am_READLINK3resfail;
+
+struct am_READLINK3res {
+ am_nfsstat3 status;
+ union {
+ am_READLINK3resok ok;
+ am_READLINK3resfail fail;
+ } res_u;
+};
+typedef struct am_READLINK3res am_READLINK3res;
+
+struct am_devicedata3 {
+ am_sattr3 dev_attributes;
+ am_specdata3 spec;
+};
+typedef struct am_devicedata3 am_devicedata3;
+
+struct am_mknoddata3 {
+ am_ftype3 type;
+ union {
+ am_devicedata3 chr_device;
+ am_devicedata3 blk_device;
+ am_sattr3 sock_attributes;
+ am_sattr3 pipe_attributes;
+ } am_mknoddata3_u;
+};
+typedef struct am_mknoddata3 am_mknoddata3;
+
+struct am_MKNOD3args {
+ am_diropargs3 where;
+ am_mknoddata3 what;
+};
+typedef struct am_MKNOD3args am_MKNOD3args;
+
+struct am_MKNOD3resok {
+ am_post_op_fh3 obj;
+ am_post_op_attr obj_attributes;
+ am_wcc_data dir_wcc;
+};
+typedef struct am_MKNOD3resok am_MKNOD3resok;
+
+struct am_MKNOD3resfail {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_MKNOD3resfail am_MKNOD3resfail;
+
+struct am_MKNOD3res {
+ am_nfsstat3 status;
+ union {
+ am_MKNOD3resok ok;
+ am_MKNOD3resfail fail;
+ } res_u;
+};
+typedef struct am_MKNOD3res am_MKNOD3res;
+
+struct am_MKDIR3args {
+ am_diropargs3 where;
+ am_sattr3 attributes;
+};
+typedef struct am_MKDIR3args am_MKDIR3args;
+
+struct am_MKDIR3resok {
+ am_post_op_fh3 obj;
+ am_post_op_attr obj_attributes;
+ am_wcc_data dir_wcc;
+};
+typedef struct am_MKDIR3resok am_MKDIR3resok;
+
+struct am_MKDIR3resfail {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_MKDIR3resfail am_MKDIR3resfail;
+
+struct am_MKDIR3res {
+ am_nfsstat3 status;
+ union {
+ am_MKDIR3resok ok;
+ am_MKDIR3resfail fail;
+ } res_u;
+};
+typedef struct am_MKDIR3res am_MKDIR3res;
+
+struct am_RMDIR3args {
+ am_diropargs3 object;
+};
+typedef struct am_RMDIR3args am_RMDIR3args;
+
+struct am_RMDIR3resok {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_RMDIR3resok am_RMDIR3resok;
+
+struct am_RMDIR3resfail {
+ am_wcc_data dir_wcc;
+};
+typedef struct am_RMDIR3resfail am_RMDIR3resfail;
+
+struct am_RMDIR3res {
+ am_nfsstat3 status;
+ union {
+ am_RMDIR3resok ok;
+ am_RMDIR3resfail fail;
+ } res_u;
+};
+typedef struct am_RMDIR3res am_RMDIR3res;
+
+struct am_RENAME3args {
+ am_diropargs3 from;
+ am_diropargs3 to;
+};
+typedef struct am_RENAME3args am_RENAME3args;
+
+struct am_RENAME3resok {
+ am_wcc_data fromdir_wcc;
+ am_wcc_data todir_wcc;
+};
+typedef struct am_RENAME3resok am_RENAME3resok;
+
+struct am_RENAME3resfail {
+ am_wcc_data fromdir_wcc;
+ am_wcc_data todir_wcc;
+};
+typedef struct am_RENAME3resfail am_RENAME3resfail;
+
+struct am_RENAME3res {
+ am_nfsstat3 status;
+ union {
+ am_RENAME3resok ok;
+ am_RENAME3resfail fail;
+ } res_u;
+};
+typedef struct am_RENAME3res am_RENAME3res;
+
+struct am_READDIRPLUS3args {
+ am_nfs_fh3 dir;
+ am_cookie3 cookie;
+ am_cookieverf3 cookieverf;
+ am_count3 dircount;
+ am_count3 maxcount;
+};
+typedef struct am_READDIRPLUS3args am_READDIRPLUS3args;
+
+struct am_entryplus3 {
+ am_fileid3 fileid;
+ am_filename3 name;
+ am_cookie3 cookie;
+ am_post_op_attr name_attributes;
+ am_post_op_fh3 name_handle;
+ struct am_entryplus3 *nextentry;
+};
+typedef struct am_entryplus3 am_entryplus3;
+
+struct am_dirlistplus3 {
+ am_entryplus3 *entries;
+ bool_t eof;
+};
+typedef struct am_dirlistplus3 am_dirlistplus3;
+
+struct am_READDIRPLUS3resok {
+ am_post_op_attr dir_attributes;
+ am_cookieverf3 cookieverf;
+ am_dirlistplus3 reply;
+};
+typedef struct am_READDIRPLUS3resok am_READDIRPLUS3resok;
+
+struct am_READDIRPLUS3resfail {
+ am_post_op_attr dir_attributes;
+};
+typedef struct am_READDIRPLUS3resfail am_READDIRPLUS3resfail;
+
+struct am_READDIRPLUS3res {
+ am_nfsstat3 status;
+ union {
+ am_READDIRPLUS3resok ok;
+ am_READDIRPLUS3resfail fail;
+ } res_u;
+};
+typedef struct am_READDIRPLUS3res am_READDIRPLUS3res;
+
+struct am_READDIR3args {
+ am_nfs_fh3 dir;
+ am_cookie3 cookie;
+ am_cookieverf3 cookieverf;
+ am_count3 count;
+};
+typedef struct am_READDIR3args am_READDIR3args;
+
+struct am_entry3 {
+ am_fileid3 fileid;
+ am_filename3 name;
+ am_cookie3 cookie;
+ struct am_entry3 *nextentry;
+};
+typedef struct am_entry3 am_entry3;
+
+struct am_dirlist3 {
+ am_entry3 *entries;
+ bool_t eof;
+};
+typedef struct am_dirlist3 am_dirlist3;
+
+struct am_READDIR3resok {
+ am_post_op_attr dir_attributes;
+ am_cookieverf3 cookieverf;
+ am_dirlist3 reply;
+};
+typedef struct am_READDIR3resok am_READDIR3resok;
+
+struct am_READDIR3resfail {
+ am_post_op_attr dir_attributes;
+};
+typedef struct am_READDIR3resfail am_READDIR3resfail;
+
+struct am_READDIR3res {
+ am_nfsstat3 status;
+ union {
+ am_READDIR3resok ok;
+ am_READDIR3resfail fail;
+ } res_u;
+};
+typedef struct am_READDIR3res am_READDIR3res;
+
+struct am_LINK3args {
+ am_nfs_fh3 file;
+ am_diropargs3 link;
+};
+typedef struct am_LINK3args am_LINK3args;
+
+struct am_LINK3resok {
+ am_post_op_attr file_attributes;
+ am_wcc_data linkdir_wcc;
+};
+typedef struct am_LINK3resok am_LINK3resok;
+
+struct am_LINK3resfail {
+ am_post_op_attr file_attributes;
+ am_wcc_data linkdir_wcc;
+};
+typedef struct am_LINK3resfail am_LINK3resfail;
+
+struct am_LINK3res {
+ am_nfsstat3 status;
+ union {
+ am_LINK3resok ok;
+ am_LINK3resfail fail;
+ } res_u;
+};
+typedef struct am_LINK3res am_LINK3res;
+
+struct am_sattrguard3 {
+ bool_t check;
+ union {
+ am_nfstime3 obj_ctime;
+ } am_sattrguard3_u;
+};
+typedef struct am_sattrguard3 am_sattrguard3;
+
+struct am_SETATTR3args {
+ am_nfs_fh3 object;
+ am_sattr3 new_attributes;
+ am_sattrguard3 guard;
+};
+typedef struct am_SETATTR3args am_SETATTR3args;
+
+struct am_SETATTR3resok {
+ am_wcc_data obj_wcc;
+};
+typedef struct am_SETATTR3resok am_SETATTR3resok;
+
+struct am_SETATTR3resfail {
+ am_wcc_data obj_wcc;
+};
+typedef struct am_SETATTR3resfail am_SETATTR3resfail;
+
+struct am_SETATTR3res {
+ am_nfsstat3 status;
+ union {
+ am_SETATTR3resok ok;
+ am_SETATTR3resfail fail;
+ } res_u;
+};
+typedef struct am_SETATTR3res am_SETATTR3res;
#endif /* HAVE_FS_NFS3 */
/*
* NFS3 XDR FUNCTIONS:
*/
#ifdef HAVE_FS_NFS3
+#define AM_NFS3_NULL 0
+void * am_nfs3_null_3(void *, CLIENT *);
+void * am_nfs3_null_3_svc(void *, struct svc_req *);
+#define AM_NFS3_GETATTR 1
+am_GETATTR3res * am_nfs3_getattr_3(am_GETATTR3args *, CLIENT *);
+am_GETATTR3res * am_nfs3_getattr_3_svc(am_GETATTR3args *, struct svc_req *);
+#define AM_NFS3_SETATTR 2
+am_SETATTR3res * am_nfs3_setattr_3(am_SETATTR3args *, CLIENT *);
+am_SETATTR3res * am_nfs3_setattr_3_svc(am_SETATTR3args *, struct svc_req *);
+#define AM_NFS3_LOOKUP 3
+am_LOOKUP3res * am_nfs3_lookup_3(am_LOOKUP3args *, CLIENT *);
+am_LOOKUP3res * am_nfs3_lookup_3_svc(am_LOOKUP3args *, struct svc_req *);
+#define AM_NFS3_ACCESS 4
+am_ACCESS3res * am_nfs3_access_3(am_ACCESS3args *, CLIENT *);
+am_ACCESS3res * am_nfs3_access_3_svc(am_ACCESS3args *, struct svc_req *);
+#define AM_NFS3_READLINK 5
+am_READLINK3res * am_nfs3_readlink_3(am_READLINK3args *, CLIENT *);
+am_READLINK3res * am_nfs3_readlink_3_svc(am_READLINK3args *, struct svc_req *);
+#define AM_NFS3_READ 6
+am_READ3res * am_nfs3_read_3(am_READ3args *, CLIENT *);
+am_READ3res * am_nfs3_read_3_svc(am_READ3args *, struct svc_req *);
+#define AM_NFS3_WRITE 7
+am_WRITE3res * am_nfs3_write_3(am_WRITE3args *, CLIENT *);
+am_WRITE3res * am_nfs3_write_3_svc(am_WRITE3args *, struct svc_req *);
+#define AM_NFS3_CREATE 8
+am_CREATE3res * am_nfs3_create_3(am_CREATE3args *, CLIENT *);
+am_CREATE3res * am_nfs3_create_3_svc(am_CREATE3args *, struct svc_req *);
+#define AM_NFS3_MKDIR 9
+am_MKDIR3res * am_nfs3_mkdir_3(am_MKDIR3args *, CLIENT *);
+am_MKDIR3res * am_nfs3_mkdir_3_svc(am_MKDIR3args *, struct svc_req *);
+#define AM_NFS3_SYMLINK 10
+am_SYMLINK3res * am_nfs3_symlink_3(am_SYMLINK3args *, CLIENT *);
+am_SYMLINK3res * am_nfs3_symlink_3_svc(am_SYMLINK3args *, struct svc_req *);
+#define AM_NFS3_MKNOD 11
+am_MKNOD3res * am_nfs3_mknod_3(am_MKNOD3args *, CLIENT *);
+am_MKNOD3res * am_nfs3_mknod_3_svc(am_MKNOD3args *, struct svc_req *);
+#define AM_NFS3_REMOVE 12
+am_REMOVE3res * am_nfs3_remove_3(am_REMOVE3args *, CLIENT *);
+am_REMOVE3res * am_nfs3_remove_3_svc(am_REMOVE3args *, struct svc_req *);
+#define AM_NFS3_RMDIR 13
+am_RMDIR3res * am_nfs3_rmdir_3(am_RMDIR3args *, CLIENT *);
+am_RMDIR3res * am_nfs3_rmdir_3_svc(am_RMDIR3args *, struct svc_req *);
+#define AM_NFS3_RENAME 14
+am_RENAME3res * am_nfs3_rename_3(am_RENAME3args *, CLIENT *);
+am_RENAME3res * am_nfs3_rename_3_svc(am_RENAME3args *, struct svc_req *);
+#define AM_NFS3_LINK 15
+am_LINK3res * am_nfs3_link_3(am_LINK3args *, CLIENT *);
+am_LINK3res * am_nfs3_link_3_svc(am_LINK3args *, struct svc_req *);
+#define AM_NFS3_READDIR 16
+am_READDIR3res * am_nfs3_readdir_3(am_READDIR3args *, CLIENT *);
+am_READDIR3res * am_nfs3_readdir_3_svc(am_READDIR3args *, struct svc_req *);
+#define AM_NFS3_READDIRPLUS 17
+am_READDIRPLUS3res * am_nfs3_readdirplus_3(am_READDIRPLUS3args *, CLIENT *);
+am_READDIRPLUS3res * am_nfs3_readdirplus_3_svc(am_READDIRPLUS3args *, struct svc_req *);
+#define AM_NFS3_FSSTAT 18
+am_FSSTAT3res * am_nfs3_fsstat_3(am_FSSTAT3args *, CLIENT *);
+am_FSSTAT3res * am_nfs3_fsstat_3_svc(am_FSSTAT3args *, struct svc_req *);
+#define AM_NFS3_FSINFO 19
+am_FSINFO3res * am_nfs3_fsinfo_3(am_FSINFO3args *, CLIENT *);
+am_FSINFO3res * am_nfs3_fsinfo_3_svc(am_FSINFO3args *, struct svc_req *);
+#define AM_NFS3_PATHCONF 20
+am_PATHCONF3res * am_nfs3_pathconf_3(am_PATHCONF3args *, CLIENT *);
+am_PATHCONF3res * am_nfs3_pathconf_3_svc(am_PATHCONF3args *, struct svc_req *);
+#define AM_NFS3_COMMIT 21
+am_COMMIT3res * am_nfs3_commit_3(am_COMMIT3args *, CLIENT *);
+am_COMMIT3res * am_nfs3_commit_3_svc(am_COMMIT3args *, struct svc_req *);
+int nfs_program_3_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
+
bool_t xdr_am_fhandle3(XDR *xdrs, am_fhandle3 *objp);
bool_t xdr_am_mountstat3(XDR *xdrs, am_mountstat3 *objp);
bool_t xdr_am_mountres3_ok(XDR *xdrs, am_mountres3_ok *objp);
bool_t xdr_am_LOOKUP3resok(XDR *xdrs, am_LOOKUP3resok *objp);
bool_t xdr_am_nfsstat3(XDR *xdrs, am_nfsstat3 *objp);
bool_t xdr_am_nfs_fh3(XDR *xdrs, am_nfs_fh3 *objp);
+bool_t xdr_am_cookieverf3 (XDR *, am_cookieverf3);
+bool_t xdr_uint64 (XDR *, uint64*);
+bool_t xdr_am_cookie3 (XDR *, am_cookie3*);
+bool_t xdr_am_nfs_fh3 (XDR *, am_nfs_fh3*);
+bool_t xdr_am_nfsstat3 (XDR *, am_nfsstat3*);
+bool_t xdr_am_filename3 (XDR *, am_filename3*);
+bool_t xdr_am_diropargs3 (XDR *, am_diropargs3*);
+bool_t xdr_am_ftype3 (XDR *, am_ftype3*);
+bool_t xdr_am_mode3 (XDR *, am_mode3*);
+bool_t xdr_am_uid3 (XDR *, am_uid3*);
+bool_t xdr_am_gid3 (XDR *, am_gid3*);
+bool_t xdr_am_size3 (XDR *, am_size3*);
+bool_t xdr_am_fileid3 (XDR *, am_fileid3*);
+bool_t xdr_am_specdata3 (XDR *, am_specdata3*);
+bool_t xdr_am_nfstime3 (XDR *, am_nfstime3*);
+bool_t xdr_am_fattr3 (XDR *, am_fattr3*);
+bool_t xdr_am_post_op_attr (XDR *, am_post_op_attr*);
+bool_t xdr_am_stable_how (XDR *, am_stable_how*);
+bool_t xdr_am_offset3 (XDR *, am_offset3*);
+bool_t xdr_am_count3 (XDR *, am_count3*);
+bool_t xdr_am_wcc_attr (XDR *, am_wcc_attr*);
+bool_t xdr_am_pre_op_attr (XDR *, am_pre_op_attr*);
+bool_t xdr_am_wcc_data (XDR *, am_wcc_data*);
+bool_t xdr_am_WRITE3args (XDR *, am_WRITE3args*);
+bool_t xdr_am_writeverf3 (XDR *, am_writeverf3);
+bool_t xdr_am_WRITE3resok (XDR *, am_WRITE3resok*);
+bool_t xdr_am_WRITE3resfail (XDR *, am_WRITE3resfail*);
+bool_t xdr_am_WRITE3res (XDR *, am_WRITE3res*);
+bool_t xdr_am_LOOKUP3args (XDR *, am_LOOKUP3args*);
+bool_t xdr_am_LOOKUP3resok (XDR *, am_LOOKUP3resok*);
+bool_t xdr_am_LOOKUP3resfail (XDR *, am_LOOKUP3resfail*);
+bool_t xdr_am_LOOKUP3res (XDR *, am_LOOKUP3res*);
+bool_t xdr_am_COMMIT3args (XDR *, am_COMMIT3args*);
+bool_t xdr_am_COMMIT3resok (XDR *, am_COMMIT3resok*);
+bool_t xdr_am_COMMIT3resfail (XDR *, am_COMMIT3resfail*);
+bool_t xdr_am_COMMIT3res (XDR *, am_COMMIT3res*);
+bool_t xdr_am_ACCESS3args (XDR *, am_ACCESS3args*);
+bool_t xdr_am_ACCESS3resok (XDR *, am_ACCESS3resok*);
+bool_t xdr_am_ACCESS3resfail (XDR *, am_ACCESS3resfail*);
+bool_t xdr_am_ACCESS3res (XDR *, am_ACCESS3res*);
+bool_t xdr_am_GETATTR3args (XDR *, am_GETATTR3args*);
+bool_t xdr_am_GETATTR3resok (XDR *, am_GETATTR3resok*);
+bool_t xdr_am_GETATTR3res (XDR *, am_GETATTR3res*);
+bool_t xdr_am_time_how (XDR *, am_time_how*);
+bool_t xdr_am_set_mode3 (XDR *, am_set_mode3*);
+bool_t xdr_am_set_uid3 (XDR *, am_set_uid3*);
+bool_t xdr_am_set_gid3 (XDR *, am_set_gid3*);
+bool_t xdr_am_set_size3 (XDR *, am_set_size3*);
+bool_t xdr_am_set_atime (XDR *, am_set_atime*);
+bool_t xdr_am_set_mtime (XDR *, am_set_mtime*);
+bool_t xdr_am_sattr3 (XDR *, am_sattr3*);
+bool_t xdr_am_createmode3 (XDR *, am_createmode3*);
+bool_t xdr_am_createverf3 (XDR *, am_createverf3);
+bool_t xdr_am_createhow3 (XDR *, am_createhow3*);
+bool_t xdr_am_CREATE3args (XDR *, am_CREATE3args*);
+bool_t xdr_am_post_op_fh3 (XDR *, am_post_op_fh3*);
+bool_t xdr_am_CREATE3resok (XDR *, am_CREATE3resok*);
+bool_t xdr_am_CREATE3resfail (XDR *, am_CREATE3resfail*);
+bool_t xdr_am_CREATE3res (XDR *, am_CREATE3res*);
+bool_t xdr_am_REMOVE3args (XDR *, am_REMOVE3args*);
+bool_t xdr_am_REMOVE3resok (XDR *, am_REMOVE3resok*);
+bool_t xdr_am_REMOVE3resfail (XDR *, am_REMOVE3resfail*);
+bool_t xdr_am_REMOVE3res (XDR *, am_REMOVE3res*);
+bool_t xdr_am_READ3args (XDR *, am_READ3args*);
+bool_t xdr_am_READ3resok (XDR *, am_READ3resok*);
+bool_t xdr_am_READ3resfail (XDR *, am_READ3resfail*);
+bool_t xdr_am_READ3res (XDR *, am_READ3res*);
+bool_t xdr_am_FSINFO3args (XDR *, am_FSINFO3args*);
+bool_t xdr_am_FSINFO3resok (XDR *, am_FSINFO3resok*);
+bool_t xdr_am_FSINFO3resfail (XDR *, am_FSINFO3resfail*);
+bool_t xdr_am_FSINFO3res (XDR *, am_FSINFO3res*);
+bool_t xdr_am_FSSTAT3args (XDR *, am_FSSTAT3args*);
+bool_t xdr_am_FSSTAT3resok (XDR *, am_FSSTAT3resok*);
+bool_t xdr_am_FSSTAT3resfail (XDR *, am_FSSTAT3resfail*);
+bool_t xdr_am_FSSTAT3res (XDR *, am_FSSTAT3res*);
+bool_t xdr_am_PATHCONF3args (XDR *, am_PATHCONF3args*);
+bool_t xdr_am_PATHCONF3resok (XDR *, am_PATHCONF3resok*);
+bool_t xdr_am_PATHCONF3resfail (XDR *, am_PATHCONF3resfail*);
+bool_t xdr_am_PATHCONF3res (XDR *, am_PATHCONF3res*);
+bool_t xdr_am_nfspath3 (XDR *, am_nfspath3*);
+bool_t xdr_am_symlinkdata3 (XDR *, am_symlinkdata3*);
+bool_t xdr_am_SYMLINK3args (XDR *, am_SYMLINK3args*);
+bool_t xdr_am_SYMLINK3resok (XDR *, am_SYMLINK3resok*);
+bool_t xdr_am_SYMLINK3resfail (XDR *, am_SYMLINK3resfail*);
+bool_t xdr_am_SYMLINK3res (XDR *, am_SYMLINK3res*);
+bool_t xdr_am_READLINK3args (XDR *, am_READLINK3args*);
+bool_t xdr_am_READLINK3resok (XDR *, am_READLINK3resok*);
+bool_t xdr_am_READLINK3resfail (XDR *, am_READLINK3resfail*);
+bool_t xdr_am_READLINK3res (XDR *, am_READLINK3res*);
+bool_t xdr_am_devicedata3 (XDR *, am_devicedata3*);
+bool_t xdr_am_mknoddata3 (XDR *, am_mknoddata3*);
+bool_t xdr_am_MKNOD3args (XDR *, am_MKNOD3args*);
+bool_t xdr_am_MKNOD3resok (XDR *, am_MKNOD3resok*);
+bool_t xdr_am_MKNOD3resfail (XDR *, am_MKNOD3resfail*);
+bool_t xdr_am_MKNOD3res (XDR *, am_MKNOD3res*);
+bool_t xdr_am_MKDIR3args (XDR *, am_MKDIR3args*);
+bool_t xdr_am_MKDIR3resok (XDR *, am_MKDIR3resok*);
+bool_t xdr_am_MKDIR3resfail (XDR *, am_MKDIR3resfail*);
+bool_t xdr_am_MKDIR3res (XDR *, am_MKDIR3res*);
+bool_t xdr_am_RMDIR3args (XDR *, am_RMDIR3args*);
+bool_t xdr_am_RMDIR3resok (XDR *, am_RMDIR3resok*);
+bool_t xdr_am_RMDIR3resfail (XDR *, am_RMDIR3resfail*);
+bool_t xdr_am_RMDIR3res (XDR *, am_RMDIR3res*);
+bool_t xdr_am_RENAME3args (XDR *, am_RENAME3args*);
+bool_t xdr_am_RENAME3resok (XDR *, am_RENAME3resok*);
+bool_t xdr_am_RENAME3resfail (XDR *, am_RENAME3resfail*);
+bool_t xdr_am_RENAME3res (XDR *, am_RENAME3res*);
+bool_t xdr_am_READDIRPLUS3args (XDR *, am_READDIRPLUS3args*);
+bool_t xdr_am_entryplus3 (XDR *, am_entryplus3*);
+bool_t xdr_am_dirlistplus3 (XDR *, am_dirlistplus3*);
+bool_t xdr_am_READDIRPLUS3resok (XDR *, am_READDIRPLUS3resok*);
+bool_t xdr_am_READDIRPLUS3resfail (XDR *, am_READDIRPLUS3resfail*);
+bool_t xdr_am_READDIRPLUS3res (XDR *, am_READDIRPLUS3res*);
+bool_t xdr_am_READDIR3args (XDR *, am_READDIR3args*);
+bool_t xdr_am_entry3 (XDR *, am_entry3*);
+bool_t xdr_am_dirlist3 (XDR *, am_dirlist3*);
+bool_t xdr_am_READDIR3resok (XDR *, am_READDIR3resok*);
+bool_t xdr_am_READDIR3resfail (XDR *, am_READDIR3resfail*);
+bool_t xdr_am_READDIR3res (XDR *, am_READDIR3res*);
+bool_t xdr_am_LINK3args (XDR *, am_LINK3args*);
+bool_t xdr_am_LINK3resok (XDR *, am_LINK3resok*);
+bool_t xdr_am_LINK3resfail (XDR *, am_LINK3resfail*);
+bool_t xdr_am_LINK3res (XDR *, am_LINK3res*);
+bool_t xdr_am_sattrguard3 (XDR *, am_sattrguard3*);
+bool_t xdr_am_SETATTR3args (XDR *, am_SETATTR3args*);
+bool_t xdr_am_SETATTR3resok (XDR *, am_SETATTR3resok*);
+bool_t xdr_am_SETATTR3resfail (XDR *, am_SETATTR3resfail*);
+bool_t xdr_am_SETATTR3res (XDR *, am_SETATTR3res*);
#endif /* HAVE_FS_NFS3 */
#endif /* not _AM_XDR_FUNC_H */
get_hex_string(u_int len, const char *fhdata)
{
u_int i;
- static char buf[128]; /* better not go over it! */
+ static u_int xlen;
+ static char *buf;
+ static u_short *arr;
char str[16];
- short int arr[64];
- if (!fhdata)
+ if (!fhdata || len == 0 || len > 10240)
return NULL;
+ i = xlen * 4 + 1;
+ if (xlen < i) {
+ buf = xrealloc(buf, i);
+ arr = xrealloc(arr, len * sizeof(*arr));
+ xlen = i;
+ }
+
buf[0] = '\0';
- memset(&arr[0], 0, (64 * sizeof(short int)));
- memcpy(&arr[0], &fhdata[0], len);
- for (i=0; i<len/sizeof(unsigned short int); i++) {
+ memset(arr, 0, len * sizeof(*arr));
+ memcpy(arr, fhdata, len);
+ len /= sizeof(*arr);
+ for (i = 0; i < len; i++) {
xsnprintf(str, sizeof(str), "%04x", ntohs(arr[i]));
- xstrlcat(buf, str, sizeof(buf));
+ xstrlcat(buf, str, xlen);
}
return buf;
}
return (TRUE);
}
-
bool_t
xdr_am_mountres3(XDR *xdrs, am_mountres3 *objp)
{
return (TRUE);
}
+bool_t
+xdr_am_cookieverf3(XDR *xdrs, am_cookieverf3 objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_cookieverf3:");
+
+ if (!xdr_opaque(xdrs, objp, AM_NFS3_COOKIEVERFSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_uint64(XDR *xdrs, uint64 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_uint64:");
+
+ if (!xdr_u_int64_t(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_cookie3(XDR *xdrs, am_cookie3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_cookie3:");
+
+ if (!xdr_uint64(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_nfs_fh3(XDR *xdrs, am_nfs_fh3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_nfs_fh3:");
+
+ if (!xdr_u_int(xdrs, &objp->am_fh3_length))
+ return (FALSE);
+ if (objp->am_fh3_length > AM_FHSIZE3)
+ return (FALSE);
+ if (!xdr_opaque(xdrs, objp->am_fh3_data, objp->am_fh3_length))
+ return (FALSE);
+ return (TRUE);
+}
+
+bool_t
+xdr_am_nfsstat3(XDR *xdrs, am_nfsstat3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_nfsstat3:");
+
+ if (!xdr_enum(xdrs, (enum_t *)objp))
+ return (FALSE);
+ return (TRUE);
+}
bool_t
xdr_am_diropargs3(XDR *xdrs, am_diropargs3 *objp)
return (TRUE);
}
-
bool_t
xdr_am_filename3(XDR *xdrs, am_filename3 *objp)
{
return (TRUE);
}
+bool_t
+xdr_am_ftype3(XDR *xdrs, am_ftype3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_ftype3:");
+
+ if (!xdr_enum(xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_mode3(XDR *xdrs, am_mode3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_mode3:");
+
+ if (!xdr_u_int(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_uid3(XDR *xdrs, am_uid3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_uid3:");
+
+ if (!xdr_u_int(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_gid3(XDR *xdrs, am_gid3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_gid3:");
+
+ if (!xdr_u_int(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_size3(XDR *xdrs, am_size3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_size3:");
+
+ if (!xdr_uint64(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_fileid3(XDR *xdrs, am_fileid3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_fileid3:");
+
+ if (!xdr_uint64(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_specdata3(XDR *xdrs, am_specdata3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_specdata3:");
+
+ if (!xdr_u_int(xdrs, &objp->specdata1))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->specdata2))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_nfstime3(XDR *xdrs, am_nfstime3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_nfstime3:");
+
+ if (!xdr_u_int(xdrs, &objp->seconds))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->nseconds))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_fattr3(XDR *xdrs, am_fattr3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_fattr3:");
+
+ if (!xdr_am_ftype3(xdrs, &objp->type))
+ return FALSE;
+ if (!xdr_am_mode3(xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->nlink))
+ return FALSE;
+ if (!xdr_am_uid3(xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_am_gid3(xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->used))
+ return FALSE;
+ if (!xdr_am_specdata3(xdrs, &objp->rdev))
+ return FALSE;
+ if (!xdr_uint64(xdrs, &objp->fsid))
+ return FALSE;
+ if (!xdr_am_fileid3(xdrs, &objp->fileid))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->atime))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->mtime))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->ctime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_post_op_attr(XDR *xdrs, am_post_op_attr *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_post_op_attr:");
+
+ if (!xdr_bool(xdrs, &objp->attributes_follow))
+ return FALSE;
+ switch (objp->attributes_follow) {
+ case TRUE:
+ if (!xdr_am_fattr3(xdrs, &objp->am_post_op_attr_u.attributes))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_stable_how(XDR *xdrs, am_stable_how *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_stable_how:");
+
+ if (!xdr_enum(xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_offset3(XDR *xdrs, am_offset3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_offset3:");
+
+ if (!xdr_uint64(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_count3(XDR *xdrs, am_count3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_count3:");
+
+ if (!xdr_u_int(xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_wcc_attr(XDR *xdrs, am_wcc_attr *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_wcc_attr:");
+
+ if (!xdr_am_size3(xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->mtime))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->ctime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_pre_op_attr(XDR *xdrs, am_pre_op_attr *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, ":xdr_am_pre_op_attr");
+
+ if (!xdr_bool(xdrs, &objp->attributes_follow))
+ return FALSE;
+ switch (objp->attributes_follow) {
+ case TRUE:
+ if (!xdr_am_wcc_attr(xdrs, &objp->am_pre_op_attr_u.attributes))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_wcc_data(XDR *xdrs, am_wcc_data *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_wcc_data:");
+
+ if (!xdr_am_pre_op_attr(xdrs, &objp->before))
+ return FALSE;
+ if (!xdr_am_post_op_attr(xdrs, &objp->after))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_WRITE3args(XDR *xdrs, am_WRITE3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_WRITE3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_am_offset3(xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->count))
+ return FALSE;
+ if (!xdr_am_stable_how(xdrs, &objp->stable))
+ return FALSE;
+ if (!xdr_bytes(xdrs, (char **)&objp->data.data_val,
+ (u_int *) &objp->data.data_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_writeverf3(XDR *xdrs, am_writeverf3 objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_writeverf3:");
+
+ if (!xdr_opaque(xdrs, objp, AM_NFS3_WRITEVERFSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_WRITE3resok(XDR *xdrs, am_WRITE3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_WRITE3resok:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->file_wcc))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->count))
+ return FALSE;
+ if (!xdr_am_stable_how(xdrs, &objp->committed))
+ return FALSE;
+ if (!xdr_am_writeverf3(xdrs, objp->verf))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_WRITE3resfail(XDR *xdrs, am_WRITE3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_WRITE3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->file_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_WRITE3res(XDR *xdrs, am_WRITE3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_WRITE3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_WRITE3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_WRITE3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
bool_t
xdr_am_LOOKUP3args(XDR *xdrs, am_LOOKUP3args *objp)
return (TRUE);
}
-
bool_t
xdr_am_LOOKUP3res(XDR *xdrs, am_LOOKUP3res *objp)
{
return (TRUE);
}
-
bool_t
xdr_am_LOOKUP3resfail(XDR *xdrs, am_LOOKUP3resfail *objp)
{
if (amuDebug(D_XDRTRACE))
plog(XLOG_DEBUG, "xdr_am_LOOKUP3resfail:");
- /*
- * Don't xdr post_op_attr: amd doesn't need them, but they require many
- * additional xdr functions.
- */
-#if 0
- if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
+ if (!xdr_am_post_op_attr(xdrs, &objp->dir_attributes))
return (FALSE);
-#endif /* 0 */
return (TRUE);
}
-
bool_t
xdr_am_LOOKUP3resok(XDR *xdrs, am_LOOKUP3resok *objp)
{
if (!xdr_am_nfs_fh3(xdrs, &objp->object))
return (FALSE);
- /*
- * Don't xdr post_op_attr: amd doesn't need them, but they require many
- * additional xdr functions.
- */
-#if 0
- if (!xdr_post_op_attr(xdrs, &objp->obj_attributes))
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
return (FALSE);
- if (!xdr_post_op_attr(xdrs, &objp->dir_attributes))
+ if (!xdr_am_post_op_attr(xdrs, &objp->dir_attributes))
return (FALSE);
-#endif /* 0 */
return (TRUE);
}
+bool_t
+xdr_am_COMMIT3args(XDR *xdrs, am_COMMIT3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_COMMIT3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_am_offset3(xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->count))
+ return FALSE;
+ return TRUE;
+}
bool_t
-xdr_am_nfs_fh3(XDR *xdrs, am_nfs_fh3 *objp)
+xdr_am_COMMIT3resok(XDR *xdrs, am_COMMIT3resok *objp)
{
if (amuDebug(D_XDRTRACE))
- plog(XLOG_DEBUG, "xdr_am_nfs_fh3:");
+ plog(XLOG_DEBUG, "xdr_am_COMMIT3resok:");
- if (!xdr_u_int(xdrs, &objp->am_fh3_length))
- return (FALSE);
- if (objp->am_fh3_length > AM_FHSIZE3)
- return (FALSE);
- if (!xdr_opaque(xdrs, objp->am_fh3_data, objp->am_fh3_length))
- return (FALSE);
- return (TRUE);
+ if (!xdr_am_wcc_data(xdrs, &objp->file_wcc))
+ return FALSE;
+ if (!xdr_am_writeverf3(xdrs, objp->verf))
+ return FALSE;
+ return TRUE;
}
+bool_t
+xdr_am_COMMIT3resfail(XDR *xdrs, am_COMMIT3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_COMMIT3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->file_wcc))
+ return FALSE;
+ return TRUE;
+}
bool_t
-xdr_am_nfsstat3(XDR *xdrs, am_nfsstat3 *objp)
+xdr_am_COMMIT3res(XDR *xdrs, am_COMMIT3res *objp)
{
if (amuDebug(D_XDRTRACE))
- plog(XLOG_DEBUG, "xdr_am_nfsstat3:");
+ plog(XLOG_DEBUG, "xdr_am_COMMIT3res:");
- if (!xdr_enum(xdrs, (enum_t *)objp))
- return (FALSE);
- return (TRUE);
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_COMMIT3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_COMMIT3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_ACCESS3args(XDR *xdrs, am_ACCESS3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_ACCESS3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->object))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->access))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_ACCESS3resok(XDR *xdrs, am_ACCESS3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_ACCESS3resok:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->access))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_ACCESS3resfail(XDR *xdrs, am_ACCESS3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_ACCESS3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_ACCESS3res(XDR *xdrs, am_ACCESS3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_ACCESS3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_ACCESS3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_ACCESS3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_GETATTR3args(XDR *xdrs, am_GETATTR3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_GETATTR3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_GETATTR3resok(XDR *xdrs, am_GETATTR3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_GETATTR3resok:");
+
+ if (!xdr_am_fattr3(xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_GETATTR3res(XDR *xdrs, am_GETATTR3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_GETATTR3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_GETATTR3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_time_how(XDR *xdrs, am_time_how *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_time_how:");
+
+ if (!xdr_enum(xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_set_mode3(XDR *xdrs, am_set_mode3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_set_mode3:");
+
+ if (!xdr_bool(xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_am_mode3(xdrs, &objp->am_set_mode3_u.mode))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_set_uid3(XDR *xdrs, am_set_uid3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_set_uid3:");
+
+ if (!xdr_bool(xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_am_uid3(xdrs, &objp->am_set_uid3_u.uid))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_set_gid3(XDR *xdrs, am_set_gid3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_set_gid3:");
+
+ if (!xdr_bool(xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_am_gid3(xdrs, &objp->am_set_gid3_u.gid))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_set_size3(XDR *xdrs, am_set_size3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_set_size3:");
+
+ if (!xdr_bool(xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_am_size3(xdrs, &objp->am_set_size3_u.size))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_set_atime(XDR *xdrs, am_set_atime *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_set_atime:");
+
+ if (!xdr_am_time_how(xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case AM_SET_TO_CLIENT_TIME:
+ if (!xdr_am_nfstime3(xdrs, &objp->am_set_atime_u.atime))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_set_mtime(XDR *xdrs, am_set_mtime *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_set_mtime:");
+
+ if (!xdr_am_time_how(xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case AM_SET_TO_CLIENT_TIME:
+ if (!xdr_am_nfstime3(xdrs, &objp->am_set_mtime_u.mtime))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_sattr3(XDR *xdrs, am_sattr3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_sattr3:");
+
+ if (!xdr_am_set_mode3(xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_am_set_uid3(xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_am_set_gid3(xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_am_set_size3(xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_am_set_atime(xdrs, &objp->atime))
+ return FALSE;
+ if (!xdr_am_set_mtime(xdrs, &objp->mtime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_createmode3(XDR *xdrs, am_createmode3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_createmode3:");
+
+ if (!xdr_enum(xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_createverf3(XDR *xdrs, am_createverf3 objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_createverf3:");
+
+ if (!xdr_opaque(xdrs, objp, AM_NFS3_CREATEVERFSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_createhow3(XDR *xdrs, am_createhow3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_createhow3:");
+
+ if (!xdr_am_createmode3(xdrs, &objp->mode))
+ return FALSE;
+ switch (objp->mode) {
+ case AM_UNCHECKED:
+ if (!xdr_am_sattr3(xdrs, &objp->am_createhow3_u.obj_attributes))
+ return FALSE;
+ break;
+ case AM_GUARDED:
+ if (!xdr_am_sattr3(xdrs, &objp->am_createhow3_u.g_obj_attributes))
+ return FALSE;
+ break;
+ case AM_EXCLUSIVE:
+ if (!xdr_am_createverf3(xdrs, objp->am_createhow3_u.verf))
+ return FALSE;
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_CREATE3args(XDR *xdrs, am_CREATE3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_CREATE3args:");
+
+ if (!xdr_am_diropargs3(xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_am_createhow3(xdrs, &objp->how))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_post_op_fh3(XDR *xdrs, am_post_op_fh3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_post_op_fh3:");
+
+ if (!xdr_bool(xdrs, &objp->handle_follows))
+ return FALSE;
+ switch (objp->handle_follows) {
+ case TRUE:
+ if (!xdr_am_nfs_fh3(xdrs, &objp->am_post_op_fh3_u.handle))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_CREATE3resok(XDR *xdrs, am_CREATE3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_CREATE3resok:");
+
+ if (!xdr_am_post_op_fh3(xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_CREATE3resfail(XDR *xdrs, am_CREATE3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_CREATE3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_CREATE3res(XDR *xdrs, am_CREATE3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_CREATE3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_CREATE3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_CREATE3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_REMOVE3args(XDR *xdrs, am_REMOVE3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_REMOVE3args:");
+
+ if (!xdr_am_diropargs3(xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_REMOVE3resok(XDR *xdrs, am_REMOVE3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_REMOVE3resok:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_REMOVE3resfail(XDR *xdrs, am_REMOVE3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_REMOVE3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_REMOVE3res(XDR *xdrs, am_REMOVE3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_REMOVE3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_REMOVE3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_REMOVE3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_READ3args(XDR *xdrs, am_READ3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READ3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_am_offset3(xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->count))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READ3resok(XDR *xdrs, am_READ3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READ3resok:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->file_attributes))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->count))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->eof))
+ return FALSE;
+ if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READ3resfail(XDR *xdrs, am_READ3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READ3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->file_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READ3res(XDR *xdrs, am_READ3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READ3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_READ3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_READ3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSINFO3args(XDR *xdrs, am_FSINFO3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSINFO3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->fsroot))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSINFO3resok(XDR *xdrs, am_FSINFO3resok *objp)
+{
+ register int32_t *buf;
+
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSINFO3resok:");
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ buf = XDR_INLINE(xdrs, 7 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int(xdrs, &objp->rtmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->rtpref))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->rtmult))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtpref))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtmult))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->dtpref))
+ return FALSE;
+ } else {
+ IXDR_PUT_U_LONG(buf, objp->rtmax);
+ IXDR_PUT_U_LONG(buf, objp->rtpref);
+ IXDR_PUT_U_LONG(buf, objp->rtmult);
+ IXDR_PUT_U_LONG(buf, objp->wtmax);
+ IXDR_PUT_U_LONG(buf, objp->wtpref);
+ IXDR_PUT_U_LONG(buf, objp->wtmult);
+ IXDR_PUT_U_LONG(buf, objp->dtpref);
+ }
+ if (!xdr_am_size3(xdrs, &objp->maxfilesize))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->time_delta))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->properties))
+ return FALSE;
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ buf = XDR_INLINE(xdrs, 7 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int (xdrs, &objp->rtmax))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->rtpref))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->rtmult))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->wtmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtpref))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtmult))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->dtpref))
+ return FALSE;
+ } else {
+ objp->rtmax = IXDR_GET_U_LONG(buf);
+ objp->rtpref = IXDR_GET_U_LONG(buf);
+ objp->rtmult = IXDR_GET_U_LONG(buf);
+ objp->wtmax = IXDR_GET_U_LONG(buf);
+ objp->wtpref = IXDR_GET_U_LONG(buf);
+ objp->wtmult = IXDR_GET_U_LONG(buf);
+ objp->dtpref = IXDR_GET_U_LONG(buf);
+ }
+ if (!xdr_am_size3(xdrs, &objp->maxfilesize))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->time_delta))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->properties))
+ return FALSE;
+ return TRUE;
+ }
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->rtmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->rtpref))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->rtmult))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtpref))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->wtmult))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->dtpref))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->maxfilesize))
+ return FALSE;
+ if (!xdr_am_nfstime3(xdrs, &objp->time_delta))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->properties))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSINFO3resfail(XDR *xdrs, am_FSINFO3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSINFO3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSINFO3res(XDR *xdrs, am_FSINFO3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSINFO3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_FSINFO3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_FSINFO3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSSTAT3args(XDR *xdrs, am_FSSTAT3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSSTAT3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->fsroot))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSSTAT3resok(XDR *xdrs, am_FSSTAT3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSSTAT3resok:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->tbytes))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->fbytes))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->abytes))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->tfiles))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->ffiles))
+ return FALSE;
+ if (!xdr_am_size3(xdrs, &objp->afiles))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->invarsec))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSSTAT3resfail(XDR *xdrs, am_FSSTAT3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSSTAT3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_FSSTAT3res(XDR *xdrs, am_FSSTAT3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_FSSTAT3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_FSSTAT3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_FSSTAT3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_PATHCONF3args(XDR *xdrs, am_PATHCONF3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_PATHCONF3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_PATHCONF3resok(XDR *xdrs, am_PATHCONF3resok *objp)
+{
+ register int32_t *buf;
+
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_PATHCONF3resok:");
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int(xdrs, &objp->linkmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->name_max))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->no_trunc))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->chown_restricted))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->case_insensitive))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->case_preserving))
+ return FALSE;
+ } else {
+ IXDR_PUT_U_LONG(buf, objp->linkmax);
+ IXDR_PUT_U_LONG(buf, objp->name_max);
+ IXDR_PUT_BOOL(buf, objp->no_trunc);
+ IXDR_PUT_BOOL(buf, objp->chown_restricted);
+ IXDR_PUT_BOOL(buf, objp->case_insensitive);
+ IXDR_PUT_BOOL(buf, objp->case_preserving);
+ }
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int(xdrs, &objp->linkmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->name_max))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->no_trunc))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->chown_restricted))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->case_insensitive))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->case_preserving))
+ return FALSE;
+ } else {
+ objp->linkmax = IXDR_GET_U_LONG(buf);
+ objp->name_max = IXDR_GET_U_LONG(buf);
+ objp->no_trunc = IXDR_GET_BOOL(buf);
+ objp->chown_restricted = IXDR_GET_BOOL(buf);
+ objp->case_insensitive = IXDR_GET_BOOL(buf);
+ objp->case_preserving = IXDR_GET_BOOL(buf);
+ }
+ return TRUE;
+ }
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->linkmax))
+ return FALSE;
+ if (!xdr_u_int(xdrs, &objp->name_max))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->no_trunc))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->chown_restricted))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->case_insensitive))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->case_preserving))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_PATHCONF3resfail(XDR *xdrs, am_PATHCONF3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_PATHCONF3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_PATHCONF3res(XDR *xdrs, am_PATHCONF3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_PATHCONF3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_PATHCONF3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_PATHCONF3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_nfspath3(XDR *xdrs, am_nfspath3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_nfspath3:");
+
+ if (!xdr_string(xdrs, objp, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_symlinkdata3(XDR *xdrs, am_symlinkdata3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_symlinkdata3:");
+
+ if (!xdr_am_sattr3(xdrs, &objp->symlink_attributes))
+ return FALSE;
+ if (!xdr_am_nfspath3(xdrs, &objp->symlink_data))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_SYMLINK3args(XDR *xdrs, am_SYMLINK3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SYMLINK3args:");
+
+ if (!xdr_am_diropargs3(xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_am_symlinkdata3(xdrs, &objp->symlink))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_SYMLINK3resok(XDR *xdrs, am_SYMLINK3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SYMLINK3resok:");
+
+ if (!xdr_am_post_op_fh3(xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_SYMLINK3resfail(XDR *xdrs, am_SYMLINK3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SYMLINK3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_SYMLINK3res(XDR *xdrs, am_SYMLINK3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SYMLINK3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_SYMLINK3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_SYMLINK3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_READLINK3args(XDR *xdrs, am_READLINK3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READLINK3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->symlink))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READLINK3resok(XDR *xdrs, am_READLINK3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READLINK3resok:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->symlink_attributes))
+ return FALSE;
+ if (!xdr_am_nfspath3(xdrs, &objp->data))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READLINK3resfail(XDR *xdrs, am_READLINK3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READLINK3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->symlink_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READLINK3res(XDR *xdrs, am_READLINK3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READLINK3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_READLINK3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_READLINK3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_devicedata3(XDR *xdrs, am_devicedata3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_devicedata3:");
+
+ if (!xdr_am_sattr3(xdrs, &objp->dev_attributes))
+ return FALSE;
+ if (!xdr_am_specdata3(xdrs, &objp->spec))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_mknoddata3(XDR *xdrs, am_mknoddata3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_mknoddata3:");
+
+ if (!xdr_am_ftype3(xdrs, &objp->type))
+ return FALSE;
+ switch (objp->type) {
+ case AM_NF3CHR:
+ if (!xdr_am_devicedata3(xdrs, &objp->am_mknoddata3_u.chr_device))
+ return FALSE;
+ break;
+ case AM_NF3BLK:
+ if (!xdr_am_devicedata3(xdrs, &objp->am_mknoddata3_u.blk_device))
+ return FALSE;
+ break;
+ case AM_NF3SOCK:
+ if (!xdr_am_sattr3(xdrs, &objp->am_mknoddata3_u.sock_attributes))
+ return FALSE;
+ break;
+ case AM_NF3FIFO:
+ if (!xdr_am_sattr3(xdrs, &objp->am_mknoddata3_u.pipe_attributes))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKNOD3args(XDR *xdrs, am_MKNOD3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_MKNOD3args:");
+
+ if (!xdr_am_diropargs3(xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_am_mknoddata3(xdrs, &objp->what))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKNOD3resok(XDR *xdrs, am_MKNOD3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_MKNOD3resok:");
+
+ if (!xdr_am_post_op_fh3(xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKNOD3resfail(XDR *xdrs, am_MKNOD3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_MKNOD3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKNOD3res(XDR *xdrs, am_MKNOD3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, ":");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_MKNOD3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_MKNOD3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKDIR3args(XDR *xdrs, am_MKDIR3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, ":");
+
+ if (!xdr_am_diropargs3(xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_am_sattr3(xdrs, &objp->attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKDIR3resok(XDR *xdrs, am_MKDIR3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_MKDIR3resok:");
+
+ if (!xdr_am_post_op_fh3(xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_am_post_op_attr(xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKDIR3resfail(XDR *xdrs, am_MKDIR3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_MKDIR3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_MKDIR3res(XDR *xdrs, am_MKDIR3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_MKDIR3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_MKDIR3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_MKDIR3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_RMDIR3args(XDR *xdrs, am_RMDIR3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RMDIR3args:");
+
+ if (!xdr_am_diropargs3(xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_RMDIR3resok(XDR *xdrs, am_RMDIR3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RMDIR3resok:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_RMDIR3resfail(XDR *xdrs, am_RMDIR3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RMDIR3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_RMDIR3res(XDR *xdrs, am_RMDIR3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RMDIR3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_RMDIR3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_RMDIR3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_RENAME3args(XDR *xdrs, am_RENAME3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RENAME3args:");
+
+ if (!xdr_am_diropargs3(xdrs, &objp->from))
+ return FALSE;
+ if (!xdr_am_diropargs3(xdrs, &objp->to))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_RENAME3resok(XDR *xdrs, am_RENAME3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RENAME3resok:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->fromdir_wcc))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->todir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_RENAME3resfail(XDR *xdrs, am_RENAME3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RENAME3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->fromdir_wcc))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->todir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_RENAME3res(XDR *xdrs, am_RENAME3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_RENAME3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_RENAME3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_RENAME3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIRPLUS3args(XDR *xdrs, am_READDIRPLUS3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIRPLUS3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->dir))
+ return FALSE;
+ if (!xdr_am_cookie3(xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_am_cookieverf3(xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->dircount))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->maxcount))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_entryplus3(XDR *xdrs, am_entryplus3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_entryplus3:");
+
+ if (!xdr_am_fileid3(xdrs, &objp->fileid))
+ return FALSE;
+ if (!xdr_am_filename3(xdrs, &objp->name))
+ return FALSE;
+ if (!xdr_am_cookie3(xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_am_post_op_attr(xdrs, &objp->name_attributes))
+ return FALSE;
+ if (!xdr_am_post_op_fh3(xdrs, &objp->name_handle))
+ return FALSE;
+ if (!xdr_pointer(xdrs, (char **)&objp->nextentry,
+ sizeof(am_entryplus3), (xdrproc_t) xdr_am_entryplus3))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_dirlistplus3(XDR *xdrs, am_dirlistplus3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_dirlistplus3:");
+
+ if (!xdr_pointer(xdrs, (char **)&objp->entries,
+ sizeof(am_entryplus3), (xdrproc_t) xdr_am_entryplus3))
+ return FALSE;
+ if (!xdr_bool(xdrs, &objp->eof))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIRPLUS3resok(XDR *xdrs, am_READDIRPLUS3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIRPLUS3resok:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->dir_attributes))
+ return FALSE;
+ if (!xdr_am_cookieverf3(xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_am_dirlistplus3(xdrs, &objp->reply))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIRPLUS3resfail(XDR *xdrs, am_READDIRPLUS3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIRPLUS3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->dir_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIRPLUS3res(XDR *xdrs, am_READDIRPLUS3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIRPLUS3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_READDIRPLUS3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_READDIRPLUS3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIR3args(XDR *xdrs, am_READDIR3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIR3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->dir))
+ return FALSE;
+ if (!xdr_am_cookie3(xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_am_cookieverf3(xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_am_count3(xdrs, &objp->count))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_entry3(XDR *xdrs, am_entry3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_entry3:");
+
+ if (!xdr_am_fileid3(xdrs, &objp->fileid))
+ return FALSE;
+ if (!xdr_am_filename3(xdrs, &objp->name))
+ return FALSE;
+ if (!xdr_am_cookie3(xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_pointer(xdrs, (char **)&objp->nextentry,
+ sizeof(am_entry3), (xdrproc_t) xdr_am_entry3))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_dirlist3(XDR *xdrs, am_dirlist3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_dirlist3:");
+
+ if (!xdr_pointer(xdrs, (char **)&objp->entries,
+ sizeof(am_entry3), (xdrproc_t) xdr_am_entry3))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->eof))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIR3resok(XDR *xdrs, am_READDIR3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIR3resok:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->dir_attributes))
+ return FALSE;
+ if (!xdr_am_cookieverf3(xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_am_dirlist3(xdrs, &objp->reply))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIR3resfail(XDR *xdrs, am_READDIR3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIR3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->dir_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_READDIR3res(XDR *xdrs, am_READDIR3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_READDIR3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_READDIR3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_READDIR3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_LINK3args(XDR *xdrs, am_LINK3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_LINK3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_am_diropargs3(xdrs, &objp->link))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_LINK3resok(XDR *xdrs, am_LINK3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_LINK3resok:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->file_attributes))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->linkdir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_LINK3resfail(XDR *xdrs, am_LINK3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_LINK3resfail:");
+
+ if (!xdr_am_post_op_attr(xdrs, &objp->file_attributes))
+ return FALSE;
+ if (!xdr_am_wcc_data(xdrs, &objp->linkdir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_LINK3res(XDR *xdrs, am_LINK3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_LINK3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_LINK3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_LINK3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_sattrguard3(XDR *xdrs, am_sattrguard3 *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_sattrguard3:");
+
+ if (!xdr_bool(xdrs, &objp->check))
+ return FALSE;
+ switch (objp->check) {
+ case TRUE:
+ if (!xdr_am_nfstime3(xdrs, &objp->am_sattrguard3_u.obj_ctime))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_am_SETATTR3args(XDR *xdrs, am_SETATTR3args *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SETATTR3args:");
+
+ if (!xdr_am_nfs_fh3(xdrs, &objp->object))
+ return FALSE;
+ if (!xdr_am_sattr3(xdrs, &objp->new_attributes))
+ return FALSE;
+ if (!xdr_am_sattrguard3(xdrs, &objp->guard))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_SETATTR3resok(XDR *xdrs, am_SETATTR3resok *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SETATTR3resok:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->obj_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_SETATTR3resfail(XDR *xdrs, am_SETATTR3resfail *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SETATTR3resfail:");
+
+ if (!xdr_am_wcc_data(xdrs, &objp->obj_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_am_SETATTR3res(XDR *xdrs, am_SETATTR3res *objp)
+{
+ if (amuDebug(D_XDRTRACE))
+ plog(XLOG_DEBUG, "xdr_am_SETATTR3res:");
+
+ if (!xdr_am_nfsstat3(xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case AM_NFS3_OK:
+ if (!xdr_am_SETATTR3resok(xdrs, &objp->res_u.ok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_am_SETATTR3resfail(xdrs, &objp->res_u.fail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
}
-#endif /* not HAVE_FS_NFS3 */
+#endif /* HAVE_FS_NFS3 */