6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
25 * Copyright 2016 Jason King.
26 */
27
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
30
31 #ifndef _NFS_EXPORT_H
32 #define _NFS_EXPORT_H
33
34 #include <nfs/nfs_sec.h>
35 #include <nfs/auth.h>
36 #include <sys/vnode.h>
37 #include <nfs/nfs4.h>
38 #include <sys/kiconv.h>
39 #include <sys/avl.h>
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 /*
46 * nfs pseudo flavor number is owned by IANA. Need to make sure the
47 * Solaris specific NFS_FLAVOR_NOMAP number will not overlap with any
48 * new IANA defined pseudo flavor numbers. The chance for the overlap
49 * is very small since the growth of new flavor numbers is expected
50 * to be limited.
51 */
52 #define NFS_FLAVOR_NOMAP 999999 /* no nfs flavor mapping */
53
54 /*
55 * As duplicate flavors can be passed into exportfs in the arguments, we
56 * allocate a cleaned up array with non duplicate flavors on the stack.
57 * So we need to know how much to allocate.
58 */
59 #define MAX_FLAVORS 6 /* none, sys, dh, krb5, krb5i krb5p */
60
450 * +===+ (VROOT) +---+ +---+
451 *
452 *
453 * Bi-directional interconnect:
454 * treenode_t::tree_exi --------- exportinfo_t::exi_tree
455 * One-way direction connection:
456 * treenode_t::tree_vis .........> exp_visible_t
457 */
458 /* Access to treenode_t is under protection of exported_lock RW_LOCK */
459 typedef struct treenode {
460 /* support for generic n-ary trees */
461 struct treenode *tree_parent;
462 struct treenode *tree_child_first;
463 struct treenode *tree_sibling; /* next sibling */
464 /* private, nfs specific part */
465 struct exportinfo *tree_exi;
466 struct exp_visible *tree_vis;
467 } treenode_t;
468
469 /*
470 * TREE_ROOT checks if the node corresponds to a filesystem root
471 * TREE_EXPORTED checks if the node is explicitly shared
472 */
473
474 #define TREE_ROOT(t) \
475 ((t)->tree_exi && (t)->tree_exi->exi_vp->v_flag & VROOT)
476
477 #define TREE_EXPORTED(t) \
478 ((t)->tree_exi && !PSEUDO((t)->tree_exi))
479
480 /* Root of nfs pseudo namespace */
481 extern treenode_t *ns_root;
482
483 #define EXPTABLESIZE 256
484
485 struct exp_hash {
486 struct exportinfo *prev; /* ptr to the previous exportinfo */
487 struct exportinfo *next; /* ptr to the next exportinfo */
488 struct exportinfo **bckt; /* backpointer to the hash bucket */
489 };
490
491 /*
492 * A node associated with an export entry on the
493 * list of exported filesystems.
494 *
495 * exi_count+exi_lock protects an individual exportinfo from being freed
496 * when in use.
497 *
498 * You must have the writer lock on exported_lock to add/delete an exportinfo
499 * structure to/from the list.
500 *
501 * exi_volatile_dev maps to VSW_VOLATILEDEV. It means that the
502 * underlying fs devno can change on each mount. When set, the server
503 * should not use va_fsid for a GETATTR(FATTR4_FSID) reply. It must
504 * use exi_fsid because it is guaranteed to be persistent. This isn't
505 * in any way related to NFS4 volatile filehandles.
506 *
507 * The exi_cache_lock protects the exi_cache AVL trees.
508 */
509 struct exportinfo {
510 struct exportdata exi_export;
511 fsid_t exi_fsid;
512 struct fid exi_fid;
513 struct exp_hash fid_hash;
514 struct exp_hash path_hash;
515 struct treenode *exi_tree;
516 fhandle_t exi_fh;
517 krwlock_t exi_cache_lock;
518 kmutex_t exi_lock;
519 uint_t exi_count;
520 vnode_t *exi_vp;
521 vnode_t *exi_dvp;
522 avl_tree_t *exi_cache[AUTH_TABLESIZE];
523 struct log_buffer *exi_logbuffer;
524 struct exp_visible *exi_visible;
525 struct charset_cache *exi_charset;
526 unsigned exi_volatile_dev:1;
527 unsigned exi_moved:1;
528 #ifdef VOLATILE_FH_TEST
529 uint32_t exi_volatile_id;
530 struct ex_vol_rename *exi_vol_rename;
531 kmutex_t exi_vol_rename_lock;
532 #endif /* VOLATILE_FH_TEST */
533 };
534
535 typedef struct exportinfo exportinfo_t;
536 typedef struct exportdata exportdata_t;
537 typedef struct secinfo secinfo_t;
538
539 /*
540 * exp_visible is a visible list per filesystem. It is for filesystems
541 * that may need a limited view of its contents. A pseudo export and
542 * a real export at the mount point (VROOT) which has a subtree shared
543 * has a visible list.
544 *
545 * The exi_visible field is NULL for normal, non-pseudo filesystems
546 * which do not have any subtree exported. If the field is non-null,
547 * it points to a list of visible entries, identified by vis_fid and/or
548 * vis_ino. The presence of a "visible" list means that if this export
549 * can only have a limited view, it can only view the entries in the
550 * exp_visible list. The directories in the fid list comprise paths that
551 * lead to exported directories.
552 *
591 (EQFSID(&(exi)->exi_fsid, (fsid)) && EQFID(&(exi)->exi_fid, (fid)))
592
593 /*
594 * Returns true iff exported filesystem is read-only to the given host.
595 *
596 * Note: this macro should be as fast as possible since it's called
597 * on each NFS modification request.
598 */
599 #define rdonly(ro, vp) ((ro) || vn_is_readonly(vp))
600 #define rdonly4(req, cs) \
601 (vn_is_readonly((cs)->vp) || \
602 (nfsauth4_access((cs)->exi, (cs)->vp, (req), (cs)->basecr, NULL, \
603 NULL, NULL, NULL) & (NFSAUTH_RO | NFSAUTH_LIMITED)))
604
605 extern int nfsauth4_access(struct exportinfo *, vnode_t *,
606 struct svc_req *, cred_t *, uid_t *, gid_t *, uint_t *, gid_t **);
607 extern int nfsauth4_secinfo_access(struct exportinfo *,
608 struct svc_req *, int, int, cred_t *);
609 extern int nfsauth_cache_clnt_compar(const void *, const void *);
610 extern int nfs_fhbcmp(char *, char *, int);
611 extern int nfs_exportinit(void);
612 extern void nfs_exportfini(void);
613 extern int chk_clnt_sec(struct exportinfo *, struct svc_req *);
614 extern int makefh(fhandle_t *, struct vnode *, struct exportinfo *);
615 extern int makefh_ol(fhandle_t *, struct exportinfo *, uint_t);
616 extern int makefh3(nfs_fh3 *, struct vnode *, struct exportinfo *);
617 extern int makefh3_ol(nfs_fh3 *, struct exportinfo *, uint_t);
618 extern vnode_t *nfs_fhtovp(fhandle_t *, struct exportinfo *);
619 extern vnode_t *nfs3_fhtovp(nfs_fh3 *, struct exportinfo *);
620 extern struct exportinfo *checkexport(fsid_t *, struct fid *);
621 extern struct exportinfo *checkexport4(fsid_t *, struct fid *, vnode_t *);
622 extern void exi_hold(struct exportinfo *);
623 extern void exi_rele(struct exportinfo *);
624 extern struct exportinfo *nfs_vptoexi(vnode_t *, vnode_t *, cred_t *, int *,
625 int *, bool_t);
626 extern int nfs_check_vpexi(vnode_t *, vnode_t *, cred_t *,
627 struct exportinfo **);
628 extern void export_link(struct exportinfo *);
629 extern void export_unlink(struct exportinfo *);
630 extern vnode_t *untraverse(vnode_t *);
631 extern int vn_is_nfs_reparse(vnode_t *, cred_t *);
632 extern int client_is_downrev(struct svc_req *);
633 extern char *build_symlink(vnode_t *, cred_t *, size_t *);
634
635 /*
636 * Functions that handle the NFSv4 server namespace
637 */
638 extern exportinfo_t *vis2exi(treenode_t *);
639 extern int treeclimb_export(struct exportinfo *);
640 extern void treeclimb_unexport(struct exportinfo *);
641 extern int nfs_visible(struct exportinfo *, vnode_t *, int *);
642 extern int nfs_visible_inode(struct exportinfo *, ino64_t,
643 struct exp_visible **);
644 extern int has_visible(struct exportinfo *, vnode_t *);
645 extern void free_visible(struct exp_visible *);
646 extern int nfs_exported(struct exportinfo *, vnode_t *);
647 extern struct exportinfo *pseudo_exportfs(vnode_t *, fid_t *,
648 struct exp_visible *, struct exportdata *);
649 extern int vop_fid_pseudo(vnode_t *, fid_t *);
650 extern int nfs4_vget_pseudo(struct exportinfo *, vnode_t **, fid_t *);
651 extern bool_t nfs_visible_change(struct exportinfo *, vnode_t *,
652 timespec_t *);
653 extern void tree_update_change(treenode_t *, timespec_t *);
654 /*
655 * Functions that handle the NFSv4 server namespace security flavors
656 * information.
657 */
658 extern void srv_secinfo_exp2pseu(struct exportdata *, struct exportdata *);
659 extern void srv_secinfo_list_free(struct secinfo *, int);
660
661 /*
662 * "public" and default (root) location for public filehandle
663 */
664 extern struct exportinfo *exi_public, *exi_root;
665 extern fhandle_t nullfh2; /* for comparing V2 filehandles */
666 extern krwlock_t exported_lock;
667 extern struct exportinfo *exptable[];
668
669 /*
670 * Two macros for identifying public filehandles.
671 * A v2 public filehandle is 32 zero bytes.
672 * A v3 public filehandle is zero length.
673 */
674 #define PUBLIC_FH2(fh) \
675 ((fh)->fh_fsid.val[1] == 0 && \
676 bcmp((fh), &nullfh2, sizeof (fhandle_t)) == 0)
677
678 #define PUBLIC_FH3(fh) \
679 ((fh)->fh3_length == 0)
680
681 extern int makefh4(nfs_fh4 *, struct vnode *, struct exportinfo *);
682 extern vnode_t *nfs4_fhtovp(nfs_fh4 *, struct exportinfo *, nfsstat4 *);
683
684 #endif /* _KERNEL */
685
686 #ifdef __cplusplus
687 }
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
25 * Copyright 2016 Jason King.
26 * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
27 */
28
29 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
30 /* All Rights Reserved */
31
32 #ifndef _NFS_EXPORT_H
33 #define _NFS_EXPORT_H
34
35 #include <nfs/nfs_sec.h>
36 #include <nfs/auth.h>
37 #include <sys/vnode.h>
38 #include <nfs/nfs4.h>
39 #include <sys/kiconv.h>
40 #include <sys/avl.h>
41 #include <sys/zone.h>
42
43 #ifdef _KERNEL
44 #include <sys/pkp_hash.h> /* for PKP_HASH_SIZE */
45 #endif /* _KERNEL */
46
47 #ifdef __cplusplus
48 extern "C" {
49 #endif
50
51 /*
52 * nfs pseudo flavor number is owned by IANA. Need to make sure the
53 * Solaris specific NFS_FLAVOR_NOMAP number will not overlap with any
54 * new IANA defined pseudo flavor numbers. The chance for the overlap
55 * is very small since the growth of new flavor numbers is expected
56 * to be limited.
57 */
58 #define NFS_FLAVOR_NOMAP 999999 /* no nfs flavor mapping */
59
60 /*
61 * As duplicate flavors can be passed into exportfs in the arguments, we
62 * allocate a cleaned up array with non duplicate flavors on the stack.
63 * So we need to know how much to allocate.
64 */
65 #define MAX_FLAVORS 6 /* none, sys, dh, krb5, krb5i krb5p */
66
456 * +===+ (VROOT) +---+ +---+
457 *
458 *
459 * Bi-directional interconnect:
460 * treenode_t::tree_exi --------- exportinfo_t::exi_tree
461 * One-way direction connection:
462 * treenode_t::tree_vis .........> exp_visible_t
463 */
464 /* Access to treenode_t is under protection of exported_lock RW_LOCK */
465 typedef struct treenode {
466 /* support for generic n-ary trees */
467 struct treenode *tree_parent;
468 struct treenode *tree_child_first;
469 struct treenode *tree_sibling; /* next sibling */
470 /* private, nfs specific part */
471 struct exportinfo *tree_exi;
472 struct exp_visible *tree_vis;
473 } treenode_t;
474
475 /*
476 * Now that we have links to chase, we can get the zone rootvp just from
477 * an export. No current-zone-context needed.
478 */
479 #define EXI_TO_ZONEROOTVP(exi) ((exi)->exi_ne->exi_root->exi_vp)
480
481 /*
482 * TREE_ROOT checks if the node corresponds to a filesystem root or
483 * the zone's root directory.
484 * TREE_EXPORTED checks if the node is explicitly shared
485 */
486
487 #define TREE_ROOT(t) \
488 ((t)->tree_exi != NULL && \
489 (((t)->tree_exi->exi_vp->v_flag & VROOT) || \
490 VN_CMP(EXI_TO_ZONEROOTVP((t)->tree_exi), (t)->tree_exi->exi_vp)))
491
492 #define TREE_EXPORTED(t) \
493 ((t)->tree_exi && !PSEUDO((t)->tree_exi))
494
495 #define EXPTABLESIZE 256
496
497 struct exp_hash {
498 struct exportinfo *prev; /* ptr to the previous exportinfo */
499 struct exportinfo *next; /* ptr to the next exportinfo */
500 struct exportinfo **bckt; /* backpointer to the hash bucket */
501 };
502
503 /*
504 * A node associated with an export entry on the
505 * list of exported filesystems.
506 *
507 * exi_count+exi_lock protects an individual exportinfo from being freed
508 * when in use.
509 *
510 * You must have the writer lock on exported_lock to add/delete an exportinfo
511 * structure to/from the list.
512 *
513 * exi_volatile_dev maps to VSW_VOLATILEDEV. It means that the
514 * underlying fs devno can change on each mount. When set, the server
515 * should not use va_fsid for a GETATTR(FATTR4_FSID) reply. It must
516 * use exi_fsid because it is guaranteed to be persistent. This isn't
517 * in any way related to NFS4 volatile filehandles.
518 *
519 * The exi_cache_lock protects the exi_cache AVL trees.
520 */
521 struct exportinfo {
522 struct exportdata exi_export;
523 fsid_t exi_fsid;
524 struct fid exi_fid;
525 struct exp_hash fid_hash;
526 struct exp_hash path_hash;
527 struct treenode *exi_tree;
528 fhandle_t exi_fh;
529 krwlock_t exi_cache_lock;
530 kmutex_t exi_lock;
531 uint_t exi_count;
532 zoneid_t exi_zoneid;
533 vnode_t *exi_vp;
534 vnode_t *exi_dvp;
535 avl_tree_t *exi_cache[AUTH_TABLESIZE];
536 struct log_buffer *exi_logbuffer;
537 struct exp_visible *exi_visible;
538 struct charset_cache *exi_charset;
539 unsigned exi_volatile_dev:1;
540 unsigned exi_moved:1;
541 int exi_id;
542 avl_node_t exi_id_link;
543 /*
544 * Soft-reference/backpointer to zone's nfs_export_t.
545 * This allows us access to the zone's rootvp (stored in
546 * exi_ne->exi_root->exi_vp) even if the current thread isn't in
547 * same-zone context.
548 */
549 struct nfs_export *exi_ne;
550 #ifdef VOLATILE_FH_TEST
551 uint32_t exi_volatile_id;
552 struct ex_vol_rename *exi_vol_rename;
553 kmutex_t exi_vol_rename_lock;
554 #endif /* VOLATILE_FH_TEST -- keep last! */
555 };
556
557 typedef struct exportinfo exportinfo_t;
558 typedef struct exportdata exportdata_t;
559 typedef struct secinfo secinfo_t;
560
561 /*
562 * exp_visible is a visible list per filesystem. It is for filesystems
563 * that may need a limited view of its contents. A pseudo export and
564 * a real export at the mount point (VROOT) which has a subtree shared
565 * has a visible list.
566 *
567 * The exi_visible field is NULL for normal, non-pseudo filesystems
568 * which do not have any subtree exported. If the field is non-null,
569 * it points to a list of visible entries, identified by vis_fid and/or
570 * vis_ino. The presence of a "visible" list means that if this export
571 * can only have a limited view, it can only view the entries in the
572 * exp_visible list. The directories in the fid list comprise paths that
573 * lead to exported directories.
574 *
613 (EQFSID(&(exi)->exi_fsid, (fsid)) && EQFID(&(exi)->exi_fid, (fid)))
614
615 /*
616 * Returns true iff exported filesystem is read-only to the given host.
617 *
618 * Note: this macro should be as fast as possible since it's called
619 * on each NFS modification request.
620 */
621 #define rdonly(ro, vp) ((ro) || vn_is_readonly(vp))
622 #define rdonly4(req, cs) \
623 (vn_is_readonly((cs)->vp) || \
624 (nfsauth4_access((cs)->exi, (cs)->vp, (req), (cs)->basecr, NULL, \
625 NULL, NULL, NULL) & (NFSAUTH_RO | NFSAUTH_LIMITED)))
626
627 extern int nfsauth4_access(struct exportinfo *, vnode_t *,
628 struct svc_req *, cred_t *, uid_t *, gid_t *, uint_t *, gid_t **);
629 extern int nfsauth4_secinfo_access(struct exportinfo *,
630 struct svc_req *, int, int, cred_t *);
631 extern int nfsauth_cache_clnt_compar(const void *, const void *);
632 extern int nfs_fhbcmp(char *, char *, int);
633 extern void nfs_exportinit(void);
634 extern void nfs_exportfini(void);
635 extern void nfs_export_zone_init(nfs_globals_t *);
636 extern void nfs_export_zone_fini(nfs_globals_t *);
637 extern void nfs_export_zone_shutdown(nfs_globals_t *);
638 extern int nfs_export_get_rootfh(nfs_globals_t *);
639 extern int chk_clnt_sec(struct exportinfo *, struct svc_req *);
640 extern int makefh(fhandle_t *, struct vnode *, struct exportinfo *);
641 extern int makefh_ol(fhandle_t *, struct exportinfo *, uint_t);
642 extern int makefh3(nfs_fh3 *, struct vnode *, struct exportinfo *);
643 extern int makefh3_ol(nfs_fh3 *, struct exportinfo *, uint_t);
644 extern vnode_t *nfs_fhtovp(fhandle_t *, struct exportinfo *);
645 extern vnode_t *nfs3_fhtovp(nfs_fh3 *, struct exportinfo *);
646 extern struct exportinfo *checkexport(fsid_t *, struct fid *);
647 extern struct exportinfo *checkexport4(fsid_t *, struct fid *, vnode_t *);
648 extern void exi_hold(struct exportinfo *);
649 extern void exi_rele(struct exportinfo *);
650 extern struct exportinfo *nfs_vptoexi(vnode_t *, vnode_t *, cred_t *, int *,
651 int *, bool_t);
652 extern int nfs_check_vpexi(vnode_t *, vnode_t *, cred_t *,
653 struct exportinfo **);
654 extern vnode_t *untraverse(vnode_t *, vnode_t *);
655 extern int vn_is_nfs_reparse(vnode_t *, cred_t *);
656 extern int client_is_downrev(struct svc_req *);
657 extern char *build_symlink(vnode_t *, cred_t *, size_t *);
658
659 extern fhandle_t nullfh2; /* for comparing V2 filehandles */
660
661 typedef struct nfs_export {
662 /* Root of nfs pseudo namespace */
663 treenode_t *ns_root;
664
665 nfs_globals_t *ne_globals; /* "up" pointer */
666
667 struct exportinfo *exptable_path_hash[PKP_HASH_SIZE];
668 struct exportinfo *exptable[EXPTABLESIZE];
669
670 /*
671 * Read/Write lock that protects the exportinfo list. This lock
672 * must be held when searching or modifiying the exportinfo list.
673 */
674 krwlock_t exported_lock;
675
676 /* "public" and default (root) location for public filehandle */
677 struct exportinfo *exi_public;
678 struct exportinfo *exi_root;
679 /* For checking default public file handle */
680 fid_t exi_rootfid;
681 /* For comparing V2 filehandles */
682 fhandle_t nullfh2;
683
684 /* The change attribute value of the root of nfs pseudo namespace */
685 timespec_t ns_root_change;
686 } nfs_export_t;
687
688 /*
689 * Functions that handle the NFSv4 server namespace
690 */
691 extern exportinfo_t *vis2exi(treenode_t *);
692 extern int treeclimb_export(struct exportinfo *);
693 extern void treeclimb_unexport(nfs_export_t *, struct exportinfo *);
694 extern int nfs_visible(struct exportinfo *, vnode_t *, int *);
695 extern int nfs_visible_inode(struct exportinfo *, ino64_t,
696 struct exp_visible **);
697 extern int has_visible(struct exportinfo *, vnode_t *);
698 extern void free_visible(struct exp_visible *);
699 extern int nfs_exported(struct exportinfo *, vnode_t *);
700 extern struct exportinfo *pseudo_exportfs(nfs_export_t *, vnode_t *, fid_t *,
701 struct exp_visible *, struct exportdata *);
702 extern int vop_fid_pseudo(vnode_t *, fid_t *);
703 extern int nfs4_vget_pseudo(struct exportinfo *, vnode_t **, fid_t *);
704 extern bool_t nfs_visible_change(struct exportinfo *, vnode_t *,
705 timespec_t *);
706 extern void tree_update_change(nfs_export_t *, treenode_t *, timespec_t *);
707 extern void rfs4_clean_state_exi(nfs_export_t *, struct exportinfo *);
708
709 /*
710 * Functions that handle the NFSv4 server namespace security flavors
711 * information.
712 */
713 extern void srv_secinfo_exp2pseu(struct exportdata *, struct exportdata *);
714 extern void srv_secinfo_list_free(struct secinfo *, int);
715
716 extern nfs_export_t *nfs_get_export();
717 extern void export_link(nfs_export_t *, struct exportinfo *);
718 extern void export_unlink(nfs_export_t *, struct exportinfo *);
719
720 /*
721 * exi_id support
722 */
723 extern kmutex_t nfs_exi_id_lock;
724 extern avl_tree_t exi_id_tree;
725 extern int exi_id_get_next(void);
726
727 /*
728 * Two macros for identifying public filehandles.
729 * A v2 public filehandle is 32 zero bytes.
730 * A v3 public filehandle is zero length.
731 */
732 #define PUBLIC_FH2(fh) \
733 ((fh)->fh_fsid.val[1] == 0 && \
734 bcmp((fh), &nullfh2, sizeof (fhandle_t)) == 0)
735
736 #define PUBLIC_FH3(fh) \
737 ((fh)->fh3_length == 0)
738
739 extern int makefh4(nfs_fh4 *, struct vnode *, struct exportinfo *);
740 extern vnode_t *nfs4_fhtovp(nfs_fh4 *, struct exportinfo *, nfsstat4 *);
741
742 #endif /* _KERNEL */
743
744 #ifdef __cplusplus
745 }
|