Details : When multiple mount protection fails during remount, proper error
should be returned
+Severity : enhancement
+Bugzilla : 16823
+Description: Allow stripe size to be up to 4G-64k
+Details : Fix math logic to allow large stripe sizes.
+
+
--------------------------------------------------------------------------------
2007-08-10 Cluster File Systems, Inc. <info@clusterfs.com>
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_create_pool(const char *name, unsigned long stripe_size,
+extern int llapi_file_create_pool(const char *name,
+ unsigned long long stripe_size,
int stripe_offset, int stripe_count,
int stripe_pattern, char *pool_name);
extern int llapi_file_open_pool(const char *name, int flags, int mode,
- unsigned long stripe_size, int stripe_offset,
- int stripe_count, int stripe_pattern,
- char *pool_name);
+ unsigned long long stripe_size,
+ int stripe_offset, int stripe_count,
+ int stripe_pattern, char *pool_name);
extern int llapi_poollist(char *name);
extern int llapi_file_get_stripe(const char *path, struct lov_user_md *lum);
#define HAVE_LLAPI_FILE_LOOKUP
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(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 = (unsigned long)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 = (unsigned long)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 = (unsigned long)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 = (unsigned long)lsm->lsm_stripe_size * le->le_stripe_count;
+ *swidth = (obd_off)lsm->lsm_stripe_size * le->le_stripe_count;
}
static obd_off
int lov_check_index_in_pool(__u32 idx, struct pool_desc *pool);
void lov_pool_putref(struct pool_desc *pool);
+#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 lov_stripe_md *lsm = lov_r0(cl2lov(ios->cis_obj))->lo_lsm;
loff_t start = io->u.ci_rw.crw_pos;
loff_t next;
- int ssize = lsm->lsm_stripe_size;
+ unsigned long ssize = lsm->lsm_stripe_size;
LASSERT(io->ci_type == CIT_READ || io->ci_type == CIT_WRITE);
ENTRY;
struct lprocfs_static_vars lvars = { 0 };
struct lov_desc *desc;
struct lov_obd *lov = &obd->u.lov;
- int count;
int rc;
ENTRY;
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;
+ unsigned long ssize = lsm->lsm_stripe_size;
+ unsigned long stripe_size;
+ obd_off swidth;
int sindex = stripeno;
obd_size lov_size;
int magic = lsm->lsm_magic;
* 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;
__u64 l_off, s_off;
+ obd_off stripe_off, this_stripe, 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;
+ this_stripe = (obd_off)stripeno * ssize;
if (stripe_off < this_stripe) {
stripe_off = 0;
ret = -1;
}
}
- *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;
+ obd_off stripe_off, this_stripe, 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;
+ this_stripe = (obd_off)stripeno * ssize;
if (stripe_off < this_stripe) {
/* Move to end of previous stripe, or zero */
if (file_size > 0) {
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;
+ obd_off stripe_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);
+
+ /* Puts stripe_off/ssize result into stripe_off */
+ do_div(stripe_off, ssize);
- return (stripe_off/ssize +
+ return (stripe_off +
lsm_op_find(magic)->lsm_stripe_index_by_offset(lsm, offset));
}
}
}
- if ((__u64)lumv1->lmm_stripe_size * stripe_count > ~0UL) {
- CDEBUG(D_IOCTL, "stripe width %ux%i exeeds %lu bytes\n",
- lumv1->lmm_stripe_size, (int)lumv1->lmm_stripe_count,
- ~0UL);
- RETURN(-EINVAL);
- }
-
rc = lov_alloc_memmd(lsmp, stripe_count, lumv1->lmm_pattern, lmm_magic);
if (rc >= 0) {
set -e
ONLY=${ONLY:-"$*"}
-# bug number for skipped test: 16823 13297 2108 9789 3637 9789 3561 12622 12653 12653 5188 10764 16260
-ALWAYS_EXCEPT=" 27s 27u 42a 42b 42c 42d 45 51d 65a 65e 68b 75 119d $SANITY_EXCEPT"
+# bug number for skipped test: 13297 2108 9789 3637 9789 3561 12622 12653 12653 5188 10764 16260
+ALWAYS_EXCEPT=" 27u 42a 42b 42c 42d 45 51d 65a 65e 68b 75 119d $SANITY_EXCEPT"
# bug number for skipped test: 2108 9789 3637 9789 3561 5188/5749 1443
#ALWAYS_EXCEPT=${ALWAYS_EXCEPT:-"27m 42a 42b 42c 42d 45 68 76"}
# UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
return 0;
}
-int llapi_stripe_limit_check(unsigned long stripe_size, int stripe_offset,
+int llapi_stripe_limit_check(unsigned long long stripe_size, int stripe_offset,
int stripe_count, int stripe_pattern)
{
int page_size;
stripe_count);
return -EINVAL;
}
- if (stripe_count > 0 && (__u64)stripe_size * stripe_count > 0xffffffff){
+ if (stripe_size >= (1ULL << 32)){
errno = -EINVAL;
- llapi_err(LLAPI_MSG_ERROR, "error: stripe_size %lu * "
- "stripe_count %u exceeds 4GB", stripe_size,
- stripe_count);
+ llapi_err(LLAPI_MSG_ERROR, "warning: stripe size larger than 4G"
+ " is not currently supported and would wrap");
return -EINVAL;
}
return 0;
static int poolpath(char *fsname, char *pathname, char *pool_pathname);
int llapi_file_open_pool(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, char *pool_name)
{
struct lov_user_md_v3 lum = { 0 };
}
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)
{
return llapi_file_open_pool(name, flags, mode, stripe_size,
stripe_pattern, NULL);
}
-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;
return 0;
}
-int llapi_file_create_pool(const char *name, unsigned long stripe_size,
+int llapi_file_create_pool(const char *name, unsigned long long stripe_size,
int stripe_offset, int stripe_count,
int stripe_pattern, char *pool_name)
{