if (le32_to_cpu(lmv->lmv_stripe_count) == 0)
goto insane;
- if (!lmv_is_known_hash_type(le32_to_cpu(lmv->lmv_hash_type)))
+ if (!lmv_is_sane_hash_type(le32_to_cpu(lmv->lmv_hash_type)))
goto insane;
return true;
if (le32_to_cpu(lmv->lmv_stripe_count) == 0)
goto insane;
- if (!lmv_is_known_hash_type(le32_to_cpu(lmv->lmv_hash_type)))
+ if (!lmv_is_sane_hash_type(le32_to_cpu(lmv->lmv_hash_type)))
goto insane;
return true;
/* MIGRATE */
#define OBD_FAIL_MIGRATE_ENTRIES 0x1801
+#define OBD_FAIL_MIGRATE_BAD_HASH 0x1802
/* LMV */
#define OBD_FAIL_LMV_UNKNOWN_STRIPE 0x1901
#define LMV_HASH_FLAG_KNOWN 0xbe000000
+/* migration failure may leave hash type as
+ * LMV_HASH_TYPE_UNKNOWN|LMV_HASH_FLAG_BAD_TYPE, which should be treated as
+ * sane, so such directory can be accessed (resume migration or unlink).
+ */
+static inline bool lmv_is_sane_hash_type(__u32 type)
+{
+ return lmv_is_known_hash_type(type) ||
+ type == (LMV_HASH_TYPE_UNKNOWN | LMV_HASH_FLAG_BAD_TYPE);
+}
+
/* both SPLIT and MIGRATION are set for directory split */
static inline bool lmv_hash_is_splitting(__u32 hash)
{
if (rc)
GOTO(put_parent, rc);
+ if (CFS_FAIL_CHECK(OBD_FAIL_MIGRATE_BAD_HASH) &&
+ (ma->ma_valid & MA_LMV) &&
+ lmv_is_migrating(&ma->ma_lmv->lmv_md_v1)) {
+ struct lu_buf *buf = &info->mti_buf;
+ struct lmv_mds_md_v1 *lmv = &ma->ma_lmv->lmv_md_v1;
+ __u32 version = le32_to_cpu(lmv->lmv_layout_version);
+
+ lmv->lmv_hash_type = cpu_to_le32(LMV_HASH_TYPE_UNKNOWN |
+ LMV_HASH_FLAG_BAD_TYPE);
+ lmv->lmv_layout_version = cpu_to_le32(version + 1);
+ buf->lb_buf = lmv;
+ buf->lb_len = sizeof(*lmv);
+ rc = mo_xattr_set(env, mdt_object_child(pobj), buf,
+ XATTR_NAME_LMV, LU_XATTR_REPLACE);
+ mo_invalidate(env, mdt_object_child(pobj));
+ GOTO(put_parent, rc);
+ }
+
/* @spobj is the parent stripe of @sobj if @pobj is striped directory,
* if @pobj is migrating too, tpobj is the target parent stripe.
*/
}
run_test 230x "dir migration check space"
+test_230y() {
+ (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
+ (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
+ skip "Need MDS version at least 2.15.55.45"
+
+ local pid
+
+ test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
+ $LFS getdirstripe $DIR/$tdir
+ createmany -d $DIR/$tdir/d 100 || error "createmany failed"
+ $LFS migrate -m 1 -c 2 $DIR/$tdir &
+ pid=$!
+ sleep 1
+
+ #OBD_FAIL_MIGRATE_BAD_HASH 0x1802
+ do_facet mds2 lctl set_param fail_loc=0x1802
+
+ wait $pid
+ do_facet mds2 lctl set_param fail_loc=0
+ $LFS getdirstripe $DIR/$tdir
+ unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
+ rmdir $DIR/$tdir || error "rmdir $tdir failed"
+}
+run_test 230y "unlink dir with bad hash type"
+
test_231a()
{
# For simplicity this test assumes that max_pages_per_rpc