Whamcloud - gitweb
LU-3335 scrub: purge inconsistenct objects after OI scrub
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_scrub.c
index 475fbca..72ed5b8 100644 (file)
@@ -35,9 +35,6 @@
  * Author: Fan Yong <yong.fan@whamcloud.com>
  */
 
-#ifndef EXPORT_SYMTAB
-# define EXPORT_SYMTAB
-#endif
 #define DEBUG_SUBSYSTEM S_MDS
 
 #include <lustre/lustre_idl.h>
@@ -100,7 +97,8 @@ static int osd_scrub_refresh_mapping(struct osd_thread_info *info,
        ENTRY;
 
        fid_cpu_to_be(oi_fid, fid);
-       osd_id_pack(oi_id, id);
+       if (id != NULL)
+               osd_id_pack(oi_id, id);
        jh = ldiskfs_journal_start_sb(osd_sb(dev),
                                      osd_dto_credits_noquota[ops]);
        if (IS_ERR(jh)) {
@@ -519,6 +517,9 @@ iget:
                        sf->sf_items_updated_prior++;
                else
                        sf->sf_items_updated++;
+
+               /* The target has been changed, need to be re-loaded. */
+               lu_object_purge(info->oti_env, osd2lu_dev(dev), fid);
        }
 
        GOTO(out, rc);
@@ -1020,7 +1021,6 @@ static int osd_scrub_main(void *args)
        int                   rc;
        ENTRY;
 
-       cfs_daemonize("OI_scrub");
        rc = lu_env_init(&env, LCT_DT_THREAD);
        if (rc != 0) {
                CERROR("%.16s: OI scrub, fail to init env, rc = %d\n",
@@ -1522,11 +1522,12 @@ osd_ios_OBJECTS_scan(struct osd_thread_info *info, struct osd_device *dev,
 static int osd_initial_OI_scrub(struct osd_thread_info *info,
                                struct osd_device *dev)
 {
-       struct osd_ios_item *item    = NULL;
-       scandir_t            scandir = osd_ios_general_scan;
-       filldir_t            filldir = osd_ios_root_fill;
-       struct dentry       *dentry  = osd_sb(dev)->s_root;
-       int                  rc;
+       struct osd_ios_item     *item    = NULL;
+       scandir_t                scandir = osd_ios_general_scan;
+       filldir_t                filldir = osd_ios_root_fill;
+       struct dentry           *dentry  = osd_sb(dev)->s_root;
+       const struct osd_lf_map *map     = osd_lf_maps;
+       int                      rc;
        ENTRY;
 
        while (1) {
@@ -1560,7 +1561,32 @@ static int osd_initial_OI_scrub(struct osd_thread_info *info,
                OBD_FREE_PTR(item);
        }
 
-       RETURN(rc);
+       if (rc != 0)
+               RETURN(rc);
+
+       /* There maybe the case that the object has been removed, but its OI
+        * mapping is still in the OI file, such as the "CATALOGS" after MDT
+        * file-level backup/restore. So here cleanup the stale OI mappings. */
+       while (map->olm_name != NULL) {
+               struct dentry *child;
+
+               if (fid_is_zero(&map->olm_fid)) {
+                       map++;
+                       continue;
+               }
+
+               child = osd_ios_lookup_one_len(map->olm_name,
+                                              osd_sb(dev)->s_root,
+                                              strlen(map->olm_name));
+               if (!IS_ERR(child))
+                       dput(child);
+               else if (PTR_ERR(child) == -ENOENT)
+                       osd_scrub_refresh_mapping(info, dev, &map->olm_fid,
+                                                 NULL, DTO_INDEX_DELETE);
+               map++;
+       }
+
+       RETURN(0);
 }
 
 char *osd_lf_fid2name(const struct lu_fid *fid)
@@ -1612,8 +1638,8 @@ again:
 
        scrub->os_start_flags = flags;
        thread_set_flags(thread, 0);
-       rc = cfs_create_thread(osd_scrub_main, dev, 0);
-       if (rc < 0) {
+       rc = PTR_ERR(kthread_run(osd_scrub_main, dev, "OI_scrub"));
+       if (IS_ERR_VALUE(rc)) {
                CERROR("%.16s: cannot start iteration thread, rc = %d\n",
                       LDISKFS_SB(osd_sb(dev))->s_es->s_volume_name, rc);
                RETURN(rc);