lfsck->ml_bookmark_obj = obj;
- obj = dt_locate(env, mdd->mdd_child, &lfsck_it_fid);
+ obj = dt_locate(env, mdd->mdd_bottom, &lfsck_it_fid);
if (IS_ERR(obj))
return PTR_ERR(obj);
struct dt_thread_info *dti = dt_info(env);
struct ls_device *ls;
struct los_ondisk losd;
- struct dt_object *o;
struct dt_object *root = NULL;
+ struct dt_object *o = NULL;
struct thandle *th;
int rc;
cfs_atomic_inc(&ls->ls_refcount);
cfs_list_add(&(*los)->los_list, &ls->ls_los_list);
- /* initialize data allowing to generate new fids,
- * literally we need a sequence */
- o = ls_locate(env, ls, first_fid);
- if (IS_ERR(o))
- GOTO(out_los, rc = PTR_ERR(o));
-
rc = dt_root_get(env, dev, &dti->dti_fid);
if (rc)
GOTO(out_los, rc);
if (IS_ERR(root))
GOTO(out_los, rc = PTR_ERR(root));
- if (dt_try_as_dir(env, root) == 0)
- GOTO(out_los, rc = -ENOTDIR);
+ snprintf(dti->dti_buf, sizeof(dti->dti_buf), "seq-%Lx-lastid",
+ fid_seq(first_fid));
+ rc = dt_lookup_dir(env, root, dti->dti_buf, &dti->dti_fid);
+ if (rc != 0 && rc != -ENOENT)
+ GOTO(out_los, rc);
+
+ /* initialize data allowing to generate new fids,
+ * literally we need a sequence */
+ if (rc == 0)
+ o = ls_locate(env, ls, &dti->dti_fid);
+ else
+ o = ls_locate(env, ls, first_fid);
+ if (IS_ERR(o))
+ GOTO(out_los, rc = PTR_ERR(o));
dt_write_lock(env, o, 0);
if (!dt_object_exists(o)) {
+ LASSERT(rc == -ENOENT);
+
th = dt_trans_create(env, dev);
if (IS_ERR(th))
GOTO(out_lock, rc = PTR_ERR(th));
if (rc)
GOTO(out_trans, rc);
- snprintf(dti->dti_buf, sizeof(dti->dti_buf),
- "seq-%Lx-lastid", fid_seq(first_fid));
rc = dt_declare_insert(env, root,
(const struct dt_rec *)lu_object_fid(&o->do_lu),
(const struct dt_key *)dti->dti_buf,
out_lock:
dt_write_unlock(env, o);
out_los:
- if (root)
+ if (root != NULL && !IS_ERR(root))
lu_object_put_nocache(env, &root->do_lu);
- if (rc) {
+
+ if (rc != 0) {
+ cfs_list_del(&(*los)->los_list);
+ cfs_atomic_dec(&ls->ls_refcount);
OBD_FREE_PTR(*los);
*los = NULL;
- if (o)
+ if (o != NULL && !IS_ERR(o))
lu_object_put_nocache(env, &o->do_lu);
} else {
(*los)->los_seq = fid_seq(first_fid);
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);
}
iput(inode);
return ERR_PTR(EREMCHG);
}
+
return inode;
}
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)) {
+ /* 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;
- } 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;
- }
-
- if (sf->sf_flags & SF_INCONSISTENT)
- verify = 1;
}
+ 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
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",
int rc;
ENTRY;
+ if (!fid_is_norm(fid) && !fid_is_igif(fid))
+ RETURN(0);
+
again:
rc = osd_oi_lookup(oti, dev, fid, id);
if (rc != 0 && rc != -ENOENT)
RETURN(rc);
}
- 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);
goto again;
}
- RETURN(rc = -EREMCHG);
+ RETURN(0);
}
/**
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);
}
(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;
}
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);
}
return -EACCES;
rc = osd_ea_lookup_rec(env, obj, rec, key);
-
if (rc == 0)
rc = +1;
RETURN(rc);
} else
o->od_iop_mode = 1;
if (lmd_flags & LMD_FLG_NOSCRUB)
- o->od_scrub.os_no_scrub = 1;
+ o->od_noscrub = 1;
out:
if (__page)
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;
int od_connects;
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,
if (rc)
return rc;
- dev->od_scrub.os_no_scrub = !val;
+ dev->od_noscrub = !val;
return count;
}
}
}
- 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)) ||
* 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. */
};
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
echo "setupall"
setupall > /dev/null
+ local CREATED=100
local tname=`date +%s`
rm -rf $MOUNT/$tname > /dev/null
mkdir $MOUNT/$tname || error "(1) Fail to mkdir $MOUNT/$tname"
- createmany -o $MOUNT/$tname/f 100 || error "(2) Fail to create!"
+ createmany -o $MOUNT/$tname/f $CREATED || error "(2) Fail to create!"
# reset OI scrub start point by force
$START_SCRUB -r || error "(3) Fail to start OI scrub!"
# OI scrub should skip the new created objects for the first accessing
local SKIPPED=$($SHOW_SCRUB | awk '/^noscrub/ { print $2 }')
- [ $SKIPPED -eq 101 ] ||
- error "(5) Expect 101 objects skipped, but got $SKIPPED"
+ # notice we're creating a new llog for every OST on every startup
+ # new features can make this even less stable, so we only check
+ # that the number of skipped files is less than 1.5x the number of files
+ local MAXIMUM=$((CREATED * 3 / 2))
+ local MINIMUM=$((CREATED + 1)) # files + directory
+ [ $SKIPPED -ge $MAXIMUM -o $SKIPPED -lt $MINIMUM] &&
+ error "(5) Expect [ $MINIMUM , $MAXIMUM ) objects skipped, got $SKIPPED"
# reset OI scrub start point by force
$START_SCRUB -r || error "(6) Fail to start OI scrub!"