@@ -543,7 +543,13 @@ static int lov_init_dom(const struct lu_env *env, struct lov_device *dev,
u32 idx = 0;
int rc;
- LASSERT(index == 0);
+ /* DOM entry may be not zero index due to FLR but must start from 0 */
+ if (unlikely(lle->lle_extent->e_start != 0)) {
+ CERROR("%s: DOM entry must be the first stripe in a mirror\n",
+ lov2obd(dev->ld_lov)->obd_name);
+ dump_lsm(D_ERROR, lov->lo_lsm);
+ return -EINVAL;
+ }
/* find proper MDS device */
rc = lov_fld_lookup(dev, fid, &idx);
@@ -636,6 +642,7 @@ static int lov_init_composite(const struct lu_env *env, struct lov_device *dev,
int result = 0;
unsigned int seq;
int i, j;
+ bool dom_size = 0;
LASSERT(lsm->lsm_entry_count > 0);
LASSERT(!lov->lo_lsm);
@@ -679,6 +686,18 @@ static int lov_init_composite(const struct lu_env *env, struct lov_device *dev,
lle->lle_comp_ops = &raid0_ops;
break;
case LOV_PATTERN_MDT:
+ /* Allowed to have several DOM stripes in different
+ * mirrors with the same DoM size.
+ */
+ if (!dom_size) {
+ dom_size = lle->lle_lsme->lsme_extent.e_end;
+ } else if (dom_size !=
+ lle->lle_lsme->lsme_extent.e_end) {
+ CERROR("%s: DOM entries with different sizes\n",
+ lov2obd(dev->ld_lov)->obd_name);
+ dump_lsm(D_ERROR, lsm);
+ return -EINVAL;
+ }
lle->lle_comp_ops = &dom_ops;
break;
default:
@@ -869,7 +888,8 @@ static void lov_fini_composite(const struct lu_env *env,
struct lov_layout_entry *entry;
lov_foreach_layout_entry(lov, entry)
- entry->lle_comp_ops->lco_fini(env, entry);
+ if (entry->lle_comp_ops)
+ entry->lle_comp_ops->lco_fini(env, entry);
kvfree(comp->lo_entries);
comp->lo_entries = NULL;