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
* 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 */
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);
}
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);
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
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;
*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);
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;
*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
}
#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
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) {
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;
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;
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
* 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) {
}
}
- *obd_off = lov_off * ssize + stripe_off;
+ *obdoff = lov_off * ssize + stripe_off;
return ret;
}
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)
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) {
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));
}
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)
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)"
}
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 };
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;
}
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;