Whamcloud - gitweb
LU-11376 lmv: new foreign LMV format
[fs/lustre-release.git] / lustre / lmv / lmv_obd.c
index 2df8aa3..be2691e 100644 (file)
@@ -1176,15 +1176,23 @@ static int lmv_placement_policy(struct obd_device *obd,
         * 1. See if the stripe offset is specified by lum.
         * 2. Then check if there is default stripe offset.
         * 3. Finally choose MDS by name hash if the parent
-        *    is striped directory. (see lmv_locate_tgt()). */
+        *    is striped directory. (see lmv_locate_tgt()).
+        *
+        * presently explicit MDT location is not supported
+        * for foreign dirs (as it can't be embedded into free
+        * format LMV, like with lum_stripe_offset), so we only
+        * rely on default stripe offset or then name hashing.
+        */
        if (op_data->op_cli_flags & CLI_SET_MEA && lum != NULL &&
+           le32_to_cpu(lum->lum_magic != LMV_MAGIC_FOREIGN) &&
            le32_to_cpu(lum->lum_stripe_offset) != (__u32)-1) {
                *mds = le32_to_cpu(lum->lum_stripe_offset);
        } else if (op_data->op_default_stripe_offset != (__u32)-1) {
                *mds = op_data->op_default_stripe_offset;
                op_data->op_mds = *mds;
                /* Correct the stripe offset in lum */
-               if (lum != NULL)
+               if (lum != NULL &&
+                   le32_to_cpu(lum->lum_magic != LMV_MAGIC_FOREIGN))
                        lum->lum_stripe_offset = cpu_to_le32(*mds);
        } else {
                *mds = op_data->op_mds;
@@ -1633,6 +1641,10 @@ lmv_locate_tgt(struct lmv_obd *lmv, struct md_op_data *op_data,
        struct lmv_oinfo *oinfo;
        struct lmv_tgt_desc *tgt;
 
+       /* foreign dir is not striped dir */
+       if (lsm && lsm->lsm_md_magic == LMV_MAGIC_FOREIGN)
+               return ERR_PTR(-ENODATA);
+
        /* During creating VOLATILE file, it should honor the mdt
         * index if the file under striped dir is being restored, see
         * ct_restore(). */
@@ -2696,6 +2708,10 @@ int lmv_read_page(struct obd_export *exp, struct md_op_data *op_data,
        ENTRY;
 
        if (unlikely(lsm != NULL)) {
+               /* foreign dir is not striped dir */
+               if (lsm->lsm_md_magic == LMV_MAGIC_FOREIGN)
+                       return -ENODATA;
+
                rc = lmv_striped_read_page(exp, op_data, cb_op, offset, ppage);
                RETURN(rc);
        }
@@ -3011,6 +3027,16 @@ static int lmv_unpackmd(struct obd_export *exp, struct lmv_stripe_md **lsmp,
        /* Free memmd */
        if (lsm != NULL && lmm == NULL) {
                int i;
+               struct lmv_foreign_md *lfm = (struct lmv_foreign_md *)lsm;
+
+               if (lfm->lfm_magic == LMV_MAGIC_FOREIGN) {
+                       size_t lfm_size;
+
+                       lfm_size = lfm->lfm_length + offsetof(typeof(*lfm),
+                                                             lfm_value[0]);
+                       OBD_FREE_LARGE(lfm, lfm_size);
+                       RETURN(0);
+               }
 
                for (i = 0; i < lsm->lsm_md_stripe_count; i++)
                        iput(lsm->lsm_md_oinfo[i].lmo_root);
@@ -3020,6 +3046,25 @@ static int lmv_unpackmd(struct obd_export *exp, struct lmv_stripe_md **lsmp,
                RETURN(0);
        }
 
+       /* foreign lmv case */
+       if (le32_to_cpu(lmm->lmv_magic) == LMV_MAGIC_FOREIGN) {
+               struct lmv_foreign_md *lfm = (struct lmv_foreign_md *)lsm;
+
+               if (lfm == NULL) {
+                       OBD_ALLOC_LARGE(lfm, lmm_size);
+                       if (lfm == NULL)
+                               RETURN(-ENOMEM);
+                       *lsmp = (struct lmv_stripe_md *)lfm;
+               }
+               lfm->lfm_magic = le32_to_cpu(lmm->lmv_foreign_md.lfm_magic);
+               lfm->lfm_length = le32_to_cpu(lmm->lmv_foreign_md.lfm_length);
+               lfm->lfm_type = le32_to_cpu(lmm->lmv_foreign_md.lfm_type);
+               lfm->lfm_flags = le32_to_cpu(lmm->lmv_foreign_md.lfm_flags);
+               memcpy(&lfm->lfm_value, &lmm->lmv_foreign_md.lfm_value,
+                      lfm->lfm_length);
+               RETURN(lmm_size);
+       }
+
        if (le32_to_cpu(lmm->lmv_magic) == LMV_MAGIC_STRIPE)
                RETURN(-EPERM);
 
@@ -3344,6 +3389,10 @@ static int lmv_merge_attr(struct obd_export *exp,
        int rc;
        int i;
 
+       /* foreign dir is not striped dir */
+       if (lsm->lsm_md_magic == LMV_MAGIC_FOREIGN)
+               return 0;
+
        rc = lmv_revalidate_slaves(exp, lsm, cb_blocking, 0);
        if (rc < 0)
                return rc;