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 (the "License"). 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 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 29 /* 30 * Portions of this source code were derived from Berkeley 4.3 BSD 31 * under license from the Regents of the University of California. 32 */ 33 34 #ifndef _NFS4_CLNT_H 35 #define _NFS4_CLNT_H 36 37 #include <sys/errno.h> 38 #include <sys/types.h> 39 #include <sys/kstat.h> 40 #include <sys/time.h> 41 #include <sys/flock.h> 42 #include <vm/page.h> 43 #include <nfs/nfs4_kprot.h> 44 #include <nfs/nfs4.h> 45 #include <nfs/rnode.h> 46 #include <sys/avl.h> 47 #include <sys/list.h> 48 #include <rpc/auth.h> 49 #include <sys/taskq.h> 50 51 #ifdef __cplusplus 52 extern "C" { 53 #endif 54 55 #define NFS4_SIZE_OK(size) ((size) <= MAXOFFSET_T) 56 57 /* Client Sequence Heartbeat Flag bits */ 58 #define NFS4_SEQHB_STARTED 1 59 #define NFS4_SEQHB_EXITING 2 60 #define NFS4_SEQHB_EXIT 4 61 #define NFS4_SEQHB_DESTROY_INZONE 8 62 63 /* Four states of nfs4_server's lease_valid */ 64 #define NFS4_LEASE_INVALID 0 65 #define NFS4_LEASE_VALID 1 66 #define NFS4_LEASE_UNINITIALIZED 2 67 #define NFS4_LEASE_NOT_STARTED 3 68 69 /* 70 * rfs4call() flags 71 * NOTE: rfscall() can take RFSCALL_SOFT which is defined as 1 so start at 2 72 */ 73 #define RFS4CALL_SETCB 0x00000002 74 #define RFS4CALL_NOSEQ 0x00000004 /* Don't add sequence op (4.1+ only) */ 75 #define RFS4CALL_FORCE 0x00000008 /* Force OTW, even if unmounted */ 76 #define RFS4CALL_SHOLD 0x00000010 /* hold slot for caller to release */ 77 78 #define NFS4_TAG_SWAP 0x001 79 #define NFS4_TAG_DESTROY 0x002 80 #define NFS4_CBSERVER_CLEANUP 0x004 81 82 /* flag to tell the renew thread it should exit */ 83 #define NFS4_THREAD_EXIT 1 84 85 /* Default number of seconds to wait on GRACE and DELAY errors */ 86 #define NFS4ERR_DELAY_TIME 10 87 88 /* Number of hash buckets for open owners for each nfs4_server */ 89 #define NFS4_NUM_OO_BUCKETS 53 90 91 /* Number of freed open owners (per mntinfo4_t) to keep around */ 92 #define NFS4_NUM_FREED_OPEN_OWNERS 8 93 94 /* Number of seconds to wait before retrying a SETCLIENTID(_CONFIRM) op */ 95 #define NFS4_RETRY_SCLID_DELAY 10 96 97 /* Number of times we should retry a SETCLIENTID(_CONFIRM) op */ 98 #define NFS4_NUM_SCLID_RETRIES 3 99 100 /* Number of times we should retry on open after getting NFS4ERR_BAD_SEQID */ 101 #define NFS4_NUM_RETRY_BAD_SEQID 3 102 103 /* 104 * Is the attribute cache valid? If client holds a delegation, then attrs 105 * are by definition valid. If not, then check to see if attrs have timed out. 106 */ 107 #define ATTRCACHE4_VALID(vp) (VTOR4(vp)->r_deleg_type != OPEN_DELEGATE_NONE || \ 108 gethrtime() < VTOR4(vp)->r_time_attr_inval) 109 110 /* 111 * Flags to indicate whether to purge the DNLC for non-directory vnodes 112 * in a call to nfs_purge_caches. 113 */ 114 #define NFS4_NOPURGE_DNLC 0 115 #define NFS4_PURGE_DNLC 1 116 117 /* 118 * Is cache valid? 119 * Swap is always valid, if no attributes (attrtime == 0) or 120 * if mtime matches cached mtime it is valid 121 * NOTE: mtime is now a timestruc_t. 122 * Caller should be holding the rnode r_statelock mutex. 123 */ 124 #define CACHE4_VALID(rp, mtime, fsize) \ 125 ((RTOV4(rp)->v_flag & VISSWAP) == VISSWAP || \ 126 (((mtime).tv_sec == (rp)->r_attr.va_mtime.tv_sec && \ 127 (mtime).tv_nsec == (rp)->r_attr.va_mtime.tv_nsec) && \ 128 ((fsize) == (rp)->r_attr.va_size))) 129 130 /* 131 * Macro to detect forced unmount or a zone shutdown. 132 */ 133 #define FS_OR_ZONE_GONE4(vfsp) \ 134 (((vfsp)->vfs_flag & VFS_UNMOUNTED) || \ 135 zone_status_get(curproc->p_zone) >= ZONE_IS_SHUTTING_DOWN) 136 137 /* 138 * Macro to help determine whether a request failed because the underlying 139 * filesystem has been forcibly unmounted or because of zone shutdown. 140 */ 141 #define NFS4_FRC_UNMT_ERR(err, vfsp) \ 142 ((err) == EIO && FS_OR_ZONE_GONE4((vfsp))) 143 144 145 /* 146 * Returns TRUE if there are sessions related recoverable errors 147 */ 148 #define NFS4_NEED_SESS_RECOV(np) \ 149 (!(np->s_flags & N4S_SESSION_CREATED) || \ 150 (np->s_flags & N4S_NEED_BC2S)) 151 152 #define NFS41_SERVER(np) (np->s_minorversion == 1) 153 154 /* 155 * Client zone key for global zone list of callback info. 156 */ 157 zone_key_t nfs4clnt_zone_key; 158 159 /* 160 * Due to the way the address space callbacks are used to execute a delmap, 161 * we must keep track of how many times the same thread has called 162 * VOP_DELMAP()->nfs4_delmap(). This is done by having a list of 163 * nfs4_delmapcall_t's associated with each rnode4_t. This list is protected 164 * by the rnode4_t's r_statelock. The individual elements do not need to be 165 * protected as they will only ever be created, modified and destroyed by 166 * one thread (the call_id). 167 * See nfs4_delmap() for further explanation. 168 */ 169 typedef struct nfs4_delmapcall { 170 kthread_t *call_id; 171 int error; /* error from delmap */ 172 list_node_t call_node; 173 } nfs4_delmapcall_t; 174 175 /* 176 * delmap address space callback args 177 */ 178 typedef struct nfs4_delmap_args { 179 vnode_t *vp; 180 offset_t off; 181 caddr_t addr; 182 size_t len; 183 uint_t prot; 184 uint_t maxprot; 185 uint_t flags; 186 cred_t *cr; 187 nfs4_delmapcall_t *caller; /* to retrieve errors from the cb */ 188 } nfs4_delmap_args_t; 189 190 /* 191 * client side statistics 192 */ 193 /* 194 * Per-zone counters 195 */ 196 struct clstat4 { 197 kstat_named_t calls; /* client requests */ 198 kstat_named_t badcalls; /* rpc failures */ 199 kstat_named_t clgets; /* client handle gets */ 200 kstat_named_t cltoomany; /* client handle cache misses */ 201 }; 202 203 #ifdef DEBUG 204 /* 205 * The following are statistics that describe the behavior of the system as a 206 * whole and don't correspond to any particular zone. 207 */ 208 struct clstat4_debug { 209 kstat_named_t clalloc; /* number of client handles */ 210 kstat_named_t noresponse; /* server not responding cnt */ 211 kstat_named_t failover; /* server failover count */ 212 kstat_named_t remap; /* server remap count */ 213 kstat_named_t nrnode; /* number of allocated rnodes */ 214 kstat_named_t access; /* size of access cache */ 215 kstat_named_t dirent; /* size of readdir cache */ 216 kstat_named_t dirents; /* size of readdir buf cache */ 217 kstat_named_t reclaim; /* number of reclaims */ 218 kstat_named_t clreclaim; /* number of cl reclaims */ 219 kstat_named_t f_reclaim; /* number of free reclaims */ 220 kstat_named_t a_reclaim; /* number of active reclaims */ 221 kstat_named_t r_reclaim; /* number of rnode reclaims */ 222 kstat_named_t rpath; /* bytes used to store rpaths */ 223 }; 224 extern struct clstat4_debug clstat4_debug; 225 226 #endif 227 228 /* 229 * The NFS specific async_reqs structure. 230 */ 231 232 enum iotype4 { 233 NFS4_READ_AHEAD, 234 NFS4_PUTAPAGE, 235 NFS4_PAGEIO, 236 NFS4_READDIR, 237 NFS4_INACTIVE, 238 NFS4_COMMIT 239 }; 240 #define NFS4_ASYNC_TYPES (NFS4_COMMIT + 1) 241 242 struct nfs4_async_read_req { 243 void (*readahead)(); /* pointer to readahead function */ 244 u_offset_t blkoff; /* offset in file */ 245 struct seg *seg; /* segment to do i/o to */ 246 caddr_t addr; /* address to do i/o to */ 247 }; 248 249 struct nfs4_pageio_req { 250 int (*pageio)(); /* pointer to pageio function */ 251 page_t *pp; /* page list */ 252 u_offset_t io_off; /* offset in file */ 253 uint_t io_len; /* size of request */ 254 int flags; 255 }; 256 257 struct nfs4_readdir_req { 258 int (*readdir)(); /* pointer to readdir function */ 259 struct rddir4_cache *rdc; /* pointer to cache entry to fill */ 260 }; 261 262 struct nfs4_commit_req { 263 void (*commit)(); /* pointer to commit function */ 264 page_t *plist; /* page list */ 265 offset4 offset; /* starting offset */ 266 count4 count; /* size of range to be commited */ 267 }; 268 269 struct nfs4_async_reqs { 270 struct nfs4_async_reqs *a_next; /* pointer to next arg struct */ 271 #ifdef DEBUG 272 kthread_t *a_queuer; /* thread id of queueing thread */ 273 #endif 274 struct vnode *a_vp; /* vnode pointer */ 275 struct cred *a_cred; /* cred pointer */ 276 enum iotype4 a_io; /* i/o type */ 277 union { 278 struct nfs4_async_read_req a_read_args; 279 struct nfs4_pageio_req a_pageio_args; 280 struct nfs4_readdir_req a_readdir_args; 281 struct nfs4_commit_req a_commit_args; 282 } a_args; 283 }; 284 285 #define a_nfs4_readahead a_args.a_read_args.readahead 286 #define a_nfs4_blkoff a_args.a_read_args.blkoff 287 #define a_nfs4_seg a_args.a_read_args.seg 288 #define a_nfs4_addr a_args.a_read_args.addr 289 290 #define a_nfs4_putapage a_args.a_pageio_args.pageio 291 #define a_nfs4_pageio a_args.a_pageio_args.pageio 292 #define a_nfs4_pp a_args.a_pageio_args.pp 293 #define a_nfs4_off a_args.a_pageio_args.io_off 294 #define a_nfs4_len a_args.a_pageio_args.io_len 295 #define a_nfs4_flags a_args.a_pageio_args.flags 296 297 #define a_nfs4_readdir a_args.a_readdir_args.readdir 298 #define a_nfs4_rdc a_args.a_readdir_args.rdc 299 300 #define a_nfs4_commit a_args.a_commit_args.commit 301 #define a_nfs4_plist a_args.a_commit_args.plist 302 #define a_nfs4_offset a_args.a_commit_args.offset 303 #define a_nfs4_count a_args.a_commit_args.count 304 305 /* 306 * Security information 307 */ 308 typedef struct sv_secinfo { 309 uint_t count; /* how many sdata there are */ 310 uint_t index; /* which sdata[index] */ 311 struct sec_data *sdata; 312 } sv_secinfo_t; 313 314 /* 315 * Hash bucket for the mi's open owner list (mi_oo_list). 316 */ 317 typedef struct nfs4_oo_hash_bucket { 318 list_t b_oo_hash_list; 319 kmutex_t b_lock; 320 } nfs4_oo_hash_bucket_t; 321 322 /* 323 * Global array of ctags. 324 */ 325 extern ctag_t nfs4_ctags[]; 326 327 typedef enum nfs4_tag_type { 328 TAG_NONE, 329 TAG_ACCESS, 330 TAG_CLOSE, 331 TAG_CLOSE_LOST, 332 TAG_CLOSE_UNDO, 333 TAG_COMMIT, 334 TAG_DELEGRETURN, 335 TAG_FSINFO, 336 TAG_GET_SYMLINK, 337 TAG_GETATTR, 338 TAG_INACTIVE, 339 TAG_LINK, 340 TAG_LOCK, 341 TAG_LOCK_RECLAIM, 342 TAG_LOCK_RESEND, 343 TAG_LOCK_REINSTATE, 344 TAG_LOCK_UNKNOWN, 345 TAG_LOCKT, 346 TAG_LOCKU, 347 TAG_LOCKU_RESEND, 348 TAG_LOCKU_REINSTATE, 349 TAG_LOOKUP, 350 TAG_LOOKUP_PARENT, 351 TAG_LOOKUP_VALID, 352 TAG_LOOKUP_VPARENT, 353 TAG_MKDIR, 354 TAG_MKNOD, 355 TAG_MOUNT, 356 TAG_OPEN, 357 TAG_OPEN_CONFIRM, 358 TAG_OPEN_CONFIRM_LOST, 359 TAG_OPEN_DG, 360 TAG_OPEN_DG_LOST, 361 TAG_OPEN_LOST, 362 TAG_OPENATTR, 363 TAG_PATHCONF, 364 TAG_PUTROOTFH, 365 TAG_READ, 366 TAG_READAHEAD, 367 TAG_READDIR, 368 TAG_READLINK, 369 TAG_RELOCK, 370 TAG_REMAP_LOOKUP, 371 TAG_REMAP_LOOKUP_AD, 372 TAG_REMAP_LOOKUP_NA, 373 TAG_REMAP_MOUNT, 374 TAG_RMDIR, 375 TAG_REMOVE, 376 TAG_RENAME, 377 TAG_RENAME_VFH, 378 TAG_RENEW, 379 TAG_REOPEN, 380 TAG_REOPEN_LOST, 381 TAG_SECINFO, 382 TAG_SETATTR, 383 TAG_SETCLIENTID, 384 TAG_SETCLIENTID_CF, 385 TAG_SYMLINK, 386 TAG_WRITE, 387 TAG_EXCHANGE_ID, /* XXX - rick */ 388 TAG_CREATE_SESSION, 389 TAG_BIND_CONN_TO_SESSION, 390 TAG_PNFS_READ, 391 TAG_PNFS_WRITE, 392 TAG_PNFS_COMMIT, 393 TAG_PNFS_LAYOUTGET, 394 TAG_PNFS_LAYOUTRETURN, 395 TAG_PNFS_GETDEVLIST, 396 TAG_SEQUENCE, 397 TAG_DESTROY_SESSION, 398 TAG_PNFS_GETDEVINFO, 399 TAG_RECLAIM_COMPLETE, 400 TAG_LAYOUTCOMMIT 401 } nfs4_tag_type_t; 402 403 #define NFS4_TAG_INITIALIZER { \ 404 {TAG_NONE, "", \ 405 {0x20202020, 0x20202020, 0x20202020}}, \ 406 {TAG_ACCESS, "access", \ 407 {0x61636365, 0x73732020, 0x20202020}}, \ 408 {TAG_CLOSE, "close", \ 409 {0x636c6f73, 0x65202020, 0x20202020}}, \ 410 {TAG_CLOSE_LOST, "lost close", \ 411 {0x6c6f7374, 0x20636c6f, 0x73652020}}, \ 412 {TAG_CLOSE_UNDO, "undo close", \ 413 {0x756e646f, 0x20636c6f, 0x73652020}}, \ 414 {TAG_COMMIT, "commit", \ 415 {0x636f6d6d, 0x69742020, 0x20202020}}, \ 416 {TAG_DELEGRETURN, "delegreturn", \ 417 {0x64656c65, 0x67726574, 0x75726e20}}, \ 418 {TAG_FSINFO, "fsinfo", \ 419 {0x6673696e, 0x666f2020, 0x20202020}}, \ 420 {TAG_GET_SYMLINK, "get symlink text", \ 421 {0x67657420, 0x736c6e6b, 0x20747874}}, \ 422 {TAG_GETATTR, "getattr", \ 423 {0x67657461, 0x74747220, 0x20202020}}, \ 424 {TAG_INACTIVE, "inactive", \ 425 {0x696e6163, 0x74697665, 0x20202020}}, \ 426 {TAG_LINK, "link", \ 427 {0x6c696e6b, 0x20202020, 0x20202020}}, \ 428 {TAG_LOCK, "lock", \ 429 {0x6c6f636b, 0x20202020, 0x20202020}}, \ 430 {TAG_LOCK_RECLAIM, "reclaim lock", \ 431 {0x7265636c, 0x61696d20, 0x6c6f636b}}, \ 432 {TAG_LOCK_RESEND, "resend lock", \ 433 {0x72657365, 0x6e64206c, 0x6f636b20}}, \ 434 {TAG_LOCK_REINSTATE, "reinstate lock", \ 435 {0x7265696e, 0x7374206c, 0x6f636b20}}, \ 436 {TAG_LOCK_UNKNOWN, "unknown lock", \ 437 {0x756e6b6e, 0x6f776e20, 0x6c6f636b}}, \ 438 {TAG_LOCKT, "lock test", \ 439 {0x6c6f636b, 0x5f746573, 0x74202020}}, \ 440 {TAG_LOCKU, "unlock", \ 441 {0x756e6c6f, 0x636b2020, 0x20202020}}, \ 442 {TAG_LOCKU_RESEND, "resend locku", \ 443 {0x72657365, 0x6e64206c, 0x6f636b75}}, \ 444 {TAG_LOCKU_REINSTATE, "reinstate unlock", \ 445 {0x7265696e, 0x73742075, 0x6e6c636b}}, \ 446 {TAG_LOOKUP, "lookup", \ 447 {0x6c6f6f6b, 0x75702020, 0x20202020}}, \ 448 {TAG_LOOKUP_PARENT, "lookup parent", \ 449 {0x6c6f6f6b, 0x75702070, 0x6172656e}}, \ 450 {TAG_LOOKUP_VALID, "lookup valid", \ 451 {0x6c6f6f6b, 0x75702076, 0x616c6964}}, \ 452 {TAG_LOOKUP_VPARENT, "lookup valid parent", \ 453 {0x6c6f6f6b, 0x766c6420, 0x7061726e}}, \ 454 {TAG_MKDIR, "mkdir", \ 455 {0x6d6b6469, 0x72202020, 0x20202020}}, \ 456 {TAG_MKNOD, "mknod", \ 457 {0x6d6b6e6f, 0x64202020, 0x20202020}}, \ 458 {TAG_MOUNT, "mount", \ 459 {0x6d6f756e, 0x74202020, 0x20202020}}, \ 460 {TAG_OPEN, "open", \ 461 {0x6f70656e, 0x20202020, 0x20202020}}, \ 462 {TAG_OPEN_CONFIRM, "open confirm", \ 463 {0x6f70656e, 0x5f636f6e, 0x6669726d}}, \ 464 {TAG_OPEN_CONFIRM_LOST, "lost open confirm", \ 465 {0x6c6f7374, 0x206f7065, 0x6e5f636f}}, \ 466 {TAG_OPEN_DG, "open downgrade", \ 467 {0x6f70656e, 0x20646772, 0x61646520}}, \ 468 {TAG_OPEN_DG_LOST, "lost open downgrade", \ 469 {0x6c737420, 0x6f70656e, 0x20646772}}, \ 470 {TAG_OPEN_LOST, "lost open", \ 471 {0x6c6f7374, 0x206f7065, 0x6e202020}}, \ 472 {TAG_OPENATTR, "openattr", \ 473 {0x6f70656e, 0x61747472, 0x20202020}}, \ 474 {TAG_PATHCONF, "pathhconf", \ 475 {0x70617468, 0x636f6e66, 0x20202020}}, \ 476 {TAG_PUTROOTFH, "putrootfh", \ 477 {0x70757472, 0x6f6f7466, 0x68202020}}, \ 478 {TAG_READ, "read", \ 479 {0x72656164, 0x20202020, 0x20202020}}, \ 480 {TAG_READAHEAD, "readahead", \ 481 {0x72656164, 0x61686561, 0x64202020}}, \ 482 {TAG_READDIR, "readdir", \ 483 {0x72656164, 0x64697220, 0x20202020}}, \ 484 {TAG_READLINK, "readlink", \ 485 {0x72656164, 0x6c696e6b, 0x20202020}}, \ 486 {TAG_RELOCK, "relock", \ 487 {0x72656c6f, 0x636b2020, 0x20202020}}, \ 488 {TAG_REMAP_LOOKUP, "remap lookup", \ 489 {0x72656d61, 0x70206c6f, 0x6f6b7570}}, \ 490 {TAG_REMAP_LOOKUP_AD, "remap lookup attr dir", \ 491 {0x72656d70, 0x206c6b75, 0x70206164}}, \ 492 {TAG_REMAP_LOOKUP_NA, "remap lookup named attrs", \ 493 {0x72656d70, 0x206c6b75, 0x70206e61}}, \ 494 {TAG_REMAP_MOUNT, "remap mount", \ 495 {0x72656d61, 0x70206d6f, 0x756e7420}}, \ 496 {TAG_RMDIR, "rmdir", \ 497 {0x726d6469, 0x72202020, 0x20202020}}, \ 498 {TAG_REMOVE, "remove", \ 499 {0x72656d6f, 0x76652020, 0x20202020}}, \ 500 {TAG_RENAME, "rename", \ 501 {0x72656e61, 0x6d652020, 0x20202020}}, \ 502 {TAG_RENAME_VFH, "rename volatile fh", \ 503 {0x72656e61, 0x6d652028, 0x76666829}}, \ 504 {TAG_RENEW, "renew", \ 505 {0x72656e65, 0x77202020, 0x20202020}}, \ 506 {TAG_REOPEN, "reopen", \ 507 {0x72656f70, 0x656e2020, 0x20202020}}, \ 508 {TAG_REOPEN_LOST, "lost reopen", \ 509 {0x6c6f7374, 0x2072656f, 0x70656e20}}, \ 510 {TAG_SECINFO, "secinfo", \ 511 {0x73656369, 0x6e666f20, 0x20202020}}, \ 512 {TAG_SETATTR, "setattr", \ 513 {0x73657461, 0x74747220, 0x20202020}}, \ 514 {TAG_SETCLIENTID, "setclientid", \ 515 {0x73657463, 0x6c69656e, 0x74696420}}, \ 516 {TAG_SETCLIENTID_CF, "setclientid_confirm", \ 517 {0x73636c6e, 0x7469645f, 0x636f6e66}}, \ 518 {TAG_SYMLINK, "symlink", \ 519 {0x73796d6c, 0x696e6b20, 0x20202020}}, \ 520 {TAG_WRITE, "write", \ 521 {0x77726974, 0x65202020, 0x20202020}}, \ 522 {TAG_EXCHANGE_ID, "exchange_id", \ 523 {0x65786368, 0x616e6765, 0x5f696420}}, \ 524 {TAG_CREATE_SESSION, "create_session", \ 525 {0x63726561, 0x74655f73, 0x65737369}}, \ 526 {TAG_BIND_CONN_TO_SESSION, "bind_conn_to_session", \ 527 {0x62696e64, 0x5f636f6e, 0x6e5f746f}}, \ 528 {TAG_PNFS_READ, "pnfs read", \ 529 {0x706e6673, 0x20726561, 0x64202020}}, \ 530 {TAG_PNFS_WRITE, "pnfs write", \ 531 {0x706e6673, 0x20777269, 0x74652020}}, \ 532 {TAG_PNFS_COMMIT, "pnfs commit", \ 533 {0x706e6673, 0x20636f6d, 0x6d697420}}, \ 534 {TAG_PNFS_LAYOUTGET, "layoutget", \ 535 {0x6c61796f, 0x75746765, 0x74202020}}, \ 536 {TAG_PNFS_LAYOUTRETURN, "layoutreturn", \ 537 {0x6c61796f, 0x75747265, 0x7475726e}}, \ 538 {TAG_PNFS_GETDEVLIST, "pnfs devlist", \ 539 {0x706e6673, 0x20646576, 0x6c697374}}, \ 540 {TAG_SEQUENCE, "sequence", \ 541 {0x73657175, 0x656e6365, 0x20202020}}, \ 542 {TAG_DESTROY_SESSION, "destroy session", \ 543 {0x64657374, 0x726f7920, 0x73657373}}, \ 544 {TAG_PNFS_GETDEVINFO, "getdeviceinf", \ 545 {0x67657464, 0x65766963, 0x65696e66}}, \ 546 {TAG_RECLAIM_COMPLETE, "reclaim complete", \ 547 {0x7265636c, 0x61696d20, 0x636f6d70}}, \ 548 {TAG_LAYOUTCOMMIT, "layoutcommit", \ 549 {0x6c61796f, 0x75742063, 0x6f6d6d69}} \ 550 } 551 552 /* 553 * These flags are for differentiating the search criterian for 554 * find_open_owner(). The comparison is done with the open_owners's 555 * 'oo_just_created' flag. 556 */ 557 #define NFS4_PERM_CREATED 0x0 558 #define NFS4_JUST_CREATED 0x1 559 560 /* 561 * Hashed by the cr_uid and cr_ruid of credential 'oo_cred'. 'oo_cred_otw' 562 * is stored upon a successful OPEN. This is needed when the user's effective 563 * and real uid's don't match. The 'oo_cred_otw' overrides the credential 564 * passed down by VFS for async read/write, commit, lock, and close operations. 565 * 566 * The oo_ref_count keeps track the number of active references on this 567 * data structure + number of nfs4_open_streams point to this structure. 568 * 569 * 'oo_valid' tells whether this stuct is about to be freed or not. 570 * 571 * 'oo_just_created' tells us whether this struct has just been created but 572 * not been fully finalized (that is created upon an OPEN request and 573 * finalized upon the OPEN success). 574 * 575 * The 'oo_seqid_inuse' is for the open seqid synchronization. If a thread 576 * is currently using the open owner and it's open_seqid, then it sets the 577 * oo_seqid_inuse to true if it currently is not set. If it is set then it 578 * does a cv_wait on the oo_cv_seqid_sync condition variable. When the thread 579 * is done it unsets the oo_seqid_inuse and does a cv_signal to wake a process 580 * waiting on the condition variable. 581 * 582 * 'oo_last_good_seqid' is the last valid seqid this open owner sent OTW, 583 * and 'oo_last_good_op' is the operation that issued the last valid seqid. 584 * 585 * Lock ordering: 586 * mntinfo4_t::mi_lock > oo_lock (for searching mi_oo_list) 587 * 588 * oo_seqid_inuse > mntinfo4_t::mi_lock 589 * oo_seqid_inuse > rnode4_t::r_statelock 590 * oo_seqid_inuse > rnode4_t::r_statev4_lock 591 * oo_seqid_inuse > nfs4_open_stream_t::os_sync_lock 592 * 593 * The 'oo_seqid_inuse'/'oo_cv_seqid_sync' protects: 594 * oo_last_good_op 595 * oo_last_good_seqid 596 * oo_name 597 * oo_seqid 598 * 599 * The 'oo_lock' protects: 600 * oo_cred 601 * oo_cred_otw 602 * oo_foo_node 603 * oo_hash_node 604 * oo_just_created 605 * oo_ref_count 606 * oo_valid 607 */ 608 609 typedef struct nfs4_open_owner { 610 cred_t *oo_cred; 611 int oo_ref_count; 612 int oo_valid; 613 int oo_just_created; 614 seqid4 oo_seqid; 615 seqid4 oo_last_good_seqid; 616 nfs4_tag_type_t oo_last_good_op; 617 unsigned oo_seqid_inuse:1; 618 cred_t *oo_cred_otw; 619 kcondvar_t oo_cv_seqid_sync; 620 /* 621 * Fix this to always be 8 bytes 622 */ 623 uint64_t oo_name; 624 list_node_t oo_hash_node; 625 list_node_t oo_foo_node; 626 kmutex_t oo_lock; 627 } nfs4_open_owner_t; 628 629 /* 630 * Static server information. 631 * These fields are read-only once they are initialized: 632 * sv_addr 633 * sv_dhsec 634 * sv_hostname 635 * sv_hostnamelen 636 * sv_knconf 637 * sv_next 638 * sv_origknconf 639 * 640 * These fields are protected by sv_lock: 641 * sv_currsec 642 * sv_fhandle 643 * sv_flags 644 * sv_fsid 645 * sv_path 646 * sv_pathlen 647 * sv_pfhandle 648 * sv_save_secinfo 649 * sv_savesec 650 * sv_secdata 651 * sv_secinfo 652 * sv_supp_attrs 653 * 654 * Lock ordering: 655 * nfs_rtable4_lock > sv_lock 656 * rnode4_t::r_statelock > sv_lock 657 */ 658 typedef struct servinfo4 { 659 struct knetconfig *sv_knconf; /* bound TLI fd */ 660 struct knetconfig *sv_origknconf; /* For RDMA save orig knconf */ 661 struct netbuf sv_addr; /* server's address */ 662 nfs4_fhandle_t sv_fhandle; /* this server's filehandle */ 663 nfs4_fhandle_t sv_pfhandle; /* parent dir filehandle */ 664 int sv_pathlen; /* Length of server path */ 665 char *sv_path; /* Path name on server */ 666 uint32_t sv_flags; /* flags for this server */ 667 sec_data_t *sv_secdata; /* client initiated security data */ 668 sv_secinfo_t *sv_secinfo; /* server security information */ 669 sec_data_t *sv_currsec; /* security data currently used; */ 670 /* points to one of the sec_data */ 671 /* entries in sv_secinfo */ 672 sv_secinfo_t *sv_save_secinfo; /* saved secinfo */ 673 sec_data_t *sv_savesec; /* saved security data */ 674 sec_data_t *sv_dhsec; /* AUTH_DH data from the user land */ 675 char *sv_hostname; /* server's hostname */ 676 int sv_hostnamelen; /* server's hostname length */ 677 fattr4_fsid sv_fsid; /* fsid of shared obj */ 678 attrmap4 sv_supp_attrs; 679 struct servinfo4 *sv_next; /* next in list */ 680 nfs_rwlock_t sv_lock; 681 attrmap4 sv_supp_exclcreat; 682 } servinfo4_t; 683 684 /* sv_flags fields */ 685 #define SV4_TRYSECINFO 0x001 /* try secinfo data from the server */ 686 #define SV4_TRYSECDEFAULT 0x002 /* try a default flavor */ 687 #define SV4_NOTINUSE 0x004 /* servinfo4_t had fatal errors */ 688 #define SV4_ROOT_STALE 0x008 /* root vnode got ESTALE */ 689 #define SV4_ISA_DS 0x010 /* this is a data server! */ 690 691 /* 692 * Lock call types. See nfs4frlock(). 693 */ 694 typedef enum nfs4_lock_call_type { 695 NFS4_LCK_CTYPE_NORM, 696 NFS4_LCK_CTYPE_RECLAIM, 697 NFS4_LCK_CTYPE_RESEND, 698 NFS4_LCK_CTYPE_REINSTATE 699 } nfs4_lock_call_type_t; 700 701 struct nfs4_server; 702 703 /* 704 * This structure holds the information for a lost open/close/open downgrade/ 705 * lock/locku request. It is also used for requests that are queued up so 706 * that the recovery thread can release server state after a forced 707 * unmount. 708 * "lr_op" is 0 if the struct is uninitialized. Otherwise, it is set to 709 * the proper OP_* nfs_opnum4 number. The other fields contain information 710 * to reconstruct the call. 711 * 712 * lr_dvp is used for OPENs with CREATE, so that we can do a PUTFH of the 713 * parent directroy without relying on vtodv (since we may not have a vp 714 * for the file we wish to create). 715 * 716 * lr_putfirst means that the request should go to the front of the resend 717 * queue, rather than the end. 718 */ 719 typedef struct nfs4_lost_rqst { 720 list_node_t lr_node; 721 nfs_opnum4 lr_op; 722 vnode_t *lr_vp; 723 vnode_t *lr_dvp; 724 nfs4_open_owner_t *lr_oop; 725 struct nfs4_open_stream *lr_osp; 726 struct nfs4_lock_owner *lr_lop; 727 cred_t *lr_cr; 728 flock64_t *lr_flk; 729 bool_t lr_putfirst; 730 union { 731 struct { 732 nfs4_lock_call_type_t lru_ctype; 733 nfs_lock_type4 lru_locktype; 734 } lru_lockargs; /* LOCK, LOCKU */ 735 struct { 736 uint32_t lru_oaccess; 737 uint32_t lru_odeny; 738 enum open_claim_type4 lru_oclaim; 739 stateid4 lru_ostateid; /* reopen only */ 740 component4 lru_ofile; 741 struct nfs4_server *lru_slot_srv; 742 slot_ent_t *lru_slot_ent; 743 } lru_open_args; 744 struct { 745 uint32_t lru_dg_access; 746 uint32_t lru_dg_deny; 747 } lru_open_dg_args; 748 } nfs4_lr_u; 749 } nfs4_lost_rqst_t; 750 751 #define lr_oacc nfs4_lr_u.lru_open_args.lru_oaccess 752 #define lr_odeny nfs4_lr_u.lru_open_args.lru_odeny 753 #define lr_oclaim nfs4_lr_u.lru_open_args.lru_oclaim 754 #define lr_ostateid nfs4_lr_u.lru_open_args.lru_ostateid 755 #define lr_ofile nfs4_lr_u.lru_open_args.lru_ofile 756 #define lr_slot_srv nfs4_lr_u.lru_open_args.lru_slot_srv 757 #define lr_slot_ent nfs4_lr_u.lru_open_args.lru_slot_ent 758 #define lr_dg_acc nfs4_lr_u.lru_open_dg_args.lru_dg_access 759 #define lr_dg_deny nfs4_lr_u.lru_open_dg_args.lru_dg_deny 760 #define lr_ctype nfs4_lr_u.lru_lockargs.lru_ctype 761 #define lr_locktype nfs4_lr_u.lru_lockargs.lru_locktype 762 763 /* 764 * Recovery actions. Some actions can imply further recovery using a 765 * different recovery action (e.g., recovering the clientid leads to 766 * recovering open files and locks). 767 */ 768 769 typedef enum { 770 NR_UNUSED, 771 NR_CLIENTID, 772 NR_OPENFILES, 773 NR_FHEXPIRED, 774 NR_FAILOVER, 775 NR_WRONGSEC, 776 NR_EXPIRED, 777 NR_BAD_STATEID, 778 NR_BADHANDLE, 779 NR_BAD_SEQID, 780 NR_OLDSTATEID, 781 NR_GRACE, 782 NR_DELAY, 783 NR_LOST_LOCK, 784 NR_LOST_STATE_RQST, 785 NR_STALE, 786 NR_BADSESSION, 787 NR_BC2S, 788 NR_SEQRETRY 789 } nfs4_recov_t; 790 791 /* 792 * Administrative and debug message framework. 793 */ 794 795 #define NFS4_MSG_MAX 100 796 extern int nfs4_msg_max; 797 798 typedef enum { 799 RE_BAD_SEQID, 800 RE_BADHANDLE, 801 RE_CLIENTID, 802 RE_DEAD_FILE, 803 RE_END, 804 RE_FAIL_RELOCK, 805 RE_FAIL_REMAP_LEN, 806 RE_FAIL_REMAP_OP, 807 RE_FAILOVER, 808 RE_FILE_DIFF, 809 RE_LOST_STATE, 810 RE_OPENS_CHANGED, 811 RE_SIGLOST, 812 RE_SIGLOST_NO_DUMP, 813 RE_START, 814 RE_UNEXPECTED_ACTION, 815 RE_UNEXPECTED_ERRNO, 816 RE_UNEXPECTED_STATUS, 817 RE_WRONGSEC, 818 RE_LOST_STATE_BAD_OP 819 } nfs4_event_type_t; 820 821 typedef enum { 822 RFS_NO_INSPECT, 823 RFS_INSPECT 824 } nfs4_fact_status_t; 825 826 typedef enum { 827 RF_BADOWNER, 828 RF_ERR, 829 RF_RENEW_EXPIRED, 830 RF_SRV_NOT_RESPOND, 831 RF_SRV_OK, 832 RF_SRVS_NOT_RESPOND, 833 RF_SRVS_OK, 834 RF_DELMAP_CB_ERR, 835 RF_SENDQ_FULL 836 } nfs4_fact_type_t; 837 838 typedef enum { 839 NFS4_MS_DUMP, 840 NFS4_MS_NO_DUMP 841 } nfs4_msg_status_t; 842 843 typedef struct nfs4_rfact { 844 nfs4_fact_type_t rf_type; 845 nfs4_fact_status_t rf_status; 846 bool_t rf_reboot; 847 nfs4_recov_t rf_action; 848 nfs_opnum4 rf_op; 849 nfsstat4 rf_stat4; 850 timespec_t rf_time; 851 int rf_error; 852 struct rnode4 *rf_rp1; 853 char *rf_char1; 854 } nfs4_rfact_t; 855 856 typedef struct nfs4_revent { 857 nfs4_event_type_t re_type; 858 nfsstat4 re_stat4; 859 uint_t re_uint; 860 pid_t re_pid; 861 struct mntinfo4 *re_mi; 862 struct rnode4 *re_rp1; 863 struct rnode4 *re_rp2; 864 char *re_char1; 865 char *re_char2; 866 nfs4_tag_type_t re_tag1; 867 nfs4_tag_type_t re_tag2; 868 seqid4 re_seqid1; 869 seqid4 re_seqid2; 870 } nfs4_revent_t; 871 872 typedef enum { 873 RM_EVENT, 874 RM_FACT 875 } nfs4_msg_type_t; 876 877 typedef struct nfs4_debug_msg { 878 timespec_t msg_time; 879 nfs4_msg_type_t msg_type; 880 char *msg_srv; 881 char *msg_mntpt; 882 union { 883 nfs4_rfact_t msg_fact; 884 nfs4_revent_t msg_event; 885 } rmsg_u; 886 nfs4_msg_status_t msg_status; 887 list_node_t msg_node; 888 } nfs4_debug_msg_t; 889 890 /* 891 * NFS private data per mounted file system 892 * The mi_lock mutex protects the following fields: 893 * mi_flags 894 * mi_in_recovery 895 * mi_recovflags 896 * mi_recovthread 897 * mi_error 898 * mi_printed 899 * mi_down 900 * mi_stsize 901 * mi_curread 902 * mi_curwrite 903 * mi_timers 904 * mi_curr_serv 905 * mi_klmconfig 906 * mi_oo_list 907 * mi_foo_list 908 * mi_foo_num 909 * mi_foo_max 910 * mi_lost_state 911 * mi_bseqid_list 912 * mi_ephemeral 913 * mi_ephemeral_tree 914 * 915 * Normally the netconfig information for the mount comes from 916 * mi_curr_serv and mi_klmconfig is NULL. If NLM calls need to use a 917 * different transport, mi_klmconfig contains the necessary netconfig 918 * information. 919 * 920 * The mi_async_lock mutex protects the following fields: 921 * mi_async_reqs 922 * mi_async_req_count 923 * mi_async_tail 924 * mi_async_curr 925 * mi_async_clusters 926 * mi_async_init_clusters 927 * mi_threads 928 * mi_inactive_thread 929 * mi_manager_thread 930 * 931 * The nfs4_server_t::s_lock protects the following fields: 932 * mi_clientid 933 * mi_clientid_next 934 * mi_clientid_prev 935 * mi_open_files 936 * 937 * The mntinfo4_t::mi_recovlock protects the following fields: 938 * mi_srvsettime 939 * mi_srvset_cnt 940 * mi_srv 941 * 942 * Changing mi_srv from one nfs4_server_t to a different one requires 943 * holding the mi_recovlock as RW_WRITER. 944 * Exception: setting mi_srv the first time in mount/mountroot is done 945 * holding the mi_recovlock as RW_READER. 946 * 947 * Locking order: 948 * mi4_globals::mig_lock > mi_async_lock 949 * mi_async_lock > nfs4_server_t::s_lock > mi_lock 950 * mi_recovlock > mi_rename_lock > nfs_rtable4_lock 951 * nfs4_server_t::s_recovlock > mi_recovlock 952 * rnode4_t::r_rwlock > mi_rename_lock 953 * nfs_rtable4_lock > mi_lock 954 * nfs4_server_t::s_lock > mi_msg_list_lock 955 * mi_recovlock > nfs4_server_t::s_lock 956 * mi_recovlock > nfs4_server_lst_lock 957 * 958 * The 'mi_oo_list' represents the hash buckets that contain the 959 * nfs4_open_owenrs for this particular mntinfo4. 960 * 961 * The 'mi_foo_list' represents the freed nfs4_open_owners for this mntinfo4. 962 * 'mi_foo_num' is the current number of freed open owners on the list, 963 * 'mi_foo_max' is the maximum number of freed open owners that are allowable 964 * on the list. 965 * 966 * mi_rootfh and mi_srvparentfh are read-only once created, but that just 967 * refers to the pointer. The contents must be updated to keep in sync 968 * with mi_curr_serv. 969 * 970 * The mi_msg_list_lock protects against adding/deleting entries to the 971 * mi_msg_list, and also the updating/retrieving of mi_lease_period; 972 * 973 * 'mi_zone' is initialized at structure creation time, and never 974 * changes; it may be read without a lock. 975 * 976 * mi_zone_node is linkage into the mi4_globals.mig_list, and is 977 * protected by mi4_globals.mig_list_lock. 978 * 979 * If MI4_EPHEMERAL is set in mi_flags, then mi_ephemeral points to an 980 * ephemeral structure for this ephemeral mount point. It can not be 981 * NULL. Also, mi_ephemeral_tree points to the root of the ephemeral 982 * tree. 983 * 984 * If MI4_EPHEMERAL is not set in mi_flags, then mi_ephemeral has 985 * to be NULL. If mi_ephemeral_tree is non-NULL, then this node 986 * is the enclosing mntinfo4 for the ephemeral tree. 987 */ 988 struct zone; 989 struct nfs4_ephemeral; 990 struct nfs4_ephemeral_tree; 991 struct nfs4_server; 992 typedef struct mntinfo4 { 993 kmutex_t mi_lock; /* protects mntinfo4 fields */ 994 struct servinfo4 *mi_servers; /* server list */ 995 struct servinfo4 *mi_curr_serv; /* current server */ 996 struct nfs4_sharedfh *mi_rootfh; /* root filehandle */ 997 struct nfs4_sharedfh *mi_srvparentfh; /* root's parent on server */ 998 uint32_t mi_minorversion; 999 kcondvar_t mi_failover_cv; /* failover synchronization */ 1000 struct vfs *mi_vfsp; /* back pointer to vfs */ 1001 enum vtype mi_type; /* file type of the root vnode */ 1002 uint_t mi_flags; /* see below */ 1003 uint_t mi_recovflags; /* if recovery active; see below */ 1004 kthread_t *mi_recovthread; /* active recov thread or NULL */ 1005 uint_t mi_error; /* only set/valid when MI4_RECOV_FAIL */ 1006 /* is set in mi_flags */ 1007 int mi_tsize; /* transfer size (bytes) */ 1008 /* really read size */ 1009 int mi_stsize; /* server's max transfer size (bytes) */ 1010 /* really write size */ 1011 int mi_timeo; /* inital timeout in 10th sec */ 1012 int mi_retrans; /* times to retry request */ 1013 hrtime_t mi_acregmin; /* min time to hold cached file attr */ 1014 hrtime_t mi_acregmax; /* max time to hold cached file attr */ 1015 hrtime_t mi_acdirmin; /* min time to hold cached dir attr */ 1016 hrtime_t mi_acdirmax; /* max time to hold cached dir attr */ 1017 len_t mi_maxfilesize; /* for pathconf _PC_FILESIZEBITS */ 1018 int mi_curread; /* current read size */ 1019 int mi_curwrite; /* current write size */ 1020 uint_t mi_count; /* ref count */ 1021 /* 1022 * async I/O management. There may be a pool of threads to handle 1023 * async I/O requests, etc., plus there is always one thread that 1024 * handles over-the-wire requests for VOP_INACTIVE. The async pool 1025 * can also help out with VOP_INACTIVE. 1026 */ 1027 struct nfs4_async_reqs *mi_async_reqs[NFS4_ASYNC_TYPES]; 1028 struct nfs4_async_reqs *mi_async_tail[NFS4_ASYNC_TYPES]; 1029 struct nfs4_async_reqs **mi_async_curr; /* current async queue */ 1030 uint_t mi_async_clusters[NFS4_ASYNC_TYPES]; 1031 uint_t mi_async_init_clusters; 1032 uint_t mi_async_req_count; /* # outstanding work requests */ 1033 kcondvar_t mi_async_reqs_cv; /* signaled when there's work */ 1034 ushort_t mi_threads; /* number of active async threads */ 1035 ushort_t mi_max_threads; /* max number of async threads */ 1036 kthread_t *mi_manager_thread; /* async manager thread id */ 1037 kthread_t *mi_inactive_thread; /* inactive thread id */ 1038 kcondvar_t mi_inact_req_cv; /* notify VOP_INACTIVE thread */ 1039 kcondvar_t mi_async_work_cv; /* tell workers to work */ 1040 kcondvar_t mi_async_cv; /* all pool threads exited */ 1041 kmutex_t mi_async_lock; 1042 /* 1043 * Other stuff 1044 */ 1045 struct pathcnf *mi_pathconf; /* static pathconf kludge */ 1046 rpcprog_t mi_prog; /* RPC program number */ 1047 rpcvers_t mi_vers; /* RPC program version number */ 1048 char **mi_rfsnames; /* mapping to proc names */ 1049 kstat_named_t *mi_reqs; /* count of requests */ 1050 clock_t mi_printftime; /* last error printf time */ 1051 nfs_rwlock_t mi_recovlock; /* separate ops from recovery (v4) */ 1052 time_t mi_grace_wait; /* non-zero represents time to wait */ 1053 /* when we switched nfs4_server_t - only for observability purposes */ 1054 time_t mi_srvsettime; 1055 nfs_rwlock_t mi_rename_lock; /* atomic volfh rename */ 1056 struct nfs4_fname *mi_fname; /* root fname */ 1057 list_t mi_lost_state; /* resend list */ 1058 list_t mi_bseqid_list; /* bad seqid list */ 1059 /* 1060 * Client Side Failover stats 1061 */ 1062 uint_t mi_noresponse; /* server not responding count */ 1063 uint_t mi_failover; /* failover to new server count */ 1064 uint_t mi_remap; /* remap to new server count */ 1065 /* 1066 * Kstat statistics 1067 */ 1068 struct kstat *mi_io_kstats; 1069 struct kstat *mi_ro_kstats; 1070 kstat_t *mi_recov_ksp; /* ptr to the recovery kstat */ 1071 1072 /* 1073 * Volatile fh flags (nfsv4) 1074 */ 1075 uint32_t mi_fh_expire_type; 1076 /* 1077 * Lease Management 1078 */ 1079 struct mntinfo4 *mi_clientid_next; 1080 struct mntinfo4 *mi_clientid_prev; 1081 clientid4 mi_clientid; /* redundant info found in nfs4_server */ 1082 int mi_open_files; /* count of open files */ 1083 int mi_in_recovery; /* count of recovery instances */ 1084 kcondvar_t mi_cv_in_recov; /* cv for recovery threads */ 1085 /* 1086 * Open owner stuff. 1087 */ 1088 struct nfs4_oo_hash_bucket mi_oo_list[NFS4_NUM_OO_BUCKETS]; 1089 list_t mi_foo_list; 1090 int mi_foo_num; 1091 int mi_foo_max; 1092 /* 1093 * Shared filehandle pool. 1094 */ 1095 nfs_rwlock_t mi_fh_lock; 1096 avl_tree_t mi_filehandles; 1097 1098 /* 1099 * pNFS support 1100 */ 1101 kmutex_t mi_pnfs_lock; 1102 taskq_t *mi_pnfs_io_taskq; 1103 taskq_t *mi_pnfs_other_taskq; 1104 clock_t mi_last_getdevicelist; 1105 1106 /* 1107 * Debug message queue. 1108 */ 1109 list_t mi_msg_list; 1110 int mi_msg_count; 1111 time_t mi_lease_period; 1112 /* 1113 * not guaranteed to be accurate. 1114 * only should be used by debug queue. 1115 */ 1116 kmutex_t mi_msg_list_lock; 1117 /* 1118 * Zones support. 1119 */ 1120 struct zone *mi_zone; /* Zone mounted in */ 1121 list_node_t mi_zone_node; /* linkage into per-zone mi list */ 1122 1123 /* 1124 * Links for unmounting ephemeral mounts. 1125 */ 1126 struct nfs4_ephemeral *mi_ephemeral; 1127 struct nfs4_ephemeral_tree *mi_ephemeral_tree; 1128 1129 uint_t mi_srvset_cnt; /* increment when changing the nfs4_server_t */ 1130 struct nfs4_server *mi_srv; /* backpointer to nfs4_server_t */ 1131 attrvers_t mi_attrvers; 1132 } mntinfo4_t; 1133 1134 /* 1135 * The values for mi_flags. 1136 * 1137 * MI4_HARD hard or soft mount 1138 * MI4_PRINTED responding message printed 1139 * MI4_INT allow INTR on hard mount 1140 * MI4_DOWN server is down 1141 * MI4_NOAC don't cache attributes 1142 * MI4_NOCTO no close-to-open consistency 1143 * MI4_LLOCK local locking only (no lockmgr) 1144 * MI4_GRPID System V group id inheritance 1145 * MI4_SHUTDOWN System is rebooting or shutting down 1146 * MI4_LINK server supports link 1147 * MI4_SYMLINK server supports symlink 1148 * MI4_EPHEMERAL_RECURSED an ephemeral mount being unmounted 1149 * due to a recursive call - no need 1150 * for additional recursion 1151 * MI4_PNFS server supports pNFS 1152 * MI4_ACL server supports NFSv4 ACLs 1153 * MI4_MIRRORMOUNT is a mirrormount 1154 * MI4_NOPRINT don't print messages 1155 * MI4_DIRECTIO do direct I/O 1156 * MI4_RECOV_ACTIV filesystem has recovery a thread 1157 * MI4_REMOVE_ON_LAST_CLOSE remove from server's list 1158 * MI4_RECOV_FAIL client recovery failed 1159 * MI4_PUBLIC public/url option used 1160 * MI4_MOUNTING mount in progress, don't failover 1161 * MI4_POSIX_LOCK if server is using POSIX locking 1162 * MI4_LOCK_DEBUG cmn_err'd posix lock err msg 1163 * MI4_DEAD zone has released it 1164 * MI4_INACTIVE_IDLE inactive thread idle 1165 * MI4_BADOWNER_DEBUG badowner error msg per mount 1166 * MI4_ASYNC_MGR_STOP tell async manager to die 1167 * MI4_TIMEDOUT saw a timeout during zone shutdown 1168 * MI4_EPHEMERAL is an ephemeral mount 1169 */ 1170 #define MI4_HARD 0x1 1171 #define MI4_PRINTED 0x2 1172 #define MI4_INT 0x4 1173 #define MI4_DOWN 0x8 1174 #define MI4_NOAC 0x10 1175 #define MI4_NOCTO 0x20 1176 #define MI4_LLOCK 0x80 1177 #define MI4_GRPID 0x100 1178 #define MI4_SHUTDOWN 0x200 1179 #define MI4_LINK 0x400 1180 #define MI4_SYMLINK 0x800 1181 #define MI4_EPHEMERAL_RECURSED 0x1000 1182 #define MI4_ACL 0x2000 1183 /* MI4_MIRRORMOUNT is also defined in nfsstat.c */ 1184 #define MI4_MIRRORMOUNT 0x4000 1185 #define MI4_PNFS 0x8000 1186 /* 0x10000 is available */ 1187 #define MI4_NOPRINT 0x20000 1188 #define MI4_DIRECTIO 0x40000 1189 /* 0x80000 is available */ 1190 #define MI4_RECOV_ACTIV 0x100000 1191 #define MI4_REMOVE_ON_LAST_CLOSE 0x200000 1192 #define MI4_RECOV_FAIL 0x400000 1193 #define MI4_PUBLIC 0x800000 1194 #define MI4_MOUNTING 0x1000000 1195 #define MI4_POSIX_LOCK 0x2000000 1196 #define MI4_LOCK_DEBUG 0x4000000 1197 #define MI4_DEAD 0x8000000 1198 #define MI4_INACTIVE_IDLE 0x10000000 1199 #define MI4_BADOWNER_DEBUG 0x20000000 1200 #define MI4_ASYNC_MGR_STOP 0x40000000 1201 #define MI4_TIMEDOUT 0x80000000 1202 1203 /* 1204 * Note that when we add referrals, then MI4_EPHEMERAL 1205 * will be MI4_MIRRORMOUNT | MI4_REFERRAL. 1206 */ 1207 #define MI4_EPHEMERAL MI4_MIRRORMOUNT 1208 1209 #define INTR4(vp) (VTOMI4(vp)->mi_flags & MI4_INT) 1210 1211 #define FAILOVER_MOUNT4(mi) (mi->mi_servers->sv_next) 1212 1213 /* 1214 * Recovery flags. 1215 * 1216 * MI4R_NEED_CLIENTID is sort of redundant (it's the nfs4_server_t flag 1217 * that's important), but some flag is needed to indicate that recovery is 1218 * going on for the filesystem. 1219 */ 1220 #define MI4R_NEED_CLIENTID 0x1 1221 #define MI4R_REOPEN_FILES 0x2 1222 #define MI4R_NEED_SECINFO 0x4 1223 #define MI4R_NEED_NEW_SERVER 0x8 1224 #define MI4R_REMAP_FILES 0x10 1225 #define MI4R_SRV_REBOOT 0x20 /* server has rebooted */ 1226 #define MI4R_LOST_STATE 0x40 1227 #define MI4R_BAD_SEQID 0x80 1228 #define MI4R_NEED_SESSION 0x100 1229 #define MI4R_NEED_BC2S 0x200 1230 1231 #define MI4_HOLD(mi) { \ 1232 mi_hold(mi); \ 1233 } 1234 1235 #define MI4_RELE(mi) { \ 1236 mi_rele(mi); \ 1237 } 1238 1239 #define NFS4_MINORVERSION(mi) (mi->mi_minorversion) 1240 1241 /* 1242 * vfs pointer to mount info 1243 */ 1244 #define VFTOMI4(vfsp) ((mntinfo4_t *)((vfsp)->vfs_data)) 1245 1246 /* 1247 * vnode pointer to mount info 1248 */ 1249 #define VTOMI4(vp) ((mntinfo4_t *)(((vp)->v_vfsp)->vfs_data)) 1250 1251 /* 1252 * Lease Management 1253 * 1254 * lease_valid is initially set to NFS4_LEASE_NOT_STARTED. This is when the 1255 * nfs4_server is first created. lease_valid is then set to 1256 * NFS4_LEASE_UNITIALIZED when the renew thread is started. The extra state of 1257 * NFS4_LEASE_NOT_STARTED is needed for client recovery (so we know if a thread 1258 * already exists when we do SETCLIENTID). lease_valid is then set to 1259 * NFS4_LEASE_VALID (if it is at NFS4_LEASE_UNITIALIZED) when a state creating 1260 * operation (OPEN) is done. lease_valid stays at NFS4_LEASE_VALID as long as 1261 * the lease is renewed. It is set to NFS4_LEASE_INVALID when the lease 1262 * expires. Client recovery is needed to set the lease back to 1263 * NFS4_LEASE_VALID from NFS4_LEASE_INVALID. 1264 * 1265 * The s_cred is the credential used to mount the first file system for this 1266 * server. It used as the credential for the renew thread's calls to the 1267 * server. 1268 * 1269 * The renew thread waits on the condition variable cv_thread_exit. If the cv 1270 * is signalled, then the thread knows it must check s_thread_exit to see if 1271 * it should exit. The cv is signaled when the last file system is unmounted 1272 * from a particular server. s_thread_exit is set to 0 upon thread startup, 1273 * and set to NFS4_THREAD_EXIT, when the last file system is unmounted thereby 1274 * telling the thread to exit. s_thread_exit is needed to avoid spurious 1275 * wakeups. 1276 * 1277 * state_ref_count is incremented every time a new file is opened and 1278 * decremented every time a file is closed otw. This keeps track of whether 1279 * the nfs4_server has state associated with it or not. 1280 * 1281 * s_refcnt is the reference count for storage management of the struct 1282 * itself. 1283 * 1284 * mntinfo4_list points to the doubly linked list of mntinfo4s that share 1285 * this nfs4_server (ie: <clientid, saddr> pair) in the current zone. This is 1286 * needed for a nfs4_server to get a mntinfo4 for use in rfs4call. 1287 * 1288 * s_recovlock is used to synchronize recovery operations. The thread 1289 * that is recovering the client must acquire it as a writer. If the 1290 * thread is using the clientid (including recovery operations on other 1291 * state), acquire it as a reader. 1292 * 1293 * The 's_otw_call_count' keeps track of the number of outstanding over the 1294 * wire requests for this structure. The struct will not go away as long 1295 * as this is non-zero (or s_refcnt is non-zero). 1296 * 1297 * The 's_cv_otw_count' is used in conjuntion with the 's_otw_call_count' 1298 * variable to let the renew thread when an outstanding otw request has 1299 * finished. 1300 * 1301 * 'zoneid' and 'zone_globals' are set at creation of this structure 1302 * and are read-only after that; no lock is required to read them. 1303 * 1304 * s_lock protects: everything except cv_thread_exit and s_recovlock. 1305 * 1306 * s_program is used as the index into the nfs4_callback_globals's 1307 * nfs4prog2server table. When a callback request comes in, we can 1308 * use that request's program number (minus NFS4_CALLBACK) as an index 1309 * into the nfs4prog2server. That entry will hold the nfs4_server_t ptr. 1310 * We can then access that nfs4_server_t and its 's_deleg_list' (its list of 1311 * delegated rnode4_ts). 1312 * 1313 * Lock order: 1314 * nfs4_server::s_lock > mntinfo4::mi_lock 1315 * nfs_rtable4_lock > s_lock 1316 * nfs4_server_lst_lock > s_lock 1317 * s_recovlock > s_lock 1318 */ 1319 struct nfs4_callback_globals; 1320 struct devnode; 1321 1322 /* 1323 * The nfs4_fsidlt_t will be the structure inserted as a node onto 1324 * the nfs4_server_t's fsidlt (fsid layout tree). There will be one 1325 * per fsid that has done a layoutget. Note that the fsid structures, 1326 * once added to the fsidlt, will remain there until the nfs4_server_t 1327 * is destroyed, even if all layouts have been returned for the fsid. 1328 * 1329 * The locking order is that, the s_lt_lock in the nfs4_server_t will 1330 * lock the fsidlt tree. Once the appropriate fsidlt node is found, it 1331 * will be locked via its lt_rtl_lock, then the s_lt_lock can be dropped. 1332 * 1333 * Also note, that if the rnode4->r_statelock and the lt_rtl_lock are both 1334 * required, the lt_rtl_lock must be taken out before the r_statelock 1335 * and the lt_rtl_lock must be release after the r_statelock is released. 1336 */ 1337 typedef struct nfs4_fsidlt 1338 { 1339 fsid4 lt_fsid; /* fsid */ 1340 avl_node_t lt_node; /* link to nfs4_fsidlt tree */ 1341 kmutex_t lt_rlt_lock; /* rnode layout tree lock */ 1342 avl_tree_t lt_rlayout_tree; /* rnode layout tree by fh */ 1343 uint_t lt_lobulkblock; /* operations blocking bulk lor */ 1344 uint_t lt_loinuse; /* layouts in use */ 1345 uint_t lt_locnt; /* valid layouts held for FSID */ 1346 kcondvar_t lt_lowait; /* condition variable */ 1347 uint_t lt_flags; /* layout flags */ 1348 } nfs4_fsidlt_t; 1349 1350 /* 1351 * s_loflags and lt_flags bit field values for nfs4_server and nfs4_fsidlt 1352 */ 1353 #define PNFS_CBLORECALL 0x01 /* Layout Recall Active Or Pending */ 1354 #define PNFS_CBLOWAITER 0x02 /* Thread waiting for Bulk Lyaout Recall */ 1355 1356 /* 1357 * Max slots and available slots can be accessed by stok_t->st_currw 1358 * and stok_t->st_fslots. 1359 */ 1360 typedef struct nfs4_session { 1361 sessionid4 sessionid; 1362 stok_t *slot_table; /* Fore channel slot table. */ 1363 stok_t *cb_slot_table; /* Back Channel slot table */ 1364 int bi_rpc; 1365 channel_attrs4 fore_chan_attr; 1366 channel_attrs4 back_chan_attr; 1367 list_node_t ssx_list; 1368 struct netbuf saddr; 1369 } nfs4_session_t; 1370 1371 typedef struct nfs4_server { 1372 struct nfs4_server *forw; 1373 struct nfs4_server *back; 1374 struct netbuf saddr; 1375 uint_t s_flags; /* see below */ 1376 uint_t s_refcnt; 1377 clientid4 clientid; /* what we get from server */ 1378 nfs_client_id4 clidtosend; /* what we send to server */ 1379 1380 /* seqid for the next CREATE_SESSION */ 1381 sequenceid4 csa_seqid; 1382 1383 nfs4_session_t ssx; /* sessions extension */ 1384 int seqhb_flags; 1385 mntinfo4_t *mntinfo4_list; 1386 uint32_t s_minorversion; /* last tried minorversion */ 1387 int lease_valid; 1388 time_t s_lease_time; 1389 time_t last_renewal_time; 1390 timespec_t propagation_delay; 1391 cred_t *s_cred; 1392 kcondvar_t cv_thread_exit; 1393 int s_thread_exit; 1394 int state_ref_count; 1395 int s_otw_call_count; 1396 kcondvar_t s_cv_otw_count; 1397 kcondvar_t s_clientid_pend; 1398 kmutex_t s_lock; 1399 list_t s_deleg_list; 1400 rpcprog_t s_program; 1401 nfs_rwlock_t s_recovlock; 1402 kthread_t *s_recovthread; /* active recov thrd or NULL */ 1403 kcondvar_t wait_cb_null; /* used to wait for CB_NULL */ 1404 zoneid_t zoneid; /* zone using this nfs4_server_t */ 1405 struct nfs4_callback_globals *zone_globals; /* globals */ 1406 kcondvar_t ssx_wait; /* wait for destroy session */ 1407 servinfo4_t *s_ds_svp; /* for dataservers, the servinfo4 */ 1408 uint_t s_lobulkblock; /* active ops block bulk lor */ 1409 uint_t s_loinuse; /* active ops using layouts */ 1410 uint_t s_loflags; /* layout flags */ 1411 uint_t s_locnt; /* Valid layouts held for clientid */ 1412 kcondvar_t s_lowait; /* bulk lor waiting here */ 1413 kmutex_t s_lt_lock; /* layout tree lock */ 1414 avl_tree_t s_fsidlt; /* fsid layout tree */ 1415 avl_tree_t s_devid_tree; /* Device ID tree */ 1416 mntinfo4_t *s_hb_mi; /* mi held by hb thread */ 1417 servinfo4_t *s_hb_svp; /* servinfo4 for hb thread */ 1418 struct devnode *s_devnode; 1419 } nfs4_server_t; 1420 1421 /* nfs4_server flags */ 1422 #define N4S_CLIENTID_SET 1 /* server has our clientid */ 1423 #define N4S_CLIENTID_PEND 0x2 /* server doesn't have clientid */ 1424 #define N4S_CB_PINGED 0x4 /* server has sent us a CB_NULL */ 1425 #define N4S_CB_WAITER 0x8 /* is/has wait{ing/ed} for cb_null */ 1426 #define N4S_INSERTED 0x10 /* list has reference for server */ 1427 #define N4S_BADOWNER_DEBUG 0x20 /* bad owner err msg per client */ 1428 #define N4S_USE_PNFS_MDS 0x40 /* server is a pnfs MDS server */ 1429 #define N4S_USE_PNFS_DS 0x80 /* server is a pnfs DS server */ 1430 #define N4S_SESSION_CREATED 0x100 /* Session Created To Server */ 1431 #define N4S_EXID_FAILED 0x200 /* Exchange ID failed */ 1432 #define N4S_USE_NON_PNFS 0x400 /* server is a non pNFS 4.1 server */ 1433 #define N4S_NEED_BC2S 0x800 /* need bind_conn_to_session */ 1434 #define N4S_RECOV_ACTIV 0x1000 /* Recovery is active for this server */ 1435 #define N4S_SRV_DEAD 0x2000 /* nfs4_mark_srv_dead() called */ 1436 1437 #define N4S_CB_PAUSE_TIME 10000 /* Amount of time to pause (10ms) */ 1438 1439 struct lease_time_arg { 1440 time_t lease_time; 1441 }; 1442 1443 enum nfs4_delegreturn_policy { 1444 IMMEDIATE, 1445 FIRSTCLOSE, 1446 LASTCLOSE, 1447 INACTIVE 1448 }; 1449 1450 /* 1451 * Operation hints for the recovery framework (mostly). 1452 * 1453 * EXCEPTIONS: 1454 * OH_ACCESS, OH_GETACL, OH_GETATTR, OH_LOOKUP, OH_READDIR 1455 * These hints exist to allow user visit/readdir a R4SRVSTUB dir. 1456 * (dir represents the root of a server fs that has not yet been 1457 * mounted at client) 1458 */ 1459 typedef enum { 1460 OH_OTHER, 1461 OH_READ, 1462 OH_WRITE, 1463 OH_COMMIT, 1464 OH_VFH_RENAME, 1465 OH_MOUNT, 1466 OH_CLOSE, 1467 OH_LOCKU, 1468 OH_DELEGRETURN, 1469 OH_ACCESS, 1470 OH_GETACL, 1471 OH_GETATTR, 1472 OH_LOOKUP, 1473 OH_READDIR, 1474 OH_SEQUENCE, 1475 OH_DESTROY_SESS 1476 } nfs4_op_hint_t; 1477 1478 /* 1479 * This data structure is used to track ephemeral mounts for both 1480 * mirror mounts and referrals. 1481 * 1482 * Note that each nfs4_ephemeral can only have one other nfs4_ephemeral 1483 * pointing at it. So we don't need two backpointers to walk 1484 * back up the tree. 1485 * 1486 * An ephemeral tree is pointed to by an enclosing non-ephemeral 1487 * mntinfo4. The root is also pointed to by its ephemeral 1488 * mntinfo4. ne_child will get us back to it, while ne_prior 1489 * will get us back to the non-ephemeral mntinfo4. This is an 1490 * edge case we will need to be wary of when walking back up the 1491 * tree. 1492 * 1493 * The way we handle this edge case is to have ne_prior be NULL 1494 * for the root nfs4_ephemeral node. 1495 */ 1496 typedef struct nfs4_ephemeral { 1497 mntinfo4_t *ne_mount; /* who encloses us */ 1498 struct nfs4_ephemeral *ne_child; /* first child node */ 1499 struct nfs4_ephemeral *ne_peer; /* next sibling */ 1500 struct nfs4_ephemeral *ne_prior; /* who points at us */ 1501 time_t ne_ref_time; /* time last referenced */ 1502 uint_t ne_mount_to; /* timeout at */ 1503 int ne_state; /* used to traverse */ 1504 } nfs4_ephemeral_t; 1505 1506 /* 1507 * State for the node (set in ne_state): 1508 */ 1509 #define NFS4_EPHEMERAL_OK 0x0 1510 #define NFS4_EPHEMERAL_VISIT_CHILD 0x1 1511 #define NFS4_EPHEMERAL_VISIT_SIBLING 0x2 1512 #define NFS4_EPHEMERAL_PROCESS_ME 0x4 1513 #define NFS4_EPHEMERAL_CHILD_ERROR 0x8 1514 #define NFS4_EPHEMERAL_PEER_ERROR 0x10 1515 1516 /* 1517 * These are the locks used in processing ephemeral data: 1518 * 1519 * mi->mi_lock 1520 * 1521 * net->net_tree_lock 1522 * This lock is used to gate all tree operations. 1523 * If it is held, then no other process may 1524 * traverse the tree. This allows us to not 1525 * throw a hold on each vfs_t in the tree. 1526 * Can be held for a "long" time. 1527 * 1528 * net->net_cnt_lock 1529 * Used to protect refcnt and status. 1530 * Must be held for a really short time. 1531 * 1532 * nfs4_ephemeral_thread_lock 1533 * Is only held to create the harvester for the zone. 1534 * There is no ordering imposed on it. 1535 * Held for a really short time. 1536 * 1537 * Some further detail on the interactions: 1538 * 1539 * net_tree_lock controls access to net_root. Access needs to first be 1540 * attempted in a non-blocking check. 1541 * 1542 * net_cnt_lock controls access to net_refcnt and net_status. It must only be 1543 * held for very short periods of time, unless the refcnt is 0 and the status 1544 * is INVALID. 1545 * 1546 * Before a caller can grab net_tree_lock, it must first grab net_cnt_lock 1547 * to bump the net_refcnt. It then releases it and does the action specific 1548 * algorithm to get the net_tree_lock. Once it has that, then it is okay to 1549 * grab the net_cnt_lock and change the status. The status can only be 1550 * changed if the caller has the net_tree_lock held as well. 1551 * 1552 * Note that the initial grab of net_cnt_lock must occur whilst 1553 * mi_lock is being held. This prevents stale data in that if the 1554 * ephemeral tree is non-NULL, then the harvester can not remove 1555 * the tree from the mntinfo node until it grabs that lock. I.e., 1556 * we get the pointer to the tree and hold the lock atomically 1557 * with respect to being in mi_lock. 1558 * 1559 * When a caller is done with net_tree_lock, it can decrement the net_refcnt 1560 * either before it releases net_tree_lock or after. 1561 * 1562 * In either event, to decrement net_refcnt, it must hold net_cnt_lock. 1563 * 1564 * Note that the overall locking scheme for the nodes is to control access 1565 * via the tree. The current scheme could easily be extended such that 1566 * the enclosing root referenced a "forest" of trees. The underlying trees 1567 * would be autonomous with respect to locks. 1568 * 1569 * Note that net_next is controlled by external locks 1570 * particular to the data structure that the tree is being added to. 1571 */ 1572 typedef struct nfs4_ephemeral_tree { 1573 mntinfo4_t *net_mount; 1574 nfs4_ephemeral_t *net_root; 1575 struct nfs4_ephemeral_tree *net_next; 1576 kmutex_t net_tree_lock; 1577 kmutex_t net_cnt_lock; 1578 uint_t net_status; 1579 uint_t net_refcnt; 1580 } nfs4_ephemeral_tree_t; 1581 1582 /* 1583 * State for the tree (set in net_status): 1584 */ 1585 #define NFS4_EPHEMERAL_TREE_OK 0x0 1586 #define NFS4_EPHEMERAL_TREE_BUILDING 0x1 1587 #define NFS4_EPHEMERAL_TREE_DEROOTING 0x2 1588 #define NFS4_EPHEMERAL_TREE_INVALID 0x4 1589 #define NFS4_EPHEMERAL_TREE_MOUNTING 0x8 1590 #define NFS4_EPHEMERAL_TREE_UMOUNTING 0x10 1591 #define NFS4_EPHEMERAL_TREE_LOCKED 0x20 1592 1593 #define NFS4_EPHEMERAL_TREE_PROCESSING (NFS4_EPHEMERAL_TREE_DEROOTING | \ 1594 NFS4_EPHEMERAL_TREE_INVALID | NFS4_EPHEMERAL_TREE_UMOUNTING | \ 1595 NFS4_EPHEMERAL_TREE_LOCKED) 1596 1597 /* 1598 * This macro evaluates to non-zero if the given op releases state at the 1599 * server. For 4.1 sequence and destroy session, they are allowed after 1600 * an unmount. 1601 */ 1602 #define OH_IS_STATE_RELE(op) ((op) == OH_CLOSE || (op) == OH_LOCKU || \ 1603 (op) == OH_DELEGRETURN || \ 1604 (op) == OH_SEQUENCE || (op) == OH_DESTROY_SESS) 1605 1606 #ifdef _KERNEL 1607 1608 extern int layoutcmp(const void *, const void *); 1609 extern void nfs4_set_mod(vnode_t *); 1610 extern void nfs4_set_pageerror(page_t *); 1611 extern void nfs4_async_manager(struct vfs *); 1612 extern void nfs4_async_manager_stop(struct vfs *); 1613 extern void nfs4_async_stop(struct vfs *); 1614 extern int nfs4_async_stop_sig(struct vfs *); 1615 extern int nfs4_async_readahead(vnode_t *, u_offset_t, caddr_t, 1616 struct seg *, cred_t *, 1617 void (*)(vnode_t *, u_offset_t, 1618 caddr_t, struct seg *, cred_t *)); 1619 extern int nfs4_async_putapage(vnode_t *, page_t *, u_offset_t, size_t, 1620 int, cred_t *, int (*)(vnode_t *, page_t *, 1621 u_offset_t, size_t, int, cred_t *)); 1622 extern int nfs4_async_pageio(vnode_t *, page_t *, u_offset_t, size_t, 1623 int, cred_t *, int (*)(vnode_t *, page_t *, 1624 u_offset_t, size_t, int, cred_t *)); 1625 extern void nfs4_async_commit(vnode_t *, page_t *, offset3, count3, 1626 cred_t *, void (*)(vnode_t *, page_t *, 1627 offset3, count3, cred_t *)); 1628 extern void nfs4_async_inactive(vnode_t *, cred_t *); 1629 extern void nfs4_inactive_thread(mntinfo4_t *mi); 1630 extern void nfs4_inactive_otw(vnode_t *, cred_t *); 1631 extern int nfs4_putpages(vnode_t *, u_offset_t, size_t, int, cred_t *); 1632 1633 extern int nfs4_setopts(vnode_t *, model_t, struct nfs_args *); 1634 extern void nfs4_mnt_kstat_init(struct vfs *); 1635 1636 extern void nfs4_acl_fill_cache(struct rnode4 *, vsecattr_t *); 1637 extern int nfs4_attr_otw(vnode_t *, nfs4_tag_type_t, 1638 nfs4_ga_res_t *, attrmap4 *, cred_t *); 1639 1640 extern void nfs4_attrcache_noinval(vnode_t *, nfs4_ga_res_t *, hrtime_t); 1641 extern void nfs4_attr_cache(vnode_t *, nfs4_ga_res_t *, 1642 hrtime_t, cred_t *, int, 1643 change_info4 *); 1644 extern void nfs4_purge_rddir_cache(vnode_t *); 1645 extern void nfs4_invalidate_pages(vnode_t *, u_offset_t, cred_t *); 1646 extern void nfs4_purge_caches(vnode_t *, int, cred_t *, int); 1647 extern void nfs4_purge_stale_fh(int, vnode_t *, cred_t *); 1648 1649 extern void nfs4rename_update(vnode_t *, vnode_t *, nfs_fh4 *, char *); 1650 extern void nfs4_update_paths(vnode_t *, char *, vnode_t *, char *, 1651 vnode_t *); 1652 1653 extern void nfs4args_copen_free(OPEN4cargs *); 1654 1655 extern void nfs4_printfhandle(nfs4_fhandle_t *); 1656 1657 extern void nfs_free_mi4(mntinfo4_t *); 1658 extern servinfo4_t *new_servinfo4(mntinfo4_t *, char *, struct knetconfig *, 1659 struct netbuf *, int); 1660 extern void sv4_free(servinfo4_t *); 1661 1662 extern void nfs4_mi_zonelist_add(mntinfo4_t *); 1663 extern int nfs4_mi_zonelist_remove(mntinfo4_t *); 1664 extern int nfs4_secinfo_recov(mntinfo4_t *, vnode_t *, vnode_t *); 1665 extern void nfs4_secinfo_init(void); 1666 extern void nfs4_secinfo_fini(void); 1667 extern int nfs4_secinfo_path(mntinfo4_t *, cred_t *, int); 1668 extern int nfs4_secinfo_vnode_otw(vnode_t *, char *, cred_t *); 1669 extern void secinfo_free(sv_secinfo_t *); 1670 extern void save_mnt_secinfo(servinfo4_t *); 1671 extern void check_mnt_secinfo(servinfo4_t *, vnode_t *); 1672 extern int vattr_to_fattr4(vattr_t *, vsecattr_t *, fattr4 *, int, 1673 enum nfs_opnum4, attrmap4 *, int, file_layouthint4 *); 1674 extern int nfs4_putapage(vnode_t *, page_t *, u_offset_t *, size_t *, 1675 int, cred_t *); 1676 extern void nfs4_write_error(vnode_t *, int, cred_t *); 1677 extern void nfs4_lockcompletion(vnode_t *, int); 1678 extern bool_t nfs4_map_lost_lock_conflict(vnode_t *); 1679 extern int vtodv(vnode_t *, vnode_t **, cred_t *, bool_t); 1680 extern void nfs4open_confirm(vnode_t *, seqid4*, stateid4 *, cred_t *, 1681 bool_t, bool_t *, nfs4_open_owner_t *, bool_t, 1682 nfs4_error_t *, int *); 1683 extern void nfs4_error_zinit(nfs4_error_t *); 1684 extern void nfs4_error_init(nfs4_error_t *, int); 1685 extern void nfs4_free_args(struct nfs_args *); 1686 extern void nfs4_error_set(nfs4_error_t *, enum clnt_stat, enum nfsstat4); 1687 1688 extern void mi_hold(mntinfo4_t *); 1689 extern void mi_rele(mntinfo4_t *); 1690 1691 extern sec_data_t *copy_sec_data(sec_data_t *); 1692 extern gss_clntdata_t *copy_sec_data_gss(gss_clntdata_t *); 1693 1694 #ifdef DEBUG 1695 extern int nfs4_consistent_type(vnode_t *); 1696 #endif 1697 1698 extern void nfs4_init_dot_entries(void); 1699 extern void nfs4_destroy_dot_entries(void); 1700 extern struct nfs4_callback_globals *nfs4_get_callback_globals(void); 1701 extern int nfs4_commit(vnode_t *, page_t *, offset4, count4, cred_t *); 1702 extern int nfs4_commit_normal(vnode_t *, page_t *, offset4, count4, 1703 cred_t *); 1704 1705 extern struct nfs4_server nfs4_server_lst; 1706 1707 extern clock_t nfs_write_error_interval; 1708 1709 #endif /* _KERNEL */ 1710 1711 /* 1712 * Flags for nfs4getfh_otw. 1713 */ 1714 1715 #define NFS4_GETFH_PUBLIC 0x01 1716 #define NFS4_GETFH_NEEDSOP 0x02 1717 1718 /* 1719 * Found through rnodes. 1720 * 1721 * The os_open_ref_count keeps track the number of open file descriptor 1722 * refernces on this data structure. It will be bumped for any successful 1723 * OTW OPEN call and any OPEN call that determines the OTW call is not 1724 * necessary and the open stream hasn't just been created (see 1725 * nfs4_is_otw_open_necessary). 1726 * 1727 * os_mapcnt is a count of the number of mmapped pages for a particular 1728 * open stream; this in conjunction w/ os_open_ref_count is used to 1729 * determine when to do a close to the server. This is necessary because 1730 * of the semantics of doing open, mmap, close; the OTW close must be wait 1731 * until all open and mmap references have vanished. 1732 * 1733 * 'os_valid' tells us whether this structure is about to be freed or not, 1734 * if it is then don't return it in find_open_stream(). 1735 * 1736 * 'os_final_close' is set when a CLOSE OTW was attempted. This is needed 1737 * so we can properly count the os_open_ref_count in cases where we VOP_CLOSE 1738 * without a VOP_OPEN, and have nfs4_inactive() drive the OTW CLOSE. It 1739 * also helps differentiate the VOP_OPEN/VN_RELE case from the VOP_CLOSE 1740 * that tried to close OTW but failed, and left the state cleanup to 1741 * nfs4_inactive/CLOSE_FORCE. 1742 * 1743 * 'os_force_close' is used to let us know if an intervening thread came 1744 * and reopened the open stream after we decided to issue a CLOSE_FORCE, 1745 * but before we could actually process the CLOSE_FORCE. 1746 * 1747 * 'os_pending_close' is set when an over-the-wire CLOSE is deferred to the 1748 * lost state queue. 1749 * 1750 * 'open_stateid' is set the last open stateid returned by the server unless 1751 * 'os_delegation' is 1, in which case 'open_stateid' refers to the 1752 * delegation stateid returned by the server. This is used in cases where the 1753 * client tries to OPEN a file but already has a suitable delegation, so we 1754 * just stick the delegation stateid in the open stream. 1755 * 1756 * os_dc_openacc are open access bits which have been granted to the 1757 * open stream by virtue of a delegation, but which have not been seen 1758 * by the server. This applies even if the open stream does not have 1759 * os_delegation set. These bits are used when setting file locks to 1760 * determine whether an open with CLAIM_DELEGATE_CUR needs to be done 1761 * before the lock request can be sent to the server. See 1762 * nfs4frlock_check_deleg(). 1763 * 1764 * 'os_mmap_read/write' keep track of the read and write access our memory 1765 * maps require. We need to keep track of this so we can provide the proper 1766 * access bits in the open/mmap/close/reboot/reopen case. 1767 * 1768 * 'os_failed_reopen' tells us that we failed to successfully reopen this 1769 * open stream; therefore, we should not use this open stateid as it is 1770 * not valid anymore. This flag is also used to indicate an unsuccessful 1771 * attempt to reopen a delegation open stream with CLAIM_DELEGATE_CUR. 1772 * 1773 * If 'os_orig_oo_name' is different than os_open_owner's oo_name 1774 * then this tells us that this open stream's open owner used a 1775 * bad seqid (that is, got NFS4ERR_BAD_SEQID). If different, this open 1776 * stream will no longer be used for future OTW state releasing calls. 1777 * 1778 * Lock ordering: 1779 * rnode4_t::r_os_lock > os_sync_lock 1780 * os_sync_lock > rnode4_t::r_statelock 1781 * os_sync_lock > rnode4_t::r_statev4_lock 1782 * os_sync_lock > mntinfo4_t::mi_lock (via hold over rfs4call) 1783 * 1784 * The 'os_sync_lock' protects: 1785 * open_stateid 1786 * os_dc_openacc 1787 * os_delegation 1788 * os_failed_reopen 1789 * os_final_close 1790 * os_force_close 1791 * os_mapcnt 1792 * os_mmap_read 1793 * os_mmap_write 1794 * os_open_ref_count 1795 * os_pending_close 1796 * os_share_acc_read 1797 * os_share_acc_write 1798 * os_share_deny_none 1799 * os_share_deny_read 1800 * os_share_deny_write 1801 * os_ref_count 1802 * os_valid 1803 * 1804 * The rnode4_t::r_os_lock protects: 1805 * os_node 1806 * 1807 * These fields are set at creation time and 1808 * read only after that: 1809 * os_open_owner 1810 * os_orig_oo_name 1811 */ 1812 typedef struct nfs4_open_stream { 1813 uint64_t os_share_acc_read; 1814 uint64_t os_share_acc_write; 1815 uint64_t os_mmap_read; 1816 uint64_t os_mmap_write; 1817 uint32_t os_share_deny_none; 1818 uint32_t os_share_deny_read; 1819 uint32_t os_share_deny_write; 1820 stateid4 open_stateid; 1821 int os_dc_openacc; 1822 int os_ref_count; 1823 unsigned os_valid:1; 1824 unsigned os_delegation:1; 1825 unsigned os_final_close:1; 1826 unsigned os_pending_close:1; 1827 unsigned os_failed_reopen:1; 1828 unsigned os_force_close:1; 1829 int os_open_ref_count; 1830 long os_mapcnt; 1831 list_node_t os_node; 1832 struct nfs4_open_owner *os_open_owner; 1833 uint64_t os_orig_oo_name; 1834 kmutex_t os_sync_lock; 1835 } nfs4_open_stream_t; 1836 1837 /* 1838 * This structure describes the format of the lock_owner_name 1839 * field of the lock owner. 1840 */ 1841 1842 typedef struct nfs4_lo_name { 1843 uint64_t ln_seq_num; 1844 pid_t ln_pid; 1845 } nfs4_lo_name_t; 1846 1847 /* 1848 * Flags for lo_flags. 1849 */ 1850 #define NFS4_LOCK_SEQID_INUSE 0x1 1851 #define NFS4_BAD_SEQID_LOCK 0x2 1852 1853 /* 1854 * The lo_prev_rnode and lo_next_rnode are for a circular list that hangs 1855 * off the rnode. If the links are NULL it means this object is not on the 1856 * list. 1857 * 1858 * 'lo_pending_rqsts' is non-zero if we ever tried to send a request and 1859 * didn't get a response back. This is used to figure out if we have 1860 * possible remote v4 locks, so that we can clean up at process exit. In 1861 * theory, the client should be able to figure out if the server received 1862 * the request (based on what seqid works), so maybe we can get rid of this 1863 * flag someday. 1864 * 1865 * 'lo_ref_count' tells us how many processes/threads are using this data 1866 * structure. The rnode's list accounts for one reference. 1867 * 1868 * 'lo_just_created' is set to NFS4_JUST_CREATED when we first create the 1869 * data structure. It is then set to NFS4_PERM_CREATED when a lock request 1870 * is successful using this lock owner structure. We need to keep 'temporary' 1871 * lock owners around so we can properly keep the lock seqid synchronization 1872 * when multiple processes/threads are trying to create the lock owner for the 1873 * first time (especially with the DENIED error case). Once 1874 * 'lo_just_created' is set to NFS4_PERM_CREATED, it doesn't change. 1875 * 1876 * 'lo_valid' tells us whether this structure is about to be freed or not, 1877 * if it is then don't return it from find_lock_owner(). 1878 * 1879 * Retrieving and setting of 'lock_seqid' is protected by the 1880 * NFS4_LOCK_SEQID_INUSE flag. Waiters for NFS4_LOCK_SEQID_INUSE should 1881 * use 'lo_cv_seqid_sync'. 1882 * 1883 * The setting of 'lock_stateid' is protected by the 1884 * NFS4_LOCK_SEQID_INUSE flag and 'lo_lock'. The retrieving of the 1885 * 'lock_stateid' is protected by 'lo_lock', with the additional 1886 * requirement that the calling function can handle NFS4ERR_OLD_STATEID and 1887 * NFS4ERR_BAD_STATEID as appropiate. 1888 * 1889 * The setting of NFS4_BAD_SEQID_LOCK to lo_flags tells us whether this lock 1890 * owner used a bad seqid (that is, got NFS4ERR_BAD_SEQID). With this set, 1891 * this lock owner will no longer be used for future OTW calls. Once set, 1892 * it is never unset. 1893 * 1894 * Lock ordering: 1895 * rnode4_t::r_statev4_lock > lo_lock 1896 */ 1897 typedef struct nfs4_lock_owner { 1898 struct nfs4_lock_owner *lo_next_rnode; 1899 struct nfs4_lock_owner *lo_prev_rnode; 1900 int lo_pid; 1901 stateid4 lock_stateid; 1902 seqid4 lock_seqid; 1903 /* 1904 * Fix this to always be 12 bytes 1905 */ 1906 nfs4_lo_name_t lock_owner_name; 1907 int lo_ref_count; 1908 int lo_valid; 1909 int lo_pending_rqsts; 1910 int lo_just_created; 1911 int lo_flags; 1912 kcondvar_t lo_cv_seqid_sync; 1913 kmutex_t lo_lock; 1914 kthread_t *lo_seqid_holder; /* debugging aid */ 1915 } nfs4_lock_owner_t; 1916 1917 /* for nfs4_lock_owner_t lookups */ 1918 typedef enum {LOWN_ANY, LOWN_VALID_STATEID} lown_which_t; 1919 1920 /* Number of times to retry a call that fails with state independent error */ 1921 #define NFS4_NUM_RECOV_RETRIES 3 1922 1923 typedef enum { 1924 NO_SID, 1925 DEL_SID, 1926 LOCK_SID, 1927 OPEN_SID, 1928 SPEC_SID 1929 } nfs4_stateid_type_t; 1930 1931 typedef struct nfs4_stateid_types { 1932 stateid4 d_sid; 1933 stateid4 l_sid; 1934 stateid4 o_sid; 1935 nfs4_stateid_type_t cur_sid_type; 1936 } nfs4_stateid_types_t; 1937 1938 /* 1939 * Flags used to determine stateid we want. 1940 */ 1941 1942 #define GETSID_TRYNEXT 0x00000001 /* Try next stateid */ 1943 #define GETSID_LAYOUT 0x00000002 /* Need Stateid For Layoutget */ 1944 1945 1946 /* 1947 * Per-zone data for dealing with callbacks. Included here solely for the 1948 * benefit of MDB. 1949 */ 1950 struct nfs4_callback_stats { 1951 kstat_named_t delegations; 1952 kstat_named_t cb_getattr; 1953 kstat_named_t cb_recall; 1954 kstat_named_t cb_null; 1955 kstat_named_t cb_dispatch; 1956 kstat_named_t delegaccept_r; 1957 kstat_named_t delegaccept_rw; 1958 kstat_named_t delegreturn; 1959 kstat_named_t callbacks; 1960 kstat_named_t claim_cur; 1961 kstat_named_t claim_cur_ok; 1962 kstat_named_t recall_trunc; 1963 kstat_named_t recall_failed; 1964 kstat_named_t return_limit_write; 1965 kstat_named_t return_limit_addmap; 1966 kstat_named_t deleg_recover; 1967 kstat_named_t cb_illegal; 1968 kstat_named_t cb_sequence; 1969 }; 1970 1971 struct nfs41_cb_info { 1972 rpcprog_t cb_prog; 1973 SVC_DISPATCH *cb_dispatch; 1974 CLIENT *cb_client; 1975 struct nfs4_clnt *cb_nfscl; 1976 int cb_state; 1977 kmutex_t cb_cbconn_lock; 1978 kcondvar_t cb_cbconn_wait; /* cbconn heartbeat */ 1979 int cb_cbconn_exit; 1980 int cb_refcnt; 1981 kmutex_t cb_reflock; 1982 kcondvar_t cb_destroy_wait; 1983 } nfs41_cb_info_t; 1984 1985 struct nfs4_callback_globals { 1986 kmutex_t nfs4_cb_lock; 1987 kmutex_t nfs4_dlist_lock; 1988 int nfs4_program_hint; 1989 /* this table maps the program number to the nfs4_server structure */ 1990 struct nfs4_server **nfs4prog2server; 1991 struct nfs41_cb_info **nfs4prog2cbinfo; 1992 list_t nfs4_dlist; 1993 list_t nfs4_cb_ports; 1994 struct nfs4_callback_stats nfs4_callback_stats; 1995 #ifdef DEBUG 1996 int nfs4_dlistadd_c; 1997 int nfs4_dlistclean_c; 1998 #endif 1999 }; 2000 2001 typedef enum { 2002 CLOSE_NORM, 2003 CLOSE_DELMAP, 2004 CLOSE_FORCE, 2005 CLOSE_RESEND, 2006 CLOSE_AFTER_RESEND 2007 } nfs4_close_type_t; 2008 2009 /* 2010 * Structure to hold the bad seqid information that is passed 2011 * to the recovery framework. 2012 */ 2013 typedef struct nfs4_bseqid_entry { 2014 nfs4_open_owner_t *bs_oop; 2015 nfs4_lock_owner_t *bs_lop; 2016 vnode_t *bs_vp; 2017 pid_t bs_pid; 2018 nfs4_tag_type_t bs_tag; 2019 seqid4 bs_seqid; 2020 list_node_t bs_node; 2021 } nfs4_bseqid_entry_t; 2022 2023 typedef struct nfs4_tagswap { 2024 sessionid4 ts_oldtag; 2025 sessionid4 *ts_newtag; 2026 } nfs4_tagswap_t; 2027 2028 #ifdef _KERNEL 2029 2030 extern void nfs4close_one(vnode_t *, nfs4_open_stream_t *, cred_t *, int, 2031 nfs4_lost_rqst_t *, nfs4_error_t *, nfs4_close_type_t, 2032 size_t, uint_t, uint_t); 2033 extern void nfs4close_notw(vnode_t *, nfs4_open_stream_t *, int *); 2034 extern void nfs4_set_lock_stateid(nfs4_lock_owner_t *, stateid4); 2035 extern void open_owner_hold(nfs4_open_owner_t *); 2036 extern void open_owner_rele(nfs4_open_owner_t *); 2037 extern nfs4_open_stream_t *find_or_create_open_stream(nfs4_open_owner_t *, 2038 struct rnode4 *, int *); 2039 extern nfs4_open_stream_t *find_open_stream(nfs4_open_owner_t *, 2040 struct rnode4 *); 2041 extern nfs4_open_stream_t *create_open_stream(nfs4_open_owner_t *oop, 2042 struct rnode4 *rp); 2043 extern void open_stream_hold(nfs4_open_stream_t *); 2044 extern void open_stream_rele(nfs4_open_stream_t *, struct rnode4 *); 2045 extern int nfs4close_all(vnode_t *, cred_t *); 2046 extern void lock_owner_hold(nfs4_lock_owner_t *); 2047 extern void lock_owner_rele(nfs4_lock_owner_t *); 2048 extern nfs4_lock_owner_t *create_lock_owner(struct rnode4 *, pid_t); 2049 extern nfs4_lock_owner_t *find_lock_owner(struct rnode4 *, pid_t, lown_which_t); 2050 extern void nfs4_rnode_remove_lock_owner(struct rnode4 *, 2051 nfs4_lock_owner_t *); 2052 extern void nfs4_flush_lock_owners(struct rnode4 *); 2053 extern void nfs4_setlockowner_args(lock_owner4 *, struct rnode4 *, pid_t); 2054 extern void nfs4_set_open_seqid(seqid4, nfs4_open_owner_t *, 2055 nfs4_tag_type_t); 2056 extern void nfs4_set_lock_seqid(seqid4, nfs4_lock_owner_t *); 2057 extern void nfs4_end_open_seqid_sync(nfs4_open_owner_t *); 2058 extern int nfs4_start_open_seqid_sync(nfs4_open_owner_t *, mntinfo4_t *); 2059 extern void nfs4_end_lock_seqid_sync(nfs4_lock_owner_t *); 2060 extern int nfs4_start_lock_seqid_sync(nfs4_lock_owner_t *, mntinfo4_t *); 2061 extern void nfs4_setup_lock_args(nfs4_lock_owner_t *, nfs4_open_owner_t *, 2062 nfs4_open_stream_t *, mntinfo4_t *, locker4 *); 2063 extern void nfs4_destroy_open_owner(nfs4_open_owner_t *); 2064 2065 extern void nfs4_renew_lease_thread(nfs4_server_t *); 2066 extern void nfs4_sequence_heartbeat_thread(nfs4_server_t *); 2067 extern void nfs4_cbconn_thread(nfs4_server_t *); 2068 extern nfs4_server_t *find_nfs4_server(mntinfo4_t *); 2069 extern nfs4_server_t *find_nfs4_server_nolock(mntinfo4_t *); 2070 extern nfs4_server_t *find_nfs4_server_all(mntinfo4_t *, int all); 2071 extern nfs4_server_t *find_nfs4_server_by_servinfo4(servinfo4_t *); 2072 extern nfs4_server_t *new_nfs4_server(servinfo4_t *, cred_t *); 2073 extern nfs4_server_t *add_new_nfs4_server(servinfo4_t *, cred_t *); 2074 extern void nfs4_mark_srv_dead(nfs4_server_t *, uint_t); 2075 extern nfs4_server_t *servinfo4_to_nfs4_server(servinfo4_t *); 2076 extern void nfs4_inc_state_ref_count(mntinfo4_t *); 2077 extern void nfs4_inc_state_ref_count_nolock(nfs4_server_t *, 2078 mntinfo4_t *); 2079 extern void nfs4_dec_state_ref_count(mntinfo4_t *); 2080 extern void nfs4_dec_state_ref_count_nolock(nfs4_server_t *, 2081 mntinfo4_t *); 2082 extern clientid4 mi2clientid(mntinfo4_t *); 2083 extern int nfs4_server_in_recovery(nfs4_server_t *); 2084 extern bool_t nfs4_server_vlock(nfs4_server_t *, int); 2085 extern nfs4_open_owner_t *create_open_owner(cred_t *, mntinfo4_t *); 2086 extern uint64_t nfs4_get_new_oo_name(void); 2087 extern nfs4_open_owner_t *find_open_owner(cred_t *, int, mntinfo4_t *); 2088 extern nfs4_open_owner_t *find_open_owner_nolock(cred_t *, int, mntinfo4_t *); 2089 extern void nfs4frlock(nfs4_lock_call_type_t, vnode_t *, int, flock64_t *, 2090 int, u_offset_t, cred_t *, nfs4_error_t *, 2091 nfs4_lost_rqst_t *, int *); 2092 extern void nfs4open_dg_save_lost_rqst(int, nfs4_lost_rqst_t *, 2093 nfs4_open_owner_t *, nfs4_open_stream_t *, cred_t *, 2094 vnode_t *, int, int); 2095 extern void nfs4_open_downgrade(int, int, nfs4_open_owner_t *, 2096 nfs4_open_stream_t *, vnode_t *, cred_t *, 2097 nfs4_lost_rqst_t *, nfs4_error_t *, cred_t **, seqid4 *); 2098 extern seqid4 nfs4_get_open_seqid(nfs4_open_owner_t *); 2099 extern cred_t *nfs4_get_otw_cred(cred_t *, mntinfo4_t *, nfs4_open_owner_t *); 2100 extern void nfs4_init_stateid_types(nfs4_stateid_types_t *); 2101 extern void nfs4_save_stateid(stateid4 *, nfs4_stateid_types_t *); 2102 2103 extern kmutex_t nfs4_server_lst_lock; 2104 2105 extern void nfs4_cleanup_oldsession(mntinfo4_t *, servinfo4_t *, 2106 nfs4_server_t *); 2107 2108 /* flags for nfs4destroy_session */ 2109 #define N4DS_TERMINATE_HB_THREAD 1 2110 #define N4DS_DESTROY_OTW 2 2111 #define N4DS_DESTROY_INZONE 4 2112 2113 extern void nfs4destroy_session(nfs4_server_t *, mntinfo4_t *, 2114 servinfo4_t *, nfs4_error_t *, int); 2115 extern void nfs41_cbinfo_rele(struct nfs41_cb_info *); 2116 extern void nfs4callback_destroy(nfs4_server_t *); 2117 extern void nfs4_callback_init(void); 2118 extern void nfs4_callback_fini(void); 2119 2120 extern void nfs41_cb_args(nfs4_server_t *, struct knetconfig *, 2121 CREATE_SESSION4args *); 2122 extern void nfs4_cb_args(nfs4_server_t *, struct knetconfig *, 2123 SETCLIENTID4args *); 2124 extern void nfs41set_callback(nfs4_server_t *, servinfo4_t *, 2125 mntinfo4_t *, cred_t *); 2126 extern void nfs4delegreturn_async(struct rnode4 *, int, bool_t); 2127 2128 extern enum nfs4_delegreturn_policy nfs4_delegreturn_policy; 2129 2130 extern void nfs4_add_mi_to_server(nfs4_server_t *, mntinfo4_t *); 2131 extern void nfs4_remove_mi_from_server(mntinfo4_t *, nfs4_server_t *); 2132 extern nfs4_server_t *nfs4_move_mi(mntinfo4_t *, servinfo4_t *, servinfo4_t *); 2133 extern bool_t nfs4_fs_active(nfs4_server_t *); 2134 extern void nfs4_server_hold(nfs4_server_t *); 2135 extern void nfs4_server_rele(nfs4_server_t *); 2136 extern void nfs4_server_rele_lockt(nfs4_server_t *); 2137 extern bool_t inlease(nfs4_server_t *); 2138 extern bool_t nfs4_has_pages(vnode_t *); 2139 extern void nfs4_log_badowner(mntinfo4_t *, nfs_opnum4); 2140 2141 #endif /* _KERNEL */ 2142 2143 /* 2144 * Client State Recovery 2145 */ 2146 2147 /* 2148 * The following defines are used for rs_flags in 2149 * a nfs4_recov_state_t structure. 2150 * 2151 * NFS4_RS_RENAME_HELD Indicates that the mi_rename_lock was held. 2152 * NFS4_RS_GRACE_MSG Set once we have uprintf'ed a grace message. 2153 * NFS4_RS_DELAY_MSG Set once we have uprintf'ed a delay message. 2154 * NFS4_RS_RECALL_HELD1 r_deleg_recall_lock for vp1 was held. 2155 * NFS4_RS_RECALL_HELD2 r_deleg_recall_lock for vp2 was held. 2156 * NFS4_RS_NEEDS_RECOVERY Indicates recovery needed (for debug). 2157 */ 2158 #define NFS4_RS_RENAME_HELD 0x000000001 2159 #define NFS4_RS_GRACE_MSG 0x000000002 2160 #define NFS4_RS_DELAY_MSG 0x000000004 2161 #define NFS4_RS_RECALL_HELD1 0x000000008 2162 #define NFS4_RS_RECALL_HELD2 0x000000010 2163 #define NFS4_RS_NEEDS_RECOVERY 0x000000020 2164 2165 #define NFS4_RS_RECOVSTR(rs) \ 2166 (((rs)->rs_flags & NFS4_RS_NEEDS_RECOVERY) ? "recov" : "first") 2167 2168 /* 2169 * Information that is retrieved from nfs4_start_op() and that is 2170 * passed into nfs4_end_op(). 2171 * 2172 * rs_sp is a reference to the nfs4_server that was found, or NULL. 2173 * 2174 * rs_num_retry_despite_err is the number times client retried an 2175 * OTW op despite a recovery error. It is only incremented for hints 2176 * exempt to normal R4RECOVERR processing 2177 * (OH_CLOSE/OH_LOCKU/OH_DELEGRETURN). (XXX this special-case code 2178 * needs review for possible removal.) 2179 * It is initialized wherever nfs4_recov_state_t is declared -- usually 2180 * very near initialization of rs_flags. 2181 */ 2182 typedef struct { 2183 nfs4_server_t *rs_sp; 2184 int rs_flags; 2185 int rs_num_retry_despite_err; 2186 } nfs4_recov_state_t; 2187 2188 /* 2189 * Flags for nfs4_check_remap, nfs4_remap_file and nfs4_remap_root. 2190 */ 2191 2192 #define NFS4_REMAP_CKATTRS 1 2193 #define NFS4_REMAP_NEEDSOP 2 2194 2195 #ifdef _KERNEL 2196 2197 extern int nfs4_is_otw_open_necessary(nfs4_open_owner_t *, int, 2198 vnode_t *, int, int *, int, nfs4_recov_state_t *); 2199 extern void nfs4exchange_id(struct mntinfo4 *, struct cred *, bool_t, 2200 nfs4_error_t *); 2201 extern void nfs4create_session(mntinfo4_t *, servinfo4_t *, cred_t *, 2202 nfs4_server_t *, nfs4_error_t *); 2203 extern int nfs4bind_conn_to_session(nfs4_server_t *, servinfo4_t *, 2204 struct mntinfo4 *, cred_t *, channel_dir_from_client4); 2205 extern int nfs4_tag_ctl(nfs4_server_t *, mntinfo4_t *, servinfo4_t *, 2206 sessionid4, int, cred_t *); 2207 extern void nfs4_reopen(vnode_t *, nfs4_open_stream_t *, nfs4_error_t *, 2208 open_claim_type4, bool_t, bool_t); 2209 extern void nfs4_remap_root(struct mntinfo4 *, nfs4_error_t *, int); 2210 extern void nfs4_check_remap(mntinfo4_t *mi, vnode_t *vp, int, 2211 nfs4_error_t *); 2212 extern void nfs4_remap_file(mntinfo4_t *mi, vnode_t *vp, int, 2213 nfs4_error_t *); 2214 extern int nfs4_make_dotdot(struct nfs4_sharedfh *, hrtime_t, 2215 vnode_t *, cred_t *, vnode_t **, int); 2216 extern void nfs4_fail_recov(vnode_t *, char *, int, nfsstat4); 2217 2218 extern int nfs4_recov_marks_dead(nfsstat4); 2219 extern char *nfs4_recov_action_to_str(nfs4_recov_t); 2220 2221 /* 2222 * In sequence, code desiring to unmount an ephemeral tree must 2223 * call nfs4_ephemeral_umount, nfs4_ephemeral_umount_activate, 2224 * and nfs4_ephemeral_umount_unlock. The _unlock must also be 2225 * called on all error paths that occur before it would naturally 2226 * be invoked. 2227 * 2228 * The caller must also provde a pointer to a boolean to keep track 2229 * of whether or not the code in _unlock is to be ran. 2230 */ 2231 extern void nfs4_ephemeral_umount_activate(mntinfo4_t *, 2232 bool_t *, bool_t *, nfs4_ephemeral_tree_t **); 2233 extern int nfs4_ephemeral_umount(mntinfo4_t *, int, cred_t *, 2234 bool_t *, bool_t *, nfs4_ephemeral_tree_t **); 2235 extern void nfs4_ephemeral_umount_unlock(bool_t *, bool_t *, 2236 nfs4_ephemeral_tree_t **); 2237 2238 extern int nfs4_record_ephemeral_mount(mntinfo4_t *mi, vnode_t *mvp); 2239 2240 extern int wait_for_recall(vnode_t *, vnode_t *, nfs4_op_hint_t, 2241 nfs4_recov_state_t *); 2242 extern void nfs4_end_op_recall(vnode_t *, vnode_t *, nfs4_recov_state_t *); 2243 extern void nfs4_send_siglost(pid_t, mntinfo4_t *mi, vnode_t *vp, bool_t, 2244 int, nfsstat4); 2245 extern time_t nfs4err_delay_time; 2246 extern void nfs4_set_grace_wait(mntinfo4_t *); 2247 extern void nfs4_set_delay_wait(vnode_t *); 2248 extern int nfs4_wait_for_grace(mntinfo4_t *, nfs4_recov_state_t *, int); 2249 extern int nfs4_wait_for_delay(vnode_t *, nfs4_recov_state_t *, int); 2250 extern nfs4_bseqid_entry_t *nfs4_create_bseqid_entry(nfs4_open_owner_t *, 2251 nfs4_lock_owner_t *, vnode_t *, pid_t, nfs4_tag_type_t, 2252 seqid4); 2253 2254 extern void nfs4_resend_open_otw(vnode_t **, nfs4_lost_rqst_t *, 2255 nfs4_error_t *); 2256 extern void nfs4_resend_delegreturn(nfs4_lost_rqst_t *, nfs4_error_t *, 2257 nfs4_server_t *); 2258 extern int nfs4_rpc_retry_error(int); 2259 extern int nfs4_try_failover(nfs4_error_t *); 2260 extern void nfs4_free_msg(nfs4_debug_msg_t *); 2261 extern void nfs4_mnt_recov_kstat_init(vfs_t *); 2262 extern void nfs4_mi_kstat_inc_delay(mntinfo4_t *); 2263 extern void nfs4_mi_kstat_inc_no_grace(mntinfo4_t *); 2264 extern char *nfs4_stat_to_str(nfsstat4); 2265 extern void nfs4exchange_id_otw(mntinfo4_t *, servinfo4_t *, cred_t *, 2266 nfs4_server_t *, nfs4_error_t *, int *); 2267 extern void nfs4session_init(void); 2268 extern void nfs4_pnfs_init_n4s(struct nfs4_server *); 2269 extern void pnfs_rele_device(struct nfs4_server *, struct devnode *); 2270 2271 extern void nfs4_queue_event(nfs4_event_type_t, mntinfo4_t *, char *, 2272 uint_t, vnode_t *, vnode_t *, nfsstat4, char *, pid_t, 2273 nfs4_tag_type_t, nfs4_tag_type_t, seqid4, seqid4); 2274 extern void nfs4_queue_fact(nfs4_fact_type_t, mntinfo4_t *, nfsstat4, 2275 nfs4_recov_t, nfs_opnum4, bool_t, char *, int, vnode_t *); 2276 #pragma rarely_called(nfs4_queue_event) 2277 #pragma rarely_called(nfs4_queue_fact) 2278 2279 /* Used for preformed "." and ".." dirents */ 2280 extern char *nfs4_dot_entries; 2281 extern char *nfs4_dot_dot_entry; 2282 2283 #ifdef DEBUG 2284 extern uint_t nfs4_tsd_key; 2285 #endif 2286 2287 #endif /* _KERNEL */ 2288 2289 /* 2290 * Filehandle management. 2291 * 2292 * Filehandles can change in v4, so rather than storing the filehandle 2293 * directly in the rnode, etc., we manage the filehandle through one of 2294 * these objects. 2295 * Locking: sfh_fh and sfh_tree is protected by the filesystem's 2296 * mi_fh_lock. The reference count and flags are protected by sfh_lock. 2297 * sfh_mi is read-only. 2298 * 2299 * mntinfo4_t::mi_fh_lock > sfh_lock. 2300 */ 2301 2302 typedef struct nfs4_sharedfh { 2303 nfs_fh4 sfh_fh; /* key and current filehandle */ 2304 kmutex_t sfh_lock; 2305 uint_t sfh_refcnt; /* reference count */ 2306 uint_t sfh_flags; 2307 mntinfo4_t *sfh_mi; /* backptr to filesystem */ 2308 avl_node_t sfh_tree; /* used by avl package */ 2309 } nfs4_sharedfh_t; 2310 2311 #define SFH4_SAME(sfh1, sfh2) ((sfh1) == (sfh2)) 2312 2313 /* 2314 * Flags. 2315 */ 2316 #define SFH4_IN_TREE 0x1 /* currently in an AVL tree */ 2317 2318 #ifdef _KERNEL 2319 2320 extern void sfh4_createtab(avl_tree_t *); 2321 extern nfs4_sharedfh_t *sfh4_get(const nfs_fh4 *, mntinfo4_t *); 2322 extern nfs4_sharedfh_t *sfh4_put(const nfs_fh4 *, mntinfo4_t *, 2323 nfs4_sharedfh_t *); 2324 extern void sfh4_update(nfs4_sharedfh_t *, const nfs_fh4 *); 2325 extern void sfh4_copyval(const nfs4_sharedfh_t *, nfs4_fhandle_t *); 2326 extern void sfh4_hold(nfs4_sharedfh_t *); 2327 extern void sfh4_rele(nfs4_sharedfh_t **); 2328 extern void sfh4_printfhandle(const nfs4_sharedfh_t *); 2329 2330 #endif 2331 2332 /* 2333 * Path and file name management. 2334 * 2335 * This type stores the name of an entry in the filesystem and keeps enough 2336 * information that it can provide a complete path. All fields are 2337 * protected by fn_lock, except for the reference count, which is managed 2338 * using atomic add/subtract. 2339 * 2340 * Additionally shared filehandle for this fname is stored. 2341 * Normally, fn_get() when it creates this fname stores the passed in 2342 * shared fh in fn_sfh by doing sfh_hold. Similarly the path which 2343 * destroys this fname releases the reference on this fh by doing sfh_rele. 2344 * 2345 * fn_get uses the fn_sfh to refine the comparision in cases 2346 * where we have matched the name but have differing file handles, 2347 * this normally happens due to 2348 * 2349 * 1. Server side rename of a file/directory. 2350 * 2. Another client renaming a file/directory on the server. 2351 * 2352 * Differing names but same filehandle is possible as in the case of hardlinks, 2353 * but differing filehandles with same name component will later confuse 2354 * the client and can cause various panics. 2355 * 2356 * Lock order: child and then parent. 2357 */ 2358 2359 typedef struct nfs4_fname { 2360 struct nfs4_fname *fn_parent; /* parent name; null if fs root */ 2361 char *fn_name; /* the actual name */ 2362 ssize_t fn_len; /* strlen(fn_name) */ 2363 uint32_t fn_refcnt; /* reference count */ 2364 kmutex_t fn_lock; 2365 avl_node_t fn_tree; 2366 avl_tree_t fn_children; /* children, if any */ 2367 nfs4_sharedfh_t *fn_sfh; /* The fh for this fname */ 2368 } nfs4_fname_t; 2369 2370 #ifdef _KERNEL 2371 2372 extern vnode_t nfs4_xattr_notsupp_vnode; 2373 #define NFS4_XATTR_DIR_NOTSUPP &nfs4_xattr_notsupp_vnode 2374 2375 extern nfs4_fname_t *fn_get(nfs4_fname_t *, char *, nfs4_sharedfh_t *); 2376 extern void fn_hold(nfs4_fname_t *); 2377 extern void fn_rele(nfs4_fname_t **); 2378 extern char *fn_name(nfs4_fname_t *); 2379 extern char *fn_path(nfs4_fname_t *); 2380 extern void fn_move(nfs4_fname_t *, nfs4_fname_t *, char *); 2381 extern nfs4_fname_t *fn_parent(nfs4_fname_t *); 2382 #endif 2383 2384 /* 2385 * Per-zone data for managing client handles, included in this file for the 2386 * benefit of MDB. 2387 */ 2388 struct nfs4_clnt { 2389 struct chhead *nfscl_chtable4; 2390 kmutex_t nfscl_chtable4_lock; 2391 zoneid_t nfscl_zoneid; 2392 list_node_t nfscl_node; 2393 /* 2394 * nfscl_stat[0] for minor version 0 2395 * nfscl_stat[1] for minor version 1 2396 */ 2397 struct clstat4 nfscl_stat[NFS4_MINORVERSMAX + 1]; 2398 }; 2399 2400 /* 2401 * New recovery interfaces & structures 2402 */ 2403 typedef struct nfs4_call { 2404 mntinfo4_t *nc_mi; 2405 vnode_t *nc_vp1; 2406 vnode_t *nc_vp2; 2407 2408 /* needed by nfs4_start_fop */ 2409 nfs4_op_hint_t nc_ophint; 2410 int nc_start_recov; 2411 2412 /* needed by nfs4_needs_recovery */ 2413 int nc_stateful; 2414 nfs4_error_t nc_e; 2415 2416 /* needed by start_recovery */ 2417 nfs_opnum4 nc_opnum; 2418 nfs4_lost_rqst_t *nc_lost_rqst; 2419 nfs4_bseqid_entry_t *nc_bseqid_rqst; 2420 2421 /* needed by rfs4call */ 2422 int nc_doqueue[1]; 2423 int nc_rfs4call_flags; 2424 cred_t *nc_cr; 2425 servinfo4_t *nc_svp; 2426 nfs4_server_t *nc_slot_srv; 2427 slot_ent_t *nc_slot_ent; 2428 2429 /* new pnfs stuffs */ 2430 servinfo4_t *nc_ds_servinfo; /* NULL if call targets MDS */ 2431 nfs4_server_t *nc_ds_nfs4_srv; /* NULL if call targets MDS */ 2432 kmutex_t nc_lock[1]; 2433 uint_t nc_count; 2434 int nc_needs_recovery; 2435 int nc_wait_for_recovery; 2436 2437 COMPOUND4args_clnt nc_args; 2438 COMPOUND4res_clnt nc_res; 2439 int nc_flags; 2440 } nfs4_call_t; 2441 2442 #define NFS4_CALL_FLAG_RESFREE 0x01 /* need to free nc_res */ 2443 #define NFS4_CALL_FLAG_SEQADDED 0x02 /* sequence op added */ 2444 #define NFS4_CALL_FLAG_RCV_DONTBLOCK 0x04 /* Don't block, return EAGAIN */ 2445 #define NFS4_CALL_FLAG_SLOT_HELD 0x08 /* slot is held */ 2446 #define NFS4_CALL_FLAG_SLOT_RECALLED 0x10 /* slot was recalled */ 2447 #define NFS4_CALL_FLAG_SLOT_INCR 0x20 /* increment slot seq */ 2448 2449 #ifdef _KERNEL 2450 extern nfs4_call_t *nfs4_call_init(int, nfs_opnum4, nfs4_op_hint_t, int, 2451 mntinfo4_t *, vnode_t *, vnode_t *, cred_t *); 2452 extern void nfs4_call_hold(nfs4_call_t *); 2453 extern void nfs4_call_rele(nfs4_call_t *); 2454 extern void nfs4_call_slot_release(nfs4_call_t *); 2455 extern void nfs4_call_slot_clear(nfs4_call_t *); 2456 extern void nfs4_call_opresfree(nfs4_call_t *); 2457 extern COMPOUND4node_clnt *nfs4_op_generic(nfs4_call_t *, nfs_opnum4); 2458 extern SEQUENCE4res *nfs4_op_sequence(nfs4_call_t *); 2459 extern PUTFH4res *nfs4_op_cputfh(nfs4_call_t *, nfs4_sharedfh_t *); 2460 extern GETFH4res *nfs4_op_getfh(nfs4_call_t *); 2461 extern SAVEFH4res *nfs4_op_savefh(nfs4_call_t *); 2462 extern RESTOREFH4res *nfs4_op_restorefh(nfs4_call_t *); 2463 extern ACCESS4res *nfs4_op_access(nfs4_call_t *, uint32_t); 2464 extern GETATTR4res *nfs4_op_getattr(nfs4_call_t *, attrmap4); 2465 extern OPEN4res *nfs4_op_copen(nfs4_call_t *, OPEN4cargs **); 2466 extern OPEN_DOWNGRADE4res *nfs4_op_open_downgrade(nfs4_call_t *, stateid4 *, 2467 seqid4, uint32_t, uint32_t); 2468 extern CLOSE4res *nfs4_op_close(nfs4_call_t *, seqid4, stateid4); 2469 extern LAYOUTCOMMIT4res *nfs4_op_layoutcommit(nfs4_call_t *, 2470 LAYOUTCOMMIT4args **); 2471 extern WRITE4res *nfs4_op_write(nfs4_call_t *, stable_how4, WRITE4args **); 2472 extern READ4res *nfs4_op_read(nfs4_call_t *, READ4args **); 2473 extern SETATTR4res *nfs4_op_setattr(nfs4_call_t *, SETATTR4args **); 2474 extern VERIFY4res *nfs4_op_verify(nfs4_call_t *, VERIFY4args **); 2475 extern NVERIFY4res *nfs4_op_nverify(nfs4_call_t *, NVERIFY4args **); 2476 extern READLINK4res *nfs4_op_readlink(nfs4_call_t *); 2477 extern REMOVE4res *nfs4_op_cremove(nfs4_call_t *, char *); 2478 extern LOOKUP4res *nfs4_op_lookup(nfs4_call_t *, utf8string *); 2479 extern LOOKUP4res *nfs4_op_clookup(nfs4_call_t *, char *); 2480 extern LOOKUPP4res *nfs4_op_lookupp(nfs4_call_t *); 2481 extern OPENATTR4res *nfs4_op_openattr(nfs4_call_t *, bool_t); 2482 extern CREATE4res *nfs4_op_ccreate(nfs4_call_t *, char *, nfs_ftype4, void *, 2483 CREATE4cargs **); 2484 extern LINK4res *nfs4_op_clink(nfs4_call_t *, char *); 2485 extern RENAME4res *nfs4_op_crename(nfs4_call_t *, char *, char *); 2486 extern READDIR4res_clnt *nfs4_op_readdir(nfs4_call_t *, READDIR4args **); 2487 extern COMMIT4res *nfs4_op_commit(nfs4_call_t *, offset4, count4); 2488 extern OPEN_CONFIRM4res *nfs4_op_open_confirm(nfs4_call_t *, seqid4, 2489 stateid4 *); 2490 extern LOCK4res *nfs4_op_lock(nfs4_call_t *, LOCK4args **); 2491 extern LOCKU4res *nfs4_op_locku(nfs4_call_t *, LOCKU4args **); 2492 extern LOCKT4res *nfs4_op_lockt(nfs4_call_t *, LOCKT4args **); 2493 extern PUTPUBFH4res *nfs4_op_putpubfh(nfs4_call_t *); 2494 extern PUTROOTFH4res *nfs4_op_putrootfh(nfs4_call_t *); 2495 extern SECINFO4res *nfs4_op_secinfo(nfs4_call_t *, component4 *); 2496 extern SECINFO4res *nfs4_op_csecinfo(nfs4_call_t *, char *); 2497 extern BIND_CONN_TO_SESSION4res *nfs4_op_bind_conn_to_session(nfs4_call_t *cp, 2498 sessionid4 *, channel_dir_from_client4, bool_t); 2499 extern DELEGRETURN4res *nfs4_op_delegreturn(nfs4_call_t *, stateid4 *); 2500 extern RENEW4res *nfs4_op_renew(nfs4_call_t *, clientid4); 2501 extern EXCHANGE_ID4res *nfs4_op_exchange_id(nfs4_call_t *, EXCHANGE_ID4args **); 2502 extern CREATE_SESSION4res *nfs4_op_create_session(nfs4_call_t *, 2503 CREATE_SESSION4args **); 2504 extern SETCLIENTID4res *nfs4_op_setclientid(nfs4_call_t *, SETCLIENTID4args **); 2505 extern SETCLIENTID_CONFIRM4res *nfs4_op_setclientid_confirm(nfs4_call_t *, 2506 clientid4, verifier4); 2507 extern RECLAIM_COMPLETE4res *nfs4_op_reclaim_complete(nfs4_call_t *, bool_t); 2508 extern GETDEVICEINFO4res *nfs4_op_getdeviceinfo(nfs4_call_t *, deviceid4, 2509 layouttype4, count4, bitmap4); 2510 extern LAYOUTRETURN4res *nfs4_op_layoutreturn(nfs4_call_t *, 2511 LAYOUTRETURN4args **); 2512 extern LAYOUTGET4res *nfs4_op_layoutget(nfs4_call_t *, LAYOUTGET4args **); 2513 extern GETDEVICELIST4res *nfs4_op_getdevicelist(nfs4_call_t *, 2514 GETDEVICELIST4args **); 2515 extern DESTROY_SESSION4res *nfs4_op_destroy_session(nfs4_call_t *, sessionid4); 2516 2517 extern void nfs4lookup_setup(nfs4_call_t *, char *, lkp4_attr_setup_t, 2518 attrmap4, int); 2519 extern void nfs4args_lookup_free(nfs4_call_t *); 2520 extern void rfs4call(nfs4_call_t *, nfs4_error_t *); 2521 extern int nfs4_start_op(nfs4_call_t *, nfs4_recov_state_t *); 2522 extern void nfs4_end_op(nfs4_call_t *, nfs4_recov_state_t *); 2523 extern void nfs4_needs_recovery(nfs4_call_t *); 2524 extern bool_t nfs4_start_recovery(nfs4_call_t *); 2525 2526 /* interim */ 2527 extern int nfs4_needs_recovery_old(nfs4_error_t *, bool_t, vfs_t *); 2528 extern bool_t nfs4_start_recovery_old(nfs4_error_t *, struct mntinfo4 *, 2529 vnode_t *, vnode_t *, nfs4_lost_rqst_t *, nfs_opnum4, 2530 nfs4_bseqid_entry_t *); 2531 #endif /* _KERNEL */ 2532 2533 #ifdef __cplusplus 2534 } 2535 #endif 2536 2537 #endif /* _NFS4_CLNT_H */ 2538