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;