struct dt_object *parent,
struct lu_buf *buf, __u32 ea_off,
struct lov_mds_md_v1 **lmm,
- struct lov_ost_data_v1 **objs)
+ struct lov_ost_data_v1 **objs,
+ struct ost_layout_compr *compr)
{
int size;
__u32 stripe_size = ol->ol_stripe_size;
__u32 pattern = LOV_PATTERN_RAID0;
__u16 count;
+ if (compr->ol_compr_type != LL_COMPR_TYPE_NONE)
+ pattern |= LOV_PATTERN_COMPRESS;
+
if (ol->ol_stripe_count != 0)
count = ol->ol_stripe_count;
else
lcme->lcme_offset = cpu_to_le32(offset);
lcme->lcme_size = cpu_to_le32(lcme_size);
lcme->lcme_layout_gen = lcm->lcm_layout_gen;
+
+ if (rec->lor_layout_compr.ol_compr_type != LL_COMPR_TYPE_NONE) {
+ pattern |= LOV_PATTERN_COMPRESS;
+ lcme->lcme_flags |= cpu_to_le32(LCME_FL_COMPRESS);
+ lcme->lcme_compr_type = rec->lor_layout_compr.ol_compr_type;
+ lcme->lcme_compr_lvl = rec->lor_layout_compr.ol_compr_lvl;
+ lcme->lcme_compr_chunk_log_bits =
+ rec->lor_layout_compr.ol_compr_chunk_log_bits;
+ }
+
if (ol->ol_stripe_count > 1)
pattern |= LOV_PATTERN_F_HOLE;
static void lfsck_layout_update_lcm(struct lov_comp_md_v1 *lcm,
struct lov_comp_md_entry_v1 *lcme,
- __u32 version, __u32 range)
+ __u32 version, __u32 range,
+ struct ost_layout_compr *compr)
{
struct lov_comp_md_entry_v1 *tmp;
__u64 start = le64_to_cpu(lcme->lcme_extent.e_start);
else if (flags == LCM_FL_NONE && le16_to_cpu(lcm->lcm_mirror_count) > 0)
lcm->lcm_flags = cpu_to_le16(LCM_FL_RDONLY);
+ if (compr->ol_compr_type != LL_COMPR_TYPE_NONE) {
+ lcme->lcme_flags |= cpu_to_le32(LCME_FL_COMPRESS);
+ lcme->lcme_compr_type = compr->ol_compr_type;
+ lcme->lcme_compr_lvl = compr->ol_compr_lvl;
+ lcme->lcme_compr_chunk_log_bits =
+ compr->ol_compr_chunk_log_bits;
+ }
+
for (i = 0; i < count; i++) {
tmp = &lcm->lcm_entries[i];
if (le64_to_cpu(tmp->lcme_extent.e_end) <= start)
pattern |= LOV_PATTERN_F_HOLE;
lmm = buf->lb_buf + offset;
- /* 5. Insert teh new component body at the 'offset'. */
+ /* 5. Insert the new component body at the 'offset'. */
+ if (rec->lor_layout_compr.ol_compr_type != LL_COMPR_TYPE_NONE)
+ pattern |= LOV_PATTERN_COMPRESS;
+
objs = __lfsck_layout_new_v1_lovea(lmm, lfsck_dto2fid(parent),
ol->ol_stripe_size, ea_off,
pattern, ol->ol_stripe_count);
/* 6. Update mirror related flags and version. */
lfsck_layout_update_lcm(lcm, lcme, rec->lor_layout_version,
- rec->lor_range);
+ rec->lor_range, &rec->lor_layout_compr);
rc = lfsck_layout_refill_lovea(env, lfsck, handle, parent, cfid, buf,
lmm, objs, LU_XATTR_REPLACE, ost_idx,
else
rc = lfsck_layout_new_v1_lovea(env, lfsck, &rec->lor_layout,
parent, buf, ea_off, &lmm,
- &objs);
+ &objs, &rec->lor_layout_compr);
if (rc > 0)
rc = lfsck_layout_refill_lovea(env, lfsck, handle, parent, cfid,
buf, lmm, objs, fl, ost_idx, rc);
struct dt_object *child,
const struct lu_fid *pfid,
const struct ost_layout *ol, __u32 offset,
- __u32 version, __u32 range)
+ __u32 version, __u32 range,
+ struct ost_layout_compr *compr)
{
struct dt_device *dev = lfsck_obj2dev(child);
struct filter_fid *ff = &lfsck_env_info(env)->lti_ff;
ost_layout_cpu_to_le(&ff->ff_layout, ol);
ff->ff_layout_version = cpu_to_le32(version);
ff->ff_range = cpu_to_le32(range);
+ ff->ff_layout_compr = *compr;
lfsck_buf_init(&buf, ff, sizeof(*ff));
handle = lfsck_trans_create(env, dev, com->lc_lfsck);
lu_object_fid(&parent->do_lu),
&rec->lor_layout, ea_off,
rec->lor_layout_version,
- rec->lor_range);
+ rec->lor_range, &rec->lor_layout_compr);
lfsck_object_put(env, child);
RETURN(rc == 0 ? 1 : rc);
rc = __lfsck_layout_update_pfid(env, com, cobj, pfid,
&rec->lor_layout, ea_off,
rec->lor_layout_version,
- rec->lor_range);
+ rec->lor_range,
+ &rec->lor_layout_compr);
}
GOTO(stop, rc);
lcme->lcme_flags = cpu_to_le32(flags | LCME_FL_INIT);
lfsck_layout_update_lcm(lcm, lcme,
rec->lor_layout_version,
- rec->lor_range);
+ rec->lor_range,
+ &rec->lor_layout_compr);
}
rc = lfsck_layout_extend_v1v3_lovea(env, lfsck, handle, ol,
LCME_FL_INIT);
lfsck_layout_update_lcm(lcm, lcme,
rec->lor_layout_version,
- rec->lor_range);
+ rec->lor_range,
+ &rec->lor_layout_compr);
}
LASSERTF(buf->lb_len >= lovea_size,
ol->ol_comp_end = le64_to_cpu(lcme->lcme_extent.e_end);
ol->ol_comp_id = le32_to_cpu(lcme->lcme_id);
ff->ff_layout_version = le32_to_cpu(lcme->lcme_layout_gen);
+ ff->ff_layout_compr.ol_compr_type = lcme->lcme_compr_type;
+ ff->ff_layout_compr.ol_compr_lvl = lcme->lcme_compr_lvl;
+ ff->ff_layout_compr.ol_compr_chunk_log_bits =
+ lcme->lcme_compr_chunk_log_bits;
ff->ff_range = 0;
} else {
GOTO(out, rc = -EINVAL);
&lrl->lrl_ff_client.ff_layout,
lrl->lrl_ff_client.ff_layout_version,
lrl->lrl_ff_client.ff_range,
- lrl->lrl_ff_client.ff_parent.f_ver);
+ lrl->lrl_ff_client.ff_parent.f_ver,
+ &lrl->lrl_ff_client.ff_layout_compr);
GOTO(unlock, rc);
if (rc < sizeof(struct lu_fid))
GOTO(out, rc = (rc < 0 ? rc : -EINVAL));
+ if (rc < sizeof(struct filter_fid))
+ memset(&ff->ff_layout_compr, 0, sizeof(ff->ff_layout_compr));
+
fid_le_to_cpu(&rec->lor_rec.lor_fid, &ff->ff_parent);
/* Currently, the filter_fid::ff_parent::f_ver is not the real parent
* MDT-object's FID::f_ver, instead it is the OST-object index in its
rec->lor_layout_version =
le32_to_cpu(ff->ff_layout_version & ~LU_LAYOUT_RESYNC);
rec->lor_range = le32_to_cpu(ff->ff_range);
+ rec->lor_layout_compr = ff->ff_layout_compr;
- CDEBUG(D_LFSCK, "%s: return orphan "DFID", PFID "DFID", owner %u:%u, "
- "stripe size %u, stripe count %u, COMP id %u, COMP start %llu, "
- "COMP end %llu, layout version %u, range %u\n",
+ CDEBUG(D_LFSCK, "%s: return orphan "DFID", PFID "DFID", owner %u:%u, stripe size %u, stripe count %u, COMP id %u, COMP start %llu, COMP end %llu, layout version %u, range %u, compression %s, compression level %u, compression chunk log bits %u\n",
lfsck_lfsck2name(com->lc_lfsck), PFID(key),
PFID(&rec->lor_rec.lor_fid), rec->lor_rec.lor_uid,
rec->lor_rec.lor_gid, ol->ol_stripe_size, ol->ol_stripe_count,
ol->ol_comp_id, ol->ol_comp_start, ol->ol_comp_end,
- rec->lor_layout_version, rec->lor_range);
+ rec->lor_layout_version, rec->lor_range,
+ compress_type_2str(rec->lor_layout_compr.ol_compr_type),
+ rec->lor_layout_compr.ol_compr_lvl,
+ rec->lor_layout_compr.ol_compr_chunk_log_bits);
GOTO(out, rc = 0);
}
run_test 18h "LFSCK can repair crashed PFL extent range"
+test_18i() {
+ (( $MDS1_VERSION >= $(version_code 2.14.0-ddn137) )) ||
+ skip "Need MDS version at least 2.14.0-ddn137"
+
+ local tfile=$DIR/$tdir/f0
+ local guard=$DIR/$tdir/guard
+
+ check_mount_and_prep
+ mkdir -p $DIR/$tdir
+
+ $LFS setstripe -Z gzip:5 -E 2M -S 1M -c 1 -E -1 $tfile ||
+ error "(0) Fail to create PFL $tfile"
+
+ cat $LUSTRE/tests/test-framework.sh > $tfile ||
+ error "(1.1) Fail to write $tfile"
+
+ dd if=$LUSTRE/tests/test-framework.sh of=$tfile bs=1M seek=2 ||
+ error "(1.2) Fail to write $tfile"
+
+ cp $tfile $guard ||
+ error "(1.3) Failed to copy $tfile to $guard"
+
+ echo "Inject failure to simulate bad PFL"
+ #define OBD_FAIL_LFSCK_BAD_PFL_RANGE 0x162f
+ do_facet $SINGLEMDS $LCTL set_param fail_loc=0x162f
+
+ chown 1.1 $tfile
+
+ cancel_lru_locks
+ do_facet $SINGLEMDS $LCTL set_param fail_loc=0
+
+ echo "Trigger layout LFSCK to fix them"
+ $START_LAYOUT -r -o || error "(2) Fail to start LFSCK for layout!"
+
+ for ((k = 1; k <= MDSCOUNT; k++)); do
+ wait_update_facet mds${k} "$LCTL get_param -n \
+ mdd.$(facet_svc mds${k}).lfsck_layout |
+ awk '/^status/ { print \\\$2 }'" "completed" $LTIME ||
+ error "(3.1) MDS${k} is not the expected 'completed'"
+ done
+
+ for ((k = 1; k <= MDSCOUNT; k++)); do
+ cur_status=$(do_facet ost${k} $LCTL get_param -n \
+ obdfilter.$(facet_svc ost${k}).lfsck_layout |
+ awk '/^status/ { print $2 }')
+ [ "$cur_status" == "completed" ] ||
+ error "(3.2) OST${k} Expect 'completed', but got '$cur_status'"
+
+ done
+
+ local repaired=$($SHOW_LAYOUT |
+ awk '/^repaired_orphan/ { print $2 }')
+ [ $repaired -eq 2 ] ||
+ error "(4) Fail to repair crashed PFL range: $repaired"
+
+ echo "Data in $tfile should not be broken"
+ diff $tfile $guard ||
+ error "(5) Data in $tfile is broken"
+}
+run_test 18i "LFSCK can repair crashed PFL with compression"
+
$LCTL set_param debug=-cache > /dev/null
test_19a() {