diff options
Diffstat (limited to 'drivers/staging/lustre/lustre/lov/lov_ea.c')
-rw-r--r-- | drivers/staging/lustre/lustre/lov/lov_ea.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/staging/lustre/lustre/lov/lov_ea.c b/drivers/staging/lustre/lustre/lov/lov_ea.c index 340dbcf829e8..e6c60151dc65 100644 --- a/drivers/staging/lustre/lustre/lov/lov_ea.c +++ b/drivers/staging/lustre/lustre/lov/lov_ea.c @@ -57,7 +57,7 @@ struct lovea_unpack_args { static int lsm_lmm_verify_common(struct lov_mds_md *lmm, int lmm_bytes, __u16 stripe_count) { - if (stripe_count == 0 || stripe_count > LOV_V1_INSANE_STRIPE_COUNT) { + if (stripe_count > LOV_V1_INSANE_STRIPE_COUNT) { CERROR("bad stripe count %d\n", stripe_count); lov_dump_lmm_common(D_WARNING, lmm); return -EINVAL; @@ -69,7 +69,7 @@ static int lsm_lmm_verify_common(struct lov_mds_md *lmm, int lmm_bytes, return -EINVAL; } - if (lmm->lmm_pattern != cpu_to_le32(LOV_PATTERN_RAID0)) { + if (lov_pattern(le32_to_cpu(lmm->lmm_pattern)) != LOV_PATTERN_RAID0) { CERROR("bad striping pattern\n"); lov_dump_lmm_common(D_WARNING, lmm); return -EINVAL; @@ -197,6 +197,8 @@ static int lsm_lmm_verify_v1(struct lov_mds_md_v1 *lmm, int lmm_bytes, } *stripe_count = le16_to_cpu(lmm->lmm_stripe_count); + if (le32_to_cpu(lmm->lmm_pattern) & LOV_PATTERN_F_RELEASED) + *stripe_count = 0; if (lmm_bytes < lov_mds_md_size(*stripe_count, LOV_MAGIC_V1)) { CERROR("LOV EA V1 too small: %d, need %d\n", @@ -213,11 +215,14 @@ int lsm_unpackmd_v1(struct lov_obd *lov, struct lov_stripe_md *lsm, { struct lov_oinfo *loi; int i; + int stripe_count; __u64 stripe_maxbytes = OBD_OBJECT_EOF; lsm_unpackmd_common(lsm, lmm); - for (i = 0; i < lsm->lsm_stripe_count; i++) { + stripe_count = lsm_is_released(lsm) ? 0 : lsm->lsm_stripe_count; + + for (i = 0; i < stripe_count; i++) { /* XXX LOV STACKING call down to osc_unpackmd() */ loi = lsm->lsm_oinfo[i]; ostid_le_to_cpu(&lmm->lmm_objects[i].l_ost_oi, &loi->loi_oi); @@ -240,6 +245,8 @@ int lsm_unpackmd_v1(struct lov_obd *lov, struct lov_stripe_md *lsm, } lsm->lsm_maxbytes = stripe_maxbytes * lsm->lsm_stripe_count; + if (lsm->lsm_stripe_count == 0) + lsm->lsm_maxbytes = stripe_maxbytes * lov->desc.ld_tgt_count; return 0; } @@ -267,6 +274,8 @@ static int lsm_lmm_verify_v3(struct lov_mds_md *lmmv1, int lmm_bytes, } *stripe_count = le16_to_cpu(lmm->lmm_stripe_count); + if (le32_to_cpu(lmm->lmm_pattern) & LOV_PATTERN_F_RELEASED) + *stripe_count = 0; if (lmm_bytes < lov_mds_md_size(*stripe_count, LOV_MAGIC_V3)) { CERROR("LOV EA V3 too small: %d, need %d\n", @@ -285,18 +294,22 @@ int lsm_unpackmd_v3(struct lov_obd *lov, struct lov_stripe_md *lsm, struct lov_mds_md_v3 *lmm; struct lov_oinfo *loi; int i; + int stripe_count; __u64 stripe_maxbytes = OBD_OBJECT_EOF; int cplen = 0; lmm = (struct lov_mds_md_v3 *)lmmv1; lsm_unpackmd_common(lsm, (struct lov_mds_md_v1 *)lmm); + + stripe_count = lsm_is_released(lsm) ? 0 : lsm->lsm_stripe_count; + cplen = strlcpy(lsm->lsm_pool_name, lmm->lmm_pool_name, sizeof(lsm->lsm_pool_name)); if (cplen >= sizeof(lsm->lsm_pool_name)) return -E2BIG; - for (i = 0; i < lsm->lsm_stripe_count; i++) { + for (i = 0; i < stripe_count; i++) { /* XXX LOV STACKING call down to osc_unpackmd() */ loi = lsm->lsm_oinfo[i]; ostid_le_to_cpu(&lmm->lmm_objects[i].l_ost_oi, &loi->loi_oi); @@ -319,6 +332,8 @@ int lsm_unpackmd_v3(struct lov_obd *lov, struct lov_stripe_md *lsm, } lsm->lsm_maxbytes = stripe_maxbytes * lsm->lsm_stripe_count; + if (lsm->lsm_stripe_count == 0) + lsm->lsm_maxbytes = stripe_maxbytes * lov->desc.ld_tgt_count; return 0; } |