Whamcloud - gitweb
LU-4788 lfsck: replace cfs_list_t with list_head
[fs/lustre-release.git] / lustre / lfsck / lfsck_namespace.c
index 0016a85..2c8918e 100644 (file)
@@ -34,7 +34,6 @@
 #include <lu_object.h>
 #include <dt_object.h>
 #include <md_object.h>
-#include <lustre_linkea.h>
 #include <lustre_fid.h>
 #include <lustre_lib.h>
 #include <lustre_net.h>
@@ -794,11 +793,10 @@ static int lfsck_namespace_prep(const struct lu_env *env,
                if (!lfsck->li_drop_dryrun ||
                    lfsck_pos_is_zero(&ns->ln_pos_first_inconsistent)) {
                        ns->ln_status = LS_SCANNING_PHASE2;
-                       cfs_list_del_init(&com->lc_link);
-                       cfs_list_add_tail(&com->lc_link,
-                                         &lfsck->li_list_double_scan);
-                       if (!cfs_list_empty(&com->lc_link_dir))
-                               cfs_list_del_init(&com->lc_link_dir);
+                       list_move_tail(&com->lc_link,
+                                      &lfsck->li_list_double_scan);
+                       if (!list_empty(&com->lc_link_dir))
+                               list_del_init(&com->lc_link_dir);
                        lfsck_pos_set_zero(pos);
                } else {
                        ns->ln_status = LS_SCANNING_PHASE1;
@@ -815,16 +813,16 @@ static int lfsck_namespace_prep(const struct lu_env *env,
                        ns->ln_objs_nlink_repaired = 0;
                        ns->ln_objs_lost_found = 0;
                        fid_zero(&ns->ln_fid_latest_scanned_phase2);
-                       if (cfs_list_empty(&com->lc_link_dir))
-                               cfs_list_add_tail(&com->lc_link_dir,
-                                                 &lfsck->li_list_dir);
+                       if (list_empty(&com->lc_link_dir))
+                               list_add_tail(&com->lc_link_dir,
+                                             &lfsck->li_list_dir);
                        *pos = ns->ln_pos_first_inconsistent;
                }
        } else {
                ns->ln_status = LS_SCANNING_PHASE1;
-               if (cfs_list_empty(&com->lc_link_dir))
-                       cfs_list_add_tail(&com->lc_link_dir,
-                                         &lfsck->li_list_dir);
+               if (list_empty(&com->lc_link_dir))
+                       list_add_tail(&com->lc_link_dir,
+                                     &lfsck->li_list_dir);
                if (!lfsck->li_drop_dryrun ||
                    lfsck_pos_is_zero(&ns->ln_pos_first_inconsistent)) {
                        *pos = ns->ln_pos_last_checkpoint;
@@ -1092,23 +1090,20 @@ static int lfsck_namespace_post(const struct lu_env *env,
                ns->ln_status = LS_SCANNING_PHASE2;
                ns->ln_flags |= LF_SCANNED_ONCE;
                ns->ln_flags &= ~LF_UPGRADE;
-               cfs_list_del_init(&com->lc_link);
-               cfs_list_del_init(&com->lc_link_dir);
-               cfs_list_add_tail(&com->lc_link, &lfsck->li_list_double_scan);
+               list_del_init(&com->lc_link_dir);
+               list_move_tail(&com->lc_link, &lfsck->li_list_double_scan);
        } else if (result == 0) {
                ns->ln_status = lfsck->li_status;
                if (ns->ln_status == 0)
                        ns->ln_status = LS_STOPPED;
                if (ns->ln_status != LS_PAUSED) {
-                       cfs_list_del_init(&com->lc_link);
-                       cfs_list_del_init(&com->lc_link_dir);
-                       cfs_list_add_tail(&com->lc_link, &lfsck->li_list_idle);
+                       list_del_init(&com->lc_link_dir);
+                       list_move_tail(&com->lc_link, &lfsck->li_list_idle);
                }
        } else {
                ns->ln_status = LS_FAILED;
-               cfs_list_del_init(&com->lc_link);
-               cfs_list_del_init(&com->lc_link_dir);
-               cfs_list_add_tail(&com->lc_link, &lfsck->li_list_idle);
+               list_del_init(&com->lc_link_dir);
+               list_move_tail(&com->lc_link, &lfsck->li_list_idle);
        }
        spin_unlock(&lfsck->li_lock);
 
@@ -1607,6 +1602,86 @@ static struct lfsck_operations lfsck_namespace_ops = {
        .lfsck_query            = lfsck_namespace_query,
 };
 
+/**
+ * Verify the specified linkEA entry for the given directory object.
+ * If the object has no such linkEA entry or it has more other linkEA
+ * entries, then re-generate the linkEA with the given information.
+ *
+ * \param[in] env      pointer to the thread context
+ * \param[in] dev      pointer to the dt_device
+ * \param[in] obj      pointer to the dt_object to be handled
+ * \param[in] cname    the name for the child in the parent directory
+ * \param[in] pfid     the parent directory's FID for the linkEA
+ *
+ * \retval             0 for success
+ * \retval             negative error number on failure
+ */
+int lfsck_verify_linkea(const struct lu_env *env, struct dt_device *dev,
+                       struct dt_object *obj, const struct lu_name *cname,
+                       const struct lu_fid *pfid)
+{
+       struct linkea_data       ldata  = { 0 };
+       struct lu_buf            linkea_buf;
+       struct thandle          *th;
+       int                      rc;
+       int                      fl     = LU_XATTR_CREATE;
+       bool                     dirty  = false;
+       ENTRY;
+
+       LASSERT(S_ISDIR(lfsck_object_type(obj)));
+
+       rc = lfsck_links_read(env, obj, &ldata);
+       if (rc == -ENODATA) {
+               dirty = true;
+       } else if (rc == 0) {
+               fl = LU_XATTR_REPLACE;
+               if (ldata.ld_leh->leh_reccount != 1) {
+                       dirty = true;
+               } else {
+                       rc = linkea_links_find(&ldata, cname, pfid);
+                       if (rc != 0)
+                               dirty = true;
+               }
+       }
+
+       if (!dirty)
+               RETURN(rc);
+
+       rc = linkea_data_new(&ldata, &lfsck_env_info(env)->lti_linkea_buf);
+       if (rc != 0)
+               RETURN(rc);
+
+       rc = linkea_add_buf(&ldata, cname, pfid);
+       if (rc != 0)
+               RETURN(rc);
+
+       linkea_buf.lb_buf = ldata.ld_buf->lb_buf;
+       linkea_buf.lb_len = ldata.ld_leh->leh_len;
+       th = dt_trans_create(env, dev);
+       if (IS_ERR(th))
+               RETURN(PTR_ERR(th));
+
+       rc = dt_declare_xattr_set(env, obj, &linkea_buf,
+                                 XATTR_NAME_LINK, fl, th);
+       if (rc != 0)
+               GOTO(stop, rc = PTR_ERR(th));
+
+       rc = dt_trans_start_local(env, dev, th);
+       if (rc != 0)
+               GOTO(stop, rc);
+
+       dt_write_lock(env, obj, 0);
+       rc = dt_xattr_set(env, obj, &linkea_buf,
+                         XATTR_NAME_LINK, fl, th, BYPASS_CAPA);
+       dt_write_unlock(env, obj);
+
+       GOTO(stop, rc);
+
+stop:
+       dt_trans_stop(env, dev, th);
+       return rc;
+}
+
 int lfsck_namespace_setup(const struct lu_env *env,
                          struct lfsck_instance *lfsck)
 {
@@ -1623,8 +1698,8 @@ int lfsck_namespace_setup(const struct lu_env *env,
        if (com == NULL)
                RETURN(-ENOMEM);
 
-       CFS_INIT_LIST_HEAD(&com->lc_link);
-       CFS_INIT_LIST_HEAD(&com->lc_link_dir);
+       INIT_LIST_HEAD(&com->lc_link);
+       INIT_LIST_HEAD(&com->lc_link_dir);
        init_rwsem(&com->lc_sem);
        atomic_set(&com->lc_ref, 1);
        com->lc_lfsck = lfsck;
@@ -1673,7 +1748,7 @@ int lfsck_namespace_setup(const struct lu_env *env,
        case LS_FAILED:
        case LS_STOPPED:
                spin_lock(&lfsck->li_lock);
-               cfs_list_add_tail(&com->lc_link, &lfsck->li_list_idle);
+               list_add_tail(&com->lc_link, &lfsck->li_list_idle);
                spin_unlock(&lfsck->li_lock);
                break;
        default:
@@ -1690,8 +1765,8 @@ int lfsck_namespace_setup(const struct lu_env *env,
        case LS_PAUSED:
        case LS_CRASHED:
                spin_lock(&lfsck->li_lock);
-               cfs_list_add_tail(&com->lc_link, &lfsck->li_list_scan);
-               cfs_list_add_tail(&com->lc_link_dir, &lfsck->li_list_dir);
+               list_add_tail(&com->lc_link, &lfsck->li_list_scan);
+               list_add_tail(&com->lc_link_dir, &lfsck->li_list_dir);
                spin_unlock(&lfsck->li_lock);
                break;
        }