Whamcloud - gitweb
LU-80 lov: large stripe count support
authorAlexander Boyko <alexander_boyko@xyratex.com>
Fri, 30 Dec 2011 06:24:10 +0000 (14:24 +0800)
committerOleg Drokin <green@whamcloud.com>
Fri, 6 Jan 2012 03:16:16 +0000 (22:16 -0500)
Currently a file can be stripped across OSTs up to a limit of
160 stripes. This patch expands that limit to 2000 and it is
possible to go even to larger stripe counts.

Signed-off-by: Alexander Boyko <alexander_boyko@xyratex.com>
Change-Id: I42e1aad35dd056faac23a0d5b025e0a23fc4ec2f
Reviewed-on: http://review.whamcloud.com/1111
Reviewed-by: Yu Jian <yujian@whamcloud.com>
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: James Simmons <uja.ornl@gmail.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
13 files changed:
lustre/include/dt_object.h
lustre/include/lustre/lustre_idl.h
lustre/include/lustre_net.h
lustre/include/obd.h
lustre/include/obd_lov.h
lustre/lov/lov_internal.h
lustre/lov/lov_pack.c
lustre/lov/lov_qos.c
lustre/lov/lov_request.c
lustre/mdd/mdd_lov.c
lustre/mds/mds_log.c
lustre/mds/mds_lov.c
lustre/osd-ldiskfs/osd_handler.c

index 39fde4b..db232da 100644 (file)
@@ -81,6 +81,7 @@ struct dt_device_param {
         unsigned           ddp_max_nlink;
         unsigned           ddp_block_shift;
         mntopt_t           ddp_mntopts;
         unsigned           ddp_max_nlink;
         unsigned           ddp_block_shift;
         mntopt_t           ddp_mntopts;
+        unsigned           ddp_max_ea_size;
 };
 
 /**
 };
 
 /**
index 732846c..f030e2b 100644 (file)
@@ -1141,7 +1141,8 @@ extern void lustre_swab_ptlrpc_body(struct ptlrpc_body *pb);
                                 OBD_CONNECT_RMT_CLIENT_FORCE | OBD_CONNECT_VBR | \
                                 OBD_CONNECT_MDS | OBD_CONNECT_SKIP_ORPHAN | \
                                 OBD_CONNECT_GRANT_SHRINK | OBD_CONNECT_FULL20 | \
                                 OBD_CONNECT_RMT_CLIENT_FORCE | OBD_CONNECT_VBR | \
                                 OBD_CONNECT_MDS | OBD_CONNECT_SKIP_ORPHAN | \
                                 OBD_CONNECT_GRANT_SHRINK | OBD_CONNECT_FULL20 | \
-                                OBD_CONNECT_64BITHASH | OBD_CONNECT_MAXBYTES)
+                                OBD_CONNECT_64BITHASH | OBD_CONNECT_MAXBYTES | \
+                                OBD_CONNECT_MAX_EASIZE)
 #define ECHO_CONNECT_SUPPORTED (0)
 #define MGS_CONNECT_SUPPORTED  (OBD_CONNECT_VERSION | OBD_CONNECT_AT | \
                                 OBD_CONNECT_FULL20 | OBD_CONNECT_IMP_RECOV)
 #define ECHO_CONNECT_SUPPORTED (0)
 #define MGS_CONNECT_SUPPORTED  (OBD_CONNECT_VERSION | OBD_CONNECT_AT | \
                                 OBD_CONNECT_FULL20 | OBD_CONNECT_IMP_RECOV)
@@ -2130,7 +2131,17 @@ enum seq_op {
 
 #define LOV_MIN_STRIPE_BITS 16   /* maximum PAGE_SIZE (ia64), power of 2 */
 #define LOV_MIN_STRIPE_SIZE (1<<LOV_MIN_STRIPE_BITS)
 
 #define LOV_MIN_STRIPE_BITS 16   /* maximum PAGE_SIZE (ia64), power of 2 */
 #define LOV_MIN_STRIPE_SIZE (1<<LOV_MIN_STRIPE_BITS)
-#define LOV_MAX_STRIPE_COUNT  160   /* until bug 4424 is fixed */
+#define LOV_MAX_STRIPE_COUNT_OLD 160
+/* This calculation is crafted so that input of 4096 will result in 160
+ * which in turn is equal to old maximal stripe count.
+ * XXX: In fact this is too simpified for now, what it also need is to get
+ * ea_type argument to clearly know how much space each stripe consumes.
+ *
+ * The limit of 12 pages is somewhat arbitrary, but is a reasonably large
+ * allocation that is sufficient for the current generation of systems.
+ *
+ * (max buffer size - lov+rpc header) / sizeof(struct lov_ost_data_v1) */
+#define LOV_MAX_STRIPE_COUNT 2000  /* ((12 * 4096 - 256) / 24) */
 #define LOV_V1_INSANE_STRIPE_COUNT 65532 /* maximum stripe count bz13933 */
 
 #define LOV_MAX_UUID_BUFFER_SIZE  8192
 #define LOV_V1_INSANE_STRIPE_COUNT 65532 /* maximum stripe count bz13933 */
 
 #define LOV_MAX_UUID_BUFFER_SIZE  8192
index 54bc06b..c065b86 100644 (file)
 #define MDT_MAX_THREADS 512UL
 #endif
 #define MDS_NBUFS       (64 * cfs_num_online_cpus())
 #define MDT_MAX_THREADS 512UL
 #endif
 #define MDS_NBUFS       (64 * cfs_num_online_cpus())
-#define MDS_BUFSIZE     (8 * 1024)
 /**
  * Assume file name length = FNAME_MAX = 256 (true for ext3).
  *        path name length = PATH_MAX = 4096
 /**
  * Assume file name length = FNAME_MAX = 256 (true for ext3).
  *        path name length = PATH_MAX = 4096
- *        LOV MD size max  = EA_MAX = 4000
+ *        LOV MD size max  = EA_MAX = 48000 (2000 stripes)
  * symlink:  FNAME_MAX + PATH_MAX  <- largest
  * link:     FNAME_MAX + PATH_MAX  (mds_rec_link < mds_rec_create)
  * rename:   FNAME_MAX + FNAME_MAX
  * symlink:  FNAME_MAX + PATH_MAX  <- largest
  * link:     FNAME_MAX + PATH_MAX  (mds_rec_link < mds_rec_create)
  * rename:   FNAME_MAX + FNAME_MAX
  * Realistic size is about 512 bytes (20 character name + 128 char symlink),
  * except in the open case where there are a large number of OSTs in a LOV.
  */
  * Realistic size is about 512 bytes (20 character name + 128 char symlink),
  * except in the open case where there are a large number of OSTs in a LOV.
  */
-#define MDS_MAXREQSIZE  (5 * 1024)
-#define MDS_MAXREPSIZE  max(9 * 1024, 362 + LOV_MAX_STRIPE_COUNT * 56)
+#define MDS_MAXREPSIZE  max(10 * 1024, 362 + LOV_MAX_STRIPE_COUNT * 56)
+#define MDS_MAXREQSIZE  MDS_MAXREPSIZE
+
+/** MDS_BUFSIZE = max_reqsize + max sptlrpc payload size */
+#define MDS_BUFSIZE     (MDS_MAXREQSIZE + 1024)
 
 /** FLD_MAXREQSIZE == lustre_msg + __u32 padding + ptlrpc_body + opc */
 #define FLD_MAXREQSIZE  (160)
 
 /** FLD_MAXREQSIZE == lustre_msg + __u32 padding + ptlrpc_body + opc */
 #define FLD_MAXREQSIZE  (160)
index c6e27ea..e670dba 100644 (file)
@@ -230,6 +230,10 @@ struct brw_page {
 
 struct ost_server_data;
 
 
 struct ost_server_data;
 
+struct osd_properties {
+        size_t osd_max_ea_size;
+};
+
 #define OBT_MAGIC       0xBDDECEAE
 /* hold common fields for "target" device */
 struct obd_device_target {
 #define OBT_MAGIC       0xBDDECEAE
 /* hold common fields for "target" device */
 struct obd_device_target {
@@ -246,6 +250,7 @@ struct obd_device_target {
         cfs_rw_semaphore_t        obt_rwsem;
         struct vfsmount          *obt_vfsmnt;
         struct file              *obt_health_check_filp;
         cfs_rw_semaphore_t        obt_rwsem;
         struct vfsmount          *obt_vfsmnt;
         struct file              *obt_health_check_filp;
+        struct osd_properties    obt_osd_properties;
 };
 
 /* llog contexts */
 };
 
 /* llog contexts */
index 8ffbff5..35b322f 100644 (file)
@@ -42,7 +42,7 @@ static inline int lov_stripe_md_size(int stripes)
         return sizeof(struct lov_stripe_md) + stripes*sizeof(struct lov_oinfo*);
 }
 
         return sizeof(struct lov_stripe_md) + stripes*sizeof(struct lov_oinfo*);
 }
 
-static inline int lov_mds_md_size(int stripes, int lmm_magic)
+static inline __u32 lov_mds_md_size(int stripes, __u32 lmm_magic)
 {
         if (lmm_magic == LOV_MAGIC_V3)
                 return sizeof(struct lov_mds_md_v3) +
 {
         if (lmm_magic == LOV_MAGIC_V3)
                 return sizeof(struct lov_mds_md_v3) +
@@ -52,6 +52,36 @@ static inline int lov_mds_md_size(int stripes, int lmm_magic)
                         stripes * sizeof(struct lov_ost_data_v1);
 }
 
                         stripes * sizeof(struct lov_ost_data_v1);
 }
 
+struct lov_version_size {
+        __u32   lvs_magic;
+        size_t  lvs_lmm_size;
+        size_t  lvs_lod_size;
+};
+
+static inline __u32 lov_mds_md_stripecnt(int ea_size, __u32 lmm_magic)
+{
+        static const struct lov_version_size lmm_ver_size[] = {
+                        { .lvs_magic = LOV_MAGIC_V3,
+                          .lvs_lmm_size = sizeof(struct lov_mds_md_v3),
+                          .lvs_lod_size = sizeof(struct lov_ost_data_v1) },
+                        { .lvs_magic = LOV_MAGIC_V1,
+                          .lvs_lmm_size = sizeof(struct lov_mds_md_v1),
+                          .lvs_lod_size = sizeof(struct lov_ost_data_v1)} };
+        int i;
+
+        for (i = 0; i < ARRAY_SIZE(lmm_ver_size); i++) {
+                if (lmm_magic == lmm_ver_size[i].lvs_magic) {
+                        if (ea_size <= lmm_ver_size[i].lvs_lmm_size)
+                                return 0;
+                        return (ea_size - lmm_ver_size[i].lvs_lmm_size) /
+                                lmm_ver_size[i].lvs_lod_size;
+                }
+        }
+
+        /* Invalid LOV magic, so no stripes could fit */
+        return 0;
+}
+
 #define IOC_LOV_TYPE                   'g'
 #define IOC_LOV_MIN_NR                 50
 #define IOC_LOV_SET_OSC_ACTIVE         _IOWR('g', 50, long)
 #define IOC_LOV_TYPE                   'g'
 #define IOC_LOV_MIN_NR                 50
 #define IOC_LOV_SET_OSC_ACTIVE         _IOWR('g', 50, long)
index 28ddbd2..8d3fd4d 100644 (file)
@@ -264,7 +264,7 @@ void lov_fix_desc_stripe_size(__u64 *val);
 void lov_fix_desc_stripe_count(__u32 *val);
 void lov_fix_desc_pattern(__u32 *val);
 void lov_fix_desc_qos_maxage(__u32 *val);
 void lov_fix_desc_stripe_count(__u32 *val);
 void lov_fix_desc_pattern(__u32 *val);
 void lov_fix_desc_qos_maxage(__u32 *val);
-int lov_get_stripecnt(struct lov_obd *lov, __u32 stripe_count);
+__u32 lov_get_stripecnt(struct lov_obd *lov, __u32 magic, __u32 stripe_count);
 int lov_connect_obd(struct obd_device *obd, __u32 index, int activate,
                     struct obd_connect_data *data);
 int lov_setup(struct obd_device *obd, struct lustre_cfg *lcfg);
 int lov_connect_obd(struct obd_device *obd, __u32 index, int activate,
                     struct obd_connect_data *data);
 int lov_setup(struct obd_device *obd, struct lustre_cfg *lcfg);
index 32cc2ad..a3b94ff 100644 (file)
@@ -148,24 +148,7 @@ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
 
         if (lsm) {
                 lmm_magic = lsm->lsm_magic;
 
         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 {
         } 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
                 if (lmmp && *lmmp)
                         lmm_magic = le32_to_cpu((*lmmp)->lmm_magic);
                 else
@@ -181,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);
 
         /* XXX LOV STACKING call into osc for sizes */
         lmm_size = lov_mds_md_size(stripe_count, lmm_magic);
 
@@ -245,19 +249,26 @@ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp,
 }
 
 /* Find the max stripecount we should use */
 }
 
 /* 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;
         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;
 }
 
         return stripe_count;
 }
@@ -349,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 {
                         RETURN(rc);
                 magic = le32_to_cpu(lmm->lmm_magic);
         } else {
-                stripe_count = lov_get_stripecnt(lov, 0);
                 magic = LOV_MAGIC;
                 magic = LOV_MAGIC;
+                stripe_count = lov_get_stripecnt(lov, magic, 0);
         }
 
         /* If we aren't passed an lsmp struct, we just want the size */
         }
 
         /* If we aren't passed an lsmp struct, we just want the size */
@@ -450,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);
         }
                        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 -
 
         if (max_lmm_size) {
                 int max_stripes = (max_lmm_size -
index f454a59..d114aa3 100644 (file)
@@ -1005,7 +1005,7 @@ int qos_prep_create(struct obd_export *exp, struct lov_request_set *set)
         LASSERT(src_oa->o_valid & OBD_MD_FLGROUP);
 
         if (set->set_oi->oi_md == NULL) {
         LASSERT(src_oa->o_valid & OBD_MD_FLGROUP);
 
         if (set->set_oi->oi_md == NULL) {
-                int stripes_def = lov_get_stripecnt(lov, 0);
+                __u32 stripes_def = lov_get_stripecnt(lov, LOV_MAGIC, 0);
 
                 /* If the MDS file was truncated up to some size, stripe over
                  * enough OSTs to allow the file to be created at that size.
 
                 /* If the MDS file was truncated up to some size, stripe over
                  * enough OSTs to allow the file to be created at that size.
@@ -1029,8 +1029,8 @@ int qos_prep_create(struct obd_export *exp, struct lov_request_set *set)
                         if (stripes < stripes_def)
                                 stripes = stripes_def;
                 } else {
                         if (stripes < stripes_def)
                                 stripes = stripes_def;
                 } else {
-                         flag = LOV_USES_DEFAULT_STRIPE;
-                         stripes = stripes_def;
+                        flag = LOV_USES_DEFAULT_STRIPE;
+                        stripes = stripes_def;
                 }
 
                 rc = lov_alloc_memmd(&set->set_oi->oi_md, stripes,
                 }
 
                 rc = lov_alloc_memmd(&set->set_oi->oi_md, stripes,
index 3e29f43..d8c1fea 100644 (file)
@@ -1495,8 +1495,8 @@ int lov_fini_statfs(struct obd_device *obd, struct obd_statfs *osfs,int success)
         ENTRY;
 
         if (success) {
         ENTRY;
 
         if (success) {
-                __u32 expected_stripes = lov_get_stripecnt(&obd->u.lov, 0);
-
+                __u32 expected_stripes = lov_get_stripecnt(&obd->u.lov,
+                                                           LOV_MAGIC, 0);
                 if (osfs->os_files != LOV_U64_MAX)
                         do_div(osfs->os_files, expected_stripes);
                 if (osfs->os_ffree != LOV_U64_MAX)
                 if (osfs->os_files != LOV_U64_MAX)
                         do_div(osfs->os_files, expected_stripes);
                 if (osfs->os_ffree != LOV_U64_MAX)
index 46d1580..69df68e 100644 (file)
@@ -152,6 +152,9 @@ int mdd_init_obd(const struct lu_env *env, struct mdd_device *mdd,
         obd->obd_recovering = 1;
         cfs_spin_unlock(&obd->obd_dev_lock);
         obd->u.mds.mds_id = mds_id;
         obd->obd_recovering = 1;
         cfs_spin_unlock(&obd->obd_dev_lock);
         obd->u.mds.mds_id = mds_id;
+        obd->u.obt.obt_osd_properties.osd_max_ea_size =
+                                               mdd->mdd_dt_conf.ddp_max_ea_size;
+
         rc = class_setup(obd, lcfg);
         if (rc)
                 GOTO(class_detach, rc);
         rc = class_setup(obd, lcfg);
         if (rc)
                 GOTO(class_detach, rc);
@@ -163,6 +166,7 @@ int mdd_init_obd(const struct lu_env *env, struct mdd_device *mdd,
         obd->obd_upcall.onu_upcall = mdd_notify;
         obd->obd_upcall.onu_owner = mdd;
         mdd->mdd_obd_dev = obd;
         obd->obd_upcall.onu_upcall = mdd_notify;
         obd->obd_upcall.onu_owner = mdd;
         mdd->mdd_obd_dev = obd;
+
         EXIT;
 class_detach:
         if (rc)
         EXIT;
 class_detach:
         if (rc)
index 91ea64c..f256053 100644 (file)
@@ -297,6 +297,9 @@ static int mds_llog_add_unlink(struct obd_device *obd,
         struct llog_ctxt *ctxt;
         int rc;
 
         struct llog_ctxt *ctxt;
         int rc;
 
+        if (cookies < lsm->lsm_stripe_count)
+                RETURN(rc = -EFBIG);
+
         /* first prepare unlink log record */
         OBD_ALLOC_PTR(lur);
         if (!lur)
         /* first prepare unlink log record */
         OBD_ALLOC_PTR(lur);
         if (!lur)
index ce9ce98..df26eda 100644 (file)
@@ -201,12 +201,14 @@ static int mds_lov_update_max_ost(struct mds_obd *mds, obd_id index)
         /* workaround - New target not in objids file; increase mdsize */
         /* ld_tgt_count is used as the max index everywhere, despite its name. */
         if (data[off] == 0) {
         /* workaround - New target not in objids file; increase mdsize */
         /* ld_tgt_count is used as the max index everywhere, despite its name. */
         if (data[off] == 0) {
+                __u32 max_easize;
                 __u32 stripes;
 
                 __u32 stripes;
 
+                max_easize = mds->mds_obt.obt_osd_properties.osd_max_ea_size;
                 data[off] = 1;
                 mds->mds_lov_objid_count++;
                 data[off] = 1;
                 mds->mds_lov_objid_count++;
-                stripes = min_t(__u32, LOV_MAX_STRIPE_COUNT,
-                                mds->mds_lov_objid_count);
+                stripes = min(lov_mds_md_stripecnt(max_easize, LOV_MAGIC_V3),
+                              mds->mds_lov_objid_count);
 
                 mds->mds_max_mdsize = lov_mds_md_size(stripes, LOV_MAGIC_V3);
                 mds->mds_max_cookiesize = stripes * sizeof(struct llog_cookie);
 
                 mds->mds_max_mdsize = lov_mds_md_size(stripes, LOV_MAGIC_V3);
                 mds->mds_max_cookiesize = stripes * sizeof(struct llog_cookie);
@@ -368,8 +370,8 @@ EXPORT_SYMBOL(mds_lov_update_objids);
 static int mds_lov_update_from_read(struct mds_obd *mds, obd_id *data,
                                     __u32 count)
 {
 static int mds_lov_update_from_read(struct mds_obd *mds, obd_id *data,
                                     __u32 count)
 {
-        __u32 i;
-        __u32 stripes;
+        __u32 max_easize = mds->mds_obt.obt_osd_properties.osd_max_ea_size;
+        __u32 i, stripes;
 
         for (i = 0; i < count; i++) {
                 if (data[i] == 0)
 
         for (i = 0; i < count; i++) {
                 if (data[i] == 0)
@@ -378,7 +380,7 @@ static int mds_lov_update_from_read(struct mds_obd *mds, obd_id *data,
                 mds->mds_lov_objid_count++;
         }
 
                 mds->mds_lov_objid_count++;
         }
 
-        stripes = min_t(__u32, LOV_MAX_STRIPE_COUNT,
+        stripes = min(lov_mds_md_stripecnt(max_easize, LOV_MAGIC_V3),
                          mds->mds_lov_objid_count);
 
         mds->mds_max_mdsize = lov_mds_md_size(stripes, LOV_MAGIC_V3);
                          mds->mds_lov_objid_count);
 
         mds->mds_max_mdsize = lov_mds_md_size(stripes, LOV_MAGIC_V3);
@@ -717,12 +719,14 @@ int mds_lov_connect(struct obd_device *obd, char * lov_name)
                                   OBD_CONNECT_OSS_CAPA  | OBD_CONNECT_FULL20  |
                                   OBD_CONNECT_CHANGE_QS | OBD_CONNECT_AT      |
                                   OBD_CONNECT_MDS | OBD_CONNECT_SKIP_ORPHAN   |
                                   OBD_CONNECT_OSS_CAPA  | OBD_CONNECT_FULL20  |
                                   OBD_CONNECT_CHANGE_QS | OBD_CONNECT_AT      |
                                   OBD_CONNECT_MDS | OBD_CONNECT_SKIP_ORPHAN   |
-                                  OBD_CONNECT_SOM;
+                                  OBD_CONNECT_SOM | OBD_CONNECT_MAX_EASIZE;
 #ifdef HAVE_LRU_RESIZE_SUPPORT
         data->ocd_connect_flags |= OBD_CONNECT_LRU_RESIZE;
 #endif
         data->ocd_version = LUSTRE_VERSION_CODE;
         data->ocd_group = mdt_to_obd_objseq(mds->mds_id);
 #ifdef HAVE_LRU_RESIZE_SUPPORT
         data->ocd_connect_flags |= OBD_CONNECT_LRU_RESIZE;
 #endif
         data->ocd_version = LUSTRE_VERSION_CODE;
         data->ocd_group = mdt_to_obd_objseq(mds->mds_id);
+        data->ocd_max_easize = mds->mds_obt.obt_osd_properties.osd_max_ea_size;
+
         /* send max bytes per rpc */
         data->ocd_brw_size = PTLRPC_MAX_BRW_PAGES << CFS_PAGE_SHIFT;
         /* send the list of supported checksum types */
         /* send max bytes per rpc */
         data->ocd_brw_size = PTLRPC_MAX_BRW_PAGES << CFS_PAGE_SHIFT;
         /* send the list of supported checksum types */
index c461662..bffa028 100644 (file)
@@ -939,6 +939,14 @@ static void osd_conf_get(const struct lu_env *env,
                 param->ddp_mntopts |= MNTOPT_USERXATTR;
         if (test_opt(sb, POSIX_ACL))
                 param->ddp_mntopts |= MNTOPT_ACL;
                 param->ddp_mntopts |= MNTOPT_USERXATTR;
         if (test_opt(sb, POSIX_ACL))
                 param->ddp_mntopts |= MNTOPT_ACL;
+
+#if defined(LDISKFS_FEATURE_INCOMPAT_EA_INODE)
+        if (LDISKFS_HAS_INCOMPAT_FEATURE(sb, LDISKFS_FEATURE_INCOMPAT_EA_INODE))
+                param->ddp_max_ea_size = LDISKFS_XATTR_MAX_LARGE_EA_SIZE;
+        else
+#endif
+                param->ddp_max_ea_size = sb->s_blocksize;
+
 }
 
 /**
 }
 
 /**