struct osd_scrub *scrub;
struct scrub_file *sf;
int result;
- int saved = 0;
- bool cached = true;
- bool triggered = false;
+ int rc1 = 0;
+ bool cached = true;
+ bool remote = false;
ENTRY;
LINVRNT(osd_invariant(obj));
if (result == -EREMCHG) {
trigger:
- if (unlikely(triggered))
- GOTO(out, result = saved);
-
- triggered = true;
- if (thread_is_running(&scrub->os_thread)) {
- result = -EINPROGRESS;
- } else if (!dev->od_noscrub) {
- result = osd_scrub_start(dev, SS_AUTO_FULL |
- SS_CLEAR_DRYRUN | SS_CLEAR_FAILOUT);
- 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
- result = -EREMCHG;
- } else {
- result = -EREMCHG;
- }
-
- if (fid_is_on_ost(info, dev, fid, OI_CHECK_FLD))
- GOTO(out, result);
-
/* We still have chance to get the valid inode: for the
* object which is referenced by remote name entry, the
* object on the local MDT will be linked under the dir
* only happened for the RPC from other MDT during the
* OI scrub, or for the client side RPC with FID only,
* such as FID to path, or from old connected client. */
- saved = result;
- result = osd_lookup_in_remote_parent(info, dev,
- fid, id);
- if (result == 0) {
- cached = true;
- goto iget;
+ if (!remote &&
+ !fid_is_on_ost(info, dev, fid, OI_CHECK_FLD)) {
+ rc1 = osd_lookup_in_remote_parent(info, dev,
+ fid, id);
+ if (rc1 == 0) {
+ remote = true;
+ cached = true;
+ goto iget;
+ }
}
- result = saved;
+ if (thread_is_running(&scrub->os_thread)) {
+ if (remote) {
+ osd_add_oi_cache(info, dev, id, fid);
+ osd_oii_insert(dev, oic, true);
+ } else {
+ result = -EINPROGRESS;
+ }
+ } else if (!dev->od_noscrub) {
+ __u32 flags = SS_CLEAR_DRYRUN |
+ SS_CLEAR_FAILOUT;
+
+ flags |= (remote ? SS_AUTO_PARTIAL :
+ SS_AUTO_FULL);
+ rc1 = osd_scrub_start(dev, flags);
+ LCONSOLE_WARN("%.16s: trigger OI scrub by RPC "
+ "for the "DFID" with flags 0x%x,"
+ " rc = %d\n", osd_name(dev),
+ PFID(fid), flags, rc1);
+ if (rc1 == 0 || rc1 == -EALREADY) {
+ result = -EINPROGRESS;
+ if (remote) {
+ osd_add_oi_cache(info, dev, id,
+ fid);
+ osd_oii_insert(dev, oic, true);
+ }
+ } else {
+ result = -EREMCHG;
+ }
+ } else {
+ result = -EREMCHG;
+ }
}
GOTO(out, result);
+ } else if (remote) {
+ result = 0;
+ goto trigger;
}
obj->oo_inode = inode;
osd_trans_exec_op(env, th, OSD_OT_INSERT);
osd_id_gen(id, obj->oo_inode->i_ino, obj->oo_inode->i_generation);
- rc = osd_oi_insert(info, osd, fid, id, oh->ot_handle, OI_CHECK_FLD);
+ rc = osd_oi_insert(info, osd, fid, id, oh->ot_handle,
+ OI_CHECK_FLD, NULL);
osd_trans_exec_check(env, th, OSD_OT_INSERT);
return rc;
int osd_oi_insert(struct osd_thread_info *info, struct osd_device *osd,
const struct lu_fid *fid, const struct osd_inode_id *id,
- handle_t *th, enum oi_check_flags flags)
+ handle_t *th, enum oi_check_flags flags, bool *exist)
{
struct lu_fid *oi_fid = &info->oti_fid2;
struct osd_inode_id *oi_id = &info->oti_id2;
(const struct dt_key *)oi_fid, th, false);
if (rc != 0)
return rc;
+
+ if (exist != NULL)
+ *exist = true;
}
if (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE))
enum oi_check_flags flags);
int osd_oi_insert(struct osd_thread_info *info, struct osd_device *osd,
const struct lu_fid *fid, const struct osd_inode_id *id,
- handle_t *th, enum oi_check_flags flags);
+ handle_t *th, enum oi_check_flags flags, bool *exist);
int osd_oi_delete(struct osd_thread_info *info,
struct osd_device *osd, const struct lu_fid *fid,
handle_t *th, enum oi_check_flags flags);
const struct lu_fid *fid,
const struct osd_inode_id *id,
int ops, bool force,
- enum oi_check_flags flags)
+ enum oi_check_flags flags, bool *exist)
{
handle_t *th;
int rc;
}
break;
case DTO_INDEX_INSERT:
- rc = osd_oi_insert(info, dev, fid, id, th, flags);
+ rc = osd_oi_insert(info, dev, fid, id, th, flags, exist);
if (unlikely(rc == -EEXIST)) {
rc = 1;
/* XXX: There are trouble things when adding OI
struct osd_inconsistent_item *oii = NULL;
struct inode *inode = NULL;
int ops = DTO_INDEX_UPDATE;
- int idx;
int rc;
bool converted = false;
+ bool exist = false;
ENTRY;
down_write(&scrub->os_rwsem);
if (!scrub->os_partial_scan)
scrub->os_full_speed = 1;
- idx = osd_oi_fid2idx(dev, fid);
switch (val) {
case SCRUB_NEXT_NOLMA:
sf->sf_flags |= SF_UPGRADE;
case SCRUB_NEXT_OSTOBJ_OLD:
break;
default:
- sf->sf_flags |= SF_RECREATED;
- if (unlikely(!ldiskfs_test_bit(idx, sf->sf_oi_bitmap)))
- ldiskfs_set_bit(idx, sf->sf_oi_bitmap);
break;
}
} else if (osd_id_eq(lid, lid2)) {
rc = osd_scrub_refresh_mapping(info, dev, fid, lid, ops, false,
(val == SCRUB_NEXT_OSTOBJ ||
- val == SCRUB_NEXT_OSTOBJ_OLD) ? OI_KNOWN_ON_OST : 0);
+ val == SCRUB_NEXT_OSTOBJ_OLD) ? OI_KNOWN_ON_OST : 0,
+ &exist);
if (rc == 0) {
if (scrub->os_in_prior)
sf->sf_items_updated_prior++;
else
sf->sf_items_updated++;
+
+ if (ops == DTO_INDEX_INSERT && val == 0 && !exist) {
+ int idx = osd_oi_fid2idx(dev, fid);
+
+ sf->sf_flags |= SF_RECREATED;
+ if (unlikely(!ldiskfs_test_bit(idx, sf->sf_oi_bitmap)))
+ ldiskfs_set_bit(idx, sf->sf_oi_bitmap);
+ }
}
GOTO(out, rc);
DTO_INDEX_DELETE, false,
(val == SCRUB_NEXT_OSTOBJ ||
val == SCRUB_NEXT_OSTOBJ_OLD) ?
- OI_KNOWN_ON_OST : 0);
+ OI_KNOWN_ON_OST : 0, NULL);
up_write(&scrub->os_rwsem);
if (inode != NULL && !IS_ERR(inode))
RETURN(rc);
rc = osd_scrub_refresh_mapping(info, dev, &tfid, id,
- DTO_INDEX_INSERT, true, 0);
+ DTO_INDEX_INSERT, true, 0, NULL);
if (rc > 0)
rc = 0;
}
rc = osd_scrub_refresh_mapping(info, dev, &tfid, id,
- DTO_INDEX_UPDATE, true, 0);
+ DTO_INDEX_UPDATE, true, 0, NULL);
if (rc > 0)
rc = 0;
else if (PTR_ERR(child) == -ENOENT)
osd_scrub_refresh_mapping(info, dev, &map->olm_fid,
NULL, DTO_INDEX_DELETE,
- true, 0);
+ true, 0, NULL);
map++;
}
local -a updated0
for n in $(seq $MDSCOUNT); do
updated0[$n]=$(scrub_status $n |
- awk '/^sf_items_updated_prior/ { print $2 }')
+ awk '/^prior_updated/ { print $2 }')
done
scrub_check_data2 sanity-scrub.sh 9
local -a updated1
for n in $(seq $MDSCOUNT); do
updated1[$n]=$(scrub_status $n |
- awk '/^sf_items_updated_prior/ { print $2 }')
+ awk '/^prior_updated/ { print $2 }')
[ ${updated0[$n]} -eq ${updated1[$n]} ] ||
error "(10) NOT auto trigger full scrub as expected"
done
local -a updated0
for n in $(seq $MDSCOUNT); do
updated0[$n]=$(scrub_status $n |
- awk '/^sf_items_updated_prior/ { print $2 }')
+ awk '/^prior_updated/ { print $2 }')
done
scrub_check_data2 sanity-scrub.sh 9
local -a updated1
for n in $(seq $MDSCOUNT); do
updated1[$n]=$(scrub_status $n |
- awk '/^sf_items_updated_prior/ { print $2 }')
+ awk '/^prior_updated/ { print $2 }')
[ ${updated0[$n]} -lt ${updated1[$n]} ] ||
error "(12) Auto trigger full scrub unexpectedly"
done
for n in $(seq $MDSCOUNT); do
updated0[$n]=$(scrub_status $n |
- awk '/^sf_items_updated_prior/ { print $2 }')
+ awk '/^prior_updated/ { print $2 }')
[ ${updated0[$n]} -gt ${updated1[$n]} ] ||
error "(16) Auto trigger full scrub unexpectedly"
done
for n in $(seq $MDSCOUNT); do
updated1[$n]=$(scrub_status $n |
- awk '/^sf_items_updated_prior/ { print $2 }')
+ awk '/^prior_updated/ { print $2 }')
[ ${updated0[$n]} -eq ${updated1[$n]} ] ||
error "(18) NOT auto trigger full scrub as expected"
done
local -a updated0
for n in $(seq $MDSCOUNT); do
updated0[$n]=$(scrub_status $n |
- awk '/^sf_items_updated_prior/ { print $2 }')
+ awk '/^prior_updated/ { print $2 }')
done
scrub_check_data2 sanity-scrub.sh 9
local -a updated1
for n in $(seq $MDSCOUNT); do
updated1[$n]=$(scrub_status $n |
- awk '/^sf_items_updated_prior/ { print $2 }')
+ awk '/^prior_updated/ { print $2 }')
[ ${updated0[$n]} -lt ${updated1[$n]} ] ||
error "(12) Auto trigger full scrub unexpectedly"
done
for n in $(seq $MDSCOUNT); do
updated0[$n]=$(scrub_status $n |
- awk '/^sf_items_updated_prior/ { print $2 }')
+ awk '/^prior_updated/ { print $2 }')
[ ${updated0[$n]} -gt ${updated1[$n]} ] ||
error "(16) Auto trigger full scrub unexpectedly"
done
for n in $(seq $MDSCOUNT); do
updated1[$n]=$(scrub_status $n |
- awk '/^sf_items_updated_prior/ { print $2 }')
+ awk '/^prior_updated/ { print $2 }')
[ ${updated0[$n]} -eq ${updated1[$n]} ] ||
error "(18) NOT auto trigger full scrub as expected"
done