Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[firefly-linux-kernel-4.4.55.git] / fs / nfsd / state.h
index 4a89e00d7461c8658293504e14c3c5646b5ff240..9d3be371240a582b79e28677c33ae8e9fc00b24e 100644 (file)
@@ -62,16 +62,21 @@ typedef struct {
        (s)->si_generation
 
 struct nfsd4_callback {
-       void *cb_op;
        struct nfs4_client *cb_clp;
        struct list_head cb_per_client;
        u32 cb_minorversion;
        struct rpc_message cb_msg;
-       const struct rpc_call_ops *cb_ops;
+       struct nfsd4_callback_ops *cb_ops;
        struct work_struct cb_work;
        bool cb_done;
 };
 
+struct nfsd4_callback_ops {
+       void (*prepare)(struct nfsd4_callback *);
+       int (*done)(struct nfsd4_callback *, struct rpc_task *);
+       void (*release)(struct nfsd4_callback *);
+};
+
 /*
  * A core object that represents a "common" stateid. These are generally
  * embedded within the different (more specific) stateid objects and contain
@@ -127,6 +132,9 @@ struct nfs4_delegation {
        struct nfsd4_callback   dl_recall;
 };
 
+#define cb_to_delegation(cb) \
+       container_of(cb, struct nfs4_delegation, dl_recall)
+
 /* client delegation callback info */
 struct nfs4_cb_conn {
        /* SETCLIENTID info */
@@ -306,6 +314,7 @@ struct nfs4_client {
 #define NFSD4_CLIENT_STABLE            (2)     /* client on stable storage */
 #define NFSD4_CLIENT_RECLAIM_COMPLETE  (3)     /* reclaim_complete done */
 #define NFSD4_CLIENT_CONFIRMED         (4)     /* client is confirmed */
+#define NFSD4_CLIENT_UPCALL_LOCK       (5)     /* upcall serialization */
 #define NFSD4_CLIENT_CB_FLAG_MASK      (1 << NFSD4_CLIENT_CB_UPDATE | \
                                         1 << NFSD4_CLIENT_CB_KILL)
        unsigned long           cl_flags;
@@ -454,17 +463,24 @@ static inline struct nfs4_lockowner * lockowner(struct nfs4_stateowner *so)
 /*
  * nfs4_file: a file opened by some number of (open) nfs4_stateowners.
  *
- * These objects are global. nfsd only keeps one instance of a nfs4_file per
- * inode (though it may keep multiple file descriptors open per inode). These
- * are tracked in the file_hashtbl which is protected by the state_lock
- * spinlock.
+ * These objects are global. nfsd keeps one instance of a nfs4_file per
+ * filehandle (though it may keep multiple file descriptors for each). Each
+ * inode can have multiple filehandles associated with it, so there is
+ * (potentially) a many to one relationship between this struct and struct
+ * inode.
+ *
+ * These are hashed by filehandle in the file_hashtbl, which is protected by
+ * the global state_lock spinlock.
  */
 struct nfs4_file {
        atomic_t                fi_ref;
        spinlock_t              fi_lock;
-       struct hlist_node       fi_hash;    /* hash by "struct inode *" */
+       struct hlist_node       fi_hash;        /* hash on fi_fhandle */
        struct list_head        fi_stateids;
-       struct list_head        fi_delegations;
+       union {
+               struct list_head        fi_delegations;
+               struct rcu_head         fi_rcu;
+       };
        /* One each for O_RDONLY, O_WRONLY, O_RDWR: */
        struct file *           fi_fds[3];
        /*
@@ -477,7 +493,6 @@ struct nfs4_file {
        atomic_t                fi_access[2];
        u32                     fi_share_deny;
        struct file             *fi_deleg_file;
-       struct file_lock        *fi_lease;
        atomic_t                fi_delegees;
        struct knfsd_fh         fi_fhandle;
        bool                    fi_had_conflict;
@@ -517,6 +532,13 @@ static inline struct nfs4_ol_stateid *openlockstateid(struct nfs4_stid *s)
 #define RD_STATE               0x00000010
 #define WR_STATE               0x00000020
 
+enum nfsd4_cb_op {
+       NFSPROC4_CLNT_CB_NULL = 0,
+       NFSPROC4_CLNT_CB_RECALL,
+       NFSPROC4_CLNT_CB_SEQUENCE,
+};
+
+
 struct nfsd4_compound_state;
 struct nfsd_net;
 
@@ -531,12 +553,12 @@ extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir,
 extern __be32 nfs4_check_open_reclaim(clientid_t *clid,
                struct nfsd4_compound_state *cstate, struct nfsd_net *nn);
 extern int set_callback_cred(void);
-void nfsd4_run_cb_null(struct work_struct *w);
-void nfsd4_run_cb_recall(struct work_struct *w);
 extern void nfsd4_probe_callback(struct nfs4_client *clp);
 extern void nfsd4_probe_callback_sync(struct nfs4_client *clp);
 extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *);
-extern void nfsd4_cb_recall(struct nfs4_delegation *dp);
+extern void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,
+               struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op);
+extern void nfsd4_run_cb(struct nfsd4_callback *cb);
 extern int nfsd4_create_callback_queue(void);
 extern void nfsd4_destroy_callback_queue(void);
 extern void nfsd4_shutdown_callback(struct nfs4_client *);
@@ -545,13 +567,16 @@ extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(const char *name,
                                                        struct nfsd_net *nn);
 extern bool nfs4_has_reclaimed_state(const char *name, struct nfsd_net *nn);
 
+/* grace period management */
+void nfsd4_end_grace(struct nfsd_net *nn);
+
 /* nfs4recover operations */
 extern int nfsd4_client_tracking_init(struct net *net);
 extern void nfsd4_client_tracking_exit(struct net *net);
 extern void nfsd4_client_record_create(struct nfs4_client *clp);
 extern void nfsd4_client_record_remove(struct nfs4_client *clp);
 extern int nfsd4_client_record_check(struct nfs4_client *clp);
-extern void nfsd4_record_grace_done(struct nfsd_net *nn, time_t boot_time);
+extern void nfsd4_record_grace_done(struct nfsd_net *nn);
 
 /* nfs fault injection functions */
 #ifdef CONFIG_NFSD_FAULT_INJECTION