#include <lustre_handles.h>
#include <lustre_export.h> /* for obd_export, for LDLM_DEBUG */
#include <interval_tree.h> /* for interval_node{}, ldlm_extent */
+#include <lu_ref.h>
struct obd_ops;
struct obd_device;
/**
* Lower limit to number of pages in lock to keep it in cache.
*/
- unsigned int ns_shrink_thumb;
+ unsigned long ns_shrink_thumb;
/**
* Next debug dump, jiffies.
typedef int (*ldlm_completion_callback)(struct ldlm_lock *lock, int flags,
void *data);
typedef int (*ldlm_glimpse_callback)(struct ldlm_lock *lock, void *data);
+typedef unsigned long (*ldlm_weigh_callback)(struct ldlm_lock *lock);
/* Interval node data for each LDLM_EXTENT lock */
struct ldlm_interval {
* Lock glimpse handler.
*/
ldlm_glimpse_callback l_glimpse_ast;
+ ldlm_weigh_callback l_weigh_ast;
/**
* Lock export.
*/
struct list_head l_sl_mode;
struct list_head l_sl_policy;
+ struct lu_ref l_reference;
};
struct ldlm_resource {
/* when the resource was considered as contended */
cfs_time_t lr_contention_time;
+ /**
+ * List of references to this resource. For debugging.
+ */
+ struct lu_ref lr_reference;
};
struct ldlm_ast_work {
void *ei_cb_bl; /* blocking lock callback */
void *ei_cb_cp; /* lock completion callback */
void *ei_cb_gl; /* lock glimpse callback */
+ void *ei_cb_wg; /* lock weigh callback */
void *ei_cbdata; /* Data to be passed into callbacks. */
short ei_async:1; /* async request */
};
void ldlm_cancel_callback(struct ldlm_lock *);
int ldlm_lock_set_data(struct lustre_handle *, void *data);
int ldlm_lock_remove_from_lru(struct ldlm_lock *);
-struct ldlm_lock *ldlm_handle2lock_ns(struct ldlm_namespace *,
- const struct lustre_handle *);
static inline struct ldlm_lock *ldlm_handle2lock(const struct lustre_handle *h)
{
return __ldlm_handle2lock(h, 0);
}
+#define LDLM_LOCK_REF_DEL(lock) \
+ lu_ref_del(&lock->l_reference, "handle", cfs_current())
+
+static inline struct ldlm_lock *
+ldlm_handle2lock_long(const struct lustre_handle *h, int flags)
+{
+ struct ldlm_lock *lock;
+
+ lock = __ldlm_handle2lock(h, flags);
+ if (lock != NULL)
+ LDLM_LOCK_REF_DEL(lock);
+ return lock;
+}
+
static inline int ldlm_res_lvbo_update(struct ldlm_resource *res,
struct lustre_msg *m, int buf_idx,
int increase)
return 0;
}
+int ldlm_error2errno(ldlm_error_t error);
+ldlm_error_t ldlm_errno2error(int err_no); /* don't call it `errno': this
+ * confuses user-space. */
+
+/**
+ * Release a temporary lock reference obtained by ldlm_handle2lock() or
+ * __ldlm_handle2lock().
+ */
#define LDLM_LOCK_PUT(lock) \
do { \
+ LDLM_LOCK_REF_DEL(lock); \
+ /*LDLM_DEBUG((lock), "put");*/ \
+ ldlm_lock_put(lock); \
+} while (0)
+
+/**
+ * Release a lock reference obtained by some other means (see
+ * LDLM_LOCK_PUT()).
+ */
+#define LDLM_LOCK_RELEASE(lock) \
+do { \
/*LDLM_DEBUG((lock), "put");*/ \
ldlm_lock_put(lock); \
} while (0)
if (c-- == 0) \
break; \
list_del_init(&_lock->member); \
- LDLM_LOCK_PUT(_lock); \
+ LDLM_LOCK_RELEASE(_lock); \
} \
LASSERT(c <= 0); \
})
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, __u32 mode);
+int ldlm_lock_addref_try(struct lustre_handle *lockh, __u32 mode);
void ldlm_lock_decref(struct lustre_handle *lockh, __u32 mode);
void ldlm_lock_decref_and_cancel(struct lustre_handle *lockh, __u32 mode);
void ldlm_lock_allow_match(struct ldlm_lock *lock);
int ldlm_lock_change_resource(struct ldlm_namespace *, struct ldlm_lock *,
const struct ldlm_res_id *);
+#define LDLM_RESOURCE_ADDREF(res) do { \
+ lu_ref_add(&(res)->lr_reference, __FUNCTION__, cfs_current()); \
+} while (0)
+
+#define LDLM_RESOURCE_DELREF(res) do { \
+ lu_ref_del(&(res)->lr_reference, __FUNCTION__, cfs_current()); \
+} while (0)
+
struct ldlm_callback_suite {
ldlm_completion_callback lcs_completion;
ldlm_blocking_callback lcs_blocking;
ldlm_glimpse_callback lcs_glimpse;
+ ldlm_weigh_callback lcs_weigh;
};
/* ldlm_request.c */
int ldlm_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
void *data, int flag);
int ldlm_glimpse_ast(struct ldlm_lock *lock, void *reqp);
+int ldlm_completion_ast_async(struct ldlm_lock *lock, int flags, void *data);
int ldlm_completion_ast(struct ldlm_lock *lock, int flags, void *data);
int ldlm_cli_enqueue(struct obd_export *exp, struct ptlrpc_request **reqp,
struct ldlm_enqueue_info *einfo,
ldlm_mode_t mode, int flags, void *opaque);
int ldlm_cli_cancel_req(struct obd_export *exp, struct list_head *head,
int count, int flags);
-int ldlm_cli_join_lru(struct ldlm_namespace *,
- const struct ldlm_res_id *, int join);
int ldlm_cancel_resource_local(struct ldlm_resource *res,
struct list_head *cancels,
ldlm_policy_data_t *policy,