Whamcloud - gitweb
LU-14119 osd: delete stale OI mapping entry 41/41741/4
authorLai Siyao <lai.siyao@whamcloud.com>
Wed, 24 Feb 2021 03:31:06 +0000 (11:31 +0800)
committerOleg Drokin <green@whamcloud.com>
Tue, 6 Apr 2021 03:02:34 +0000 (03:02 +0000)
Once LMA check shows OI mapping entry is stale, delete it from
OI table, as can avoid removing whole OI files.

Don't add OI mapping into cache until osd_fid_lookup(), because
the mapping in OI is not trustable until FID in LMA is checked,
otherwise it may mislead LFSCK.

Signed-off-by: Lai Siyao <lai.siyao@whamcloud.com>
Change-Id: I4b50dcc02149d485e4bf4a361ca2994daa280feb
Reviewed-on: https://review.whamcloud.com/41741
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Hongchao Zhang <hongchao@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/osd-ldiskfs/osd_handler.c
lustre/osd-ldiskfs/osd_internal.h
lustre/osd-ldiskfs/osd_scrub.c
lustre/osd-zfs/osd_internal.h
lustre/osd-zfs/osd_object.c
lustre/osd-zfs/osd_scrub.c

index 972f2b9..00e3ebd 100644 (file)
@@ -933,7 +933,6 @@ struct osd_check_lmv_buf {
        struct dir_context ctx;
        struct osd_thread_info *oclb_info;
        struct osd_device *oclb_dev;
        struct dir_context ctx;
        struct osd_thread_info *oclb_info;
        struct osd_device *oclb_dev;
-       struct osd_idmap_cache *oclb_oic;
        int oclb_items;
        bool oclb_found;
 };
        int oclb_items;
        bool oclb_found;
 };
@@ -959,7 +958,6 @@ static int osd_stripe_dir_filldir(void *buf,
        struct lu_fid *fid = &oti->oti_fid3;
        struct osd_inode_id *id = &oti->oti_id3;
        struct osd_device *dev = oclb->oclb_dev;
        struct lu_fid *fid = &oti->oti_fid3;
        struct osd_inode_id *id = &oti->oti_id3;
        struct osd_device *dev = oclb->oclb_dev;
-       struct osd_idmap_cache *oic = oclb->oclb_oic;
        struct inode *inode;
 
        oclb->oclb_items++;
        struct inode *inode;
 
        oclb->oclb_items++;
@@ -982,10 +980,7 @@ static int osd_stripe_dir_filldir(void *buf,
 
        iput(inode);
        osd_add_oi_cache(oti, dev, id, fid);
 
        iput(inode);
        osd_add_oi_cache(oti, dev, id, fid);
-       oic->oic_fid = *fid;
-       oic->oic_lid = *id;
-       oic->oic_dev = dev;
-       osd_oii_insert(dev, oic, true);
+       osd_oii_insert(dev, fid, id, true);
        oclb->oclb_found = true;
 
        return 1;
        oclb->oclb_found = true;
 
        return 1;
@@ -1028,7 +1023,7 @@ static int osd_stripe_dir_filldir(void *buf,
  *    the correct OI mapping for the slave MDT-object.
  */
 static int osd_check_lmv(struct osd_thread_info *oti, struct osd_device *dev,
  *    the correct OI mapping for the slave MDT-object.
  */
 static int osd_check_lmv(struct osd_thread_info *oti, struct osd_device *dev,
-                        struct inode *inode, struct osd_idmap_cache *oic)
+                        struct inode *inode)
 {
        struct lu_buf *buf = &oti->oti_big_buf;
        struct dentry *dentry = &oti->oti_obj_dentry;
 {
        struct lu_buf *buf = &oti->oti_big_buf;
        struct dentry *dentry = &oti->oti_obj_dentry;
@@ -1038,7 +1033,6 @@ static int osd_check_lmv(struct osd_thread_info *oti, struct osd_device *dev,
                .ctx.actor = osd_stripe_dir_filldir,
                .oclb_info = oti,
                .oclb_dev = dev,
                .ctx.actor = osd_stripe_dir_filldir,
                .oclb_info = oti,
                .oclb_dev = dev,
-               .oclb_oic = oic,
                .oclb_found = false,
        };
        int rc = 0;
                .oclb_found = false,
        };
        int rc = 0;
@@ -1092,9 +1086,9 @@ again:
 out:
        if (rc < 0)
                CDEBUG(D_LFSCK,
 out:
        if (rc < 0)
                CDEBUG(D_LFSCK,
-                      "%s: cannot check LMV, ino = %lu/%u "DFID": rc = %d\n",
+                      "%s: cannot check LMV, ino = %lu/%u: rc = %d\n",
                       osd_ino2name(inode), inode->i_ino, inode->i_generation,
                       osd_ino2name(inode), inode->i_ino, inode->i_generation,
-                      PFID(&oic->oic_fid), rc);
+                      rc);
        else
                rc = 0;
 
        else
                rc = 0;
 
@@ -1252,16 +1246,15 @@ trigger:
                if (scrub->os_partial_scan && !scrub->os_in_join)
                        goto join;
 
                if (scrub->os_partial_scan && !scrub->os_in_join)
                        goto join;
 
-               osd_add_oi_cache(info, dev, id, fid);
                if (IS_ERR_OR_NULL(inode) || result) {
                if (IS_ERR_OR_NULL(inode) || result) {
-                       osd_oii_insert(dev, oic, result == -ENOENT);
+                       osd_oii_insert(dev, fid, id, result == -ENOENT);
                        GOTO(out, result = -EINPROGRESS);
                }
 
                LASSERT(remote);
                LASSERT(obj->oo_inode == inode);
 
                        GOTO(out, result = -EINPROGRESS);
                }
 
                LASSERT(remote);
                LASSERT(obj->oo_inode == inode);
 
-               osd_oii_insert(dev, oic, true);
+               osd_oii_insert(dev, fid, id, true);
                goto found;
        }
 
                goto found;
        }
 
@@ -1283,16 +1276,15 @@ join:
        if (rc1 && rc1 != -EALREADY)
                GOTO(out, result = -EREMCHG);
 
        if (rc1 && rc1 != -EALREADY)
                GOTO(out, result = -EREMCHG);
 
-       osd_add_oi_cache(info, dev, id, fid);
        if (IS_ERR_OR_NULL(inode) || result) {
        if (IS_ERR_OR_NULL(inode) || result) {
-               osd_oii_insert(dev, oic, result == -ENOENT);
+               osd_oii_insert(dev, fid, id, result == -ENOENT);
                GOTO(out, result = -EINPROGRESS);
        }
 
        LASSERT(remote);
        LASSERT(obj->oo_inode == inode);
 
                GOTO(out, result = -EINPROGRESS);
        }
 
        LASSERT(remote);
        LASSERT(obj->oo_inode == inode);
 
-       osd_oii_insert(dev, oic, true);
+       osd_oii_insert(dev, fid, id, true);
        goto found;
 
 check_lma:
        goto found;
 
 check_lma:
@@ -1389,6 +1381,8 @@ check_lma:
 
        if (saved_ino == id->oii_ino && saved_gen == id->oii_gen) {
                result = -EREMCHG;
 
        if (saved_ino == id->oii_ino && saved_gen == id->oii_gen) {
                result = -EREMCHG;
+               osd_scrub_refresh_mapping(info, dev, fid, id, DTO_INDEX_DELETE,
+                                         true, 0, NULL);
                goto trigger;
        }
 
                goto trigger;
        }
 
@@ -1423,7 +1417,7 @@ found:
 
        if (S_ISDIR(inode->i_mode) &&
            (flags & SS_AUTO_PARTIAL || sf->sf_status == SS_SCANNING))
 
        if (S_ISDIR(inode->i_mode) &&
            (flags & SS_AUTO_PARTIAL || sf->sf_status == SS_SCANNING))
-               osd_check_lmv(info, dev, inode, oic);
+               osd_check_lmv(info, dev, inode);
 
        result = osd_attach_jinode(inode);
        if (result)
 
        result = osd_attach_jinode(inode);
        if (result)
@@ -5770,11 +5764,9 @@ static int osd_ea_add_rec(const struct lu_env *env, struct osd_object *pobj,
 
 static int
 osd_consistency_check(struct osd_thread_info *oti, struct osd_device *dev,
 
 static int
 osd_consistency_check(struct osd_thread_info *oti, struct osd_device *dev,
-                     struct osd_idmap_cache *oic)
+                     const struct lu_fid *fid, struct osd_inode_id *id)
 {
        struct lustre_scrub *scrub = &dev->od_scrub.os_scrub;
 {
        struct lustre_scrub *scrub = &dev->od_scrub.os_scrub;
-       struct lu_fid *fid = &oic->oic_fid;
-       struct osd_inode_id *id = &oic->oic_lid;
        struct inode *inode = NULL;
        int once = 0;
        bool insert;
        struct inode *inode = NULL;
        int once = 0;
        bool insert;
@@ -5837,7 +5829,7 @@ trigger:
                        }
                }
 
                        }
                }
 
-               rc = osd_oii_insert(dev, oic, insert);
+               rc = osd_oii_insert(dev, fid, id, insert);
                /*
                 * There is race condition between osd_oi_lookup and OI scrub.
                 * The OI scrub finished just after osd_oi_lookup() failure.
                /*
                 * There is race condition between osd_oi_lookup and OI scrub.
                 * The OI scrub finished just after osd_oi_lookup() failure.
@@ -5850,7 +5842,7 @@ trigger:
                if (!S_ISDIR(inode->i_mode))
                        rc = 0;
                else
                if (!S_ISDIR(inode->i_mode))
                        rc = 0;
                else
-                       rc = osd_check_lmv(oti, dev, inode, oic);
+                       rc = osd_check_lmv(oti, dev, inode);
 
                GOTO(out, rc);
        }
 
                GOTO(out, rc);
        }
@@ -5875,10 +5867,10 @@ out:
 
 static int osd_fail_fid_lookup(struct osd_thread_info *oti,
                               struct osd_device *dev,
 
 static int osd_fail_fid_lookup(struct osd_thread_info *oti,
                               struct osd_device *dev,
-                              struct osd_idmap_cache *oic,
                               struct lu_fid *fid, __u32 ino)
 {
        struct lustre_ost_attrs *loa = &oti->oti_ost_attrs;
                               struct lu_fid *fid, __u32 ino)
 {
        struct lustre_ost_attrs *loa = &oti->oti_ost_attrs;
+       struct osd_idmap_cache *oic = &oti->oti_cache;
        struct inode *inode;
        int rc;
 
        struct inode *inode;
        int rc;
 
@@ -6069,13 +6061,12 @@ static int osd_ea_lookup_rec(const struct lu_env *env, struct osd_object *obj,
        if (!IS_ERR(bh)) {
                struct osd_thread_info *oti = osd_oti_get(env);
                struct osd_inode_id *id = &oti->oti_id;
        if (!IS_ERR(bh)) {
                struct osd_thread_info *oti = osd_oti_get(env);
                struct osd_inode_id *id = &oti->oti_id;
-               struct osd_idmap_cache *oic = &oti->oti_cache;
                struct osd_device *dev = osd_obj2dev(obj);
 
                ino = le32_to_cpu(de->inode);
                if (OBD_FAIL_CHECK(OBD_FAIL_FID_LOOKUP)) {
                        brelse(bh);
                struct osd_device *dev = osd_obj2dev(obj);
 
                ino = le32_to_cpu(de->inode);
                if (OBD_FAIL_CHECK(OBD_FAIL_FID_LOOKUP)) {
                        brelse(bh);
-                       rc = osd_fail_fid_lookup(oti, dev, oic, fid, ino);
+                       rc = osd_fail_fid_lookup(oti, dev, fid, ino);
                        GOTO(out, rc);
                }
 
                        GOTO(out, rc);
                }
 
@@ -6103,19 +6094,24 @@ static int osd_ea_lookup_rec(const struct lu_env *env, struct osd_object *obj,
                        osd_id_gen(id, ino, OSD_OII_NOGEN);
                }
 
                        osd_id_gen(id, ino, OSD_OII_NOGEN);
                }
 
-               if (rc != 0 || osd_remote_fid(env, dev, fid)) {
-                       fid_zero(&oic->oic_fid);
-
+               if (rc != 0 || osd_remote_fid(env, dev, fid))
                        GOTO(out, rc);
                        GOTO(out, rc);
-               }
 
 
-               osd_add_oi_cache(osd_oti_get(env), osd_obj2dev(obj), id, fid);
-               rc = osd_consistency_check(oti, dev, oic);
-               if (rc == -ENOENT)
-                       fid_zero(&oic->oic_fid);
-               else
+               rc = osd_consistency_check(oti, dev, fid, id);
+               if (rc != -ENOENT) {
                        /* Other error should not affect lookup result. */
                        rc = 0;
                        /* Other error should not affect lookup result. */
                        rc = 0;
+
+                       /* Normal file mapping should be added into OI cache
+                        * after FID in LMA check, but for local files like
+                        * hsm_actions, their FIDs are not stored in OI files,
+                        * see osd_initial_OI_scrub(), and here is the only
+                        * place to load mapping into OI cache.
+                        */
+                       if (!fid_is_namespace_visible(fid))
+                               osd_add_oi_cache(osd_oti_get(env),
+                                                osd_obj2dev(obj), id, fid);
+               }
        } else {
                rc = PTR_ERR(bh);
        }
        } else {
                rc = PTR_ERR(bh);
        }
index b6e5a1e..f9db66f 100644 (file)
@@ -800,8 +800,8 @@ int osd_scrub_start(const struct lu_env *env, struct osd_device *dev,
 void osd_scrub_stop(struct osd_device *dev);
 int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev);
 void osd_scrub_cleanup(const struct lu_env *env, struct osd_device *dev);
 void osd_scrub_stop(struct osd_device *dev);
 int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev);
 void osd_scrub_cleanup(const struct lu_env *env, struct osd_device *dev);
-int osd_oii_insert(struct osd_device *dev, struct osd_idmap_cache *oic,
-                  int insert);
+int osd_oii_insert(struct osd_device *dev, const struct lu_fid *fid,
+                  struct osd_inode_id *id, int insert);
 int osd_oii_lookup(struct osd_device *dev, const struct lu_fid *fid,
                   struct osd_inode_id *id);
 void osd_scrub_dump(struct seq_file *m, struct osd_device *dev);
 int osd_oii_lookup(struct osd_device *dev, const struct lu_fid *fid,
                   struct osd_inode_id *id);
 void osd_scrub_dump(struct seq_file *m, struct osd_device *dev);
@@ -828,6 +828,13 @@ int osd_lookup_in_remote_parent(struct osd_thread_info *oti,
 
 int osd_ost_seq_exists(struct osd_thread_info *info, struct osd_device *osd,
                       __u64 seq);
 
 int osd_ost_seq_exists(struct osd_thread_info *info, struct osd_device *osd,
                       __u64 seq);
+int osd_scrub_refresh_mapping(struct osd_thread_info *info,
+                             struct osd_device *dev,
+                             const struct lu_fid *fid,
+                             const struct osd_inode_id *id,
+                             int ops, bool force,
+                             enum oi_check_flags flags, bool *exist);
+
 /* osd_quota_fmt.c */
 int walk_tree_dqentry(const struct lu_env *env, struct osd_object *obj,
                       int type, uint blk, int depth, uint index,
 /* osd_quota_fmt.c */
 int walk_tree_dqentry(const struct lu_env *env, struct osd_object *obj,
                       int type, uint blk, int depth, uint index,
index 0352876..ecc7631 100644 (file)
@@ -64,12 +64,12 @@ static inline int osd_scrub_has_window(struct lustre_scrub *scrub,
  * \retval   0, changed successfully
  * \retval -ve, on error
  */
  * \retval   0, changed successfully
  * \retval -ve, on error
  */
-static int osd_scrub_refresh_mapping(struct osd_thread_info *info,
-                                    struct osd_device *dev,
-                                    const struct lu_fid *fid,
-                                    const struct osd_inode_id *id,
-                                    int ops, bool force,
-                                    enum oi_check_flags flags, bool *exist)
+int osd_scrub_refresh_mapping(struct osd_thread_info *info,
+                             struct osd_device *dev,
+                             const struct lu_fid *fid,
+                             const struct osd_inode_id *id,
+                             int ops, bool force,
+                             enum oi_check_flags flags, bool *exist)
 {
        handle_t *th;
        int       rc;
 {
        handle_t *th;
        int       rc;
@@ -3019,8 +3019,8 @@ const struct dt_index_operations osd_otable_ops = {
 
 #define SCRUB_BAD_OIMAP_DECAY_INTERVAL 60
 
 
 #define SCRUB_BAD_OIMAP_DECAY_INTERVAL 60
 
-int osd_oii_insert(struct osd_device *dev, struct osd_idmap_cache *oic,
-                  int insert)
+int osd_oii_insert(struct osd_device *dev, const struct lu_fid *fid,
+                  struct osd_inode_id *id, int insert)
 {
        struct osd_inconsistent_item *oii;
        struct osd_scrub *oscrub = &dev->od_scrub;
 {
        struct osd_inconsistent_item *oii;
        struct osd_scrub *oscrub = &dev->od_scrub;
@@ -3033,7 +3033,9 @@ int osd_oii_insert(struct osd_device *dev, struct osd_idmap_cache *oic,
                RETURN(-ENOMEM);
 
        INIT_LIST_HEAD(&oii->oii_list);
                RETURN(-ENOMEM);
 
        INIT_LIST_HEAD(&oii->oii_list);
-       oii->oii_cache = *oic;
+       oii->oii_cache.oic_fid = *fid;
+       oii->oii_cache.oic_lid = *id;
+       oii->oii_cache.oic_dev = dev;
        oii->oii_insert = insert;
 
        spin_lock(&lscrub->os_lock);
        oii->oii_insert = insert;
 
        spin_lock(&lscrub->os_lock);
index cd50e1d..f5754c1 100644 (file)
@@ -700,6 +700,23 @@ int osd_oii_insert(const struct lu_env *env, struct osd_device *dev,
 int osd_oii_lookup(struct osd_device *dev, const struct lu_fid *fid,
                   uint64_t *oid);
 
 int osd_oii_lookup(struct osd_device *dev, const struct lu_fid *fid,
                   uint64_t *oid);
 
+/**
+ * Basic transaction credit op
+ */
+enum dt_txn_op {
+       DTO_INDEX_INSERT,
+       DTO_INDEX_DELETE,
+       DTO_INDEX_UPDATE,
+       DTO_NR
+};
+
+int osd_scrub_refresh_mapping(const struct lu_env *env,
+                             struct osd_device *dev,
+                             const struct lu_fid *fid,
+                             uint64_t oid, enum dt_txn_op ops,
+                             bool force, const char *name);
+
+
 /* osd_xattr.c */
 int __osd_sa_xattr_schedule_update(const struct lu_env *env,
                                   struct osd_object *obj,
 /* osd_xattr.c */
 int __osd_sa_xattr_schedule_update(const struct lu_env *env,
                                   struct osd_object *obj,
index 9817cc5..d1e4374 100644 (file)
@@ -616,9 +616,12 @@ zget:
                GOTO(out, rc = 0);
 
        rc = osd_check_lma(env, obj);
                GOTO(out, rc = 0);
 
        rc = osd_check_lma(env, obj);
-       if ((!rc && !remote) || (rc != -EREMCHG))
+       if (rc != -EREMCHG)
                GOTO(out, rc);
 
                GOTO(out, rc);
 
+       osd_scrub_refresh_mapping(env, osd, fid, oid, DTO_INDEX_DELETE, true,
+                                 NULL);
+
 trigger:
        /* We still have chance to get the valid dnode: for the object that is
         * referenced by remote name entry, the object on the local MDT will be
 trigger:
        /* We still have chance to get the valid dnode: for the object that is
         * referenced by remote name entry, the object on the local MDT will be
index 1f5e903..8579ee0 100644 (file)
 #define OSD_OTABLE_MAX_HASH            ((1ULL << 48) - 1)
 #define OTABLE_PREFETCH                        256
 
 #define OSD_OTABLE_MAX_HASH            ((1ULL << 48) - 1)
 #define OTABLE_PREFETCH                        256
 
-#define DTO_INDEX_INSERT               1
-#define DTO_INDEX_DELETE               2
-#define DTO_INDEX_UPDATE               3
-
 static inline bool osd_scrub_has_window(struct osd_otable_it *it)
 {
        return it->ooi_prefetched < OTABLE_PREFETCH;
 static inline bool osd_scrub_has_window(struct osd_otable_it *it)
 {
        return it->ooi_prefetched < OTABLE_PREFETCH;
@@ -71,11 +67,11 @@ static inline bool osd_scrub_has_window(struct osd_otable_it *it)
  * \retval   0, changed successfully
  * \retval -ve, on error
  */
  * \retval   0, changed successfully
  * \retval -ve, on error
  */
-static int osd_scrub_refresh_mapping(const struct lu_env *env,
-                                    struct osd_device *dev,
-                                    const struct lu_fid *fid,
-                                    uint64_t oid, int ops,
-                                    bool force, const char *name)
+int osd_scrub_refresh_mapping(const struct lu_env *env,
+                             struct osd_device *dev,
+                             const struct lu_fid *fid,
+                             uint64_t oid, enum dt_txn_op ops,
+                             bool force, const char *name)
 {
        struct osd_thread_info *info = osd_oti_get(env);
        struct zpl_direntry *zde = &info->oti_zde.lzd_reg;
 {
        struct osd_thread_info *info = osd_oti_get(env);
        struct zpl_direntry *zde = &info->oti_zde.lzd_reg;