* error may happen if coordinator crashes or stopped
* with running request
*/
- car = mdt_cdt_find_request(cdt, larr->arr_hai.hai_cookie, NULL);
+ car = mdt_cdt_find_request(cdt, larr->arr_hai.hai_cookie);
if (car == NULL) {
last = larr->arr_req_change;
} else {
init_rwsem(&cdt->cdt_request_lock);
mutex_init(&cdt->cdt_restore_lock);
- INIT_LIST_HEAD(&cdt->cdt_requests);
+ INIT_LIST_HEAD(&cdt->cdt_request_list);
INIT_LIST_HEAD(&cdt->cdt_agents);
INIT_LIST_HEAD(&cdt->cdt_restore_hdl);
+ cdt->cdt_request_cookie_hash = cfs_hash_create("REQUEST_COOKIE_HASH",
+ CFS_HASH_BITS_MIN,
+ CFS_HASH_BITS_MAX,
+ CFS_HASH_BKT_BITS,
+ 0 /* extra bytes */,
+ CFS_HASH_MIN_THETA,
+ CFS_HASH_MAX_THETA,
+ &cdt_request_cookie_hash_ops,
+ CFS_HASH_DEFAULT);
+ if (cdt->cdt_request_cookie_hash == NULL)
+ RETURN(-ENOMEM);
+
rc = lu_env_init(&cdt->cdt_env, LCT_MD_THREAD);
if (rc < 0)
- RETURN(rc);
+ GOTO(out_request_cookie_hash, rc);
/* for mdt_ucred(), lu_ucred stored in lu_ucred_key */
rc = lu_context_init(&cdt->cdt_session, LCT_SERVER_SESSION);
- if (rc == 0) {
- lu_context_enter(&cdt->cdt_session);
- cdt->cdt_env.le_ses = &cdt->cdt_session;
- } else {
- lu_env_fini(&cdt->cdt_env);
- RETURN(rc);
- }
+ if (rc < 0)
+ GOTO(out_env, rc);
+
+ lu_context_enter(&cdt->cdt_session);
+ cdt->cdt_env.le_ses = &cdt->cdt_session;
cdt_mti = lu_context_key_get(&cdt->cdt_env.le_ctx, &mdt_thread_key);
LASSERT(cdt_mti != NULL);
cdt->cdt_active_req_timeout = 3600;
RETURN(0);
+
+out_env:
+ lu_env_fini(&cdt->cdt_env);
+out_request_cookie_hash:
+ cfs_hash_putref(cdt->cdt_request_cookie_hash);
+ cdt->cdt_request_cookie_hash = NULL;
+
+ return rc;
}
/**
lu_env_fini(&cdt->cdt_env);
+ cfs_hash_putref(cdt->cdt_request_cookie_hash);
+ cdt->cdt_request_cookie_hash = NULL;
+
RETURN(0);
}
/* start cleaning */
down_write(&cdt->cdt_request_lock);
- list_for_each_entry_safe(car, tmp1, &cdt->cdt_requests,
+ list_for_each_entry_safe(car, tmp1, &cdt->cdt_request_list,
car_request_list) {
+ cfs_hash_del(cdt->cdt_request_cookie_hash,
+ &car->car_hai->hai_cookie,
+ &car->car_cookie_hash);
list_del(&car->car_request_list);
- mdt_cdt_free_request(car);
+ mdt_cdt_put_request(car);
}
up_write(&cdt->cdt_request_lock);
}
/* find the running request to set it canceled */
- car = mdt_cdt_find_request(cdt, hai->hai_cookie, NULL);
+ car = mdt_cdt_find_request(cdt, hai->hai_cookie);
if (car != NULL) {
car->car_canceled = 1;
/* uuid has to be changed to the one running the
/* send cancel to all running requests */
down_read(&cdt->cdt_request_lock);
- list_for_each_entry(car, &cdt->cdt_requests, car_request_list) {
+ list_for_each_entry(car, &cdt->cdt_request_list, car_request_list) {
mdt_cdt_get_request(car);
/* request is not yet removed from list, it will be done
* when copytool will return progress
#define DEBUG_SUBSYSTEM S_MDS
+#include <libcfs/libcfs.h>
+#include <libcfs/libcfs_hash.h>
#include <obd_support.h>
#include <lustre/lustre_user.h>
#include <lprocfs_status.h>
#include "mdt_internal.h"
+static unsigned int
+cdt_request_cookie_hash(struct cfs_hash *hs, const void *key, unsigned int mask)
+{
+ return cfs_hash_djb2_hash(key, sizeof(u64), mask);
+}
+
+static void *cdt_request_cookie_object(struct hlist_node *hnode)
+{
+ return hlist_entry(hnode, struct cdt_agent_req, car_cookie_hash);
+}
+
+static void *cdt_request_cookie_key(struct hlist_node *hnode)
+{
+ struct cdt_agent_req *car = cdt_request_cookie_object(hnode);
+
+ return &car->car_hai->hai_cookie;
+}
+
+static int cdt_request_cookie_keycmp(const void *key, struct hlist_node *hnode)
+{
+ const u64 *cookie2 = cdt_request_cookie_key(hnode);
+
+ return *(u64 *)key == *cookie2;
+}
+
+static void
+cdt_request_cookie_get(struct cfs_hash *hs, struct hlist_node *hnode)
+{
+ struct cdt_agent_req *car = cdt_request_cookie_object(hnode);
+
+ mdt_cdt_get_request(car);
+}
+
+static void
+cdt_request_cookie_put(struct cfs_hash *hs, struct hlist_node *hnode)
+{
+ struct cdt_agent_req *car = cdt_request_cookie_object(hnode);
+
+ mdt_cdt_put_request(car);
+}
+
+struct cfs_hash_ops cdt_request_cookie_hash_ops = {
+ .hs_hash = cdt_request_cookie_hash,
+ .hs_key = cdt_request_cookie_key,
+ .hs_keycmp = cdt_request_cookie_keycmp,
+ .hs_object = cdt_request_cookie_object,
+ .hs_get = cdt_request_cookie_get,
+ .hs_put_locked = cdt_request_cookie_put,
+};
+
/**
* dump requests list
* \param cdt [IN] coordinator
struct cdt_agent_req *car;
down_read(&cdt->cdt_request_lock);
- list_for_each_entry(car, &cdt->cdt_requests, car_request_list) {
+ list_for_each_entry(car, &cdt->cdt_request_list, car_request_list) {
CDEBUG(D_HSM, "%s fid="DFID" dfid="DFID
" compound/cookie=%#llx/%#llx"
" action=%s archive#=%d flags=%#llx"
}
/**
- * find request in the list by cookie or by fid
- * lock cdt_request_lock needs to be held by caller
- * \param cdt [IN] coordinator
- * \param cookie [IN] request cookie
- * \param fid [IN] fid
- * \retval request pointer or NULL if not found
- */
-static struct cdt_agent_req *cdt_find_request_nolock(struct coordinator *cdt,
- __u64 cookie,
- const struct lu_fid *fid)
-{
- struct cdt_agent_req *car;
- struct cdt_agent_req *found = NULL;
- ENTRY;
-
- list_for_each_entry(car, &cdt->cdt_requests, car_request_list) {
- if (car->car_hai->hai_cookie == cookie ||
- (fid != NULL && lu_fid_eq(fid, &car->car_hai->hai_fid))) {
- mdt_cdt_get_request(car);
- found = car;
- break;
- }
- }
-
- RETURN(found);
-}
-
-/**
* add a request to the list
* \param cdt [IN] coordinator
* \param car [IN] request
* \retval 0 success
* \retval -ve failure
*/
-int mdt_cdt_add_request(struct coordinator *cdt, struct cdt_agent_req *new_car)
+int mdt_cdt_add_request(struct coordinator *cdt, struct cdt_agent_req *car)
{
- struct cdt_agent_req *car;
+ int rc;
ENTRY;
/* cancel requests are not kept in memory */
- LASSERT(new_car->car_hai->hai_action != HSMA_CANCEL);
+ LASSERT(car->car_hai->hai_action != HSMA_CANCEL);
down_write(&cdt->cdt_request_lock);
- car = cdt_find_request_nolock(cdt, new_car->car_hai->hai_cookie, NULL);
- if (car != NULL) {
- mdt_cdt_put_request(car);
+
+ rc = cfs_hash_add_unique(cdt->cdt_request_cookie_hash,
+ &car->car_hai->hai_cookie,
+ &car->car_cookie_hash);
+ if (rc < 0) {
up_write(&cdt->cdt_request_lock);
RETURN(-EEXIST);
}
- list_add_tail(&new_car->car_request_list, &cdt->cdt_requests);
+ list_add_tail(&car->car_request_list, &cdt->cdt_request_list);
+
up_write(&cdt->cdt_request_lock);
- mdt_hsm_agent_update_statistics(cdt, 0, 0, 1, &new_car->car_uuid);
+ mdt_hsm_agent_update_statistics(cdt, 0, 0, 1, &car->car_uuid);
atomic_inc(&cdt->cdt_request_count);
* \param fid [IN] fid
* \retval request pointer or NULL if not found
*/
-struct cdt_agent_req *mdt_cdt_find_request(struct coordinator *cdt,
- const __u64 cookie,
- const struct lu_fid *fid)
+struct cdt_agent_req *mdt_cdt_find_request(struct coordinator *cdt, u64 cookie)
{
struct cdt_agent_req *car;
ENTRY;
down_read(&cdt->cdt_request_lock);
- car = cdt_find_request_nolock(cdt, cookie, fid);
+ car = cfs_hash_lookup(cdt->cdt_request_cookie_hash, &cookie);
up_read(&cdt->cdt_request_lock);
RETURN(car);
ENTRY;
down_write(&cdt->cdt_request_lock);
- car = cdt_find_request_nolock(cdt, cookie, NULL);
- if (car != NULL) {
- list_del(&car->car_request_list);
+ car = cfs_hash_del_key(cdt->cdt_request_cookie_hash, &cookie);
+ if (car == NULL) {
up_write(&cdt->cdt_request_lock);
+ RETURN(-ENOENT);
+ }
- /* reference from cdt_requests list */
- mdt_cdt_put_request(car);
-
- /* reference from cdt_find_request_nolock() */
- mdt_cdt_put_request(car);
+ list_del(&car->car_request_list);
+ up_write(&cdt->cdt_request_lock);
- LASSERT(atomic_read(&cdt->cdt_request_count) >= 1);
- atomic_dec(&cdt->cdt_request_count);
+ /* Drop reference from cdt_request_list. */
+ mdt_cdt_put_request(car);
- RETURN(0);
- }
- up_write(&cdt->cdt_request_lock);
+ LASSERT(atomic_read(&cdt->cdt_request_count) >= 1);
+ atomic_dec(&cdt->cdt_request_count);
- RETURN(-ENOENT);
+ RETURN(0);
}
/**
int rc;
ENTRY;
- car = mdt_cdt_find_request(cdt, pgs->hpk_cookie, NULL);
+ car = mdt_cdt_find_request(cdt, pgs->hpk_cookie);
if (car == NULL)
RETURN(ERR_PTR(-ENOENT));
down_read(&cdt->cdt_request_lock);
- if (list_empty(&cdt->cdt_requests))
+ if (list_empty(&cdt->cdt_request_list))
RETURN(NULL);
if (*p == 0)
RETURN(SEQ_START_TOKEN);
i = 0;
- list_for_each(pos, &cdt->cdt_requests) {
+ list_for_each(pos, &cdt->cdt_request_list) {
i++;
if (i >= *p)
RETURN(pos);
ENTRY;
if (pos == SEQ_START_TOKEN)
- pos = cdt->cdt_requests.next;
+ pos = cdt->cdt_request_list.next;
else
pos = pos->next;
(*p)++;
- if (pos != &cdt->cdt_requests)
+ if (pos != &cdt->cdt_request_list)
RETURN(pos);
else
RETURN(NULL);
#ifndef _MDT_INTERNAL_H
#define _MDT_INTERNAL_H
-
+#include <libcfs/libcfs.h>
+#include <libcfs/libcfs_hash.h>
#include <upcall_cache.h>
#include <lustre_net.h>
#include <lustre/lustre_idl.h>
* requests */
atomic_t cdt_request_count; /**< current count of
* started requests */
- struct list_head cdt_requests; /**< list of started
- * requests */
+ /* started requests (struct cdt_agent_req:car_cookie_hash)
+ * indexed by cookie */
+ struct cfs_hash *cdt_request_cookie_hash;
+ /* started requests (struct cdt_agent_req:car_request_list) */
+ struct list_head cdt_request_list;
struct list_head cdt_agents; /**< list of register
* agents */
struct list_head cdt_restore_hdl; /**< list of restore lock
};
struct cdt_agent_req {
+ struct hlist_node car_cookie_hash; /**< find req by cookie */
struct list_head car_request_list; /**< to chain all the req. */
atomic_t car_refcount; /**< reference counter */
__u64 car_compound_id; /**< compound id */
struct hsm_action_list *hal);
int mdt_hsm_get_actions(struct mdt_thread_info *mti,
struct hsm_action_list *hal);
-int mdt_hsm_get_running(struct mdt_thread_info *mti,
- struct hsm_action_list *hal);
bool mdt_hsm_restore_is_running(struct mdt_thread_info *mti,
const struct lu_fid *fid);
/* mdt/mdt_hsm_cdt_requests.c */
+extern struct cfs_hash_ops cdt_request_cookie_hash_ops;
extern const struct file_operations mdt_hsm_active_requests_fops;
void dump_requests(char *prefix, struct coordinator *cdt);
struct cdt_agent_req *mdt_cdt_alloc_request(__u64 compound_id, __u32 archive_id,
struct hsm_action_item *hai);
void mdt_cdt_free_request(struct cdt_agent_req *car);
int mdt_cdt_add_request(struct coordinator *cdt, struct cdt_agent_req *new_car);
-struct cdt_agent_req *mdt_cdt_find_request(struct coordinator *cdt,
- const __u64 cookie,
- const struct lu_fid *fid);
+struct cdt_agent_req *mdt_cdt_find_request(struct coordinator *cdt, u64 cookie);
void mdt_cdt_get_work_done(struct cdt_agent_req *car, __u64 *done_sz);
void mdt_cdt_get_request(struct cdt_agent_req *car);
void mdt_cdt_put_request(struct cdt_agent_req *car);