Whamcloud - gitweb
LU-2041 oi: keep oi mapping cache consistency
authorFan Yong <yong.fan@whamcloud.com>
Mon, 8 Oct 2012 07:35:55 +0000 (15:35 +0800)
committerOleg Drokin <green@whamcloud.com>
Tue, 9 Oct 2012 03:19:41 +0000 (23:19 -0400)
Sometimes the local ID of the per RPC thread OI mappig cache may be
changed, but the FID of such OI mapping cache has not been updated,
which will cause the RPC thread finds some unexpected object with
the given FID, should be fixed.

Move osd_device::osd_scrub::os_no_scrub to osd_device::od_noscrub.

Signed-off-by: Fan Yong <yong.fan@whamcloud.com>
Change-Id: Idbc46cd70b136b7ffc2528331d5593fbac725900
Reviewed-on: http://review.whamcloud.com/4207
Tested-by: Hudson
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Liang Zhen <liang@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_lproc.c
lustre/osd-ldiskfs/osd_scrub.c
lustre/osd-ldiskfs/osd_scrub.h
lustre/tests/sanity-scrub.sh

index f27fd30..060e1aa 100644 (file)
@@ -366,12 +366,10 @@ osd_iget_verify(struct osd_thread_info *info, struct osd_device *dev,
                return inode;
 
        rc = osd_get_lma(inode, &info->oti_obj_dentry, lma);
+       if (rc == -ENODATA)
+               return inode;
+
        if (rc != 0) {
-               if (rc == -ENODATA) {
-                       CDEBUG(D_LFSCK, "inconsistent obj: NULL, %lu, "DFID"\n",
-                              inode->i_ino, PFID(fid));
-                       rc = -EREMCHG;
-               }
                iput(inode);
                return ERR_PTR(rc);
        }
@@ -380,7 +378,7 @@ osd_iget_verify(struct osd_thread_info *info, struct osd_device *dev,
                CDEBUG(D_LFSCK, "inconsistent obj: "DFID", %lu, "DFID"\n",
                       PFID(&lma->lma_self_fid), inode->i_ino, PFID(fid));
                iput(inode);
-               return ERR_PTR(EREMCHG);
+               return ERR_PTR(-EREMCHG);
        }
        return inode;
 }
@@ -411,26 +409,27 @@ static int osd_fid_lookup(const struct lu_env *env, struct osd_object *obj,
        info = osd_oti_get(env);
        LASSERT(info);
        oic = &info->oti_cache;
-       id  = &oic->oic_lid;
 
        if (OBD_FAIL_CHECK(OBD_FAIL_OST_ENOENT))
                RETURN(-ENOENT);
 
-       if (fid_is_norm(fid)) {
-               /* Search order: 1. per-thread cache. */
-               if (lu_fid_eq(fid, &oic->oic_fid)) {
-                       goto iget;
-               } else if (!cfs_list_empty(&scrub->os_inconsistent_items)) {
-                       /* Search order: 2. OI scrub pending list. */
-                       result = osd_oii_lookup(dev, fid, id);
-                       if (result == 0)
-                               goto iget;
-               }
+       /* Search order: 1. per-thread cache. */
+       if (lu_fid_eq(fid, &oic->oic_fid)) {
+               id = &oic->oic_lid;
+               goto iget;
+       }
 
-               if (sf->sf_flags & SF_INCONSISTENT)
-                       verify = 1;
+       id = &info->oti_id;
+       if (!cfs_list_empty(&scrub->os_inconsistent_items)) {
+               /* Search order: 2. OI scrub pending list. */
+               result = osd_oii_lookup(dev, fid, id);
+               if (result == 0)
+                       goto iget;
        }
 
+       if (sf->sf_flags & SF_INCONSISTENT)
+               verify = 1;
+
        /*
         * Objects are created as locking anchors or place holders for objects
         * yet to be created. No need to osd_oi_lookup() at here because FID
@@ -470,7 +469,7 @@ iget:
 trigger:
                        if (thread_is_running(&scrub->os_thread)) {
                                result = -EINPROGRESS;
-                       } else if (!scrub->os_no_scrub) {
+                       } else if (!dev->od_noscrub) {
                                result = osd_scrub_start(dev);
                                LCONSOLE_ERROR("%.16s: trigger OI scrub by RPC "
                                               "for "DFID", rc = %d [1]\n",
@@ -3327,7 +3326,7 @@ static int osd_ea_add_rec(const struct lu_env *env, struct osd_object *pobj,
         return rc;
 }
 
-static int
+static void
 osd_consistency_check(struct osd_thread_info *oti, struct osd_device *dev,
                      struct osd_idmap_cache *oic)
 {
@@ -3338,13 +3337,16 @@ osd_consistency_check(struct osd_thread_info *oti, struct osd_device *dev,
        int                  rc;
        ENTRY;
 
+       if (!fid_is_norm(fid) && !fid_is_igif(fid))
+               RETURN_EXIT;
+
 again:
        rc = osd_oi_lookup(oti, dev, fid, id);
        if (rc != 0 && rc != -ENOENT)
-               RETURN(rc);
+               RETURN_EXIT;
 
        if (rc == 0 && osd_id_eq(id, &oic->oic_lid))
-               RETURN(0);
+               RETURN_EXIT;
 
        if (thread_is_running(&scrub->os_thread)) {
                rc = osd_oii_insert(dev, oic, rc == -ENOENT);
@@ -3355,10 +3357,10 @@ again:
                if (unlikely(rc == -EAGAIN))
                        goto again;
 
-               RETURN(rc);
+               RETURN_EXIT;
        }
 
-       if (!scrub->os_no_scrub && ++once == 1) {
+       if (!dev->od_noscrub && ++once == 1) {
                CDEBUG(D_LFSCK, "Trigger OI scrub by RPC for "DFID"\n",
                       PFID(fid));
                rc = osd_scrub_start(dev);
@@ -3370,7 +3372,7 @@ again:
                        goto again;
        }
 
-       RETURN(rc = -EREMCHG);
+       EXIT;
 }
 
 /**
@@ -3423,7 +3425,7 @@ static int osd_ea_lookup_rec(const struct lu_env *env, struct osd_object *obj,
                        rc = osd_ea_fid_get(env, obj, ino, fid, &oic->oic_lid);
                else
                        osd_id_gen(&oic->oic_lid, ino, OSD_OII_NOGEN);
-               if (rc != 0 || !fid_is_norm(fid)) {
+               if (rc != 0) {
                        fid_zero(&oic->oic_fid);
                        GOTO(out, rc);
                }
@@ -3433,7 +3435,7 @@ static int osd_ea_lookup_rec(const struct lu_env *env, struct osd_object *obj,
                    (sf->sf_flags & SF_INCONSISTENT ||
                     ldiskfs_test_bit(osd_oi_fid2idx(dev, fid),
                                      sf->sf_oi_bitmap)))
-                       rc = osd_consistency_check(oti, dev, oic);
+                       osd_consistency_check(oti, dev, oic);
        } else {
                rc = -ENOENT;
        }
@@ -4130,8 +4132,10 @@ static inline int osd_it_ea_rec(const struct lu_env *env,
 
        if (!fid_is_sane(fid)) {
                rc = osd_ea_fid_get(env, obj, ino, fid, &oic->oic_lid);
-               if (rc != 0)
+               if (rc != 0) {
+                       fid_zero(&oic->oic_fid);
                        RETURN(rc);
+               }
        } else {
                osd_id_gen(&oic->oic_lid, ino, OSD_OII_NOGEN);
        }
@@ -4140,16 +4144,11 @@ static inline int osd_it_ea_rec(const struct lu_env *env,
                           it->oie_dirent->oied_name,
                           it->oie_dirent->oied_namelen,
                           it->oie_dirent->oied_type, attr);
-       if (!fid_is_norm(fid)) {
-               fid_zero(&oic->oic_fid);
-               RETURN(0);
-       }
-
        oic->oic_fid = *fid;
        if ((scrub->os_pos_current <= ino) &&
            (sf->sf_flags & SF_INCONSISTENT ||
             ldiskfs_test_bit(osd_oi_fid2idx(dev, fid), sf->sf_oi_bitmap)))
-               rc = osd_consistency_check(oti, dev, oic);
+               osd_consistency_check(oti, dev, oic);
 
        RETURN(rc);
 }
@@ -4219,7 +4218,6 @@ static int osd_index_ea_lookup(const struct lu_env *env, struct dt_object *dt,
                 return -EACCES;
 
         rc = osd_ea_lookup_rec(env, obj, rec, key);
-
         if (rc == 0)
                 rc = +1;
         RETURN(rc);
@@ -4375,6 +4373,9 @@ static int osd_mount(const struct lu_env *env,
         lsi = s2lsi(lmi->lmi_sb);
         ldd = lsi->lsi_ldd;
 
+       if (get_mount_flags(lmi->lmi_sb) & LMD_FLG_NOSCRUB)
+               o->od_noscrub = 1;
+
         if (ldd->ldd_flags & LDD_F_IAM_DIR) {
                 o->od_iop_mode = 0;
                 LCONSOLE_WARN("%s: OSD: IAM mode enabled\n", dev);
index eeb57db..4130727 100644 (file)
@@ -280,11 +280,8 @@ struct osd_device {
         struct obd_statfs         od_statfs;
         cfs_spinlock_t            od_osfs_lock;
 
-        /**
-         * The following flag indicates, if it is interop mode or not.
-         * It will be initialized, using mount param.
-         */
-        __u32                     od_iop_mode;
+       unsigned int              od_iop_mode:1,
+                                 od_noscrub:1;
 
         struct fsfilt_operations *od_fsops;
 
index dea02f3..9009dc6 100644 (file)
@@ -370,7 +370,7 @@ static int lprocfs_osd_rd_auto_scrub(char *page, char **start, off_t off,
                return -EINPROGRESS;
 
        *eof = 1;
-       return snprintf(page, count, "%d\n", !dev->od_scrub.os_no_scrub);
+       return snprintf(page, count, "%d\n", !dev->od_noscrub);
 }
 
 static int lprocfs_osd_wr_auto_scrub(struct file *file, const char *buffer,
@@ -387,7 +387,7 @@ static int lprocfs_osd_wr_auto_scrub(struct file *file, const char *buffer,
        if (rc)
                return rc;
 
-       dev->od_scrub.os_no_scrub = !val;
+       dev->od_noscrub = !val;
        return count;
 }
 
index 762ea07..8f57596 100644 (file)
@@ -385,12 +385,15 @@ iget:
                GOTO(out, rc = -ENOMEM);
        }
 
-       if (ops == DTO_INDEX_UPDATE)
+       if (ops == DTO_INDEX_UPDATE) {
                rc = iam_update(jh, bag, (const struct iam_key *)oi_fid,
                                (struct iam_rec *)oi_id, ipd);
-       else
+       } else {
                rc = iam_insert(jh, bag, (const struct iam_key *)oi_fid,
                                (struct iam_rec *)oi_id, ipd);
+               if (rc == -EEXIST)
+                       rc = 1;
+       }
        osd_ipd_put(info->oti_env, bag, ipd);
        ldiskfs_journal_stop(jh);
        if (rc == 0) {
@@ -403,11 +406,13 @@ iget:
        GOTO(out, rc);
 
 out:
-       if (rc != 0) {
+       if (rc < 0) {
                sf->sf_items_failed++;
                if (sf->sf_pos_first_inconsistent == 0 ||
                    sf->sf_pos_first_inconsistent > lid->oii_ino)
                        sf->sf_pos_first_inconsistent = lid->oii_ino;
+       } else {
+               rc = 0;
        }
 
        if (ops == DTO_INDEX_INSERT) {
@@ -1042,8 +1047,6 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev)
        cfs_init_rwsem(&scrub->os_rwsem);
        cfs_spin_lock_init(&scrub->os_lock);
        CFS_INIT_LIST_HEAD(&scrub->os_inconsistent_items);
-       if (get_mount_flags(dev->od_mount->lmi_sb) & LMD_FLG_NOSCRUB)
-               scrub->os_no_scrub = 1;
 
        push_ctxt(&saved, ctxt, NULL);
        filp = filp_open(osd_scrub_name, O_RDWR | O_CREAT, 0644);
@@ -1107,7 +1110,7 @@ int osd_scrub_setup(const struct lu_env *env, struct osd_device *dev)
                }
        }
 
-       if (rc == 0 && !scrub->os_no_scrub &&
+       if (rc == 0 && !dev->od_noscrub &&
            ((sf->sf_status == SS_PAUSED) ||
             (sf->sf_status == SS_CRASHED &&
              sf->sf_flags & (SF_RECREATED | SF_INCONSISTENT | SF_AUTO)) ||
index c012d6b..2437772 100644 (file)
@@ -198,7 +198,6 @@ struct osd_scrub {
                                                * found by RPC prior */
                                os_waiting:1, /* Waiting for scan window. */
                                os_full_speed:1, /* run w/o speed limit */
-                               os_no_scrub:1, /* NOT auto trigger OI scrub*/
                                os_paused:1; /* The scrub is paused. */
 };
 
index 1b2c6cd..a40335d 100644 (file)
@@ -122,7 +122,7 @@ test_1b() {
 
                local FLAGS=$($SHOW_SCRUB | awk '/^flags/ { print $2 }')
                [ "$FLAGS" == "recreated" ] ||
-                       error "(3) Expect 'recreated', but got '$STATUS'"
+                       error "(3) Expect 'recreated', but got '$FLAGS'"
 
                $START_SCRUB || error "(4) Fail to start OI scrub!"
                sleep 3