osd_scrub_convert_ff(struct osd_thread_info *info, struct osd_device *dev,
struct inode *inode, const struct lu_fid *fid)
{
- struct filter_fid_old *ff = &info->oti_ff;
- struct dentry *dentry = &info->oti_obj_dentry;
- struct lu_fid *tfid = &info->oti_fid;
- handle_t *jh;
- int size = 0;
- int rc;
- bool reset = false;
+ struct filter_fid_18_23 *ff = &info->oti_ff_old;
+ struct dentry *dentry = &info->oti_obj_dentry;
+ struct lu_fid *tfid = &info->oti_fid;
+ bool fid_18_23 = false;
+ handle_t *jh;
+ int size = 0;
+ int rc;
ENTRY;
if (dev->od_scrub.os_scrub.os_file.sf_param & SP_DRYRUN)
rc = __osd_xattr_get(inode, dentry, XATTR_NAME_FID, ff, sizeof(*ff));
if (rc == sizeof(*ff)) {
/* 2) delete the old XATTR_NAME_FID */
- ll_vfs_dq_init(inode);
- rc = inode->i_op->removexattr(dentry, XATTR_NAME_FID);
+ dquot_initialize(inode);
+ rc = osd_removexattr(dentry, inode, XATTR_NAME_FID);
if (rc)
GOTO(stop, rc);
- reset = true;
- } else if (rc != -ENODATA && rc != sizeof(struct filter_fid)) {
+ fid_18_23 = true;
+ } else if (rc != -ENODATA && rc < (int)sizeof(struct filter_fid_24_29)) {
GOTO(stop, rc = -EINVAL);
}
/* 3) make new LMA and add it */
rc = osd_ea_fid_set(info, inode, tfid, LMAC_FID_ON_OST, 0);
- if (reset) {
+ if (fid_18_23) {
if (rc)
/* If failed, we should try to add the old back. */
size = sizeof(*ff);
}
if (flags & SS_RESET)
- scrub_file_reset(scrub,
- LDISKFS_SB(osd_sb(dev))->s_es->s_uuid, 0);
+ scrub_file_reset(scrub, dev->od_uuid, 0);
if (flags & SS_AUTO_FULL) {
scrub->os_full_speed = 1;
} else {
sf->sf_status = SS_FAILED;
}
- sf->sf_run_time += cfs_duration_sec(cfs_time_current() + HALF_SEC -
- scrub->os_time_last_checkpoint);
+ sf->sf_run_time += ktime_get_seconds() -
+ scrub->os_time_last_checkpoint;
+
rc = scrub_file_store(env, scrub);
up_write(&scrub->os_rwsem);
* quite possible for FID-on-MDT. */
if (dev->od_is_ost)
return SCRUB_NEXT_OSTOBJ_OLD;
- else
- return 0;
+
+ return 0;
}
static int osd_scrub_get_fid(struct osd_thread_info *info,
struct lu_fid *fid, bool scrub)
{
struct lustre_mdt_attrs *lma = &info->oti_ost_attrs.loa_lma;
- int rc;
bool has_lma = false;
+ int rc;
rc = osd_get_lma(info, inode, &info->oti_obj_dentry,
&info->oti_ost_attrs);
rc = osd_get_idif(info, inode, &info->oti_obj_dentry, fid);
if (rc == 0) {
if (scrub)
- /* It is old 2.x (x <= 3) or 1.8 OST-object. */
+ /* It is 2.3 or older OST-object. */
rc = SCRUB_NEXT_OSTOBJ_OLD;
return rc;
}
* to generate its FID, ignore it directly. */
rc = SCRUB_NEXT_CONTINUE;
else
- /* It is 2.4 OST-object. */
+ /* It is 2.4 or newer OST-object. */
rc = SCRUB_NEXT_OSTOBJ_OLD;
return rc;
}
/* Not handle the backend root object and agent parent object.
* They are neither visible to namespace nor have OI mappings. */
if (unlikely(pos == osd_sb(dev)->s_root->d_inode->i_ino ||
- pos == osd_remote_parent_ino(dev)))
+ is_remote_parent_ino(dev, pos)))
RETURN(SCRUB_NEXT_CONTINUE);
+ /* Skip project quota inode since it is greater than s_first_ino. */
+#ifdef HAVE_PROJECT_QUOTA
+ if (ldiskfs_has_feature_project(sb) &&
+ pos == le32_to_cpu(LDISKFS_SB(sb)->s_es->s_prj_quota_inum))
+ RETURN(SCRUB_NEXT_CONTINUE);
+#endif
+
osd_id_gen(lid, pos, OSD_OII_NOGEN);
inode = osd_iget(info, dev, lid);
if (IS_ERR(inode)) {
sf->sf_param &= ~SP_DRYRUN;
if (flags & SS_RESET) {
- scrub_file_reset(scrub, LDISKFS_SB(osd_sb(dev))->s_es->s_uuid,
- inconsistent ? SF_INCONSISTENT : 0);
+ scrub_file_reset(scrub, dev->od_uuid,
+ inconsistent ? SF_INCONSISTENT : 0);
sf->sf_status = SS_SCANNING;
}
/* PENDING */
{
- .olm_name = "PENDING",
- .olm_namelen = sizeof("PENDING") - 1,
+ .olm_name = MDT_ORPHAN_DIR,
+ .olm_namelen = sizeof(MDT_ORPHAN_DIR) - 1,
},
/* ROOT */
.olm_name = LUSTRE_NODEMAP_NAME,
},
+ /* index_backup */
+ {
+ .olm_name = INDEX_BACKUP_DIR,
+ .olm_fid = {
+ .f_seq = FID_SEQ_LOCAL_FILE,
+ .f_oid = INDEX_BACKUP_OID,
+ },
+ .olm_flags = OLF_SCAN_SUBITEMS | OLF_NOT_BACKUP,
+ .olm_namelen = sizeof(INDEX_BACKUP_DIR) - 1,
+ .olm_scandir = osd_ios_general_scan,
+ .olm_filldir = osd_ios_varfid_fill,
+ },
+
{
.olm_name = NULL
}
int oifb_items;
};
-static inline struct dentry *
-osd_ios_lookup_one_len(const char *name, struct dentry *parent, int namelen)
-{
- struct dentry *dentry;
-
- dentry = ll_lookup_one_len(name, parent, namelen);
- if (IS_ERR(dentry)) {
- int rc = PTR_ERR(dentry);
-
- if (rc != -ENOENT)
- CERROR("Fail to find %.*s in %.*s (%lu/%u): rc = %d\n",
- namelen, name, parent->d_name.len,
- parent->d_name.name, parent->d_inode->i_ino,
- parent->d_inode->i_generation, rc);
-
- return dentry;
- }
-
- if (dentry->d_inode == NULL) {
- dput(dentry);
- return ERR_PTR(-ENOENT);
- }
-
- return dentry;
-}
-
static int
osd_ios_new_item(struct osd_device *dev, struct dentry *dentry,
scandir_t scandir, filldir_t filldir)
RETURN(0);
}
+static bool osd_index_need_recreate(const struct lu_env *env,
+ struct osd_device *dev, struct inode *inode)
+{
+ struct osd_directory *iam = &osd_oti_get(env)->oti_iam;
+ struct iam_container *bag = &iam->od_container;
+ int rc;
+ ENTRY;
+
+ rc = iam_container_init(bag, &iam->od_descr, inode);
+ if (rc)
+ RETURN(true);
+
+ rc = iam_container_setup(bag);
+ iam_container_fini(bag);
+ if (rc)
+ RETURN(true);
+
+ RETURN(false);
+}
+
+static void osd_ios_index_register(const struct lu_env *env,
+ struct osd_device *osd,
+ const struct lu_fid *fid,
+ struct inode *inode)
+{
+ struct osd_directory *iam = &osd_oti_get(env)->oti_iam;
+ struct iam_container *bag = &iam->od_container;
+ struct super_block *sb = osd_sb(osd);
+ struct iam_descr *descr;
+ __u32 keysize = 0;
+ __u32 recsize = 0;
+ int rc;
+ ENTRY;
+
+ /* Index must be a regular file. */
+ if (!S_ISREG(inode->i_mode))
+ RETURN_EXIT;
+
+ /* Index's size must be block aligned. */
+ if (inode->i_size < sb->s_blocksize ||
+ (inode->i_size & (sb->s_blocksize - 1)) != 0)
+ RETURN_EXIT;
+
+ iam_container_init(bag, &iam->od_descr, inode);
+ rc = iam_container_setup(bag);
+ if (rc)
+ GOTO(fini, rc = 1);
+
+ descr = bag->ic_descr;
+ /* May be regular file with IAM_LFIX_ROOT_MAGIC matched
+ * coincidentally, or corrupted index object, skip it. */
+ if (descr->id_ptr_size != 4)
+ GOTO(fini, rc = 1);
+
+ keysize = descr->id_key_size;
+ recsize = descr->id_rec_size;
+ rc = osd_index_register(osd, fid, keysize, recsize);
+
+ GOTO(fini, rc);
+
+fini:
+ iam_container_fini(bag);
+ if (!rc)
+ CDEBUG(D_LFSCK, "%s: index object "DFID" (%u/%u) registered\n",
+ osd_name(osd), PFID(fid), keysize, recsize);
+}
+
+static void osd_index_restore(const struct lu_env *env, struct osd_device *dev,
+ struct lustre_index_restore_unit *liru,
+ void *buf, int bufsize)
+{
+ struct osd_thread_info *info = osd_oti_get(env);
+ struct osd_inode_id *id = &info->oti_id;
+ struct lu_fid *tgt_fid = &liru->liru_cfid;
+ struct inode *bak_inode = NULL;
+ struct ldiskfs_dir_entry_2 *de = NULL;
+ struct buffer_head *bh = NULL;
+ struct dentry *dentry;
+ char *name = buf;
+ struct lu_fid bak_fid;
+ int rc;
+ ENTRY;
+
+ lustre_fid2lbx(name, tgt_fid, bufsize);
+ dentry = osd_child_dentry_by_inode(env, dev->od_index_backup_inode,
+ name, strlen(name));
+ bh = osd_ldiskfs_find_entry(dev->od_index_backup_inode,
+ &dentry->d_name, &de, NULL, NULL);
+ if (IS_ERR(bh))
+ GOTO(log, rc = PTR_ERR(bh));
+
+ osd_id_gen(id, le32_to_cpu(de->inode), OSD_OII_NOGEN);
+ brelse(bh);
+ bak_inode = osd_iget_fid(info, dev, id, &bak_fid);
+ if (IS_ERR(bak_inode))
+ GOTO(log, rc = PTR_ERR(bak_inode));
+
+ iput(bak_inode);
+ /* The OI mapping for index may be invalid, since it will be
+ * re-created, not update the OI mapping, just cache it in RAM. */
+ osd_id_gen(id, liru->liru_clid, OSD_OII_NOGEN);
+ osd_add_oi_cache(info, dev, id, tgt_fid);
+ rc = lustre_index_restore(env, &dev->od_dt_dev, &liru->liru_pfid,
+ tgt_fid, &bak_fid, liru->liru_name,
+ &dev->od_index_backup_list, &dev->od_lock,
+ buf, bufsize);
+ GOTO(log, rc);
+
+log:
+ CDEBUG(D_WARNING, "%s: restore index '%s' with "DFID": rc = %d\n",
+ osd_name(dev), liru->liru_name, PFID(tgt_fid), rc);
+}
+
/**
* osd_ios_scan_one() - check/fix LMA FID and OI entry for one inode
*
*/
static int
osd_ios_scan_one(struct osd_thread_info *info, struct osd_device *dev,
- struct inode *inode, const struct lu_fid *fid, int flags)
+ struct inode *parent, struct inode *inode,
+ const struct lu_fid *fid, const char *name,
+ int namelen, int flags)
{
struct lustre_mdt_attrs *lma = &info->oti_ost_attrs.loa_lma;
struct osd_inode_id *id = &info->oti_id;
int rc;
ENTRY;
+ if (!inode) {
+ CDEBUG(D_INODE, "%s: child '%.*s' lacks inode: rc = -2\n",
+ osd_name(dev), namelen, name);
+ RETURN(-ENOENT);
+ }
+
rc = osd_get_lma(info, inode, &info->oti_obj_dentry,
&info->oti_ost_attrs);
if (rc != 0 && rc != -ENODATA) {
RETURN(0);
tfid = lma->lma_self_fid;
+ if (lma->lma_compat & LMAC_IDX_BACKUP &&
+ osd_index_need_recreate(info->oti_env, dev, inode)) {
+ struct lu_fid *pfid = &info->oti_fid3;
+
+ if (parent == osd_sb(dev)->s_root->d_inode) {
+ lu_local_obj_fid(pfid, OSD_FS_ROOT_OID);
+ } else {
+ rc = osd_scrub_get_fid(info, dev, parent, pfid,
+ false);
+ if (rc)
+ RETURN(rc);
+ }
+
+ rc = lustre_liru_new(&dev->od_index_restore_list, pfid,
+ &tfid, inode->i_ino, name, namelen);
+
+ RETURN(rc);
+ }
+
+ if (!(flags & OLF_NOT_BACKUP))
+ osd_ios_index_register(info->oti_env, dev, &tfid,
+ inode);
}
rc = osd_oi_lookup(info, dev, &tfid, id2, 0);
RETURN(0);
if (!(sf->sf_flags & SF_INCONSISTENT)) {
- scrub_file_reset(scrub, LDISKFS_SB(osd_sb(dev))->s_es->s_uuid,
- SF_INCONSISTENT);
+ scrub_file_reset(scrub, dev->od_uuid, SF_INCONSISTENT);
rc = scrub_file_store(info->oti_env, scrub);
if (rc != 0)
RETURN(rc);
/**
* It scans the /lost+found, and for the OST-object (with filter_fid
- * or filter_fid_old), move them back to its proper /O/<seq>/d<x>.
+ * or filter_fid_18_23), move them back to its proper /O/<seq>/d<x>.
*/
#ifdef HAVE_FILLDIR_USE_CTX
static int osd_ios_lf_fill(struct dir_context *buf,
RETURN(0);
scrub->os_lf_scanned++;
- child = osd_ios_lookup_one_len(name, parent, namelen);
+ child = osd_lookup_one_len_unlocked(dev, name, parent, namelen);
if (IS_ERR(child)) {
CDEBUG(D_LFSCK, "%s: cannot lookup child '%.*s': rc = %d\n",
osd_name(dev), namelen, name, (int)PTR_ERR(child));
RETURN(0);
+ } else if (!child->d_inode) {
+ dput(child);
+ CDEBUG(D_INODE, "%s: child '%.*s' lacks inode\n",
+ osd_name(dev), namelen, name);
+ RETURN(0);
}
inode = child->d_inode;
if (name[0] == '.')
RETURN(0);
- child = osd_ios_lookup_one_len(name, fill_buf->oifb_dentry, namelen);
+ child = osd_lookup_one_len_unlocked(dev, 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,
- NULL, 0);
+ rc = osd_ios_scan_one(fill_buf->oifb_info, dev,
+ fill_buf->oifb_dentry->d_inode, child->d_inode,
+ NULL, name, namelen, 0);
if (rc == 0 && S_ISDIR(child->d_inode->i_mode))
rc = osd_ios_new_item(dev, child, osd_ios_general_scan,
osd_ios_varfid_fill);
if (map->olm_name == NULL)
RETURN(0);
- child = osd_ios_lookup_one_len(name, fill_buf->oifb_dentry, namelen);
+ child = osd_lookup_one_len_unlocked(dev, 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);
+ rc = osd_ios_scan_one(fill_buf->oifb_info, dev,
+ fill_buf->oifb_dentry->d_inode, child->d_inode,
+ &map->olm_fid, name, namelen, map->olm_flags);
dput(child);
RETURN(rc);
{
struct osd_ios_filldir_buf *fill_buf =
(struct osd_ios_filldir_buf *)buf;
+ struct osd_device *dev = fill_buf->oifb_dev;
struct dentry *child;
struct lu_fid tfid;
int rc = 0;
if (name[0] != '[')
RETURN(0);
- child = osd_ios_lookup_one_len(name, fill_buf->oifb_dentry, namelen);
+ child = osd_lookup_one_len_unlocked(dev, name, fill_buf->oifb_dentry,
+ namelen);
if (IS_ERR(child))
RETURN(PTR_ERR(child));
sscanf(&name[1], SFID, RFID(&tfid));
if (fid_is_sane(&tfid))
rc = osd_ios_scan_one(fill_buf->oifb_info, fill_buf->oifb_dev,
- child->d_inode, &tfid, 0);
+ fill_buf->oifb_dentry->d_inode,
+ child->d_inode, &tfid, name, namelen, 0);
else
rc = -EIO;
dput(child);
if (map->olm_name == NULL)
RETURN(0);
- child = osd_ios_lookup_one_len(name, fill_buf->oifb_dentry, namelen);
+ child = osd_lookup_one_len_unlocked(dev, name, fill_buf->oifb_dentry,
+ namelen);
if (IS_ERR(child))
RETURN(PTR_ERR(child));
+ else if (!child->d_inode)
+ GOTO(out_put, rc = -ENOENT);
if (!(map->olm_flags & OLF_NO_OI))
- rc = osd_ios_scan_one(fill_buf->oifb_info, dev, child->d_inode,
- &map->olm_fid, map->olm_flags);
+ rc = osd_ios_scan_one(fill_buf->oifb_info, dev,
+ fill_buf->oifb_dentry->d_inode, child->d_inode,
+ &map->olm_fid, name, namelen, map->olm_flags);
if (rc == 0 && map->olm_flags & OLF_SCAN_SUBITEMS)
rc = osd_ios_new_item(dev, child, map->olm_scandir,
map->olm_filldir);
+out_put:
dput(child);
RETURN(rc);
buf.oifb_items = 0;
#ifdef HAVE_DIR_CONTEXT
buf.ctx.pos = filp->f_pos;
- rc = fops->iterate(filp, &buf.ctx);
+ rc = fops->iterate_shared(filp, &buf.ctx);
filp->f_pos = buf.ctx.pos;
#else
rc = fops->readdir(filp, &buf, filldir);
* OI mapping crashed or lost also, then we have to give up under
* double failure cases. */
scrub->os_convert_igif = 1;
- child = osd_ios_lookup_one_len(dot_lustre_name, dentry,
- strlen(dot_lustre_name));
+ child = osd_lookup_one_len_unlocked(dev, dot_lustre_name, dentry,
+ strlen(dot_lustre_name));
if (IS_ERR(child)) {
- rc = PTR_ERR(child);
- if (rc == -ENOENT) {
- /* It is 1.8 MDT device. */
- if (!(sf->sf_flags & SF_UPGRADE)) {
- scrub_file_reset(scrub,
- LDISKFS_SB(osd_sb(dev))->s_es->s_uuid,
- SF_UPGRADE);
- sf->sf_internal_flags &= ~SIF_NO_HANDLE_OLD_FID;
- rc = scrub_file_store(info->oti_env, scrub);
- } else {
- rc = 0;
- }
+ if (PTR_ERR(child) != -ENOENT)
+ RETURN(PTR_ERR(child));
+ goto out_scrub;
+ }
+
+ /* For lustre-2.x (x <= 3), the ".lustre" has NO FID-in-LMA,
+ * so the client will get IGIF for the ".lustre" object when
+ * the MDT restart.
+ *
+ * From the OI scrub view, when the MDT upgrade to Lustre-2.4,
+ * it does not know whether there are some old clients cached
+ * the ".lustre" IGIF during the upgrading. Two choices:
+ *
+ * 1) Generate IGIF-in-LMA and IGIF-in-OI for the ".lustre".
+ * It will allow the old connected clients to access the
+ * ".lustre" with cached IGIF. But it will cause others
+ * on the MDT failed to check "fid_is_dot_lustre()".
+ *
+ * 2) Use fixed FID {FID_SEQ_DOT_LUSTRE, FID_OID_DOT_LUSTRE, 0}
+ * for ".lustre" in spite of whether there are some clients
+ * cached the ".lustre" IGIF or not. It enables the check
+ * "fid_is_dot_lustre()" on the MDT, although it will cause
+ * that the old connected clients cannot access the ".lustre"
+ * with the cached IGIF.
+ *
+ * Usually, it is rare case for the old connected clients
+ * to access the ".lustre" with cached IGIF. So we prefer
+ * to the solution 2).
+ */
+ rc = osd_ios_scan_one(info, dev, dentry->d_inode,
+ child->d_inode, &LU_DOT_LUSTRE_FID,
+ dot_lustre_name,
+ strlen(dot_lustre_name), 0);
+ if (rc == -ENOENT) {
+out_scrub:
+ /* It is 1.8 MDT device. */
+ if (!(sf->sf_flags & SF_UPGRADE)) {
+ scrub_file_reset(scrub, dev->od_uuid,
+ SF_UPGRADE);
+ sf->sf_internal_flags &= ~SIF_NO_HANDLE_OLD_FID;
+ rc = scrub_file_store(info->oti_env, scrub);
+ } else {
+ rc = 0;
}
- } else {
- /* For lustre-2.x (x <= 3), the ".lustre" has NO FID-in-LMA,
- * so the client will get IGIF for the ".lustre" object when
- * the MDT restart.
- *
- * From the OI scrub view, when the MDT upgrade to Lustre-2.4,
- * it does not know whether there are some old clients cached
- * the ".lustre" IGIF during the upgrading. Two choices:
- *
- * 1) Generate IGIF-in-LMA and IGIF-in-OI for the ".lustre".
- * It will allow the old connected clients to access the
- * ".lustre" with cached IGIF. But it will cause others
- * on the MDT failed to check "fid_is_dot_lustre()".
- *
- * 2) Use fixed FID {FID_SEQ_DOT_LUSTRE, FID_OID_DOT_LUSTRE, 0}
- * for ".lustre" in spite of whether there are some clients
- * cached the ".lustre" IGIF or not. It enables the check
- * "fid_is_dot_lustre()" on the MDT, although it will cause
- * that the old connected clients cannot access the ".lustre"
- * with the cached IGIF.
- *
- * Usually, it is rare case for the old connected clients
- * to access the ".lustre" with cached IGIF. So we prefer
- * 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);
+ } else if (rc == 0) {
+ rc = osd_ios_new_item(dev, child, osd_ios_general_scan,
+ osd_ios_dl_fill);
}
+ dput(child);
RETURN(rc);
}
RETURN(rc);
}
- child = osd_ios_lookup_one_len(ADMIN_USR, dentry, strlen(ADMIN_USR));
- if (!IS_ERR(child)) {
- rc = osd_ios_scan_one(info, dev, child->d_inode, NULL, 0);
- dput(child);
- } else {
+ child = osd_lookup_one_len_unlocked(dev, ADMIN_USR, dentry,
+ strlen(ADMIN_USR));
+ if (IS_ERR(child)) {
rc = PTR_ERR(child);
+ } else {
+ rc = osd_ios_scan_one(info, dev, dentry->d_inode,
+ child->d_inode, NULL, ADMIN_USR,
+ strlen(ADMIN_USR), 0);
+ dput(child);
}
if (rc != 0 && rc != -ENOENT)
- RETURN(rc);
-
- child = osd_ios_lookup_one_len(ADMIN_GRP, dentry, strlen(ADMIN_GRP));
- if (!IS_ERR(child)) {
- rc = osd_ios_scan_one(info, dev, child->d_inode, NULL, 0);
- dput(child);
- } else {
- rc = PTR_ERR(child);
- }
+ GOTO(out, rc);
- if (rc == -ENOENT)
- rc = 0;
+ child = osd_lookup_one_len_unlocked(dev, ADMIN_GRP, dentry,
+ strlen(ADMIN_GRP));
+ if (IS_ERR(child))
+ GOTO(out, rc = PTR_ERR(child));
- RETURN(rc);
+ rc = osd_ios_scan_one(info, dev, dentry->d_inode,
+ child->d_inode, NULL, ADMIN_GRP,
+ strlen(ADMIN_GRP), 0);
+ dput(child);
+out:
+ RETURN(rc == -ENOENT ? 0 : rc);
}
-static int osd_initial_OI_scrub(struct osd_thread_info *info,
- struct osd_device *dev)
+static void 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;
const struct osd_lf_map *map = osd_lf_maps;
- int rc;
ENTRY;
/* Lookup IGIF in OI by force for initial OI scrub. */
dev->od_igif_inoi = 1;
while (1) {
- rc = scandir(info, dev, dentry, filldir);
+ scandir(info, dev, dentry, filldir);
if (item != NULL) {
dput(item->oii_dentry);
OBD_FREE_PTR(item);
}
- if (rc != 0)
- break;
-
if (list_empty(&dev->od_ios_list))
break;
dentry = item->oii_dentry;
}
- while (!list_empty(&dev->od_ios_list)) {
- item = list_entry(dev->od_ios_list.next,
- struct osd_ios_item, oii_list);
- list_del_init(&item->oii_list);
- dput(item->oii_dentry);
- OBD_FREE_PTR(item);
- }
-
- 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. */
continue;
}
- child = osd_ios_lookup_one_len(map->olm_name,
- osd_sb(dev)->s_root,
- map->olm_namelen);
- if (!IS_ERR(child))
- dput(child);
- else if (PTR_ERR(child) == -ENOENT)
+ child = osd_lookup_one_len_unlocked(dev, map->olm_name,
+ osd_sb(dev)->s_root,
+ map->olm_namelen);
+ if (PTR_ERR(child) == -ENOENT ||
+ (!IS_ERR(child) && !child->d_inode))
osd_scrub_refresh_mapping(info, dev, &map->olm_fid,
NULL, DTO_INDEX_DELETE,
true, 0, NULL);
+ if (!IS_ERR(child))
+ dput(child);
map++;
}
- RETURN(0);
+ if (!list_empty(&dev->od_index_restore_list)) {
+ char *buf;
+
+ OBD_ALLOC_LARGE(buf, INDEX_BACKUP_BUFSIZE);
+ if (!buf)
+ CERROR("%s: not enough RAM for rebuild index\n",
+ osd_name(dev));
+
+ while (!list_empty(&dev->od_index_restore_list)) {
+ struct lustre_index_restore_unit *liru;
+
+ liru = list_entry(dev->od_index_restore_list.next,
+ struct lustre_index_restore_unit,
+ liru_link);
+ list_del(&liru->liru_link);
+ if (buf)
+ osd_index_restore(info->oti_env, dev, liru,
+ buf, INDEX_BACKUP_BUFSIZE);
+ OBD_FREE(liru, liru->liru_len);
+ }
+
+ if (buf)
+ OBD_FREE_LARGE(buf, INDEX_BACKUP_BUFSIZE);
+ }
+
+ EXIT;
}
char *osd_lf_fid2name(const struct lu_fid *fid)
RETURN(rc);
}
-static void osd_scrub_stop(struct osd_device *dev)
+void osd_scrub_stop(struct osd_device *dev)
{
struct lustre_scrub *scrub = &dev->od_scrub.os_scrub;
struct lvfs_run_ctxt *ctxt = &dev->od_scrub.os_ctxt;
struct scrub_file *sf = &scrub->os_file;
struct super_block *sb = osd_sb(dev);
- struct ldiskfs_super_block *es = LDISKFS_SB(sb)->s_es;
struct lvfs_run_ctxt saved;
struct file *filp;
struct inode *inode;
struct lu_fid *fid = &info->oti_fid;
- struct lu_object_conf conf;
+ struct osd_inode_id *id = &info->oti_id;
struct dt_object *obj;
bool dirty = false;
bool restored = false;
OBD_SET_CTXT_MAGIC(ctxt);
ctxt->pwdmnt = dev->od_mnt;
ctxt->pwd = dev->od_mnt->mnt_root;
- ctxt->fs = get_ds();
+ ctxt->fs = KERNEL_DS;
init_waitqueue_head(&scrub->os_thread.t_ctl_waitq);
init_rwsem(&scrub->os_rwsem);
}
}
- igrab(inode);
+ osd_id_gen(id, inode->i_ino, inode->i_generation);
+ osd_add_oi_cache(info, dev, id, fid);
filp_close(filp, NULL);
pop_ctxt(&saved, ctxt);
- conf.loc_flags = LOC_F_NEW;
- obj = lu2dt(lu_object_find_slice(env, osd2lu_dev(dev), fid, &conf));
- if (IS_ERR_OR_NULL(obj)) {
- iput(inode);
- RETURN(obj == NULL ? -ENOENT : PTR_ERR(obj));
- }
+ obj = lu2dt(lu_object_find_slice(env, osd2lu_dev(dev), fid, NULL));
+ if (IS_ERR_OR_NULL(obj))
+ RETURN(obj ? PTR_ERR(obj) : -ENOENT);
- osd_dt_obj(obj)->oo_inode = inode;
+#ifndef HAVE_S_UUID_AS_UUID_T
+ memcpy(dev->od_uuid.b, sb->s_uuid, UUID_SIZE);
+#else
+ uuid_copy(&dev->od_uuid, &sb->s_uuid);
+#endif
scrub->os_obj = obj;
rc = scrub_file_load(env, scrub);
if (rc == -ENOENT || rc == -EFAULT) {
- scrub_file_init(scrub, es->s_uuid);
+ scrub_file_init(scrub, dev->od_uuid);
/* If the "/O" dir does not exist when mount (indicated by
* osd_device::od_maybe_new), neither for the "/OI_scrub",
* then it is quite probably that the device is a new one,
* an old device, it can be found and cleared later.
*
* For the system with "SIF_NO_HANDLE_OLD_FID", we do not
- * need to check "filter_fid_old" and to convert it to
+ * need to check "filter_fid_18_23" and to convert it to
* "filter_fid" for each object, and all the IGIF should
* have their FID mapping in OI files already. */
if (dev->od_maybe_new && rc == -ENOENT)
} else if (rc < 0) {
GOTO(cleanup_obj, rc);
} else {
- if (memcmp(sf->sf_uuid, es->s_uuid, 16) != 0) {
- struct obd_uuid *old_uuid;
- struct obd_uuid *new_uuid;
-
- OBD_ALLOC_PTR(old_uuid);
- OBD_ALLOC_PTR(new_uuid);
- if (old_uuid == NULL || new_uuid == NULL) {
- CERROR("%s: UUID has been changed, but"
- "failed to allocate RAM for report\n",
- osd_dev2name(dev));
- } else {
- class_uuid_unparse(sf->sf_uuid, old_uuid);
- class_uuid_unparse(es->s_uuid, new_uuid);
- CDEBUG(D_LFSCK, "%s: UUID has been changed "
- "from %s to %s\n", osd_dev2name(dev),
- old_uuid->uuid, new_uuid->uuid);
- }
- scrub_file_reset(scrub, es->s_uuid, SF_INCONSISTENT);
+ if (!uuid_equal(&sf->sf_uuid, &dev->od_uuid)) {
+ CDEBUG(D_LFSCK,
+ "%s: UUID has been changed from %pU to %pU\n",
+ osd_dev2name(dev), &sf->sf_uuid, &dev->od_uuid);
+ scrub_file_reset(scrub, dev->od_uuid, SF_INCONSISTENT);
dirty = true;
restored = true;
- if (old_uuid != NULL)
- OBD_FREE_PTR(old_uuid);
- if (new_uuid != NULL)
- OBD_FREE_PTR(new_uuid);
} else if (sf->sf_status == SS_SCANNING) {
sf->sf_status = SS_CRASHED;
dirty = true;
if (rc < 0)
GOTO(cleanup_obj, rc);
- if (!dev->od_dt_dev.dd_rdonly) {
- rc = osd_initial_OI_scrub(info, dev);
- if (rc)
- GOTO(cleanup_oi, rc);
- }
+ if (!dev->od_dt_dev.dd_rdonly)
+ osd_initial_OI_scrub(info, dev);
if (sf->sf_flags & SF_UPGRADE ||
!(sf->sf_internal_flags & SIF_NO_HANDLE_OLD_FID ||