Whamcloud - gitweb
LU-14043 llite: allow DIO with unaligned IO count
[fs/lustre-release.git] / lustre / mdt / mdt_hsm_cdt_requests.c
index bbd7f44..7135334 100644 (file)
@@ -23,7 +23,7 @@
  * (C) Copyright 2012 Commissariat a l'energie atomique et aux energies
  *     alternatives
  *
- * Copyright (c) 2014, Intel Corporation.
+ * Copyright (c) 2014, 2017, Intel Corporation.
  */
 /*
  * lustre/mdt/mdt_hsm_cdt_requests.c
 
 #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
@@ -50,15 +101,15 @@ void dump_requests(char *prefix, struct coordinator *cdt)
        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="LPX64"/"LPX64
-                      " action=%s archive#=%d flags="LPX64
-                      " extent="LPX64"-"LPX64
-                      " gid="LPX64" refcount=%d canceled=%d\n",
+                      " cookie=%#llx"
+                      " action=%s archive#=%d flags=%#llx"
+                      " extent=%#llx-%#llx"
+                      " gid=%#llx refcount=%d canceled=%d\n",
                       prefix, PFID(&car->car_hai->hai_fid),
                       PFID(&car->car_hai->hai_dfid),
-                      car->car_compound_id, car->car_hai->hai_cookie,
+                      car->car_hai->hai_cookie,
                       hsm_copytool_action2name(car->car_hai->hai_action),
                       car->car_archive_id, car->car_flags,
                       car->car_hai->hai_extent.offset,
@@ -133,13 +184,11 @@ static void mdt_cdt_free_request_tree(struct cdt_req_progress *crp)
        }
        /* free all sub vectors */
        for (i = 0 ; i <= crp->crp_max / NODE_VECTOR_SZ ; i++)
-               OBD_FREE(crp->crp_node[i],
-                        NODE_VECTOR_SZ * sizeof(crp->crp_node[i][0]));
+               OBD_FREE_PTR_ARRAY(crp->crp_node[i], NODE_VECTOR_SZ);
 
        /* free main vector */
-       OBD_FREE(crp->crp_node,
-                sizeof(crp->crp_node[0]) *
-                 (crp->crp_max / NODE_VECTOR_SZ + 1));
+       OBD_FREE_PTR_ARRAY(crp->crp_node,
+                          (crp->crp_max / NODE_VECTOR_SZ + 1));
 
        crp->crp_cnt = 0;
        crp->crp_max = 0;
@@ -170,7 +219,7 @@ static int hsm_update_work(struct cdt_req_progress *crp,
        if (crp->crp_cnt >= crp->crp_max) {
                /* no more room */
                /* allocate a new vector */
-               OBD_ALLOC(v, NODE_VECTOR_SZ * sizeof(v[0]));
+               OBD_ALLOC_PTR_ARRAY(v, NODE_VECTOR_SZ);
                if (v == NULL)
                        GOTO(out, rc = -ENOMEM);
 
@@ -184,7 +233,7 @@ static int hsm_update_work(struct cdt_req_progress *crp,
                /* increase main vector size */
                OBD_ALLOC(new_vv, nsz);
                if (new_vv == NULL) {
-                       OBD_FREE(v, NODE_VECTOR_SZ * sizeof(v[0]));
+                       OBD_FREE_PTR_ARRAY(v, NODE_VECTOR_SZ);
                        GOTO(out, rc = -ENOMEM);
                }
 
@@ -202,7 +251,9 @@ static int hsm_update_work(struct cdt_req_progress *crp,
 
        v = crp->crp_node[crp->crp_cnt / NODE_VECTOR_SZ];
        node = &v[crp->crp_cnt % NODE_VECTOR_SZ];
-       interval_set(node, extent->offset, end);
+       rc = interval_set(node, extent->offset, end);
+       if (rc)
+               GOTO(out, rc);
        /* try to insert, if entry already exist ignore the new one
         * it can happen if ct sends 2 times the same progress */
        if (interval_insert(node, &crp->crp_root) == NULL)
@@ -227,7 +278,6 @@ static void mdt_cdt_init_request_tree(struct cdt_req_progress *crp)
 
 /** Allocate/init an agent request and its sub-structures.
  *
- * \param compound_id [IN]
  * \param archive_id [IN]
  * \param flags [IN]
  * \param uuid [IN]
@@ -235,8 +285,8 @@ static void mdt_cdt_init_request_tree(struct cdt_req_progress *crp)
  * \retval car [OUT] success valid structure
  * \retval car [OUT]
  */
-struct cdt_agent_req *mdt_cdt_alloc_request(__u64 compound_id, __u32 archive_id,
-                                           __u64 flags, struct obd_uuid *uuid,
+struct cdt_agent_req *mdt_cdt_alloc_request(__u32 archive_id, __u64 flags,
+                                           struct obd_uuid *uuid,
                                            struct hsm_action_item *hai)
 {
        struct cdt_agent_req *car;
@@ -247,11 +297,10 @@ struct cdt_agent_req *mdt_cdt_alloc_request(__u64 compound_id, __u32 archive_id,
                RETURN(ERR_PTR(-ENOMEM));
 
        atomic_set(&car->car_refcount, 1);
-       car->car_compound_id = compound_id;
        car->car_archive_id = archive_id;
        car->car_flags = flags;
        car->car_canceled = 0;
-       car->car_req_start = cfs_time_current_sec();
+       car->car_req_start = ktime_get_real_seconds();
        car->car_req_update = car->car_req_start;
        car->car_uuid = *uuid;
        OBD_ALLOC(car->car_hai, hai->hai_len);
@@ -299,61 +348,47 @@ void mdt_cdt_put_request(struct cdt_agent_req *car)
 }
 
 /**
- * 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);
-       up_write(&cdt->cdt_request_lock);
+       list_add_tail(&car->car_request_list, &cdt->cdt_request_list);
 
-       mdt_hsm_agent_update_statistics(cdt, 0, 0, 1, &new_car->car_uuid);
+       up_write(&cdt->cdt_request_lock);
 
+       mdt_hsm_agent_update_statistics(cdt, 0, 0, 1, &car->car_uuid);
+
+       switch (car->car_hai->hai_action) {
+       case HSMA_ARCHIVE:
+               atomic_inc(&cdt->cdt_archive_count);
+               break;
+       case HSMA_RESTORE:
+               atomic_inc(&cdt->cdt_restore_count);
+               break;
+       case HSMA_REMOVE:
+               atomic_inc(&cdt->cdt_remove_count);
+               break;
+       }
        atomic_inc(&cdt->cdt_request_count);
 
        RETURN(0);
@@ -366,15 +401,13 @@ int mdt_cdt_add_request(struct coordinator *cdt, struct cdt_agent_req *new_car)
  * \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);
@@ -392,25 +425,38 @@ int mdt_cdt_remove_request(struct coordinator *cdt, __u64 cookie)
        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);
+       list_del(&car->car_request_list);
+       up_write(&cdt->cdt_request_lock);
 
-               /* reference from cdt_find_request_nolock() */
-               mdt_cdt_put_request(car);
+       switch (car->car_hai->hai_action) {
+       case HSMA_ARCHIVE:
+               atomic_dec(&cdt->cdt_archive_count);
+               break;
+       case HSMA_RESTORE:
+               atomic_dec(&cdt->cdt_restore_count);
+               break;
+       case HSMA_REMOVE:
+               atomic_dec(&cdt->cdt_remove_count);
+               break;
+       }
 
-               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);
+       LASSERT(atomic_read(&cdt->cdt_request_count) >= 1);
+       if (atomic_dec_and_test(&cdt->cdt_request_count)) {
+               /* request count is empty, nudge coordinator for more work */
+               cdt->cdt_wakeup_coordinator = true;
+               wake_up_interruptible(&cdt->cdt_waitq);
        }
-       up_write(&cdt->cdt_request_lock);
 
-       RETURN(-ENOENT);
+       RETURN(0);
 }
 
 /**
@@ -428,14 +474,15 @@ struct cdt_agent_req *mdt_cdt_update_request(struct coordinator *cdt,
        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));
 
-       car->car_req_update = cfs_time_current_sec();
+       car->car_req_update = ktime_get_real_seconds();
 
-       /* update progress done by copy tool */
-       if (pgs->hpk_errval == 0 && pgs->hpk_extent.length != 0) {
+       /* update data move progress done by copy tool */
+       if (car->car_hai->hai_action != HSMA_REMOVE && pgs->hpk_errval == 0 &&
+           pgs->hpk_extent.length != 0) {
                rc = hsm_update_work(&car->car_progress, &pgs->hpk_extent);
                if (rc) {
                        mdt_cdt_put_request(car);
@@ -467,14 +514,14 @@ static void *mdt_hsm_active_requests_proc_start(struct seq_file *s, loff_t *p)
 
        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);
@@ -495,12 +542,12 @@ static void *mdt_hsm_active_requests_proc_next(struct seq_file *s, void *v,
        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);
@@ -524,13 +571,13 @@ static int mdt_hsm_active_requests_proc_show(struct seq_file *s, void *v)
        mdt_cdt_get_work_done(car, &data_moved);
 
        seq_printf(s, "fid="DFID" dfid="DFID
-                  " compound/cookie="LPX64"/"LPX64
-                  " action=%s archive#=%d flags="LPX64
-                  " extent="LPX64"-"LPX64" gid="LPX64
-                  " data=[%s] canceled=%d uuid=%s done="LPU64"\n",
+                  " compound/cookie=%#llx/%#llx"
+                  " action=%s archive#=%d flags=%#llx"
+                  " extent=%#llx-%#llx gid=%#llx"
+                  " data=[%s] canceled=%d uuid=%s done=%llu\n",
                   PFID(&car->car_hai->hai_fid),
                   PFID(&car->car_hai->hai_dfid),
-                  car->car_compound_id, car->car_hai->hai_cookie,
+                  0ULL /* compound_id */, car->car_hai->hai_cookie,
                   hsm_copytool_action2name(car->car_hai->hai_action),
                   car->car_archive_id, car->car_flags,
                   car->car_hai->hai_extent.offset,
@@ -568,8 +615,8 @@ static const struct seq_operations mdt_hsm_active_requests_proc_ops = {
  * public function called at open of /proc file to get
  * list of agents
  */
-static int lprocfs_open_hsm_active_requests(struct inode *inode,
-                                           struct file *file)
+static int ldebugfs_open_hsm_active_requests(struct inode *inode,
+                                            struct file *file)
 {
        struct seq_file *s;
        int              rc;
@@ -580,7 +627,7 @@ static int lprocfs_open_hsm_active_requests(struct inode *inode,
                RETURN(rc);
        }
        s = file->private_data;
-       s->private = PDE_DATA(inode);
+       s->private = inode->i_private;
 
        RETURN(rc);
 }
@@ -588,9 +635,9 @@ static int lprocfs_open_hsm_active_requests(struct inode *inode,
 /* methods to access hsm request list */
 const struct file_operations mdt_hsm_active_requests_fops = {
        .owner          = THIS_MODULE,
-       .open           = lprocfs_open_hsm_active_requests,
+       .open           = ldebugfs_open_hsm_active_requests,
        .read           = seq_read,
        .llseek         = seq_lseek,
-       .release        = lprocfs_seq_release,
+       .release        = seq_release,
 };