| .. | .. |
|---|
| 39 | 39 | #include <linux/refcount.h> |
|---|
| 40 | 40 | #include <linux/sunrpc/svc_xprt.h> |
|---|
| 41 | 41 | #include "nfsfh.h" |
|---|
| 42 | +#include "nfsd.h" |
|---|
| 42 | 43 | |
|---|
| 43 | 44 | typedef struct { |
|---|
| 44 | 45 | u32 cl_boot; |
|---|
| .. | .. |
|---|
| 55 | 56 | stateid_opaque_t si_opaque; |
|---|
| 56 | 57 | } stateid_t; |
|---|
| 57 | 58 | |
|---|
| 58 | | -#define STATEID_FMT "(%08x/%08x/%08x/%08x)" |
|---|
| 59 | | -#define STATEID_VAL(s) \ |
|---|
| 60 | | - (s)->si_opaque.so_clid.cl_boot, \ |
|---|
| 61 | | - (s)->si_opaque.so_clid.cl_id, \ |
|---|
| 62 | | - (s)->si_opaque.so_id, \ |
|---|
| 63 | | - (s)->si_generation |
|---|
| 59 | +typedef struct { |
|---|
| 60 | + stateid_t stid; |
|---|
| 61 | +#define NFS4_COPY_STID 1 |
|---|
| 62 | +#define NFS4_COPYNOTIFY_STID 2 |
|---|
| 63 | + unsigned char sc_type; |
|---|
| 64 | + refcount_t sc_count; |
|---|
| 65 | +} copy_stateid_t; |
|---|
| 64 | 66 | |
|---|
| 65 | 67 | struct nfsd4_callback { |
|---|
| 66 | 68 | struct nfs4_client *cb_clp; |
|---|
| .. | .. |
|---|
| 95 | 97 | #define NFS4_REVOKED_DELEG_STID 16 |
|---|
| 96 | 98 | #define NFS4_CLOSED_DELEG_STID 32 |
|---|
| 97 | 99 | #define NFS4_LAYOUT_STID 64 |
|---|
| 100 | + struct list_head sc_cp_list; |
|---|
| 98 | 101 | unsigned char sc_type; |
|---|
| 99 | 102 | stateid_t sc_stateid; |
|---|
| 100 | 103 | spinlock_t sc_lock; |
|---|
| 101 | 104 | struct nfs4_client *sc_client; |
|---|
| 102 | 105 | struct nfs4_file *sc_file; |
|---|
| 103 | 106 | void (*sc_free)(struct nfs4_stid *); |
|---|
| 107 | +}; |
|---|
| 108 | + |
|---|
| 109 | +/* Keep a list of stateids issued by the COPY_NOTIFY, associate it with the |
|---|
| 110 | + * parent OPEN/LOCK/DELEG stateid. |
|---|
| 111 | + */ |
|---|
| 112 | +struct nfs4_cpntf_state { |
|---|
| 113 | + copy_stateid_t cp_stateid; |
|---|
| 114 | + struct list_head cp_list; /* per parent nfs4_stid */ |
|---|
| 115 | + stateid_t cp_p_stateid; /* copy of parent's stateid */ |
|---|
| 116 | + clientid_t cp_p_clid; /* copy of parent's clid */ |
|---|
| 117 | + time64_t cpntf_time; /* last time stateid used */ |
|---|
| 104 | 118 | }; |
|---|
| 105 | 119 | |
|---|
| 106 | 120 | /* |
|---|
| .. | .. |
|---|
| 131 | 145 | struct list_head dl_recall_lru; /* delegation recalled */ |
|---|
| 132 | 146 | struct nfs4_clnt_odstate *dl_clnt_odstate; |
|---|
| 133 | 147 | u32 dl_type; |
|---|
| 134 | | - time_t dl_time; |
|---|
| 148 | + time64_t dl_time; |
|---|
| 135 | 149 | /* For recall: */ |
|---|
| 136 | 150 | int dl_retries; |
|---|
| 137 | 151 | struct nfsd4_callback dl_recall; |
|---|
| .. | .. |
|---|
| 309 | 323 | #endif |
|---|
| 310 | 324 | struct xdr_netobj cl_name; /* id generated by client */ |
|---|
| 311 | 325 | nfs4_verifier cl_verifier; /* generated by client */ |
|---|
| 312 | | - time_t cl_time; /* time of last lease renewal */ |
|---|
| 326 | + time64_t cl_time; /* time of last lease renewal */ |
|---|
| 313 | 327 | struct sockaddr_storage cl_addr; /* client ipaddress */ |
|---|
| 314 | 328 | bool cl_mach_cred; /* SP4_MACH_CRED in force */ |
|---|
| 315 | 329 | struct svc_cred cl_cred; /* setclientid principal */ |
|---|
| 316 | 330 | clientid_t cl_clientid; /* generated by server */ |
|---|
| 317 | 331 | nfs4_verifier cl_confirm; /* generated by server */ |
|---|
| 318 | 332 | u32 cl_minorversion; |
|---|
| 333 | + /* NFSv4.1 client implementation id: */ |
|---|
| 334 | + struct xdr_netobj cl_nii_domain; |
|---|
| 335 | + struct xdr_netobj cl_nii_name; |
|---|
| 336 | + struct timespec64 cl_nii_time; |
|---|
| 319 | 337 | |
|---|
| 320 | 338 | /* for v4.0 and v4.1 callbacks: */ |
|---|
| 321 | 339 | struct nfs4_cb_conn cl_cb_conn; |
|---|
| .. | .. |
|---|
| 328 | 346 | #define NFSD4_CLIENT_CB_FLAG_MASK (1 << NFSD4_CLIENT_CB_UPDATE | \ |
|---|
| 329 | 347 | 1 << NFSD4_CLIENT_CB_KILL) |
|---|
| 330 | 348 | unsigned long cl_flags; |
|---|
| 331 | | - struct rpc_cred *cl_cb_cred; |
|---|
| 349 | + const struct cred *cl_cb_cred; |
|---|
| 332 | 350 | struct rpc_clnt *cl_cb_client; |
|---|
| 333 | 351 | u32 cl_cb_ident; |
|---|
| 334 | 352 | #define NFSD4_CB_UP 0 |
|---|
| .. | .. |
|---|
| 347 | 365 | struct nfsd4_clid_slot cl_cs_slot; /* create_session slot */ |
|---|
| 348 | 366 | u32 cl_exchange_flags; |
|---|
| 349 | 367 | /* number of rpc's in progress over an associated session: */ |
|---|
| 350 | | - atomic_t cl_refcount; |
|---|
| 368 | + atomic_t cl_rpc_users; |
|---|
| 369 | + struct nfsdfs_client cl_nfsdfs; |
|---|
| 351 | 370 | struct nfs4_op_map cl_spo_must_allow; |
|---|
| 371 | + |
|---|
| 372 | + /* debugging info directory under nfsd/clients/ : */ |
|---|
| 373 | + struct dentry *cl_nfsd_dentry; |
|---|
| 352 | 374 | |
|---|
| 353 | 375 | /* for nfs41 callbacks */ |
|---|
| 354 | 376 | /* We currently support a single back channel with a single slot */ |
|---|
| .. | .. |
|---|
| 356 | 378 | struct rpc_wait_queue cl_cb_waitq; /* backchannel callers may */ |
|---|
| 357 | 379 | /* wait here for slots */ |
|---|
| 358 | 380 | struct net *net; |
|---|
| 381 | + struct list_head async_copies; /* list of async copies */ |
|---|
| 382 | + spinlock_t async_lock; /* lock for async copies */ |
|---|
| 383 | + atomic_t cl_cb_inflight; /* Outstanding callbacks */ |
|---|
| 359 | 384 | }; |
|---|
| 360 | 385 | |
|---|
| 361 | 386 | /* struct nfs4_client_reset |
|---|
| .. | .. |
|---|
| 366 | 391 | struct nfs4_client_reclaim { |
|---|
| 367 | 392 | struct list_head cr_strhash; /* hash by cr_name */ |
|---|
| 368 | 393 | struct nfs4_client *cr_clp; /* pointer to associated clp */ |
|---|
| 369 | | - char cr_recdir[HEXDIR_LEN]; /* recover dir */ |
|---|
| 394 | + struct xdr_netobj cr_name; /* recovery dir name */ |
|---|
| 395 | + struct xdr_netobj cr_princhash; |
|---|
| 370 | 396 | }; |
|---|
| 371 | 397 | |
|---|
| 372 | 398 | /* A reasonable value for REPLAY_ISIZE was estimated as follows: |
|---|
| .. | .. |
|---|
| 436 | 462 | */ |
|---|
| 437 | 463 | struct list_head oo_close_lru; |
|---|
| 438 | 464 | struct nfs4_ol_stateid *oo_last_closed_stid; |
|---|
| 439 | | - time_t oo_time; /* time of placement on so_close_lru */ |
|---|
| 465 | + time64_t oo_time; /* time of placement on so_close_lru */ |
|---|
| 440 | 466 | #define NFS4_OO_CONFIRMED 1 |
|---|
| 441 | 467 | unsigned char oo_flags; |
|---|
| 442 | 468 | }; |
|---|
| .. | .. |
|---|
| 495 | 521 | }; |
|---|
| 496 | 522 | struct list_head fi_clnt_odstate; |
|---|
| 497 | 523 | /* One each for O_RDONLY, O_WRONLY, O_RDWR: */ |
|---|
| 498 | | - struct file * fi_fds[3]; |
|---|
| 524 | + struct nfsd_file *fi_fds[3]; |
|---|
| 499 | 525 | /* |
|---|
| 500 | 526 | * Each open or lock stateid contributes 0-4 to the counts |
|---|
| 501 | 527 | * below depending on which bits are set in st_access_bitmap: |
|---|
| .. | .. |
|---|
| 505 | 531 | */ |
|---|
| 506 | 532 | atomic_t fi_access[2]; |
|---|
| 507 | 533 | u32 fi_share_deny; |
|---|
| 508 | | - struct file *fi_deleg_file; |
|---|
| 534 | + struct nfsd_file *fi_deleg_file; |
|---|
| 509 | 535 | int fi_delegees; |
|---|
| 510 | 536 | struct knfsd_fh fi_fhandle; |
|---|
| 511 | 537 | bool fi_had_conflict; |
|---|
| .. | .. |
|---|
| 554 | 580 | spinlock_t ls_lock; |
|---|
| 555 | 581 | struct list_head ls_layouts; |
|---|
| 556 | 582 | u32 ls_layout_type; |
|---|
| 557 | | - struct file *ls_file; |
|---|
| 583 | + struct nfsd_file *ls_file; |
|---|
| 558 | 584 | struct nfsd4_callback ls_recall; |
|---|
| 559 | 585 | stateid_t ls_recall_sid; |
|---|
| 560 | 586 | bool ls_recalled; |
|---|
| .. | .. |
|---|
| 574 | 600 | NFSPROC4_CLNT_CB_NULL = 0, |
|---|
| 575 | 601 | NFSPROC4_CLNT_CB_RECALL, |
|---|
| 576 | 602 | NFSPROC4_CLNT_CB_LAYOUT, |
|---|
| 603 | + NFSPROC4_CLNT_CB_OFFLOAD, |
|---|
| 577 | 604 | NFSPROC4_CLNT_CB_SEQUENCE, |
|---|
| 578 | 605 | NFSPROC4_CLNT_CB_NOTIFY_LOCK, |
|---|
| 579 | 606 | }; |
|---|
| .. | .. |
|---|
| 592 | 619 | struct nfsd4_blocked_lock { |
|---|
| 593 | 620 | struct list_head nbl_list; |
|---|
| 594 | 621 | struct list_head nbl_lru; |
|---|
| 595 | | - time_t nbl_time; |
|---|
| 622 | + time64_t nbl_time; |
|---|
| 596 | 623 | struct file_lock nbl_lock; |
|---|
| 597 | 624 | struct knfsd_fh nbl_fh; |
|---|
| 598 | 625 | struct nfsd4_callback nbl_cb; |
|---|
| .. | .. |
|---|
| 600 | 627 | |
|---|
| 601 | 628 | struct nfsd4_compound_state; |
|---|
| 602 | 629 | struct nfsd_net; |
|---|
| 630 | +struct nfsd4_copy; |
|---|
| 603 | 631 | |
|---|
| 604 | 632 | extern __be32 nfs4_preprocess_stateid_op(struct svc_rqst *rqstp, |
|---|
| 605 | 633 | struct nfsd4_compound_state *cstate, struct svc_fh *fhp, |
|---|
| 606 | | - stateid_t *stateid, int flags, struct file **filp, bool *tmp_file); |
|---|
| 634 | + stateid_t *stateid, int flags, struct nfsd_file **filp, |
|---|
| 635 | + struct nfs4_stid **cstid); |
|---|
| 607 | 636 | __be32 nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate, |
|---|
| 608 | 637 | stateid_t *stateid, unsigned char typemask, |
|---|
| 609 | 638 | struct nfs4_stid **s, struct nfsd_net *nn); |
|---|
| 610 | 639 | struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *slab, |
|---|
| 611 | 640 | void (*sc_free)(struct nfs4_stid *)); |
|---|
| 641 | +int nfs4_init_copy_state(struct nfsd_net *nn, struct nfsd4_copy *copy); |
|---|
| 642 | +void nfs4_free_copy_state(struct nfsd4_copy *copy); |
|---|
| 643 | +struct nfs4_cpntf_state *nfs4_alloc_init_cpntf_state(struct nfsd_net *nn, |
|---|
| 644 | + struct nfs4_stid *p_stid); |
|---|
| 612 | 645 | void nfs4_unhash_stid(struct nfs4_stid *s); |
|---|
| 613 | 646 | void nfs4_put_stid(struct nfs4_stid *s); |
|---|
| 614 | 647 | void nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid); |
|---|
| 615 | 648 | void nfs4_remove_reclaim_record(struct nfs4_client_reclaim *, struct nfsd_net *); |
|---|
| 616 | 649 | extern void nfs4_release_reclaim(struct nfsd_net *); |
|---|
| 617 | | -extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir, |
|---|
| 650 | +extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(struct xdr_netobj name, |
|---|
| 618 | 651 | struct nfsd_net *nn); |
|---|
| 619 | 652 | extern __be32 nfs4_check_open_reclaim(clientid_t *clid, |
|---|
| 620 | 653 | struct nfsd4_compound_state *cstate, struct nfsd_net *nn); |
|---|
| .. | .. |
|---|
| 627 | 660 | extern int nfsd4_create_callback_queue(void); |
|---|
| 628 | 661 | extern void nfsd4_destroy_callback_queue(void); |
|---|
| 629 | 662 | extern void nfsd4_shutdown_callback(struct nfs4_client *); |
|---|
| 663 | +extern void nfsd4_shutdown_copy(struct nfs4_client *clp); |
|---|
| 630 | 664 | extern void nfsd4_prepare_cb_recall(struct nfs4_delegation *dp); |
|---|
| 631 | | -extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(const char *name, |
|---|
| 632 | | - struct nfsd_net *nn); |
|---|
| 633 | | -extern bool nfs4_has_reclaimed_state(const char *name, struct nfsd_net *nn); |
|---|
| 665 | +extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netobj name, |
|---|
| 666 | + struct xdr_netobj princhash, struct nfsd_net *nn); |
|---|
| 667 | +extern bool nfs4_has_reclaimed_state(struct xdr_netobj name, struct nfsd_net *nn); |
|---|
| 634 | 668 | |
|---|
| 635 | 669 | struct nfs4_file *find_file(struct knfsd_fh *fh); |
|---|
| 636 | 670 | void put_nfs4_file(struct nfs4_file *fi); |
|---|
| 671 | +extern void nfs4_put_copy(struct nfsd4_copy *copy); |
|---|
| 672 | +extern struct nfsd4_copy * |
|---|
| 673 | +find_async_copy(struct nfs4_client *clp, stateid_t *staetid); |
|---|
| 674 | +extern void nfs4_put_cpntf_state(struct nfsd_net *nn, |
|---|
| 675 | + struct nfs4_cpntf_state *cps); |
|---|
| 676 | +extern __be32 manage_cpntf_state(struct nfsd_net *nn, stateid_t *st, |
|---|
| 677 | + struct nfs4_client *clp, |
|---|
| 678 | + struct nfs4_cpntf_state **cps); |
|---|
| 637 | 679 | static inline void get_nfs4_file(struct nfs4_file *fi) |
|---|
| 638 | 680 | { |
|---|
| 639 | 681 | refcount_inc(&fi->fi_ref); |
|---|
| 640 | 682 | } |
|---|
| 641 | | -struct file *find_any_file(struct nfs4_file *f); |
|---|
| 683 | +struct nfsd_file *find_any_file(struct nfs4_file *f); |
|---|
| 642 | 684 | |
|---|
| 643 | 685 | /* grace period management */ |
|---|
| 644 | 686 | void nfsd4_end_grace(struct nfsd_net *nn); |
|---|
| .. | .. |
|---|
| 650 | 692 | extern void nfsd4_client_record_remove(struct nfs4_client *clp); |
|---|
| 651 | 693 | extern int nfsd4_client_record_check(struct nfs4_client *clp); |
|---|
| 652 | 694 | extern void nfsd4_record_grace_done(struct nfsd_net *nn); |
|---|
| 653 | | - |
|---|
| 654 | | -/* nfs fault injection functions */ |
|---|
| 655 | | -#ifdef CONFIG_NFSD_FAULT_INJECTION |
|---|
| 656 | | -int nfsd_fault_inject_init(void); |
|---|
| 657 | | -void nfsd_fault_inject_cleanup(void); |
|---|
| 658 | | - |
|---|
| 659 | | -u64 nfsd_inject_print_clients(void); |
|---|
| 660 | | -u64 nfsd_inject_forget_client(struct sockaddr_storage *, size_t); |
|---|
| 661 | | -u64 nfsd_inject_forget_clients(u64); |
|---|
| 662 | | - |
|---|
| 663 | | -u64 nfsd_inject_print_locks(void); |
|---|
| 664 | | -u64 nfsd_inject_forget_client_locks(struct sockaddr_storage *, size_t); |
|---|
| 665 | | -u64 nfsd_inject_forget_locks(u64); |
|---|
| 666 | | - |
|---|
| 667 | | -u64 nfsd_inject_print_openowners(void); |
|---|
| 668 | | -u64 nfsd_inject_forget_client_openowners(struct sockaddr_storage *, size_t); |
|---|
| 669 | | -u64 nfsd_inject_forget_openowners(u64); |
|---|
| 670 | | - |
|---|
| 671 | | -u64 nfsd_inject_print_delegations(void); |
|---|
| 672 | | -u64 nfsd_inject_forget_client_delegations(struct sockaddr_storage *, size_t); |
|---|
| 673 | | -u64 nfsd_inject_forget_delegations(u64); |
|---|
| 674 | | -u64 nfsd_inject_recall_client_delegations(struct sockaddr_storage *, size_t); |
|---|
| 675 | | -u64 nfsd_inject_recall_delegations(u64); |
|---|
| 676 | | -#else /* CONFIG_NFSD_FAULT_INJECTION */ |
|---|
| 677 | | -static inline int nfsd_fault_inject_init(void) { return 0; } |
|---|
| 678 | | -static inline void nfsd_fault_inject_cleanup(void) {} |
|---|
| 679 | | -#endif /* CONFIG_NFSD_FAULT_INJECTION */ |
|---|
| 680 | 695 | |
|---|
| 681 | 696 | #endif /* NFSD4_STATE_H */ |
|---|