0
|
1 |
/*
|
|
2 |
* CDDL HEADER START
|
|
3 |
*
|
|
4 |
* The contents of this file are subject to the terms of the
|
|
5 |
* Common Development and Distribution License, Version 1.0 only
|
|
6 |
* (the "License"). You may not use this file except in compliance
|
|
7 |
* with the License.
|
|
8 |
*
|
|
9 |
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
|
10 |
* or http://www.opensolaris.org/os/licensing.
|
|
11 |
* See the License for the specific language governing permissions
|
|
12 |
* and limitations under the License.
|
|
13 |
*
|
|
14 |
* When distributing Covered Code, include this CDDL HEADER in each
|
|
15 |
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
|
16 |
* If applicable, add the following below this CDDL HEADER, with the
|
|
17 |
* fields enclosed by brackets "[]" replaced with your own identifying
|
|
18 |
* information: Portions Copyright [yyyy] [name of copyright owner]
|
|
19 |
*
|
|
20 |
* CDDL HEADER END
|
|
21 |
*/
|
|
22 |
/*
|
|
23 |
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
|
|
24 |
* Use is subject to license terms.
|
|
25 |
*/
|
|
26 |
|
|
27 |
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
|
28 |
/* All Rights Reserved */
|
|
29 |
|
|
30 |
#ifndef _NFS_EXPORT_H
|
|
31 |
#define _NFS_EXPORT_H
|
|
32 |
|
|
33 |
#pragma ident "%Z%%M% %I% %E% SMI"
|
|
34 |
|
|
35 |
#include <nfs/nfs_sec.h>
|
|
36 |
#include <rpcsvc/nfsauth_prot.h>
|
|
37 |
#include <sys/vnode.h>
|
|
38 |
#include <nfs/nfs4.h>
|
|
39 |
|
|
40 |
#ifdef __cplusplus
|
|
41 |
extern "C" {
|
|
42 |
#endif
|
|
43 |
|
|
44 |
/*
|
|
45 |
* nfs pseudo flavor number is owned by IANA. Need to make sure the
|
|
46 |
* Solaris specific NFS_FLAVOR_NOMAP number will not overlap with any
|
|
47 |
* new IANA defined pseudo flavor numbers. The chance for the overlap
|
|
48 |
* is very small since the growth of new flavor numbers is expected
|
|
49 |
* to be limited.
|
|
50 |
*/
|
|
51 |
#define NFS_FLAVOR_NOMAP 999999 /* no nfs flavor mapping */
|
|
52 |
|
|
53 |
/*
|
|
54 |
* Note: exported_lock is currently used to ensure the integrity of
|
|
55 |
* the secinfo fields.
|
|
56 |
*/
|
|
57 |
struct secinfo {
|
|
58 |
seconfig_t s_secinfo; /* /etc/nfssec.conf entry */
|
|
59 |
unsigned int s_flags; /* flags (see below) */
|
|
60 |
uint32_t s_refcnt; /* reference count for tracking */
|
|
61 |
/* how many children (self included) */
|
|
62 |
/* use this flavor. */
|
|
63 |
int s_window; /* window */
|
|
64 |
int s_rootcnt; /* count of root names */
|
|
65 |
caddr_t *s_rootnames; /* array of root names */
|
|
66 |
/* they are strings for AUTH_DES and */
|
|
67 |
/* rpc_gss_principal_t for RPCSEC_GSS */
|
|
68 |
};
|
|
69 |
|
|
70 |
#ifdef _SYSCALL32
|
|
71 |
struct secinfo32 {
|
|
72 |
seconfig32_t s_secinfo; /* /etc/nfssec.conf entry */
|
|
73 |
uint32_t s_flags; /* flags (see below) */
|
|
74 |
uint32_t s_refcnt; /* reference count for tracking */
|
|
75 |
/* how many children (self included) */
|
|
76 |
/* use this flavor. */
|
|
77 |
int32_t s_window; /* window */
|
|
78 |
int32_t s_rootcnt; /* count of root names */
|
|
79 |
caddr32_t s_rootnames; /* array of root names */
|
|
80 |
/* they are strings for AUTH_DES and */
|
|
81 |
/* rpc_gss_principal_t for RPCSEC_GSS */
|
|
82 |
};
|
|
83 |
#endif /* _SYSCALL32 */
|
|
84 |
|
|
85 |
/*
|
|
86 |
* security negotiation related
|
|
87 |
*/
|
|
88 |
|
|
89 |
#define SEC_QUERY 0x01 /* query sec modes */
|
|
90 |
|
|
91 |
struct sec_ol {
|
|
92 |
int sec_flags; /* security nego flags */
|
|
93 |
uint_t sec_index; /* index into sec flavor array */
|
|
94 |
};
|
|
95 |
|
|
96 |
/*
|
|
97 |
* Per-mode flags (secinfo.s_flags)
|
|
98 |
*/
|
|
99 |
#define M_RO 0x01 /* exported ro to all */
|
|
100 |
#define M_ROL 0x02 /* exported ro to all listed */
|
|
101 |
#define M_RW 0x04 /* exported rw to all */
|
|
102 |
#define M_RWL 0x08 /* exported ro to all listed */
|
|
103 |
#define M_ROOT 0x10 /* root list is defined */
|
|
104 |
#define M_4SEC_EXPORTED 0x20 /* this is an explicitly shared flavor */
|
|
105 |
|
|
106 |
/* invalid secinfo reference count */
|
|
107 |
#define SEC_REF_INVALID(p) ((p)->s_refcnt < 1)
|
|
108 |
|
|
109 |
/* last secinfo reference */
|
|
110 |
#define SEC_REF_LAST(p) ((p)->s_refcnt == 1)
|
|
111 |
|
|
112 |
/* sec flavor explicitly shared for the exported node */
|
|
113 |
#define SEC_REF_EXPORTED(p) ((p)->s_flags & M_4SEC_EXPORTED)
|
|
114 |
|
|
115 |
/* the only reference count left is for referring itself */
|
|
116 |
#define SEC_REF_SELF(p) (SEC_REF_LAST(p) && SEC_REF_EXPORTED(p))
|
|
117 |
|
|
118 |
/*
|
|
119 |
* The export information passed to exportfs() (Version 2)
|
|
120 |
*/
|
|
121 |
#define EX_CURRENT_VERSION 2 /* current version of exportdata struct */
|
|
122 |
|
|
123 |
struct exportdata {
|
|
124 |
int ex_version; /* structure version */
|
|
125 |
char *ex_path; /* exported path */
|
|
126 |
size_t ex_pathlen; /* path length */
|
|
127 |
int ex_flags; /* flags */
|
|
128 |
unsigned int ex_anon; /* uid for unauthenticated requests */
|
|
129 |
int ex_seccnt; /* count of security modes */
|
|
130 |
struct secinfo *ex_secinfo; /* security mode info */
|
|
131 |
char *ex_index; /* index file for public filesystem */
|
|
132 |
char *ex_log_buffer; /* path to logging buffer file */
|
|
133 |
size_t ex_log_bufferlen; /* buffer file path len */
|
|
134 |
char *ex_tag; /* tag used to identify log config */
|
|
135 |
size_t ex_taglen; /* tag length */
|
|
136 |
};
|
|
137 |
|
|
138 |
#ifdef _SYSCALL32
|
|
139 |
struct exportdata32 {
|
|
140 |
int32_t ex_version; /* structure version */
|
|
141 |
caddr32_t ex_path; /* exported path */
|
|
142 |
int32_t ex_pathlen; /* path length */
|
|
143 |
int32_t ex_flags; /* flags */
|
|
144 |
uint32_t ex_anon; /* uid for unauthenticated requests */
|
|
145 |
int32_t ex_seccnt; /* count of security modes */
|
|
146 |
caddr32_t ex_secinfo; /* security mode info */
|
|
147 |
caddr32_t ex_index; /* index file for public filesystem */
|
|
148 |
caddr32_t ex_log_buffer; /* path to logging buffer file */
|
|
149 |
int32_t ex_log_bufferlen; /* buffer file path len */
|
|
150 |
caddr32_t ex_tag; /* tag used to identify log config */
|
|
151 |
int32_t ex_taglen; /* tag length */
|
|
152 |
};
|
|
153 |
#endif /* _SYSCALL32 */
|
|
154 |
|
|
155 |
/*
|
|
156 |
* exported vfs flags.
|
|
157 |
*/
|
|
158 |
|
|
159 |
#define EX_NOSUID 0x01 /* exported with unsetable set[ug]ids */
|
|
160 |
#define EX_ACLOK 0x02 /* exported with maximal access if acl exists */
|
|
161 |
#define EX_PUBLIC 0x04 /* exported with public filehandle */
|
|
162 |
#define EX_NOSUB 0x08 /* no nfs_getfh or MCL below export point */
|
|
163 |
#define EX_INDEX 0x10 /* exported with index file specified */
|
|
164 |
#define EX_LOG 0x20 /* logging enabled */
|
|
165 |
#define EX_LOG_ALLOPS 0x40 /* logging of all RPC operations enabled */
|
|
166 |
/* by default only operations which affect */
|
|
167 |
/* transaction logging are enabled */
|
|
168 |
#define EX_PSEUDO 0x80 /* pseudo filesystem export */
|
|
169 |
#ifdef VOLATILE_FH_TEST
|
|
170 |
#define EX_VOLFH 0x100 /* XXX nfsv4 fh may expire anytime */
|
|
171 |
#define EX_VOLRNM 0x200 /* XXX nfsv4 fh expire at rename */
|
|
172 |
#define EX_VOLMIG 0x400 /* XXX nfsv4 fh expire at migration */
|
|
173 |
#define EX_NOEXPOPEN 0x800 /* XXX nfsv4 fh no expire with open */
|
|
174 |
#endif /* VOLATILE_FH_TEST */
|
|
175 |
|
|
176 |
#ifdef _KERNEL
|
|
177 |
|
|
178 |
#define RPC_IDEMPOTENT 0x1 /* idempotent or not */
|
|
179 |
/*
|
|
180 |
* Be very careful about which NFS procedures get the RPC_ALLOWANON bit.
|
|
181 |
* Right now, it this bit is on, we ignore the results of per NFS request
|
|
182 |
* access control.
|
|
183 |
*/
|
|
184 |
#define RPC_ALLOWANON 0x2 /* allow anonymous access */
|
|
185 |
#define RPC_MAPRESP 0x4 /* use mapped response buffer */
|
|
186 |
#define RPC_AVOIDWORK 0x8 /* do work avoidance for dups */
|
|
187 |
#define RPC_PUBLICFH_OK 0x10 /* allow use of public filehandle */
|
|
188 |
|
|
189 |
/*
|
|
190 |
* RPC_ALL is an or of all above bits to be used with "don't care"
|
|
191 |
* nfsv4 ops. The flags of an nfsv4 request is the bit-AND of the
|
|
192 |
* per-op flags.
|
|
193 |
*/
|
|
194 |
#define RPC_ALL (RPC_IDEMPOTENT|RPC_ALLOWANON|RPC_AVOIDWORK|RPC_PUBLICFH_OK)
|
|
195 |
|
|
196 |
|
|
197 |
#ifdef VOLATILE_FH_TEST
|
|
198 |
struct ex_vol_rename {
|
|
199 |
nfs_fh4_fmt_t vrn_fh_fmt;
|
|
200 |
struct ex_vol_rename *vrn_next;
|
|
201 |
};
|
|
202 |
#endif /* VOLATILE_FH_TEST */
|
|
203 |
|
|
204 |
/*
|
|
205 |
* An authorization cache entry
|
|
206 |
*/
|
|
207 |
struct auth_cache {
|
|
208 |
struct netbuf auth_addr;
|
|
209 |
int auth_flavor;
|
|
210 |
int auth_access;
|
|
211 |
time_t auth_time;
|
|
212 |
struct auth_cache *auth_next;
|
|
213 |
};
|
|
214 |
|
|
215 |
#define AUTH_TABLESIZE 32
|
|
216 |
|
|
217 |
/*
|
|
218 |
* Structure containing log file meta-data.
|
|
219 |
*/
|
|
220 |
struct log_file {
|
|
221 |
unsigned int lf_flags; /* flags (see below) */
|
|
222 |
int lf_writers; /* outstanding writers */
|
|
223 |
int lf_refcnt; /* references to this struct */
|
|
224 |
caddr_t lf_path; /* buffer file location */
|
|
225 |
vnode_t *lf_vp; /* vnode for the buffer file */
|
|
226 |
kmutex_t lf_lock;
|
|
227 |
kcondvar_t lf_cv_waiters;
|
|
228 |
};
|
|
229 |
|
|
230 |
/*
|
|
231 |
* log_file and log_buffer flags.
|
|
232 |
*/
|
|
233 |
#define L_WAITING 0x01 /* flush of in-core data to stable */
|
|
234 |
/* storage in progress */
|
|
235 |
#define L_PRINTED 0x02 /* error message printed to console */
|
|
236 |
#define L_ERROR 0x04 /* error condition detected */
|
|
237 |
|
|
238 |
/*
|
|
239 |
* The logging buffer information.
|
|
240 |
* This structure may be shared by multiple exportinfo structures,
|
|
241 |
* if they share the same buffer file.
|
|
242 |
* This structure contains the basic information about the buffer, such
|
|
243 |
* as it's location in the filesystem.
|
|
244 |
*
|
|
245 |
* 'lb_lock' protects all the fields in this structure except for 'lb_path',
|
|
246 |
* and 'lb_next'.
|
|
247 |
* 'lb_path' is a write-once/read-many field which needs no locking, it is
|
|
248 |
* set before the structure is linked to any exportinfo structure.
|
|
249 |
* 'lb_next' is protected by the log_buffer_list_lock.
|
|
250 |
*/
|
|
251 |
struct log_buffer {
|
|
252 |
unsigned int lb_flags; /* L_ONLIST set? */
|
|
253 |
int lb_refcnt; /* references to this struct */
|
|
254 |
unsigned int lb_rec_id; /* used to generate unique id */
|
|
255 |
caddr_t lb_path; /* buffer file pathname */
|
|
256 |
struct log_file *lb_logfile; /* points to log_file structure */
|
|
257 |
kmutex_t lb_lock;
|
|
258 |
struct log_buffer *lb_next;
|
|
259 |
kcondvar_t lb_cv_waiters;
|
|
260 |
caddr_t lb_records; /* linked list of records to write */
|
|
261 |
int lb_num_recs; /* # of records to write */
|
|
262 |
ssize_t lb_size_queued; /* number of bytes queued for write */
|
|
263 |
};
|
|
264 |
|
|
265 |
#define LOG_BUFFER_HOLD(lbp) { \
|
|
266 |
mutex_enter(&(lbp)->lb_lock); \
|
|
267 |
(lbp)->lb_refcnt++; \
|
|
268 |
mutex_exit(&(lbp)->lb_lock); \
|
|
269 |
}
|
|
270 |
|
|
271 |
#define LOG_BUFFER_RELE(lbp) { \
|
|
272 |
log_buffer_rele(lbp); \
|
|
273 |
}
|
|
274 |
|
|
275 |
#define EXPTABLESIZE 16
|
|
276 |
|
|
277 |
/*
|
|
278 |
* A node associated with an export entry on the
|
|
279 |
* list of exported filesystems.
|
|
280 |
*
|
|
281 |
* exi_count+exi_lock protects an individual exportinfo from being freed
|
|
282 |
* when in use.
|
|
283 |
* You must have the writer lock on exported_lock to add/delete an exportinfo
|
|
284 |
* structure to/from the list.
|
|
285 |
*
|
|
286 |
* exi_volatile_dev maps to VSW_VOLATILEDEV. It means that the
|
|
287 |
* underlying fs devno can change on each mount. When set, the server
|
|
288 |
* should not use va_fsid for a GETATTR(FATTR4_FSID) reply. It must
|
|
289 |
* use exi_fsid because it is guaranteed to be persistent. This isn't
|
|
290 |
* in any way related to NFS4 volatile filehandles.
|
|
291 |
*/
|
|
292 |
struct exportinfo {
|
|
293 |
struct exportdata exi_export;
|
|
294 |
fsid_t exi_fsid;
|
|
295 |
struct fid exi_fid;
|
|
296 |
struct exportinfo *exi_hash;
|
|
297 |
fhandle_t exi_fh;
|
|
298 |
krwlock_t exi_cache_lock;
|
|
299 |
kmutex_t exi_lock;
|
|
300 |
uint_t exi_count;
|
|
301 |
vnode_t *exi_vp;
|
|
302 |
vnode_t *exi_dvp;
|
|
303 |
struct auth_cache *exi_cache[AUTH_TABLESIZE];
|
|
304 |
struct log_buffer *exi_logbuffer;
|
|
305 |
struct exp_visible *exi_visible;
|
|
306 |
unsigned exi_volatile_dev:1;
|
|
307 |
#ifdef VOLATILE_FH_TEST
|
|
308 |
uint32_t exi_volatile_id;
|
|
309 |
struct ex_vol_rename *exi_vol_rename;
|
|
310 |
kmutex_t exi_vol_rename_lock;
|
|
311 |
#endif /* VOLATILE_FH_TEST */
|
|
312 |
};
|
|
313 |
|
|
314 |
/*
|
|
315 |
* exp_visible is a visible list per filesystem. It is for filesystems
|
|
316 |
* that may need a limited view of its contents. A pseudo export and
|
|
317 |
* a real export at the mount point (VROOT) which has a subtree shared
|
|
318 |
* has a visible list.
|
|
319 |
*
|
|
320 |
* The exi_visible field is NULL for normal, non=pseudo filesystems
|
|
321 |
* which do not have any subtree exported. If the field is non-null,
|
|
322 |
* it points to a list of visible entries, identified by vis_fid and/or
|
|
323 |
* vis_ino. The presence of a "visible" list means that if this export
|
|
324 |
* can only have a limited view, it can only view the entries in the
|
|
325 |
* exp_visible list. The directories in the fid list comprise paths that
|
|
326 |
* lead to exported directories.
|
|
327 |
*
|
|
328 |
* The vis_count field records the number of paths in this filesystem
|
|
329 |
* that use this directory. The vis_exported field is non-zero if the
|
|
330 |
* entry is an exported directory (leaf node).
|
|
331 |
*/
|
|
332 |
|
|
333 |
struct exp_visible {
|
|
334 |
vnode_t *vis_vp;
|
|
335 |
fid_t vis_fid;
|
|
336 |
u_longlong_t vis_ino;
|
|
337 |
int vis_count;
|
|
338 |
int vis_exported;
|
|
339 |
struct exp_visible *vis_next;
|
|
340 |
};
|
|
341 |
|
|
342 |
#define PSEUDO(exi) ((exi)->exi_export.ex_flags & EX_PSEUDO)
|
|
343 |
|
|
344 |
#define EQFSID(fsidp1, fsidp2) \
|
|
345 |
(((fsidp1)->val[0] == (fsidp2)->val[0]) && \
|
|
346 |
((fsidp1)->val[1] == (fsidp2)->val[1]))
|
|
347 |
|
|
348 |
#define EQFID(fidp1, fidp2) \
|
|
349 |
((fidp1)->fid_len == (fidp2)->fid_len && \
|
806
|
350 |
bcmp((char *)(fidp1)->fid_data, (char *)(fidp2)->fid_data, \
|
0
|
351 |
(uint_t)(fidp1)->fid_len) == 0)
|
|
352 |
|
|
353 |
#define exportmatch(exi, fsid, fid) \
|
|
354 |
(EQFSID(&(exi)->exi_fsid, (fsid)) && EQFID(&(exi)->exi_fid, (fid)))
|
|
355 |
|
|
356 |
/*
|
|
357 |
* Returns true iff exported filesystem is read-only to the given host.
|
|
358 |
*
|
|
359 |
* Note: this macro should be as fast as possible since it's called
|
|
360 |
* on each NFS modification request.
|
|
361 |
*/
|
|
362 |
#define rdonly(exi, req) (nfsauth_access(exi, req) & NFSAUTH_RO)
|
|
363 |
#define rdonly4(exi, vp, req) \
|
|
364 |
(vn_is_readonly(vp) || \
|
|
365 |
(nfsauth4_access(exi, vp, req) & (NFSAUTH_RO | NFSAUTH_LIMITED)))
|
|
366 |
|
|
367 |
extern int nfsauth4_access(struct exportinfo *, vnode_t *,
|
|
368 |
struct svc_req *);
|
|
369 |
extern int nfsauth4_secinfo_access(struct exportinfo *,
|
|
370 |
struct svc_req *, int, int);
|
|
371 |
extern int nfs_fhhash(fsid_t *, fid_t *);
|
|
372 |
extern int nfs_fhbcmp(char *, char *, int);
|
|
373 |
extern int nfs_exportinit(void);
|
|
374 |
extern void nfs_exportfini(void);
|
|
375 |
extern int chk_clnt_sec(struct exportinfo *, struct svc_req *req);
|
|
376 |
extern int makefh(fhandle_t *, struct vnode *, struct exportinfo *);
|
|
377 |
extern int makefh_ol(fhandle_t *, struct exportinfo *, uint_t);
|
|
378 |
extern int makefh3(nfs_fh3 *, struct vnode *, struct exportinfo *);
|
|
379 |
extern int makefh3_ol(nfs_fh3 *, struct exportinfo *, uint_t);
|
|
380 |
extern vnode_t *nfs_fhtovp(fhandle_t *, struct exportinfo *);
|
|
381 |
extern vnode_t *nfs3_fhtovp(nfs_fh3 *, struct exportinfo *);
|
|
382 |
extern vnode_t *lm_fhtovp(fhandle_t *fh);
|
|
383 |
extern vnode_t *lm_nfs3_fhtovp(nfs_fh3 *fh);
|
|
384 |
extern struct exportinfo *checkexport(fsid_t *, struct fid *);
|
|
385 |
extern struct exportinfo *checkexport4(fsid_t *, struct fid *, vnode_t *vp);
|
|
386 |
extern void exi_rele(struct exportinfo *);
|
|
387 |
extern struct exportinfo *nfs_vptoexi(vnode_t *, vnode_t *, cred_t *, int *,
|
|
388 |
int *, bool_t);
|
|
389 |
extern int nfs_check_vpexi(vnode_t *, vnode_t *, cred_t *,
|
|
390 |
struct exportinfo **);
|
|
391 |
extern void export_link(struct exportinfo *);
|
|
392 |
extern int export_unlink(fsid_t *, fid_t *, vnode_t *,
|
|
393 |
struct exportinfo **);
|
|
394 |
extern vnode_t *untraverse(vnode_t *);
|
|
395 |
|
|
396 |
/*
|
|
397 |
* Functions that handle the NFSv4 server namespace
|
|
398 |
*/
|
|
399 |
extern int treeclimb_export(struct exportinfo *);
|
|
400 |
extern int treeclimb_unexport(struct exportinfo *);
|
|
401 |
extern int nfs_visible(struct exportinfo *, vnode_t *, int *);
|
|
402 |
extern int nfs_visible_inode(struct exportinfo *, ino64_t, int *);
|
|
403 |
extern int has_visible(struct exportinfo *, vnode_t *);
|
|
404 |
extern void free_visible(struct exp_visible *);
|
|
405 |
extern int nfs_exported(struct exportinfo *, vnode_t *);
|
|
406 |
extern int pseudo_exportfs(vnode_t *, struct exp_visible *,
|
|
407 |
struct exportdata *);
|
|
408 |
extern int vop_fid_pseudo(vnode_t *, fid_t *fidp);
|
|
409 |
extern int nfs4_vget_pseudo(struct exportinfo *, vnode_t **, fid_t *);
|
|
410 |
/*
|
|
411 |
* Functions that handle the NFSv4 server namespace security flavors
|
|
412 |
* information.
|
|
413 |
*/
|
|
414 |
extern void srv_secinfo_exp2pseu(struct exportdata *, struct exportdata *);
|
|
415 |
|
|
416 |
/*
|
|
417 |
* "public" and default (root) location for public filehandle
|
|
418 |
*/
|
|
419 |
extern struct exportinfo *exi_public, *exi_root;
|
|
420 |
extern fhandle_t nullfh2; /* for comparing V2 filehandles */
|
|
421 |
extern krwlock_t exported_lock;
|
|
422 |
extern struct exportinfo *exptable[];
|
|
423 |
|
|
424 |
/*
|
|
425 |
* Two macros for identifying public filehandles.
|
|
426 |
* A v2 public filehandle is 32 zero bytes.
|
|
427 |
* A v3 public filehandle is zero length.
|
|
428 |
*/
|
|
429 |
#define PUBLIC_FH2(fh) \
|
|
430 |
((fh)->fh_fsid.val[1] == 0 && \
|
|
431 |
bcmp((fh), &nullfh2, sizeof (fhandle_t)) == 0)
|
|
432 |
|
|
433 |
#define PUBLIC_FH3(fh) \
|
|
434 |
((fh)->fh3_length == 0)
|
|
435 |
|
|
436 |
extern int makefh4(nfs_fh4 *, struct vnode *, struct exportinfo *);
|
|
437 |
extern vnode_t *nfs4_fhtovp(nfs_fh4 *, struct exportinfo *, nfsstat4 *);
|
|
438 |
|
|
439 |
#endif /* _KERNEL */
|
|
440 |
|
|
441 |
#ifdef __cplusplus
|
|
442 |
}
|
|
443 |
#endif
|
|
444 |
|
|
445 |
#endif /* _NFS_EXPORT_H */
|