Whamcloud - gitweb
LU-4106 scrub: Trigger OI scrub properly 02/8002/15
authorFan Yong <fan.yong@intel.com>
Mon, 13 Jan 2014 07:46:51 +0000 (15:46 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Fri, 17 Jan 2014 04:15:34 +0000 (04:15 +0000)
There is the following race case between osd_fid_lookup() and object
unlink/detroy:

Both RPC service thread_1 and RPC service thread_2 try to find the
same obj_A at the same time. At the beginning, the obj_A is not in
cache. The thread_1 is in osd_fid_lookup() and finds the OI mapping
for obj_A. But before the thread_1 finding out related inode_A, the
thread_2 moves faster and finds the inode_A and unlinks the inode_A.
So the thread_1 will fail to find the inode_A. Under such case, the
thread_1 will try to check OI again to make sure whether related OI
mapping is still there or not. If no OI mapping, then it is normal
becuase someone has unlinked the file by race; otherwise, it may be
caused by file-level backup/restore, then thread_1 will trigger OI
scrub to rebuild OI files.

But we ignored a corner case that the thread_1 recheck the OI files
may just between the thread_2 has dropped the inode_A's referene to
zero and will remove related OI mapping from the OI file. Then the
thread_1 is misguided, and will trigger OI scrbu unexpectedly.

More initial OI scrub for the /ROOT/.lustre directory to make sure
the necessary files/directories for mount are ready before used.

This patch also enhances the ls_locate()/dt_locate_at() interface
to allow the caller to pass some hints to low layer, such as flag
LOC_F_NEW for create, to help the low layer to handle efficiently
and properly.

Test-Parameters: mdtcount=4 testlist=sanity-scrub
Signed-off-by: Fan Yong <fan.yong@intel.com>
Change-Id: Ia0fa198fc4fa31056f6a32a6d3e75cf905832cd1
Reviewed-on: http://review.whamcloud.com/8002
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
12 files changed:
lustre/include/dt_object.h
lustre/mgc/mgc_request.c
lustre/mgs/mgs_fs.c
lustre/mgs/mgs_nids.c
lustre/obdclass/dt_object.c
lustre/obdclass/llog_osd.c
lustre/obdclass/local_storage.c
lustre/obdclass/local_storage.h
lustre/osd-ldiskfs/osd_handler.c
lustre/osd-ldiskfs/osd_scrub.c
lustre/quota/lquota_disk.c
lustre/tests/sanity-scrub.sh

index 8faf5f8..43f6a43 100644 (file)
@@ -840,15 +840,17 @@ struct dt_object *dt_find_or_create(const struct lu_env *env,
 struct dt_object *dt_locate_at(const struct lu_env *env,
                               struct dt_device *dev,
                               const struct lu_fid *fid,
-                              struct lu_device *top_dev);
+                              struct lu_device *top_dev,
+                              const struct lu_object_conf *conf);
+
 static inline struct dt_object *
 dt_locate(const struct lu_env *env, struct dt_device *dev,
          const struct lu_fid *fid)
 {
-       return dt_locate_at(env, dev, fid, dev->dd_lu_dev.ld_site->ls_top_dev);
+       return dt_locate_at(env, dev, fid,
+                           dev->dd_lu_dev.ld_site->ls_top_dev, NULL);
 }
 
-
 int local_oid_storage_init(const struct lu_env *env, struct dt_device *dev,
                           const struct lu_fid *first_fid,
                           struct local_oid_storage **los);
@@ -1471,6 +1473,7 @@ struct dt_thread_info {
        struct dt_object_format  dti_dof;
        struct lustre_mdt_attrs  dti_lma;
        struct lu_buf            dti_lb;
+       struct lu_object_conf    dti_conf;
        loff_t                   dti_off;
 };
 
index b98d3de..32b000e 100644 (file)
@@ -730,7 +730,7 @@ static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb)
                GOTO(out_env, rc);
 
        root = dt_locate_at(env, lsi->lsi_dt_dev, &rfid,
-                           &cli->cl_mgc_los->los_dev->dd_lu_dev);
+                           &cli->cl_mgc_los->los_dev->dd_lu_dev, NULL);
        if (unlikely(IS_ERR(root)))
                GOTO(out_los, rc = PTR_ERR(root));
 
index 3f31626..5d2b99b 100644 (file)
@@ -139,7 +139,7 @@ int mgs_fs_setup(const struct lu_env *env, struct mgs_device *mgs)
                GOTO(out_los, rc);
 
        root = dt_locate_at(env, mgs->mgs_bottom, &rfid,
-                           &mgs->mgs_dt_dev.dd_lu_dev);
+                           &mgs->mgs_dt_dev.dd_lu_dev, NULL);
        if (unlikely(IS_ERR(root)))
                GOTO(out_los, rc = PTR_ERR(root));
 
index 63c427f..a2bae59 100644 (file)
@@ -301,7 +301,7 @@ static int nidtbl_read_version(const struct lu_env *env,
        }
 
        fsdb = dt_locate_at(env, mgs->mgs_bottom, &fid,
-                           &mgs->mgs_dt_dev.dd_lu_dev);
+                           &mgs->mgs_dt_dev.dd_lu_dev, NULL);
        if (IS_ERR(fsdb))
                RETURN(PTR_ERR(fsdb));
 
index deb5863..afe90d3 100644 (file)
@@ -215,22 +215,25 @@ EXPORT_SYMBOL(dt_lookup_dir);
 /* this differs from dt_locate by top_dev as parameter
  * but not one from lu_site */
 struct dt_object *dt_locate_at(const struct lu_env *env,
-                              struct dt_device *dev, const struct lu_fid *fid,
-                              struct lu_device *top_dev)
+                              struct dt_device *dev,
+                              const struct lu_fid *fid,
+                              struct lu_device *top_dev,
+                              const struct lu_object_conf *conf)
 {
-       struct lu_object *lo, *n;
-       ENTRY;
+       struct lu_object *lo;
+       struct lu_object *n;
 
-       lo = lu_object_find_at(env, top_dev, fid, NULL);
+       lo = lu_object_find_at(env, top_dev, fid, conf);
        if (IS_ERR(lo))
-               return (void *)lo;
+               return ERR_PTR(PTR_ERR(lo));
 
        LASSERT(lo != NULL);
 
-       cfs_list_for_each_entry(n, &lo->lo_header->loh_layers, lo_linkage) {
+       list_for_each_entry(n, &lo->lo_header->loh_layers, lo_linkage) {
                if (n->lo_dev == &dev->dd_lu_dev)
                        return container_of0(n, struct dt_object, do_lu);
        }
+
        return ERR_PTR(-ENOENT);
 }
 EXPORT_SYMBOL(dt_locate_at);
index 57dcd76..d9434d7 100644 (file)
@@ -852,7 +852,7 @@ static int llog_osd_open(const struct lu_env *env, struct llog_handle *handle,
                        GOTO(out, rc);
        }
 
-       o = ls_locate(env, ls, &lgi->lgi_fid);
+       o = ls_locate(env, ls, &lgi->lgi_fid, NULL);
        if (IS_ERR(o))
                GOTO(out_name, rc = PTR_ERR(o));
 
index ff3334f..75e36a8 100644 (file)
@@ -297,12 +297,18 @@ struct dt_object *__local_file_create(const struct lu_env *env,
                                      const char *name, struct lu_attr *attr,
                                      struct dt_object_format *dof)
 {
-       struct dt_thread_info   *dti = dt_info(env);
+       struct dt_thread_info   *dti    = dt_info(env);
+       struct lu_object_conf   *conf   = &dti->dti_conf;
        struct dt_object        *dto;
        struct thandle          *th;
        int                      rc;
 
-       dto = ls_locate(env, ls, fid);
+       /* We know that the target object does not exist, to be created,
+        * then give some hints - LOC_F_NEW to help low layer to handle
+        * that efficiently and properly. */
+       memset(conf, 0, sizeof(*conf));
+       conf->loc_flags = LOC_F_NEW;
+       dto = ls_locate(env, ls, fid, conf);
        if (unlikely(IS_ERR(dto)))
                RETURN(dto);
 
@@ -398,7 +404,8 @@ struct dt_object *local_file_find_or_create(const struct lu_env *env,
        rc = dt_lookup_dir(env, parent, name, &dti->dti_fid);
        if (rc == 0)
                /* name is found, get the object */
-               dto = ls_locate(env, dt2ls_dev(los->los_dev), &dti->dti_fid);
+               dto = ls_locate(env, dt2ls_dev(los->los_dev),
+                               &dti->dti_fid, NULL);
        else if (rc != -ENOENT)
                dto = ERR_PTR(rc);
        else {
@@ -485,7 +492,8 @@ struct dt_object *local_index_find_or_create(const struct lu_env *env,
        rc = dt_lookup_dir(env, parent, name, &dti->dti_fid);
        if (rc == 0) {
                /* name is found, get the object */
-               dto = ls_locate(env, dt2ls_dev(los->los_dev), &dti->dti_fid);
+               dto = ls_locate(env, dt2ls_dev(los->los_dev),
+                               &dti->dti_fid, NULL);
        } else if (rc != -ENOENT) {
                dto = ERR_PTR(rc);
        } else {
@@ -675,7 +683,7 @@ int lastid_compat_check(const struct lu_env *env, struct dt_device *dev,
        if (rc)
                return rc;
 
-       root = ls_locate(env, ls, &dti->dti_fid);
+       root = ls_locate(env, ls, &dti->dti_fid, NULL);
        if (IS_ERR(root))
                return PTR_ERR(root);
 
@@ -685,13 +693,17 @@ int lastid_compat_check(const struct lu_env *env, struct dt_device *dev,
        rc = dt_lookup_dir(env, root, dti->dti_buf, &dti->dti_fid);
        lu_object_put_nocache(env, &root->do_lu);
        if (rc == -ENOENT) {
+               struct lu_object_conf *conf = &dti->dti_conf;
+
                /* old llog lastid accessed by FID only */
                if (lastid_seq != FID_SEQ_LLOG)
                        return 0;
                dti->dti_fid.f_seq = FID_SEQ_LLOG;
                dti->dti_fid.f_oid = 1;
                dti->dti_fid.f_ver = 0;
-               o = ls_locate(env, ls, &dti->dti_fid);
+               memset(conf, 0, sizeof(*conf));
+               conf->loc_flags = LOC_F_NEW;
+               o = ls_locate(env, ls, &dti->dti_fid, conf);
                if (IS_ERR(o))
                        return PTR_ERR(o);
 
@@ -705,7 +717,7 @@ int lastid_compat_check(const struct lu_env *env, struct dt_device *dev,
        } else {
                CDEBUG(D_INFO, "Found old lastid file for sequence "LPX64"\n",
                       lastid_seq);
-               o = ls_locate(env, ls, &dti->dti_fid);
+               o = ls_locate(env, ls, &dti->dti_fid, NULL);
                if (IS_ERR(o))
                        return PTR_ERR(o);
        }
@@ -789,7 +801,7 @@ int local_oid_storage_init(const struct lu_env *env, struct dt_device *dev,
        dti->dti_fid.f_seq = fid_seq(first_fid);
        dti->dti_fid.f_oid = LUSTRE_FID_LASTID_OID;
        dti->dti_fid.f_ver = 0;
-       o = ls_locate(env, ls, &dti->dti_fid);
+       o = ls_locate(env, ls, &dti->dti_fid, NULL);
        if (IS_ERR(o))
                GOTO(out_los, rc = PTR_ERR(o));
 
index 4471877..9a7244e 100644 (file)
@@ -67,9 +67,11 @@ static inline struct ls_object *lu2ls_obj(struct lu_object *o)
 
 static inline struct dt_object *ls_locate(const struct lu_env *env,
                                          struct ls_device *ls,
-                                         const struct lu_fid *fid)
+                                         const struct lu_fid *fid,
+                                         const struct lu_object_conf *conf)
 {
-       return dt_locate_at(env, ls->ls_osd, fid, &ls->ls_top_dev.dd_lu_dev);
+       return dt_locate_at(env, ls->ls_osd, fid,
+                           &ls->ls_top_dev.dd_lu_dev, conf);
 }
 
 struct ls_device *ls_device_get(struct dt_device *dev);
index 162668e..375d057 100644 (file)
@@ -231,8 +231,8 @@ struct inode *osd_iget(struct osd_thread_info *info, struct osd_device *dev,
                       id->oii_ino, PTR_ERR(inode));
        } else if (id->oii_gen != OSD_OII_NOGEN &&
                   inode->i_generation != id->oii_gen) {
-               CDEBUG(D_INODE, "unmatched inode: ino = %u, gen0 = %u, "
-                      "gen1 = %u\n",
+               CDEBUG(D_INODE, "unmatched inode: ino = %u, oii_gen = %u, "
+                      "i_generation = %u\n",
                       id->oii_ino, id->oii_gen, inode->i_generation);
                iput(inode);
                inode = ERR_PTR(-ESTALE);
@@ -240,7 +240,6 @@ struct inode *osd_iget(struct osd_thread_info *info, struct osd_device *dev,
                /* due to parallel readdir and unlink,
                * we can have dead inode here. */
                CDEBUG(D_INODE, "stale inode: ino = %u\n", id->oii_ino);
-               make_bad_inode(inode);
                iput(inode);
                inode = ERR_PTR(-ESTALE);
        } else if (is_bad_inode(inode)) {
@@ -290,6 +289,119 @@ osd_iget_fid(struct osd_thread_info *info, struct osd_device *dev,
        return inode;
 }
 
+static struct inode *osd_iget_check(struct osd_thread_info *info,
+                                   struct osd_device *dev,
+                                   const struct lu_fid *fid,
+                                   struct osd_inode_id *id,
+                                   bool in_oi)
+{
+       struct inode    *inode;
+       int              rc     = 0;
+       ENTRY;
+
+       inode = ldiskfs_iget(osd_sb(dev), id->oii_ino);
+       if (IS_ERR(inode)) {
+               rc = PTR_ERR(inode);
+               if (!in_oi || (rc != -ENOENT && rc != -ESTALE)) {
+                       CDEBUG(D_INODE, "no inode: ino = %u, rc = %d\n",
+                              id->oii_ino, rc);
+
+                       GOTO(put, rc);
+               }
+
+               goto check_oi;
+       }
+
+       if (is_bad_inode(inode)) {
+               rc = -ENOENT;
+               if (!in_oi) {
+                       CDEBUG(D_INODE, "bad inode: ino = %u\n", id->oii_ino);
+
+                       GOTO(put, rc);
+               }
+
+               goto check_oi;
+       }
+
+       if (id->oii_gen != OSD_OII_NOGEN &&
+           inode->i_generation != id->oii_gen) {
+               rc = -ESTALE;
+               if (!in_oi) {
+                       CDEBUG(D_INODE, "unmatched inode: ino = %u, "
+                              "oii_gen = %u, i_generation = %u\n",
+                              id->oii_ino, id->oii_gen, inode->i_generation);
+
+                       GOTO(put, rc);
+               }
+
+               goto check_oi;
+       }
+
+       if (inode->i_nlink == 0) {
+               rc = -ENOENT;
+               if (!in_oi) {
+                       CDEBUG(D_INODE, "stale inode: ino = %u\n", id->oii_ino);
+
+                       GOTO(put, rc);
+               }
+
+               goto check_oi;
+       }
+
+check_oi:
+       if (rc != 0) {
+               LASSERTF(rc == -ESTALE || rc == -ENOENT, "rc = %d\n", rc);
+
+               rc = osd_oi_lookup(info, dev, fid, id, OI_CHECK_FLD);
+               /* XXX: There are three possible cases:
+                *      1. rc = 0.
+                *         Backup/restore caused the OI invalid.
+                *      2. rc = 0.
+                *         Someone unlinked the object but NOT removed
+                *         the OI mapping, such as mount target device
+                *         as ldiskfs, and modify something directly.
+                *      3. rc = -ENOENT.
+                *         Someone just removed the object between the
+                *         former oi_lookup and the iget. It is normal.
+                *      4. Other failure cases.
+                *
+                *      Generally, when the device is mounted, it will
+                *      auto check whether the system is restored from
+                *      file-level backup or not. We trust such detect
+                *      to distinguish the 1st case from the 2nd case. */
+               if (rc == 0) {
+                       if (!IS_ERR(inode) && inode->i_generation != 0 &&
+                           inode->i_generation == id->oii_gen)
+                               rc = -ENOENT;
+                       else
+                               rc = -EREMCHG;
+               }
+       } else {
+               if (id->oii_gen == OSD_OII_NOGEN)
+                       osd_id_gen(id, inode->i_ino, inode->i_generation);
+
+               /* Do not update file c/mtime in ldiskfs.
+                * NB: we don't have any lock to protect this because we don't
+                * have reference on osd_object now, but contention with
+                * another lookup + attr_set can't happen in the tiny window
+                * between if (...) and set S_NOCMTIME. */
+               if (!(inode->i_flags & S_NOCMTIME))
+                       inode->i_flags |= S_NOCMTIME;
+       }
+
+       GOTO(put, rc);
+
+put:
+       if (rc != 0) {
+               if (!IS_ERR(inode))
+                       iput(inode);
+
+               inode = ERR_PTR(rc);
+       }
+
+       return inode;
+}
+
 /**
  * \retval +v: new filter_fid, does not contain self-fid
  * \retval 0:  filter_fid_old, contains self-fid
@@ -504,33 +616,20 @@ static int osd_fid_lookup(const struct lu_env *env, struct osd_object *obj,
        in_oi = true;
 
 iget:
-       inode = osd_iget(info, dev, id);
+       inode = osd_iget_check(info, dev, fid, id, in_oi);
        if (IS_ERR(inode)) {
                result = PTR_ERR(inode);
                if (result == -ENOENT || result == -ESTALE) {
-                       if (!in_oi) {
+                       if (!in_oi)
                                fid_zero(&oic->oic_fid);
-                               GOTO(out, result = -ENOENT);
-                       }
 
-                       /* XXX: There are three possible cases:
-                        *      1. Backup/restore caused the OI invalid.
-                        *      2. Someone unlinked the object but NOT removed
-                        *         the OI mapping, such as mount target device
-                        *         as ldiskfs, and modify something directly.
-                        *      3. Someone just removed the object between the
-                        *         former oi_lookup and the iget. It is normal.
-                        *
-                        *      It is diffcult to distinguish the 2nd from the
-                        *      1st case. Relatively speaking, the 1st case is
-                        *      common than the 2nd case, trigger OI scrub. */
-                       result = osd_oi_lookup(info, dev, fid, id, true);
-                       if (result == 0)
-                               /* It is the case 1 or 2. */
-                               goto trigger;
+                       GOTO(out, result = -ENOENT);
                } else if (result == -EREMCHG) {
 
 trigger:
+                       if (!in_oi)
+                               fid_zero(&oic->oic_fid);
+
                        if (unlikely(triggered))
                                GOTO(out, result = saved);
 
@@ -539,10 +638,9 @@ trigger:
                                result = -EINPROGRESS;
                        } else if (!dev->od_noscrub) {
                                result = osd_scrub_start(dev);
-                               LCONSOLE_ERROR("%.16s: trigger OI scrub by RPC "
-                                              "for "DFID", rc = %d [1]\n",
-                                              LDISKFS_SB(osd_sb(dev))->s_es->\
-                                              s_volume_name,PFID(fid), result);
+                               LCONSOLE_WARN("%.16s: trigger OI scrub by RPC "
+                                             "for "DFID", rc = %d [1]\n",
+                                             osd_name(dev), PFID(fid),result);
                                if (result == 0 || result == -EALREADY)
                                        result = -EINPROGRESS;
                                else
@@ -585,8 +683,18 @@ trigger:
        if (result != 0) {
                iput(inode);
                obj->oo_inode = NULL;
-               if (result == -EREMCHG)
+               if (result == -EREMCHG) {
+                       if (!in_oi) {
+                               result = osd_oi_lookup(info, dev, fid, id,
+                                                      OI_CHECK_FLD);
+                               if (result != 0) {
+                                       fid_zero(&oic->oic_fid);
+                                       GOTO(out, result);
+                               }
+                       }
+
                        goto trigger;
+               }
 
                GOTO(out, result);
        }
@@ -1923,6 +2031,7 @@ static int osd_mkfile(struct osd_thread_info *info, struct osd_object *obj,
                /* For new created object, it must be consistent,
                 * and it is unnecessary to scrub against it. */
                ldiskfs_set_inode_state(inode, LDISKFS_STATE_LUSTRE_NOSCRUB);
+               ldiskfs_clear_inode_state(inode, LDISKFS_STATE_LUSTRE_NO_OI);
                 obj->oo_inode = inode;
                 result = 0;
         } else {
@@ -2530,6 +2639,7 @@ static struct inode *osd_create_local_agent_inode(const struct lu_env *env,
                RETURN(local);
        }
 
+       ldiskfs_set_inode_state(local, LDISKFS_STATE_LUSTRE_NO_OI);
        /* Set special LMA flag for local agent inode */
        rc = osd_ea_fid_set(info, local, fid, 0, LMAI_AGENT);
        if (rc != 0) {
@@ -3893,13 +4003,11 @@ again:
        }
 
        if (!dev->od_noscrub && ++once == 1) {
-               CDEBUG(D_LFSCK, "Trigger OI scrub by RPC for "DFID"\n",
-                      PFID(fid));
                rc = osd_scrub_start(dev);
-               LCONSOLE_ERROR("%.16s: trigger OI scrub by RPC for "DFID
-                              ", rc = %d [2]\n",
-                              LDISKFS_SB(osd_sb(dev))->s_es->s_volume_name,
-                              PFID(fid), rc);
+               LCONSOLE_WARN("%.16s: trigger OI scrub by RPC for "DFID
+                             ", rc = %d [2]\n",
+                             LDISKFS_SB(osd_sb(dev))->s_es->s_volume_name,
+                             PFID(fid), rc);
                if (rc == 0)
                        goto again;
        }
@@ -4007,6 +4115,9 @@ static int osd_ea_lookup_rec(const struct lu_env *env, struct osd_object *obj,
                        GOTO(out, rc);
                }
 
+               if (osd_remote_fid(env, dev, fid))
+                       GOTO(out, rc = 0);
+
                rc = osd_add_oi_cache(osd_oti_get(env), osd_obj2dev(obj), id,
                                      fid);
                if (rc != 0)
index 3c02805..303d769 100644 (file)
@@ -1309,6 +1309,8 @@ static int osd_ios_varfid_fill(void *buf, const char *name, int namelen,
                               loff_t offset, __u64 ino, unsigned d_type);
 static int osd_ios_lf_fill(void *buf, const char *name, int namelen,
                           loff_t offset, __u64 ino, unsigned d_type);
+static int osd_ios_dl_fill(void *buf, const char *name, int namelen,
+                          loff_t offset, __u64 ino, unsigned d_type);
 
 static int
 osd_ios_general_scan(struct osd_thread_info *info, struct osd_device *dev,
@@ -1426,6 +1428,15 @@ static const struct osd_lf_map osd_lf_maps[] = {
        { NULL, { 0, 0, 0 }, 0, NULL, NULL }
 };
 
+/* Add the new introduced files under .lustre/ in the list in the future. */
+static const struct osd_lf_map osd_dl_maps[] = {
+       /* .lustre/fid */
+       { "fid", { FID_SEQ_DOT_LUSTRE, FID_OID_DOT_LUSTRE_OBF, 0 }, 0,
+               NULL, NULL },
+
+       { NULL, { 0, 0, 0 }, 0, NULL, NULL }
+};
+
 struct osd_ios_item {
        cfs_list_t       oii_list;
        struct dentry   *oii_dentry;
@@ -1649,6 +1660,42 @@ static int osd_ios_varfid_fill(void *buf, const char *name, int namelen,
        RETURN(rc);
 }
 
+static int osd_ios_dl_fill(void *buf, const char *name, int namelen,
+                          loff_t offset, __u64 ino, unsigned d_type)
+{
+       struct osd_ios_filldir_buf *fill_buf = buf;
+       struct osd_device          *dev      = fill_buf->oifb_dev;
+       const struct osd_lf_map    *map;
+       struct dentry              *child;
+       int                         rc       = 0;
+       ENTRY;
+
+       /* skip any '.' started names */
+       if (name[0] == '.')
+               RETURN(0);
+
+       for (map = osd_dl_maps; map->olm_name != NULL; map++) {
+               if (strlen(map->olm_name) != namelen)
+                       continue;
+
+               if (strncmp(map->olm_name, name, namelen) == 0)
+                       break;
+       }
+
+       if (map->olm_name == NULL)
+               RETURN(0);
+
+       child = osd_ios_lookup_one_len(name, fill_buf->oifb_dentry, namelen);
+       if (IS_ERR(child))
+               RETURN(PTR_ERR(child));
+
+       rc = osd_ios_scan_one(fill_buf->oifb_info, dev, child->d_inode,
+                             &map->olm_fid, map->olm_flags);
+       dput(child);
+
+       RETURN(rc);
+}
+
 static int osd_ios_root_fill(void *buf, const char *name, int namelen,
                             loff_t offset, __u64 ino, unsigned d_type)
 {
@@ -1782,6 +1829,9 @@ osd_ios_ROOT_scan(struct osd_thread_info *info, struct osd_device *dev,
                 * to the solution 2). */
                rc = osd_ios_scan_one(info, dev, child->d_inode,
                                      &LU_DOT_LUSTRE_FID, 0);
+               if (rc == 0)
+                       rc = osd_ios_new_item(dev, child, osd_ios_general_scan,
+                                             osd_ios_dl_fill);
                dput(child);
        }
 
index 479e13b..8d31852 100644 (file)
@@ -180,7 +180,7 @@ struct dt_object *lquota_disk_dir_find_create(const struct lu_env *env,
                        GOTO(out, rc);
 
                parent = dt_locate_at(env, dev, &qti->qti_fid,
-                                     dev->dd_lu_dev.ld_site->ls_top_dev);
+                                     dev->dd_lu_dev.ld_site->ls_top_dev, NULL);
                if (IS_ERR(parent))
                        GOTO(out, rc = PTR_ERR(parent));
        } else {
index efbbd3b..fdbd97f 100644 (file)
@@ -542,7 +542,7 @@ test_6() {
 
        local -a position1
        for n in $(seq $MDSCOUNT); do
-               positions1[$n]=$(scrub_status $n |
+               position1[$n]=$(scrub_status $n |
                        awk '/^latest_start_position/ {print $2}')
                if [ ${position0[$n]} -ne ${position1[$n]} ]; then
                        error "(14) Expected position ${position0[$n]}, but" \
@@ -562,9 +562,6 @@ test_6() {
 run_test 6 "OI scrub resumes from last checkpoint"
 
 test_7() {
-       # skip test_7 for LU-4149
-       [ $MDSCOUNT -ge 2 ] && skip "skip now for >= 2 MDTs" && return
-
        scrub_prep 500
        scrub_backup_restore 1