Whamcloud - gitweb
port llog fixes from b1_6 into HEAD
[fs/lustre-release.git] / lustre / lov / lov_ea.c
index 50f2e86..b417ae0 100755 (executable)
@@ -51,18 +51,18 @@ static int lsm_lmm_verify_common(struct lov_mds_md *lmm, int lmm_bytes,
                                  int stripe_count)
 {
 
-        if (stripe_count == 0) {
+        if (stripe_count == 0 || stripe_count > LOV_V1_INSANE_STRIPE_COUNT) {
                 CERROR("bad stripe count %d\n", stripe_count);
                 lov_dump_lmm_v1(D_WARNING, lmm);
                 return -EINVAL;
         }
-
+        
         if (lmm->lmm_object_id == 0) {
                 CERROR("zero object id\n");
                 lov_dump_lmm_v1(D_WARNING, lmm);
                 return -EINVAL;
         }
-
+        
         if (lmm->lmm_pattern != cpu_to_le32(LOV_PATTERN_RAID0)) {
                 CERROR("bad striping pattern\n");
                 lov_dump_lmm_v1(D_WARNING, lmm);
@@ -70,7 +70,9 @@ static int lsm_lmm_verify_common(struct lov_mds_md *lmm, int lmm_bytes,
         }
 
         if (lmm->lmm_stripe_size == 0 ||
-            (__u64)le32_to_cpu(lmm->lmm_stripe_size)*stripe_count > 0xffffffff){
+            (stripe_count != -1 &&
+             (__u64)le32_to_cpu(lmm->lmm_stripe_size)*stripe_count >
+             0xffffffff)) {
                 CERROR("bad stripe size %u\n",
                        le32_to_cpu(lmm->lmm_stripe_size));
                 lov_dump_lmm_v1(D_WARNING, lmm);
@@ -79,6 +81,49 @@ static int lsm_lmm_verify_common(struct lov_mds_md *lmm, int lmm_bytes,
         return 0;
 }
 
+struct lov_stripe_md *lsm_alloc_plain(int stripe_count, int *size)
+{
+        struct lov_stripe_md *lsm;
+        int i, oinfo_ptrs_size;
+        struct lov_oinfo *loi;
+
+        LASSERT(stripe_count > 0);
+
+        oinfo_ptrs_size = sizeof(struct lov_oinfo *) * stripe_count;
+        *size = sizeof(struct lov_stripe_md) + oinfo_ptrs_size;
+
+        OBD_ALLOC(lsm, *size);
+        if (!lsm)
+                return NULL;;
+
+        for (i = 0; i < stripe_count; i++) {
+                OBD_SLAB_ALLOC(loi, lov_oinfo_slab, CFS_ALLOC_IO, sizeof(*loi));
+                if (loi == NULL)
+                        goto err;
+                lsm->lsm_oinfo[i] = loi;
+        }
+        lsm->lsm_stripe_count = stripe_count;
+        return lsm;
+
+err:
+        while (--i >= 0)
+                OBD_SLAB_FREE(lsm->lsm_oinfo[i], lov_oinfo_slab, sizeof(*loi));
+        OBD_FREE(lsm, *size);
+        return NULL;
+}
+
+void lsm_free_plain(struct lov_stripe_md *lsm)
+{
+        int stripe_count = lsm->lsm_stripe_count;
+        int i;
+
+        for (i = 0; i < stripe_count; i++)
+                OBD_SLAB_FREE(lsm->lsm_oinfo[i], lov_oinfo_slab,
+                              sizeof(struct lov_oinfo));
+        OBD_FREE(lsm, sizeof(struct lov_stripe_md) +
+                 stripe_count * sizeof(struct lov_oinfo *));
+}
+
 static void lsm_unpackmd_common(struct lov_stripe_md *lsm,
                                 struct lov_mds_md *lmm)
 {
@@ -125,11 +170,6 @@ lsm_stripe_index_by_offset_plain(struct lov_stripe_md *lsm,
         return 0;
 }
 
-static void lsm_free_plain(struct lov_stripe_md *lsm)
-{
-        OBD_FREE(lsm, lov_stripe_md_size(lsm->lsm_stripe_count));
-}
-
 static int lsm_revalidate_plain(struct lov_stripe_md *lsm,
                                 struct obd_device *obd)
 {
@@ -171,8 +211,9 @@ int lsm_unpackmd_plain(struct lov_obd *lov, struct lov_stripe_md *lsm,
 
         lsm_unpackmd_common(lsm, lmm);
 
-        for (i = 0, loi = lsm->lsm_oinfo; i < lsm->lsm_stripe_count; i++) {
+        for (i = 0; i < lsm->lsm_stripe_count; i++) {
                 /* XXX LOV STACKING call down to osc_unpackmd() */
+                loi = lsm->lsm_oinfo[i];
                 loi->loi_id = le64_to_cpu(lmm->lmm_objects[i].l_object_id);
                 loi->loi_gr = le64_to_cpu(lmm->lmm_objects[i].l_object_gr);
                 loi->loi_ost_idx = le32_to_cpu(lmm->lmm_objects[i].l_ost_idx);
@@ -188,7 +229,6 @@ int lsm_unpackmd_plain(struct lov_obd *lov, struct lov_stripe_md *lsm,
                         lov_dump_lmm_v1(D_WARNING, lmm);
                         return -EINVAL;
                 }
-                loi++;
         }
 
         return 0;
@@ -271,7 +311,7 @@ static void lovea_free_array_info(struct lov_stripe_md *lsm)
 static void lsm_free_join(struct lov_stripe_md *lsm)
 {
         lovea_free_array_info(lsm);
-        OBD_FREE(lsm, lov_stripe_md_size(lsm->lsm_stripe_count));
+        lsm_free_plain(lsm);
 }
 
 static void
@@ -393,18 +433,17 @@ static int lovea_unpack_array(struct llog_handle *handle,
 
         /* unpack extent's lmm to lov_oinfo array */
         loi_index = lai->lai_ext_array[cursor].le_loi_idx;
-        loi = &lsm->lsm_oinfo[loi_index];
         CDEBUG(D_INFO, "lovea upackmd cursor %d, loi_index %d extent "
                         LPU64":"LPU64"\n", cursor, loi_index, med->med_start,
                         med->med_len);
 
-        for (i = 0; i < lmm->lmm_stripe_count; i ++) {
+        for (i = 0; i < le32_to_cpu(lmm->lmm_stripe_count); i ++, loi_index++) {
                 /* XXX LOV STACKING call down to osc_unpackmd() */
+                loi = lsm->lsm_oinfo[loi_index];
                 loi->loi_id = le64_to_cpu(lmm->lmm_objects[i].l_object_id);
                 loi->loi_gr = le64_to_cpu(lmm->lmm_objects[i].l_object_gr);
                 loi->loi_ost_idx = le32_to_cpu(lmm->lmm_objects[i].l_ost_idx);
                 loi->loi_ost_gen = le32_to_cpu(lmm->lmm_objects[i].l_ost_gen);
-                loi++;
         }
 
         RETURN(0);
@@ -431,7 +470,7 @@ static int lsm_revalidate_join(struct lov_stripe_md *lsm,
         LASSERT(ctxt);
 
         if (lsm->lsm_array && lsm->lsm_array->lai_ext_array)
-                RETURN(0);
+                GOTO(release_ctxt, rc = 0);
 
         CDEBUG(D_INFO, "get lsm logid: "LPU64":"LPU64"\n",
                lsm->lsm_array->lai_array_id.lgl_oid,
@@ -439,7 +478,7 @@ static int lsm_revalidate_join(struct lov_stripe_md *lsm,
         OBD_ALLOC(lsm->lsm_array->lai_ext_array,lsm->lsm_array->lai_ext_count *
                                                 sizeof (struct lov_extent));
         if (!lsm->lsm_array->lai_ext_array)
-                RETURN(-ENOMEM);
+                GOTO(release_ctxt, rc = -ENOMEM);        
 
         CDEBUG(D_INFO, "get lsm logid: "LPU64":"LPU64"\n",
                lsm->lsm_array->lai_array_id.lgl_oid,
@@ -460,6 +499,8 @@ static int lsm_revalidate_join(struct lov_stripe_md *lsm,
 out:
         if (rc)
                 lovea_free_array_info(lsm);
+release_ctxt:
+        llog_ctxt_put(ctxt);
         RETURN(rc);
 }
 
@@ -472,16 +513,15 @@ int lsm_destroy_join(struct lov_stripe_md *lsm, struct obdo *oa,
         ENTRY;
 
         LASSERT(md_exp != NULL);
+        /*for those orphan inode, we should keep array id*/
+        if (!(oa->o_valid & OBD_MD_FLCOOKIE))
+                RETURN(rc);
+
         ctxt = llog_get_context(md_exp->exp_obd, LLOG_LOVEA_REPL_CTXT);
         if (!ctxt)
-                GOTO(out, rc = -EINVAL);
+                RETURN(-EINVAL);
 
         LASSERT(lsm->lsm_array != NULL);
-        /*for those orphan inode, we should keep array id*/
-        if (!(oa->o_valid & OBD_MD_FLCOOKIE))
-                RETURN(0);
-
-        LASSERT(ctxt != NULL);
         rc = llog_create(ctxt, &llh, &lsm->lsm_array->lai_array_id,
                          NULL);
         if (rc)
@@ -493,6 +533,7 @@ int lsm_destroy_join(struct lov_stripe_md *lsm, struct obdo *oa,
         }
         llog_free_handle(llh);
 out:
+        llog_ctxt_put(ctxt);
         RETURN(rc);
 }