Whamcloud - gitweb
LU-3285 lvbo: pass lock as parameter to lvbo_update()
[fs/lustre-release.git] / lustre / include / lustre_dlm.h
index 5beb294..2d0952e 100644 (file)
  *
  * You should have received a copy of the GNU General Public License
  * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * GPL HEADER END
  */
@@ -27,7 +23,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2010, 2015, Intel Corporation.
+ * Copyright (c) 2010, 2016, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 struct obd_ops;
 struct obd_device;
 
+extern struct kset *ldlm_ns_kset;
+extern struct kset *ldlm_svc_kset;
+
 #define OBD_LDLM_DEVICENAME  "ldlm"
 
 #define LDLM_DEFAULT_LRU_SIZE (100 * num_online_cpus())
-#define LDLM_DEFAULT_MAX_ALIVE (cfs_time_seconds(3900)) /* 65 min */
+#define LDLM_DEFAULT_MAX_ALIVE         3900    /* 3900 seconds ~65 min */
 #define LDLM_CTIME_AGE_LIMIT (10)
 #define LDLM_DEFAULT_PARALLEL_AST_LIMIT 1024
 
@@ -255,15 +254,19 @@ struct ldlm_pool {
         *  server_slv * lock_volume_factor. */
        atomic_t                pl_lock_volume_factor;
        /** Time when last SLV from server was obtained. */
-       time_t                  pl_recalc_time;
+       time64_t                pl_recalc_time;
        /** Recalculation period for pool. */
-       time_t                  pl_recalc_period;
+       time64_t                pl_recalc_period;
        /** Recalculation and shrink operations. */
        struct ldlm_pool_ops    *pl_ops;
        /** Number of planned locks for next period. */
        int                     pl_grant_plan;
        /** Pool statistics. */
        struct lprocfs_stats    *pl_stats;
+
+       /* sysfs object */
+       struct kobject           pl_kobj;
+       struct completion        pl_kobj_unregister;
 };
 
 typedef int (*ldlm_res_policy)(struct ldlm_namespace *, struct ldlm_lock **,
@@ -286,11 +289,10 @@ typedef int (*ldlm_cancel_cbt)(struct ldlm_lock *lock);
  * of ldlm_[res_]lvbo_[init,update,fill]() functions.
  */
 struct ldlm_valblock_ops {
-        int (*lvbo_init)(struct ldlm_resource *res);
-        int (*lvbo_update)(struct ldlm_resource *res,
-                           struct ptlrpc_request *r,
-                           int increase);
-        int (*lvbo_free)(struct ldlm_resource *res);
+       int (*lvbo_init)(struct ldlm_resource *res);
+       int (*lvbo_update)(struct ldlm_resource *res, struct ldlm_lock *lock,
+                          struct ptlrpc_request *r,  int increase);
+       int (*lvbo_free)(struct ldlm_resource *res);
        /* Return size of lvb data appropriate RPC size can be reserved */
        int (*lvbo_size)(struct ldlm_lock *lock);
        /* Called to fill in lvb data to RPC buffer @buf */
@@ -420,8 +422,10 @@ struct ldlm_namespace {
         * controlled by available memory on this client and on server.
         */
        unsigned int            ns_max_unused;
+
        /** Maximum allowed age (last used time) for locks in the LRU */
-       unsigned int            ns_max_age;
+       ktime_t                 ns_max_age;
+
        /**
         * Server only: number of times we evicted clients due to lack of reply
         * to ASTs.
@@ -510,6 +514,9 @@ struct ldlm_namespace {
         * Which bucket should we start with the lock reclaim.
         */
        int                     ns_reclaim_start;
+
+       struct kobject          ns_kobj; /* sysfs object */
+       struct completion       ns_kobj_unregister;
 };
 
 /**
@@ -582,10 +589,27 @@ struct ldlm_glimpse_work {
        __u32                    gl_flags;/* see LDLM_GL_WORK_* below */
        union ldlm_gl_desc      *gl_desc; /* glimpse descriptor to be packed in
                                           * glimpse callback request */
+       ptlrpc_interpterer_t     gl_interpret_reply;
+       void                    *gl_interpret_data;
+};
+
+struct ldlm_cb_set_arg {
+       struct ptlrpc_request_set       *set;
+       int                              type; /* LDLM_{CP,BL,GL}_CALLBACK */
+       atomic_t                         restart;
+       struct list_head                *list;
+       union ldlm_gl_desc              *gl_desc; /* glimpse AST descriptor */
+       ptlrpc_interpterer_t             gl_interpret_reply;
+       void                            *gl_interpret_data;
+};
+
+struct ldlm_cb_async_args {
+       struct ldlm_cb_set_arg  *ca_set_arg;
+       struct ldlm_lock        *ca_lock;
 };
 
-/** The ldlm_glimpse_work is allocated on the stack and should not be freed. */
-#define LDLM_GL_WORK_NOFREE 0x1
+/** The ldlm_glimpse_work was slab allocated & must be freed accordingly.*/
+#define LDLM_GL_WORK_SLAB_ALLOCATED 0x1
 
 /** Interval node data for each LDLM_EXTENT lock. */
 struct ldlm_interval {
@@ -624,8 +648,7 @@ struct ldlm_flock {
        __u64 owner;
        __u64 blocking_owner;
        struct obd_export *blocking_export;
-       /* Protected by the hash lock */
-       __u32 blocking_refs;
+       atomic_t blocking_refs;
        __u32 pid;
 };
 
@@ -794,13 +817,12 @@ struct ldlm_lock {
         * Seconds. It will be updated if there is any activity related to
         * the lock, e.g. enqueue the lock or send blocking AST.
         */
-       cfs_time_t              l_last_activity;
+       time64_t                l_last_activity;
 
        /**
-        * Time last used by e.g. being matched by lock match.
-        * Jiffies. Should be converted to time if needed.
+        * Time, in nanoseconds, last used by e.g. being matched by lock match.
         */
-       cfs_time_t              l_last_used;
+       ktime_t                 l_last_used;
 
        /** Originally requested extent for the extent lock. */
        struct ldlm_extent      l_req_extent;
@@ -837,8 +859,7 @@ struct ldlm_lock {
         * The lists this could be linked into are:
         * waiting_locks_list (protected by waiting_locks_spinlock),
         * then if the lock timed out, it is moved to
-        * expired_lock_thread.elt_expired_locks for further processing.
-        * Protected by elt_lock.
+        * expired_lock_list for further processing.
         */
        struct list_head        l_pending_chain;
 
@@ -1102,8 +1123,7 @@ struct ldlm_enqueue_info {
        void            *ei_cb_gl;      /** lock glimpse callback */
        void            *ei_cbdata;     /** Data to be passed into callbacks. */
        void            *ei_namespace;  /** lock namespace **/
-       unsigned int    ei_enq_slave:1, /** whether enqueue slave stripes */
-                       ei_nonblock:1;  /** non block enqueue */
+       unsigned int    ei_enq_slave:1; /** whether enqueue slave stripes */
 };
 
 #define ei_res_id      ei_cb_gl
@@ -1145,7 +1165,7 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
  * Rate-limited version of lock printing function.
  */
 #define LDLM_DEBUG_LIMIT(mask, lock, fmt, a...) do {                         \
-        static cfs_debug_limit_state_t _ldlm_cdls;                           \
+       static struct cfs_debug_limit_state _ldlm_cdls;                      \
         LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, &_ldlm_cdls);              \
         ldlm_lock_debug(&msgdata, mask, &_ldlm_cdls, lock, "### " fmt , ##a);\
 } while (0)
@@ -1169,8 +1189,41 @@ void _ldlm_lock_debug(struct ldlm_lock *lock,
 # define LDLM_ERROR(lock, fmt, a...) ((void)0)
 #endif
 
+/*
+ * Three intentions can be used for the policy functions in
+ * ldlm_processing_policy.
+ *
+ * LDLM_PROCESS_RESCAN:
+ *
+ * It's used when policy functions are called from ldlm_reprocess_queue() to
+ * reprocess the wait & convert list and try to grant locks, blocking ASTs
+ * have already been sent in this situation, completion ASTs need be sent for
+ * the locks being granted.
+ *
+ * LDLM_PROCESS_ENQUEUE:
+ *
+ * It's used when policy functions are called from ldlm_lock_enqueue() to
+ * process the wait & convert list for handling an enqueue request, blocking
+ * ASTs have not been sent yet, so list of conflicting locks would be
+ * collected and ASTs sent.
+ *
+ * LDLM_PROCESS_RECOVERY:
+ *
+ * It's used when policy functions are called from ldlm_reprocess_queue() to
+ * reprocess the wait & convert list when recovery done. In case of blocking
+ * ASTs are lost before recovery, it needs not only to grant locks if
+ * available, but also send blocking ASTs to the locks doesn't have AST sent
+ * flag. Completion ASTs need be sent for the locks being granted.
+ */
+enum ldlm_process_intention {
+       LDLM_PROCESS_RESCAN = 0,
+       LDLM_PROCESS_ENQUEUE = 1,
+       LDLM_PROCESS_RECOVERY = 2,
+};
+
 typedef int (*ldlm_processing_policy)(struct ldlm_lock *lock, __u64 *flags,
-                                     int first_enq, enum ldlm_error *err,
+                                     enum ldlm_process_intention intention,
+                                     enum ldlm_error *err,
                                      struct list_head *work_list);
 
 /**
@@ -1204,6 +1257,19 @@ int ldlm_flock_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data);
 /* ldlm_extent.c */
 __u64 ldlm_extent_shift_kms(struct ldlm_lock *lock, __u64 old_kms);
 
+struct ldlm_prolong_args {
+       struct obd_export       *lpa_export;
+       struct ldlm_res_id      lpa_resid;
+       struct ldlm_extent      lpa_extent;
+       enum ldlm_mode          lpa_mode;
+       int                     lpa_timeout;
+       int                     lpa_locks_cnt;
+       int                     lpa_blocks_cnt;
+};
+void ldlm_lock_prolong_one(struct ldlm_lock *lock,
+                          struct ldlm_prolong_args *arg);
+void ldlm_resource_prolong(struct ldlm_prolong_args *arg);
+
 struct ldlm_callback_suite {
         ldlm_completion_callback lcs_completion;
         ldlm_blocking_callback   lcs_blocking;
@@ -1265,7 +1331,7 @@ void ldlm_lock2handle(const struct ldlm_lock *lock,
 struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *, __u64 flags);
 void ldlm_cancel_callback(struct ldlm_lock *);
 int ldlm_lock_remove_from_lru(struct ldlm_lock *);
-int ldlm_lock_set_data(struct lustre_handle *, void *);
+int ldlm_lock_set_data(const struct lustre_handle *lockh, void *data);
 
 /**
  * Obtain a lock reference by its handle.
@@ -1293,9 +1359,11 @@ ldlm_handle2lock_long(const struct lustre_handle *h, __u64 flags)
  * Update Lock Value Block Operations (LVBO) on a resource taking into account
  * data from request \a r
  */
-static inline int ldlm_res_lvbo_update(struct ldlm_resource *res,
-                                      struct ptlrpc_request *req, int increase)
+static inline int ldlm_lvbo_update(struct ldlm_resource *res,
+                                  struct ldlm_lock *lock,
+                                  struct ptlrpc_request *req, int increase)
 {
+       struct ldlm_namespace *ns = ldlm_res_to_ns(res);
        int rc;
 
        /* delayed lvb init may be required */
@@ -1305,14 +1373,18 @@ static inline int ldlm_res_lvbo_update(struct ldlm_resource *res,
                return rc;
        }
 
-       if (ldlm_res_to_ns(res)->ns_lvbo &&
-           ldlm_res_to_ns(res)->ns_lvbo->lvbo_update) {
-               return ldlm_res_to_ns(res)->ns_lvbo->lvbo_update(res, req,
-                                                                increase);
-       }
+       if (ns->ns_lvbo && ns->ns_lvbo->lvbo_update)
+               return ns->ns_lvbo->lvbo_update(res, lock, req, increase);
+
        return 0;
 }
 
+static inline int ldlm_res_lvbo_update(struct ldlm_resource *res,
+                                      struct ptlrpc_request *req, int increase)
+{
+       return ldlm_lvbo_update(res, NULL, req, increase);
+}
+
 int ldlm_error2errno(enum ldlm_error error);
 enum ldlm_error ldlm_errno2error(int err_no); /* don't call it `errno': this
                                               * confuses user-space. */
@@ -1365,10 +1437,11 @@ struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock);
 void ldlm_lock_put(struct ldlm_lock *lock);
 void ldlm_lock_destroy(struct ldlm_lock *lock);
 void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc);
-void ldlm_lock_addref(struct lustre_handle *lockh, enum ldlm_mode mode);
-int  ldlm_lock_addref_try(struct lustre_handle *lockh, enum ldlm_mode mode);
-void ldlm_lock_decref(struct lustre_handle *lockh, enum ldlm_mode mode);
-void ldlm_lock_decref_and_cancel(struct lustre_handle *lockh,
+void ldlm_lock_addref(const struct lustre_handle *lockh, enum ldlm_mode mode);
+int  ldlm_lock_addref_try(const struct lustre_handle *lockh,
+                         enum ldlm_mode mode);
+void ldlm_lock_decref(const struct lustre_handle *lockh, enum ldlm_mode mode);
+void ldlm_lock_decref_and_cancel(const struct lustre_handle *lockh,
                                 enum ldlm_mode mode);
 void ldlm_lock_fail_match_locked(struct ldlm_lock *lock);
 void ldlm_lock_fail_match(struct ldlm_lock *lock);
@@ -1378,15 +1451,15 @@ enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, __u64 flags,
                               const struct ldlm_res_id *, enum ldlm_type type,
                               union ldlm_policy_data *, enum ldlm_mode mode,
                               struct lustre_handle *, int unref);
-enum ldlm_mode ldlm_revalidate_lock_handle(struct lustre_handle *lockh,
+enum ldlm_mode ldlm_revalidate_lock_handle(const struct lustre_handle *lockh,
                                           __u64 *bits);
 struct ldlm_resource *ldlm_lock_convert(struct ldlm_lock *lock,
                                        enum ldlm_mode new_mode, __u32 *flags);
 void ldlm_lock_downgrade(struct ldlm_lock *lock, enum ldlm_mode new_mode);
 void ldlm_lock_cancel(struct ldlm_lock *lock);
 void ldlm_reprocess_all(struct ldlm_resource *res);
-void ldlm_reprocess_all_ns(struct ldlm_namespace *ns);
-void ldlm_lock_dump_handle(int level, struct lustre_handle *);
+void ldlm_reprocess_recovery_done(struct ldlm_namespace *ns);
+void ldlm_lock_dump_handle(int level, const struct lustre_handle *lockh);
 void ldlm_unlink_lock_skiplist(struct ldlm_lock *req);
 
 /* resource.c */
@@ -1480,7 +1553,7 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req,
                          enum ldlm_type type, __u8 with_policy,
                          enum ldlm_mode mode, __u64 *flags, void *lvb,
                          __u32 lvb_len,
-                         struct lustre_handle *lockh, int rc);
+                         const struct lustre_handle *lockh, int rc);
 int ldlm_cli_enqueue_local(struct ldlm_namespace *ns,
                           const struct ldlm_res_id *res_id,
                           enum ldlm_type type, union ldlm_policy_data *policy,
@@ -1491,11 +1564,10 @@ int ldlm_cli_enqueue_local(struct ldlm_namespace *ns,
                           void *data, __u32 lvb_len, enum lvb_type lvb_type,
                           const __u64 *client_cookie,
                           struct lustre_handle *lockh);
-int ldlm_server_ast(struct lustre_handle *lockh, struct ldlm_lock_desc *new,
-                   void *data, __u32 data_len);
-int ldlm_cli_convert(struct lustre_handle *, int new_mode, __u32 *flags);
+int ldlm_cli_convert(const struct lustre_handle *lockh, int new_mode,
+                    __u32 *flags);
 int ldlm_cli_update_pool(struct ptlrpc_request *req);
-int ldlm_cli_cancel(struct lustre_handle *lockh,
+int ldlm_cli_cancel(const struct lustre_handle *lockh,
                    enum ldlm_cancel_flags cancel_flags);
 int ldlm_cli_cancel_unused(struct ldlm_namespace *, const struct ldlm_res_id *,
                           enum ldlm_cancel_flags flags, void *opaque);
@@ -1587,5 +1659,18 @@ void ldlm_pool_add(struct ldlm_pool *pl, struct ldlm_lock *lock);
 void ldlm_pool_del(struct ldlm_pool *pl, struct ldlm_lock *lock);
 /** @} */
 
+static inline int ldlm_extent_overlap(const struct ldlm_extent *ex1,
+                                     const struct ldlm_extent *ex2)
+{
+       return ex1->start <= ex2->end && ex2->start <= ex1->end;
+}
+
+/* check if @ex1 contains @ex2 */
+static inline int ldlm_extent_contain(const struct ldlm_extent *ex1,
+                                     const struct ldlm_extent *ex2)
+{
+       return ex1->start <= ex2->start && ex1->end >= ex2->end;
+}
+
 #endif
 /** @} LDLM */