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>
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;
};
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++;
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;
* 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 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;
.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_found = false,
};
int rc = 0;
.oclb_found = false,
};
int rc = 0;
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);
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);
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);
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);
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)
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;
- 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.
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);
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;
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);
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))
- 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);
}
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);
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,
* \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)
#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;
RETURN(-ENOMEM);
INIT_LIST_HEAD(&oii->oii_list);
RETURN(-ENOMEM);
INIT_LIST_HEAD(&oii->oii_list);
+ 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);
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,
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))
+ 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
#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;
* \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;