.. | .. |
---|
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 */ |
---|