1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1986, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#ifndef _NFS_NFS_CLNT_H
#define _NFS_NFS_CLNT_H
#include <sys/utsname.h>
#include <sys/kstat.h>
#include <sys/time.h>
#include <vm/page.h>
#include <sys/thread.h>
#include <nfs/rnode.h>
#include <sys/list.h>
#include <sys/condvar_impl.h>
#include <sys/zone.h>
#ifdef __cplusplus
extern "C" {
#endif
#define HOSTNAMESZ 32
#define ACREGMIN 3 /* min secs to hold cached file attr */
#define ACREGMAX 60 /* max secs to hold cached file attr */
#define ACDIRMIN 30 /* min secs to hold cached dir attr */
#define ACDIRMAX 60 /* max secs to hold cached dir attr */
#define ACMINMAX 3600 /* 1 hr is longest min timeout */
#define ACMAXMAX 36000 /* 10 hr is longest max timeout */
#define NFS_CALLTYPES 3 /* Lookups, Reads, Writes */
/*
* rfscall() flags
*/
#define RFSCALL_SOFT 0x00000001 /* Do op as if fs was soft-mounted */
/*
* Fake errno passed back from rfscall to indicate transfer size adjustment
*/
#define ENFS_TRYAGAIN 999
/*
* The NFS specific async_reqs structure. iotype is grouped to support two
* types of async thread pools, please read comments section of mntinfo_t
* definition for more information. Care should be taken while adding new
* members to this group.
*/
enum iotype {
NFS_PUTAPAGE,
NFS_PAGEIO,
NFS_COMMIT,
NFS_READ_AHEAD,
NFS_READDIR,
NFS_INACTIVE,
NFS_ASYNC_TYPES
};
#define NFS_ASYNC_PGOPS_TYPES (NFS_COMMIT + 1)
/*
* NFS async requests queue type.
*/
enum ioqtype {
NFS_ASYNC_QUEUE,
NFS_ASYNC_PGOPS_QUEUE,
NFS_MAX_ASYNC_QUEUES
};
/*
* Number of NFS async threads operating exclusively on page op requests.
*/
#define NUM_ASYNC_PGOPS_THREADS 0x2
struct nfs_async_read_req {
void (*readahead)(); /* pointer to readahead function */
u_offset_t blkoff; /* offset in file */
struct seg *seg; /* segment to do i/o to */
caddr_t addr; /* address to do i/o to */
};
struct nfs_pageio_req {
int (*pageio)(); /* pointer to pageio function */
page_t *pp; /* page list */
u_offset_t io_off; /* offset in file */
uint_t io_len; /* size of request */
int flags;
};
struct nfs_readdir_req {
int (*readdir)(); /* pointer to readdir function */
struct rddir_cache *rdc; /* pointer to cache entry to fill */
};
struct nfs_commit_req {
void (*commit)(); /* pointer to commit function */
page_t *plist; /* page list */
offset3 offset; /* starting offset */
count3 count; /* size of range to be commited */
};
struct nfs_inactive_req {
void (*inactive)(); /* pointer to inactive function */
};
struct nfs_async_reqs {
struct nfs_async_reqs *a_next; /* pointer to next arg struct */
#ifdef DEBUG
kthread_t *a_queuer; /* thread id of queueing thread */
#endif
struct vnode *a_vp; /* vnode pointer */
struct cred *a_cred; /* cred pointer */
enum iotype a_io; /* i/o type */
union {
struct nfs_async_read_req a_read_args;
struct nfs_pageio_req a_pageio_args;
struct nfs_readdir_req a_readdir_args;
struct nfs_commit_req a_commit_args;
struct nfs_inactive_req a_inactive_args;
} a_args;
};
#define a_nfs_readahead a_args.a_read_args.readahead
#define a_nfs_blkoff a_args.a_read_args.blkoff
#define a_nfs_seg a_args.a_read_args.seg
#define a_nfs_addr a_args.a_read_args.addr
#define a_nfs_putapage a_args.a_pageio_args.pageio
#define a_nfs_pageio a_args.a_pageio_args.pageio
#define a_nfs_pp a_args.a_pageio_args.pp
#define a_nfs_off a_args.a_pageio_args.io_off
#define a_nfs_len a_args.a_pageio_args.io_len
#define a_nfs_flags a_args.a_pageio_args.flags
#define a_nfs_readdir a_args.a_readdir_args.readdir
#define a_nfs_rdc a_args.a_readdir_args.rdc
#define a_nfs_commit a_args.a_commit_args.commit
#define a_nfs_plist a_args.a_commit_args.plist
#define a_nfs_offset a_args.a_commit_args.offset
#define a_nfs_count a_args.a_commit_args.count
#define a_nfs_inactive a_args.a_inactive_args.inactive
/*
* Due to the way the address space callbacks are used to execute a delmap,
* we must keep track of how many times the same thread has called
* VOP_DELMAP()->nfs_delmap()/nfs3_delmap(). This is done by having a list of
* nfs_delmapcall_t's associated with each rnode_t. This list is protected
* by the rnode_t's r_statelock. The individual elements do not need to be
* protected as they will only ever be created, modified and destroyed by
* one thread (the call_id).
* See nfs_delmap()/nfs3_delmap() for further explanation.
*/
typedef struct nfs_delmapcall {
kthread_t *call_id;
int error; /* error from delmap */
list_node_t call_node;
} nfs_delmapcall_t;
/*
* delmap address space callback args
*/
typedef struct nfs_delmap_args {
vnode_t *vp;
offset_t off;
caddr_t addr;
size_t len;
uint_t prot;
uint_t maxprot;
uint_t flags;
cred_t *cr;
nfs_delmapcall_t *caller; /* to retrieve errors from the cb */
} nfs_delmap_args_t;
#ifdef _KERNEL
extern nfs_delmapcall_t *nfs_init_delmapcall(void);
extern void nfs_free_delmapcall(nfs_delmapcall_t *);
extern int nfs_find_and_delete_delmapcall(rnode_t *, int *errp);
#endif /* _KERNEL */
/*
* The following structures, chhead and chtab, make up the client handle
* cache. chhead represents a quadruple(RPC program, RPC version, Protocol
* Family, and Transport). For example, a chhead entry could represent
* NFS/V3/IPv4/TCP requests. chhead nodes are linked together as a singly
* linked list and is referenced from chtable.
*
* chtab represents an allocated client handle bound to a particular
* quadruple. These nodes chain down from a chhead node. chtab
* entries which are on the chain are considered free, so a thread may simply
* unlink the first node without traversing the chain. When the thread is
* completed with its request, it puts the chtab node back on the chain.
*/
typedef struct chhead {
struct chhead *ch_next; /* next quadruple */
struct chtab *ch_list; /* pointer to free client handle(s) */
uint64_t ch_timesused; /* times this quadruple was requested */
rpcprog_t ch_prog; /* RPC program number */
rpcvers_t ch_vers; /* RPC version number */
dev_t ch_dev; /* pseudo device number (i.e. /dev/udp) */
char *ch_protofmly; /* protocol (i.e. NC_INET, NC_LOOPBACK) */
} chhead_t;
typedef struct chtab {
struct chtab *ch_list; /* next free client handle */
struct chhead *ch_head; /* associated quadruple */
time_t ch_freed; /* timestamp when freed */
CLIENT *ch_client; /* pointer to client handle */
} chtab_t;
/*
* clinfo is a structure which encapsulates data that is needed to
* obtain a client handle from the cache
*/
typedef struct clinfo {
rpcprog_t cl_prog; /* RPC program number */
rpcvers_t cl_vers; /* RPC version number */
uint_t cl_readsize; /* transfer size */
int cl_retrans; /* times to retry request */
uint_t cl_flags; /* info flags */
} clinfo_t;
/*
* Failover information, passed opaquely through rfscall()
*/
typedef struct failinfo {
struct vnode *vp;
caddr_t fhp;
void (*copyproc)(caddr_t, vnode_t *);
int (*lookupproc)(vnode_t *, char *, vnode_t **, struct pathname *,
int, vnode_t *, struct cred *, int);
int (*xattrdirproc)(vnode_t *, vnode_t **, bool_t, cred_t *, int);
} failinfo_t;
/*
* Static server information
*
* These fields are protected by sv_lock:
* sv_flags
*/
typedef struct servinfo {
struct knetconfig *sv_knconf; /* bound TLI fd */
struct knetconfig *sv_origknconf; /* For RDMA save orig knconf */
struct netbuf sv_addr; /* server's address */
nfs_fhandle sv_fhandle; /* this server's filehandle */
struct sec_data *sv_secdata; /* security data for rpcsec module */
char *sv_hostname; /* server's hostname */
int sv_hostnamelen; /* server's hostname length */
uint_t sv_flags; /* see below */
struct servinfo *sv_next; /* next in list */
kmutex_t sv_lock;
} servinfo_t;
/*
* The values for sv_flags.
*/
#define SV_ROOT_STALE 0x1 /* root vnode got ESTALE */
/*
* Switch from RDMA knconf to original mount knconf
*/
#define ORIG_KNCONF(mi) (mi->mi_curr_serv->sv_origknconf ? \
mi->mi_curr_serv->sv_origknconf : mi->mi_curr_serv->sv_knconf)
#if defined(_KERNEL)
/*
* NFS private data per mounted file system
* The mi_lock mutex protects the following fields:
* mi_flags
* mi_printed
* mi_down
* mi_tsize
* mi_stsize
* mi_curread
* mi_curwrite
* mi_timers
* mi_curr_serv
* mi_readers
* mi_klmconfig
*
* The mi_async_lock mutex protects the following fields:
* mi_async_reqs
* mi_async_req_count
* mi_async_tail
* mi_async_curr[NFS_MAX_ASYNC_QUEUES]
* mi_async_clusters
* mi_async_init_clusters
* mi_threads[NFS_MAX_ASYNC_QUEUES]
* mi_manager_thread
*
* Normally the netconfig information for the mount comes from
* mi_curr_serv and mi_klmconfig is NULL. If NLM calls need to use a
* different transport, mi_klmconfig contains the necessary netconfig
* information.
*
* 'mi_zone' is initialized at structure creation time, and never
* changes; it may be read without a lock.
*
* mi_zone_node is linkage into the mi4_globals.mig_list, and is
* protected by mi4_globals.mig_list_lock.
*
* Locking order:
* mi_globals::mig_lock > mi_async_lock > mi_lock
*/
typedef struct mntinfo {
kmutex_t mi_lock; /* protects mntinfo fields */
struct servinfo *mi_servers; /* server list */
struct servinfo *mi_curr_serv; /* current server */
kcondvar_t mi_failover_cv; /* failover synchronization */
int mi_readers; /* failover - users of mi_curr_serv */
struct vfs *mi_vfsp; /* back pointer to vfs */
enum vtype mi_type; /* file type of the root vnode */
uint_t mi_flags; /* see below */
uint_t mi_tsize; /* max read transfer size (bytes) */
uint_t mi_stsize; /* max write transfer size (bytes) */
int mi_timeo; /* inital timeout in 10th sec */
int mi_retrans; /* times to retry request */
hrtime_t mi_acregmin; /* min time to hold cached file attr */
hrtime_t mi_acregmax; /* max time to hold cached file attr */
hrtime_t mi_acdirmin; /* min time to hold cached dir attr */
hrtime_t mi_acdirmax; /* max time to hold cached dir attr */
len_t mi_maxfilesize; /* for pathconf _PC_FILESIZEBITS */
/*
* Extra fields for congestion control, one per NFS call type,
* plus one global one.
*/
struct rpc_timers mi_timers[NFS_CALLTYPES+1];
int mi_curread; /* current read size */
int mi_curwrite; /* current write size */
/*
* Async I/O management
* We have 2 pools of threads working on async I/O:
* (i) Threads which work on all async queues. Default number of
* threads in this queue is 8. Threads in this pool work on async
* queue pointed by mi_async_curr[NFS_ASYNC_QUEUE]. Number of
* active threads in this pool is tracked by
* mi_threads[NFS_ASYNC_QUEUE].
* (ii)Threads which work only on page op async queues.
* Page ops queue comprises of NFS_PUTAPAGE, NFS_PAGEIO &
* NFS_COMMIT. Default number of threads in this queue is 2
* (NUM_ASYNC_PGOPS_THREADS). Threads in this pool work on async
* queue pointed by mi_async_curr[NFS_ASYNC_PGOPS_QUEUE]. Number
* of active threads in this pool is tracked by
* mi_threads[NFS_ASYNC_PGOPS_QUEUE].
*/
struct nfs_async_reqs *mi_async_reqs[NFS_ASYNC_TYPES];
struct nfs_async_reqs *mi_async_tail[NFS_ASYNC_TYPES];
struct nfs_async_reqs **mi_async_curr[NFS_MAX_ASYNC_QUEUES];
/* current async queue */
uint_t mi_async_clusters[NFS_ASYNC_TYPES];
uint_t mi_async_init_clusters;
uint_t mi_async_req_count; /* # outstanding work requests */
kcondvar_t mi_async_reqs_cv; /* signaled when there's work */
ushort_t mi_threads[NFS_MAX_ASYNC_QUEUES];
/* number of active async threads */
ushort_t mi_max_threads; /* max number of async worker threads */
kthread_t *mi_manager_thread; /* async manager thread */
kcondvar_t mi_async_cv; /* signaled when the last worker dies */
kcondvar_t mi_async_work_cv[NFS_MAX_ASYNC_QUEUES];
/* tell workers to work */
kmutex_t mi_async_lock; /* lock to protect async list */
/*
* Other stuff
*/
struct pathcnf *mi_pathconf; /* static pathconf kludge */
rpcprog_t mi_prog; /* RPC program number */
rpcvers_t mi_vers; /* RPC program version number */
char **mi_rfsnames; /* mapping to proc names */
kstat_named_t *mi_reqs; /* count of requests */
uchar_t *mi_call_type; /* dynamic retrans call types */
uchar_t *mi_ss_call_type; /* semisoft call type */
uchar_t *mi_timer_type; /* dynamic retrans timer types */
clock_t mi_printftime; /* last error printf time */
/*
* ACL entries
*/
char **mi_aclnames; /* mapping to proc names */
kstat_named_t *mi_aclreqs; /* count of acl requests */
uchar_t *mi_acl_call_type; /* dynamic retrans call types */
uchar_t *mi_acl_ss_call_type; /* semisoft call types */
uchar_t *mi_acl_timer_type; /* dynamic retrans timer types */
/*
* Client Side Failover stats
*/
uint_t mi_noresponse; /* server not responding count */
uint_t mi_failover; /* failover to new server count */
uint_t mi_remap; /* remap to new server count */
/*
* Kstat statistics
*/
struct kstat *mi_io_kstats;
struct kstat *mi_ro_kstats;
struct knetconfig *mi_klmconfig;
/*
* Zones support.
*/
struct zone *mi_zone; /* Zone in which FS is mounted */
zone_ref_t mi_zone_ref; /* Reference to aforementioned zone */
list_node_t mi_zone_node; /* Linkage into per-zone mi list */
/*
* Serializes threads in failover_remap.
* Need to acquire this lock first in failover_remap() function
* before acquiring any other rnode lock.
*/
kmutex_t mi_remap_lock;
/*
* List of rnode_t structures that belongs to this mntinfo
*/
kmutex_t mi_rnodes_lock; /* protects the mi_rnodes list */
list_t mi_rnodes; /* the list */
} mntinfo_t;
#endif /* _KERNEL */
/*
* vfs pointer to mount info
*/
#define VFTOMI(vfsp) ((mntinfo_t *)((vfsp)->vfs_data))
/*
* vnode pointer to mount info
*/
#define VTOMI(vp) ((mntinfo_t *)(((vp)->v_vfsp)->vfs_data))
/*
* The values for mi_flags.
*/
#define MI_HARD 0x1 /* hard or soft mount */
#define MI_PRINTED 0x2 /* not responding message printed */
#define MI_INT 0x4 /* interrupts allowed on hard mount */
#define MI_DOWN 0x8 /* server is down */
#define MI_NOAC 0x10 /* don't cache attributes */
#define MI_NOCTO 0x20 /* no close-to-open consistency */
#define MI_DYNAMIC 0x40 /* dynamic transfer size adjustment */
#define MI_LLOCK 0x80 /* local locking only (no lockmgr) */
#define MI_GRPID 0x100 /* System V group id inheritance */
#define MI_RPCTIMESYNC 0x200 /* RPC time sync */
#define MI_LINK 0x400 /* server supports link */
#define MI_SYMLINK 0x800 /* server supports symlink */
#define MI_READDIRONLY 0x1000 /* use readdir instead of readdirplus */
#define MI_ACL 0x2000 /* server supports NFS_ACL */
#define MI_BINDINPROG 0x4000 /* binding to server is changing */
#define MI_LOOPBACK 0x8000 /* Set if this is a loopback mount */
#define MI_SEMISOFT 0x10000 /* soft reads, hard modify */
#define MI_NOPRINT 0x20000 /* don't print messages */
#define MI_DIRECTIO 0x40000 /* do direct I/O */
#define MI_EXTATTR 0x80000 /* server supports extended attrs */
#define MI_ASYNC_MGR_STOP 0x100000 /* tell async mgr to die */
#define MI_DEAD 0x200000 /* mount has been terminated */
/*
* Read-only mntinfo statistics
*/
struct mntinfo_kstat {
char mik_proto[KNC_STRSIZE];
uint32_t mik_vers;
uint_t mik_flags;
uint_t mik_secmod;
uint32_t mik_curread;
uint32_t mik_curwrite;
int mik_timeo;
int mik_retrans;
uint_t mik_acregmin;
uint_t mik_acregmax;
uint_t mik_acdirmin;
uint_t mik_acdirmax;
struct {
uint32_t srtt;
uint32_t deviate;
uint32_t rtxcur;
} mik_timers[NFS_CALLTYPES+1];
uint32_t mik_noresponse;
uint32_t mik_failover;
uint32_t mik_remap;
char mik_curserver[SYS_NMLN];
};
/*
* Macro to wakeup sleeping async worker threads.
*/
#define NFS_WAKE_ASYNC_WORKER(work_cv) { \
if (CV_HAS_WAITERS(&work_cv[NFS_ASYNC_QUEUE])) \
cv_signal(&work_cv[NFS_ASYNC_QUEUE]); \
else if (CV_HAS_WAITERS(&work_cv[NFS_ASYNC_PGOPS_QUEUE])) \
cv_signal(&work_cv[NFS_ASYNC_PGOPS_QUEUE]); \
}
#define NFS_WAKEALL_ASYNC_WORKERS(work_cv) { \
cv_broadcast(&work_cv[NFS_ASYNC_QUEUE]); \
cv_broadcast(&work_cv[NFS_ASYNC_PGOPS_QUEUE]); \
}
/*
* Mark cached attributes as timed out
*
* The caller must not be holding the rnode r_statelock mutex.
*/
#define PURGE_ATTRCACHE(vp) { \
rnode_t *rp = VTOR(vp); \
mutex_enter(&rp->r_statelock); \
PURGE_ATTRCACHE_LOCKED(rp); \
mutex_exit(&rp->r_statelock); \
}
#define PURGE_ATTRCACHE_LOCKED(rp) { \
ASSERT(MUTEX_HELD(&rp->r_statelock)); \
rp->r_attrtime = gethrtime(); \
rp->r_mtime = rp->r_attrtime; \
}
/*
* Is the attribute cache valid?
*/
#define ATTRCACHE_VALID(vp) (gethrtime() < VTOR(vp)->r_attrtime)
/*
* Flags to indicate whether to purge the DNLC for non-directory vnodes
* in a call to nfs_purge_caches.
*/
#define NFS_NOPURGE_DNLC 0
#define NFS_PURGE_DNLC 1
/*
* If returned error is ESTALE flush all caches.
*/
#define PURGE_STALE_FH(error, vp, cr) \
if ((error) == ESTALE) { \
struct rnode *rp = VTOR(vp); \
if (vp->v_flag & VROOT) { \
servinfo_t *svp = rp->r_server; \
mutex_enter(&svp->sv_lock); \
svp->sv_flags |= SV_ROOT_STALE; \
mutex_exit(&svp->sv_lock); \
} \
mutex_enter(&rp->r_statelock); \
rp->r_flags |= RSTALE; \
if (!rp->r_error) \
rp->r_error = (error); \
mutex_exit(&rp->r_statelock); \
if (vn_has_cached_data(vp)) \
nfs_invalidate_pages((vp), (u_offset_t)0, (cr)); \
nfs_purge_caches((vp), NFS_PURGE_DNLC, (cr)); \
}
/*
* Is cache valid?
* Swap is always valid, if no attributes (attrtime == 0) or
* if mtime matches cached mtime it is valid
* NOTE: mtime is now a timestruc_t.
* Caller should be holding the rnode r_statelock mutex.
*/
#define CACHE_VALID(rp, mtime, fsize) \
((RTOV(rp)->v_flag & VISSWAP) == VISSWAP || \
(((mtime).tv_sec == (rp)->r_attr.va_mtime.tv_sec && \
(mtime).tv_nsec == (rp)->r_attr.va_mtime.tv_nsec) && \
((fsize) == (rp)->r_attr.va_size)))
/*
* Macro to detect forced unmount or a zone shutdown.
*/
#define FS_OR_ZONE_GONE(vfsp) \
(((vfsp)->vfs_flag & VFS_UNMOUNTED) || \
zone_status_get(curproc->p_zone) >= ZONE_IS_SHUTTING_DOWN)
/*
* Convert NFS tunables to hrtime_t units, seconds to nanoseconds.
*/
#define SEC2HR(sec) ((sec) * (long long)NANOSEC)
#define HR2SEC(hr) ((hr) / (long long)NANOSEC)
/*
* Structure to identify owner of a PC file share reservation.
*/
struct nfs_owner {
int magic; /* magic uniquifying number */
char hname[16]; /* first 16 bytes of hostname */
char lowner[8]; /* local owner from fcntl */
};
/*
* Values for magic.
*/
#define NFS_OWNER_MAGIC 0x1D81E
/*
* Support for extended attributes
*/
#define XATTR_DIR_NAME "/@/" /* used for DNLC entries */
#define XATTR_RPATH "ExTaTtR" /* used for r_path for failover */
/*
* Short hand for checking to see whether the file system was mounted
* interruptible or not.
*/
#define INTR(vp) (VTOMI(vp)->mi_flags & MI_INT)
/*
* Short hand for checking whether failover is enabled or not
*/
#define FAILOVER_MOUNT(mi) (mi->mi_servers->sv_next)
/*
* How long will async threads wait for additional work.
*/
#define NFS_ASYNC_TIMEOUT (60 * 1 * hz) /* 1 minute */
#ifdef _KERNEL
extern int clget(clinfo_t *, servinfo_t *, cred_t *, CLIENT **,
struct chtab **);
extern void clfree(CLIENT *, struct chtab *);
extern void nfs_mi_zonelist_add(mntinfo_t *);
extern void nfs_free_mi(mntinfo_t *);
extern void nfs_mnt_kstat_init(struct vfs *);
#endif
/*
* Per-zone data for managing client handles. Included here solely for the
* benefit of MDB.
*/
/*
* client side statistics
*/
struct clstat {
kstat_named_t calls; /* client requests */
kstat_named_t badcalls; /* rpc failures */
kstat_named_t clgets; /* client handle gets */
kstat_named_t cltoomany; /* client handle cache misses */
#ifdef DEBUG
kstat_named_t clalloc; /* number of client handles */
kstat_named_t noresponse; /* server not responding cnt */
kstat_named_t failover; /* server failover count */
kstat_named_t remap; /* server remap count */
#endif
};
struct nfs_clnt {
struct chhead *nfscl_chtable;
kmutex_t nfscl_chtable_lock;
zoneid_t nfscl_zoneid;
list_node_t nfscl_node;
struct clstat nfscl_stat;
};
#ifdef __cplusplus
}
#endif
#endif /* _NFS_NFS_CLNT_H */
|