Whamcloud - gitweb
LU-80 lov: large stripe count support
[fs/lustre-release.git] / lustre / lov / lov_pack.c
index fea8cce..a3b94ff 100644 (file)
  * GPL HEADER END
  */
 /*
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  */
 /*
+ * Copyright (c) 2011 Whamcloud, Inc.
+ */
+/*
  * This file is part of Lustre, http://www.lustre.org/
  * Lustre is a trademark of Sun Microsystems, Inc.
  *
@@ -145,24 +148,7 @@ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
 
         if (lsm) {
                 lmm_magic = lsm->lsm_magic;
-
-                /* If we are just sizing the EA, limit the stripe count
-                 * to the actual number of OSTs in this filesystem. */
-                if (!lmmp) {
-                        stripe_count = lov_get_stripecnt(lov,
-                                                         lsm->lsm_stripe_count);
-                        lsm->lsm_stripe_count = stripe_count;
-                } else {
-                        stripe_count = lsm->lsm_stripe_count;
-                }
         } else {
-                /* No needs to allocated more than LOV_MAX_STRIPE_COUNT.
-                 * Anyway, this is pretty inaccurate since ld_tgt_count now
-                 * represents max index and we should rely on the actual number
-                 * of OSTs instead */
-                stripe_count = min((__u32)LOV_MAX_STRIPE_COUNT,
-                                   lov->desc.ld_tgt_count);
-
                 if (lmmp && *lmmp)
                         lmm_magic = le32_to_cpu((*lmmp)->lmm_magic);
                 else
@@ -178,6 +164,27 @@ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
 
         }
 
+        if (lsm) {
+                /* If we are just sizing the EA, limit the stripe count
+                 * to the actual number of OSTs in this filesystem. */
+                if (!lmmp) {
+                        stripe_count = lov_get_stripecnt(lov, lmm_magic,
+                                                         lsm->lsm_stripe_count);
+                        lsm->lsm_stripe_count = stripe_count;
+                } else {
+                        stripe_count = lsm->lsm_stripe_count;
+                }
+        } else {
+                /* No need to allocate more than maximum supported stripes.
+                 * Anyway, this is pretty inaccurate since ld_tgt_count now
+                 * represents max index and we should rely on the actual number
+                 * of OSTs instead */
+                stripe_count = lov_mds_md_stripecnt(lov->lov_ocd.ocd_max_easize,
+                                                    lmm_magic);
+                if (stripe_count > lov->desc.ld_tgt_count)
+                        stripe_count = lov->desc.ld_tgt_count;
+        }
+
         /* XXX LOV STACKING call into osc for sizes */
         lmm_size = lov_mds_md_size(stripe_count, lmm_magic);
 
@@ -187,13 +194,13 @@ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
         if (*lmmp && !lsm) {
                 stripe_count = le32_to_cpu((*lmmp)->lmm_stripe_count);
                 lmm_size = lov_mds_md_size(stripe_count, lmm_magic);
-                OBD_FREE(*lmmp, lmm_size);
+                OBD_FREE_LARGE(*lmmp, lmm_size);
                 *lmmp = NULL;
                 RETURN(0);
         }
 
         if (!*lmmp) {
-                OBD_ALLOC(*lmmp, lmm_size);
+                OBD_ALLOC_LARGE(*lmmp, lmm_size);
                 if (!*lmmp)
                         RETURN(-ENOMEM);
         }
@@ -242,19 +249,26 @@ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
 }
 
 /* Find the max stripecount we should use */
-int lov_get_stripecnt(struct lov_obd *lov, __u32 stripe_count)
+__u32 lov_get_stripecnt(struct lov_obd *lov, __u32 magic, __u32 stripe_count)
 {
+        __u32 max_stripes = LOV_MAX_STRIPE_COUNT_OLD;
+
         if (!stripe_count)
                 stripe_count = lov->desc.ld_default_stripe_count;
         if (stripe_count > lov->desc.ld_active_tgt_count)
                 stripe_count = lov->desc.ld_active_tgt_count;
         if (!stripe_count)
                 stripe_count = 1;
-        /* for now, we limit the stripe count directly, when bug 4424 is
-         * fixed this needs to be somewhat dynamic based on whether ext3
-         * can handle larger EA sizes. */
-        if (stripe_count > LOV_MAX_STRIPE_COUNT)
-                stripe_count = LOV_MAX_STRIPE_COUNT;
+
+        /* stripe count is based on whether ldiskfs can handle
+         * larger EA sizes */
+        if (lov->lov_ocd.ocd_connect_flags & OBD_CONNECT_MAX_EASIZE &&
+            lov->lov_ocd.ocd_max_easize)
+                max_stripes = lov_mds_md_stripecnt(lov->lov_ocd.ocd_max_easize,
+                                                   magic);
+
+        if (stripe_count > max_stripes)
+                stripe_count = max_stripes;
 
         return stripe_count;
 }
@@ -271,7 +285,7 @@ static int lov_verify_lmm(void *lmm, int lmm_bytes, int *stripe_count)
                 CERROR("bad disk LOV MAGIC: 0x%08X; dumping LMM (size=%d):\n",
                        le32_to_cpu(*(__u32 *)lmm), lmm_bytes);
                 sz = lmm_bytes * 2 + 1;
-                OBD_ALLOC(buffer, sz);
+                OBD_ALLOC_LARGE(buffer, sz);
                 if (buffer != NULL) {
                         int i;
 
@@ -279,7 +293,7 @@ static int lov_verify_lmm(void *lmm, int lmm_bytes, int *stripe_count)
                                 sprintf(buffer+2*i, "%.2X", ((char *)lmm)[i]);
                         buffer[sz] = '\0';
                         CERROR("%s\n", buffer);
-                        OBD_FREE(buffer, sz);
+                        OBD_FREE_LARGE(buffer, sz);
                 }
                 return -EINVAL;
         }
@@ -289,7 +303,7 @@ static int lov_verify_lmm(void *lmm, int lmm_bytes, int *stripe_count)
 }
 
 int lov_alloc_memmd(struct lov_stripe_md **lsmp, int stripe_count,
-                      int pattern, int magic)
+                    int pattern, int magic)
 {
         int i, lsm_size;
         ENTRY;
@@ -346,8 +360,8 @@ int lov_unpackmd(struct obd_export *exp,  struct lov_stripe_md **lsmp,
                         RETURN(rc);
                 magic = le32_to_cpu(lmm->lmm_magic);
         } else {
-                stripe_count = lov_get_stripecnt(lov, 0);
                 magic = LOV_MAGIC;
+                stripe_count = lov_get_stripecnt(lov, magic, 0);
         }
 
         /* If we aren't passed an lsmp struct, we just want the size */
@@ -447,7 +461,8 @@ static int __lov_setstripe(struct obd_export *exp, int max_lmm_size,
                        lumv1->lmm_stripe_offset, lov->desc.ld_tgt_count);
                 RETURN(-EINVAL);
         }
-        stripe_count = lov_get_stripecnt(lov, lumv1->lmm_stripe_count);
+        stripe_count = lov_get_stripecnt(lov, lmm_magic,
+                                         lumv1->lmm_stripe_count);
 
         if (max_lmm_size) {
                 int max_stripes = (max_lmm_size -