diff --git a/lustre/include/lustre/liblustreapi.h b/lustre/include/lustre/liblustreapi.h
index ee7307ed7de49e5a7557abb553e5511ade7848f0..74fe4b658ebacb61fe507b5bbb5c5044fa991f4c 100644
--- a/lustre/include/lustre/liblustreapi.h
+++ b/lustre/include/lustre/liblustreapi.h
@@ -67,11 +67,11 @@ enum llapi_message_level {
 extern void llapi_msg_set_level(int level);
 extern void llapi_err(int level, char *fmt, ...);
 extern void llapi_printf(int level, char *fmt, ...);
-extern int llapi_file_create(const char *name, unsigned long stripe_size,
+extern int llapi_file_create(const char *name, unsigned long long stripe_size,
                              int stripe_offset, int stripe_count,
                              int stripe_pattern);
 extern int llapi_file_open(const char *name, int flags, int mode,
-                           unsigned long stripe_size, int stripe_offset,
+                           unsigned long long stripe_size, int stripe_offset,
                            int stripe_count, int stripe_pattern);
 extern int llapi_file_get_stripe(const char *path, struct lov_user_md *lum);
 #define HAVE_LLAPI_FILE_LOOKUP
diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h
index 0cb1013d83056278f13be74c64c413b5a937b3e4..843b43e6d5800494380d2ab95059ee27b945da55 100644
--- a/lustre/include/lustre/lustre_idl.h
+++ b/lustre/include/lustre/lustre_idl.h
@@ -1011,7 +1011,8 @@ extern void lustre_swab_mds_rec_rename (struct mds_rec_rename *rn);
  *  LOV data structures
  */
 
-#define LOV_MIN_STRIPE_SIZE 65536   /* maximum PAGE_SIZE (ia64), power of 2 */
+#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_V1_INSANE_STRIPE_COUNT 65532 /* maximum stripe count bz13933 */
 
diff --git a/lustre/include/obd.h b/lustre/include/obd.h
index 6c911941698c4600645878e850b3b9d63ba8a886..15470a12af14226efb9a02725a22fddd4e3b130b 100644
--- a/lustre/include/obd.h
+++ b/lustre/include/obd.h
@@ -1143,9 +1143,9 @@ struct lsm_operations {
         int (*lsm_destroy)(struct lov_stripe_md *, struct obdo *oa,
                            struct obd_export *md_exp);
         void (*lsm_stripe_by_index)(struct lov_stripe_md *, int *, obd_off *,
-                                     unsigned long *);
+                                    obd_off *);
         void (*lsm_stripe_by_offset)(struct lov_stripe_md *, int *, obd_off *,
-                                     unsigned long *);
+                                     obd_off *);
         obd_off (*lsm_stripe_offset_by_index)(struct lov_stripe_md *, int);
         obd_off (*lsm_stripe_offset_by_offset)(struct lov_stripe_md *, obd_off);
         int (*lsm_stripe_index_by_offset)(struct lov_stripe_md *, obd_off);
diff --git a/lustre/lov/lov_ea.c b/lustre/lov/lov_ea.c
index f244f8080a2f4857abbc209e2a46d5e55c741298..84da9aad162d377ce15c479707ad99e12b64e4c7 100755
--- a/lustre/lov/lov_ea.c
+++ b/lustre/lov/lov_ea.c
@@ -85,9 +85,7 @@ static int lsm_lmm_verify_common(struct lov_mds_md *lmm, int lmm_bytes,
         }
 
         if (lmm->lmm_stripe_size == 0 ||
-            (stripe_count != -1 &&
-             (__u64)le32_to_cpu(lmm->lmm_stripe_size)*stripe_count >
-             0xffffffff)) {
+             (le32_to_cpu(lmm->lmm_stripe_size)&(LOV_MIN_STRIPE_SIZE-1)) != 0) {
                 CERROR("bad stripe size %u\n",
                        le32_to_cpu(lmm->lmm_stripe_size));
                 lov_dump_lmm_v1(D_WARNING, lmm);
@@ -150,18 +148,18 @@ static void lsm_unpackmd_common(struct lov_stripe_md *lsm,
 
 static void
 lsm_stripe_by_index_plain(struct lov_stripe_md *lsm, int *stripeno,
-                           obd_off *lov_off, unsigned long *swidth)
+                           obd_off *lov_off, obd_off *swidth)
 {
         if (swidth)
-                *swidth = (ulong)lsm->lsm_stripe_size * lsm->lsm_stripe_count;
+                *swidth = (obd_off)lsm->lsm_stripe_size * lsm->lsm_stripe_count;
 }
 
 static void
 lsm_stripe_by_offset_plain(struct lov_stripe_md *lsm, int *stripeno,
-                           obd_off *lov_off, unsigned long *swidth)
+                           obd_off *lov_off, obd_off *swidth)
 {
         if (swidth)
-                *swidth = (ulong)lsm->lsm_stripe_size * lsm->lsm_stripe_count;
+                *swidth = (obd_off)lsm->lsm_stripe_size * lsm->lsm_stripe_count;
 }
 
 static obd_off
@@ -331,7 +329,7 @@ static void lsm_free_join(struct lov_stripe_md *lsm)
 
 static void
 lsm_stripe_by_index_join(struct lov_stripe_md *lsm, int *stripeno,
-                           obd_off *lov_off, unsigned long *swidth)
+                           obd_off *lov_off, obd_off *swidth)
 {
         struct lov_extent *le;
 
@@ -344,7 +342,7 @@ lsm_stripe_by_index_join(struct lov_stripe_md *lsm, int *stripeno,
         *stripeno -= le->le_loi_idx;
 
         if (swidth)
-                *swidth = (ulong)lsm->lsm_stripe_size * le->le_stripe_count;
+                *swidth = (obd_off)lsm->lsm_stripe_size * le->le_stripe_count;
 
         if (lov_off) {
                 struct lov_extent *lov_le = lovea_off2le(lsm, *lov_off);
@@ -361,7 +359,7 @@ lsm_stripe_by_index_join(struct lov_stripe_md *lsm, int *stripeno,
 
 static void
 lsm_stripe_by_offset_join(struct lov_stripe_md *lsm, int *stripeno,
-                           obd_off *lov_off, unsigned long *swidth)
+                           obd_off *lov_off, obd_off *swidth)
 {
         struct lov_extent *le;
 
@@ -377,7 +375,7 @@ lsm_stripe_by_offset_join(struct lov_stripe_md *lsm, int *stripeno,
                 *stripeno -= le->le_loi_idx;
 
         if (swidth)
-                *swidth = (ulong)lsm->lsm_stripe_size * le->le_stripe_count;
+                *swidth = (obd_off)lsm->lsm_stripe_size * le->le_stripe_count;
 }
 
 static obd_off
diff --git a/lustre/lov/lov_internal.h b/lustre/lov/lov_internal.h
index 54936b07266290fde0d9a50b2530a23095d80b62..79394c7c5e5766e37a0260d360282e607b831393 100644
--- a/lustre/lov/lov_internal.h
+++ b/lustre/lov/lov_internal.h
@@ -302,4 +302,34 @@ static inline void lprocfs_lov_init_vars(struct lprocfs_static_vars *lvars)
 }
 #endif
 
+#if BITS_PER_LONG == 64
+# define ll_do_div64(n,base) ({                                 \
+        uint64_t __base = (base);                               \
+        uint64_t __rem;                                         \
+        __rem = ((uint64_t)(n)) % __base;                       \
+        (n) = ((uint64_t)(n)) / __base;                         \
+        __rem;                                                  \
+  })
+#elif BITS_PER_LONG == 32
+# define ll_do_div64(n,base) ({                                 \
+        uint64_t __rem;                                         \
+        if ((sizeof(base) > 4) && (((base)&0xffffffff00000000ULL) != 0)) { \
+                int __remainder;                                \
+                LASSERTF(!((base) & (LOV_MIN_STRIPE_SIZE - 1)), "64 bit lov "\
+                          "division %llu / %llu\n", (n), (base)); \
+                __remainder = (n) & (LOV_MIN_STRIPE_SIZE - 1);  \
+                (n) >>= LOV_MIN_STRIPE_BITS;                    \
+                (base) >>= LOV_MIN_STRIPE_BITS;                 \
+                __rem = do_div(n, base);                        \
+                __rem <<= LOV_MIN_STRIPE_BITS;                  \
+                __rem += __remainder;                           \
+        } else {                                                \
+                __rem = do_div(n, base);                        \
+        }                                                       \
+        __rem;                                                  \
+  })
+#else
+#error Unsupported architecture.
+#endif
+
 #endif
diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c
index 95489e7ffb1c42f0b0ad18d004d8dcdd92baff79..fa1f5b05888eaf0a663b71f0d88be5a82ee104fe 100644
--- a/lustre/lov/lov_obd.c
+++ b/lustre/lov/lov_obd.c
@@ -861,7 +861,6 @@ static int lov_setup(struct obd_device *obd, obd_count len, void *buf)
         struct lustre_cfg *lcfg = buf;
         struct lov_desc *desc;
         struct lov_obd *lov = &obd->u.lov;
-        int count;
         ENTRY;
 
         if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1) {
@@ -891,17 +890,6 @@ static int lov_setup(struct obd_device *obd, obd_count len, void *buf)
 
         lov_fix_desc(desc);
 
-        /* Because of 64-bit divide/mod operations only work with a 32-bit
-         * divisor in a 32-bit kernel, we cannot support a stripe width
-         * of 4GB or larger on 32-bit CPUs. */
-        count = desc->ld_default_stripe_count;
-        if ((count > 0 ? count : desc->ld_tgt_count) *
-            desc->ld_default_stripe_size > 0xffffffff) {
-                CERROR("LOV: stripe width "LPU64"x%u > 4294967295 bytes\n",
-                       desc->ld_default_stripe_size, count);
-                RETURN(-EINVAL);
-        }
-
         desc->ld_active_tgt_count = 0;
         lov->desc = *desc;
         lov->lov_tgt_size = 0;
diff --git a/lustre/lov/lov_offset.c b/lustre/lov/lov_offset.c
index 804fb5458c4644cf2430cec9b1803fe73571718f..487f6dae9bc0ba9f72560b5470bd29828c7d4720 100644
--- a/lustre/lov/lov_offset.c
+++ b/lustre/lov/lov_offset.c
@@ -54,8 +54,9 @@
 obd_size lov_stripe_size(struct lov_stripe_md *lsm, obd_size ost_size,
                          int stripeno)
 {
-        unsigned long ssize  = lsm->lsm_stripe_size;
-        unsigned long swidth, stripe_size;
+        obd_size ssize  = lsm->lsm_stripe_size;
+        unsigned long stripe_size;
+        obd_off swidth;
         int sindex = stripeno;
         obd_size lov_size;
         int magic = lsm->lsm_magic;
@@ -67,8 +68,8 @@ obd_size lov_stripe_size(struct lov_stripe_md *lsm, obd_size ost_size,
         LASSERT(lsm_op_find(magic) != NULL);
         lsm_op_find(magic)->lsm_stripe_by_index(lsm, &stripeno, NULL, &swidth);
  
-        /* do_div(a, b) returns a % b, and a = a / b */
-        stripe_size = do_div(ost_size, ssize);
+        /* ll_do_div64(a, b) returns a % b, and a = a / b */
+        stripe_size = ll_do_div64(ost_size, ssize);
         if (stripe_size)
                 lov_size = ost_size * swidth + stripeno * ssize + stripe_size;
         else
@@ -127,42 +128,43 @@ obd_size lov_stripe_size(struct lov_stripe_md *lsm, obd_size ost_size,
  * falls in the stripe and no shifting was done; > 0 when the offset
  * was outside the stripe and was pulled back to its final byte. */
 int lov_stripe_offset(struct lov_stripe_md *lsm, obd_off lov_off,
-                      int stripeno, obd_off *obd_off)
+                      int stripeno, obd_off *obdoff)
 {
         unsigned long ssize  = lsm->lsm_stripe_size;
-        unsigned long swidth, stripe_off, this_stripe;
+        unsigned long stripe_off, this_stripe;
         __u64 l_off, s_off;
+        obd_off swidth;
         int magic = lsm->lsm_magic;
         int ret = 0;
 
         if (lov_off == OBD_OBJECT_EOF) {
-                *obd_off = OBD_OBJECT_EOF;
+                *obdoff = OBD_OBJECT_EOF;
                 return 0;
         }
 
         LASSERT(lsm_op_find(magic) != NULL);
         /*It will check whether the lov_off and stripeno 
          *are in the same extent. 
-         *1) lov_off extent < stripeno extent, ret = -1, obd_off = 0
+         *1) lov_off extent < stripeno extent, ret = -1, obdoff = 0
          *2) lov_off extent > stripeno extent, ret = 1, 
-         *   obd_off = lov_off extent offset*/
+         *   obdoff = lov_off extent offset*/
         l_off = lsm_op_find(magic)->lsm_stripe_offset_by_index(lsm, stripeno);
         s_off = lsm_op_find(magic)->lsm_stripe_offset_by_offset(lsm, lov_off);
         if (s_off < l_off) {
                 ret = -1;
-                *obd_off = 0;
+                *obdoff = 0;
                 return ret;
         } else if (s_off > l_off) {
                 ret = 1;
-                *obd_off = s_off;
+                *obdoff = s_off;
                 return ret;
         }
         /*If they are in the same extent, original logic*/
         lsm_op_find(magic)->lsm_stripe_by_index(lsm, &stripeno, &lov_off,
                                                 &swidth);
        
-        /* do_div(a, b) returns a % b, and a = a / b */
-        stripe_off = do_div(lov_off, swidth);
+        /* ll_do_div64(a, b) returns a % b, and a = a / b */
+        stripe_off = ll_do_div64(lov_off, swidth);
 
         this_stripe = stripeno * ssize;
         if (stripe_off < this_stripe) {
@@ -177,7 +179,7 @@ int lov_stripe_offset(struct lov_stripe_md *lsm, obd_off lov_off,
                 }
         }
 
-        *obd_off = lov_off * ssize + stripe_off;
+        *obdoff = lov_off * ssize + stripe_off;
         return ret;
 }
 
@@ -204,7 +206,8 @@ obd_off lov_size_to_stripe(struct lov_stripe_md *lsm, obd_off file_size,
                            int stripeno)
 {
         unsigned long ssize  = lsm->lsm_stripe_size;
-        unsigned long swidth, stripe_off, this_stripe;
+        unsigned long stripe_off, this_stripe;
+        obd_off swidth;
         int magic = lsm->lsm_magic;
 
         if (file_size == OBD_OBJECT_EOF)
@@ -214,8 +217,8 @@ obd_off lov_size_to_stripe(struct lov_stripe_md *lsm, obd_off file_size,
         lsm_op_find(magic)->lsm_stripe_by_index(lsm, &stripeno, &file_size,
                                                 &swidth);
 
-        /* do_div(a, b) returns a % b, and a = a / b */
-        stripe_off = do_div(file_size, swidth);
+        /* ll_do_div64(a, b) returns a % b, and a = a / b */
+        stripe_off = ll_do_div64(file_size, swidth);
 
         this_stripe = stripeno * ssize;
         if (stripe_off < this_stripe) {
@@ -277,14 +280,15 @@ int lov_stripe_intersects(struct lov_stripe_md *lsm, int stripeno,
 int lov_stripe_number(struct lov_stripe_md *lsm, obd_off lov_off)
 {
         unsigned long ssize  = lsm->lsm_stripe_size;
-        unsigned long swidth, stripe_off;
+        unsigned long stripe_off;
+        obd_off swidth;
         obd_off offset = lov_off;
         int magic = lsm->lsm_magic;
 
         LASSERT(lsm_op_find(magic) != NULL);
         lsm_op_find(magic)->lsm_stripe_by_offset(lsm, NULL, &lov_off, &swidth);
 
-        stripe_off = do_div(lov_off, swidth);
+        stripe_off = ll_do_div64(lov_off, swidth);
 
         return (stripe_off/ssize +
                 lsm_op_find(magic)->lsm_stripe_index_by_offset(lsm, offset));
diff --git a/lustre/lov/lov_pack.c b/lustre/lov/lov_pack.c
index 36127eb2d00a7db9a6f84fc6b9554493a4e07068..b0ab4a50bd66bf79398f627564fa58ae49333f7a 100644
--- a/lustre/lov/lov_pack.c
+++ b/lustre/lov/lov_pack.c
@@ -372,12 +372,6 @@ int lov_setstripe(struct obd_export *exp, struct lov_stripe_md **lsmp,
         }
         stripe_count = lov_get_stripecnt(lov, lum.lmm_stripe_count);
 
-        if ((__u64)lum.lmm_stripe_size * stripe_count > ~0U) {
-                CDEBUG(D_IOCTL, "stripe width %ux%u exceeds %u bytes\n",
-                       lum.lmm_stripe_size, (int)lum.lmm_stripe_count, ~0U);
-                RETURN(-EINVAL);
-        }
-
         rc = lov_alloc_memmd(lsmp, stripe_count, lum.lmm_pattern, LOV_MAGIC);
 
         if (rc < 0)
diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh
index b7538a2f34972a0db5f0e286168ee446ce7ef37d..0719f3e3c8faabda4c53d8d80a702250006e3ffa 100644
--- a/lustre/tests/sanity.sh
+++ b/lustre/tests/sanity.sh
@@ -1031,7 +1031,7 @@ run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
 
 test_27s() { # bug 10725
 	mkdir -p $DIR/$tdir
-	$LSTRIPE $DIR/$tdir $((2048 * 1024 * 1024)) -1 2 && \
+	$LSTRIPE $DIR/$tdir $((4096 * 1024 * 1024)) -1 2 && \
 		error "stripe width >= 2^32 succeeded" || true
 }
 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c
index 7fc6b4e42df13105fa56c1130d8c0f44e2122d8d..ab2b1e78d8576fc49a0a2a298994f6331084153d 100644
--- a/lustre/utils/liblustreapi.c
+++ b/lustre/utils/liblustreapi.c
@@ -218,7 +218,7 @@ int parse_size(char *optarg, unsigned long long *size,
 }
 
 int llapi_file_open(const char *name, int flags, int mode,
-                    unsigned long stripe_size, int stripe_offset,
+                    unsigned long long stripe_size, int stripe_offset,
                     int stripe_count, int stripe_pattern)
 {
         struct lov_user_md lum = { 0 };
@@ -267,11 +267,12 @@ int llapi_file_open(const char *name, int flags, int mode,
                           stripe_count);
                 goto out;
         }
-        if (stripe_count > 0 && (__u64)stripe_size * stripe_count > 0xffffffff){
+
+        if (stripe_size >= (1ULL << 32)) {
                 errno = rc = -EINVAL;
-                llapi_err(LLAPI_MSG_ERROR, "error: stripe_size %lu * "
-                          "stripe_count %u exceeds 4GB", stripe_size, 
-                          stripe_count);
+                llapi_err_noerrno(LLAPI_MSG_ERROR,
+                                  "warning: stripe size larger than 4G "
+                                  "is not currently supported and would wrap");
                 goto out;
         }
 
@@ -301,7 +302,7 @@ out:
         return fd;
 }
 
-int llapi_file_create(const char *name, unsigned long stripe_size,
+int llapi_file_create(const char *name, unsigned long long stripe_size,
                       int stripe_offset, int stripe_count, int stripe_pattern)
 {
         int fd;