Example #1
0
/* compute object size given "stripeno" and the ost size */
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 stripe_size;
        obd_off swidth;
        obd_size lov_size;
        int magic = lsm->lsm_magic;
        ENTRY;

        if (ost_size == 0)
                RETURN(0);

        LASSERT(lsm_op_find(magic) != NULL);
        lsm_op_find(magic)->lsm_stripe_by_index(lsm, &stripeno, NULL, &swidth);

	/* lov_do_div64(a, b) returns a % b, and a = a / b */
	stripe_size = lov_do_div64(ost_size, ssize);
	if (stripe_size)
		lov_size = ost_size * swidth + stripeno * ssize + stripe_size;
	else
		lov_size = (ost_size - 1) * swidth + (stripeno + 1) * ssize;

        RETURN(lov_size);
}
Example #2
0
/* compute which stripe number "lov_off" will be written into */
int lov_stripe_number(struct lov_stripe_md *lsm, obd_off lov_off)
{
	unsigned long ssize  = lsm->lsm_stripe_size;
	obd_off stripe_off, swidth;
	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 = lov_do_div64(lov_off, swidth);

	/* Puts stripe_off/ssize result into stripe_off */
	lov_do_div64(stripe_off, ssize);

	return stripe_off;
}
Example #3
0
/* Given a whole-file size and a stripe number, give the file size which
 * corresponds to the individual object of that stripe.
 *
 * This behaves basically in the same was as lov_stripe_offset, except that
 * file sizes falling before the beginning of a stripe are clamped to the end
 * of the previous stripe, not the beginning of the next:
 *
 *                                               S
 * ---------------------------------------------------------------------
 * |    0    |     1     |     2     |    0    |     1     |     2     |
 * ---------------------------------------------------------------------
 *
 * if clamped to stripe 2 becomes:
 *
 *                                   S
 * ---------------------------------------------------------------------
 * |    0    |     1     |     2     |    0    |     1     |     2     |
 * ---------------------------------------------------------------------
 */
loff_t lov_size_to_stripe(struct lov_stripe_md *lsm, u64 file_size,
			  int stripeno)
{
	unsigned long ssize  = lsm->lsm_stripe_size;
	loff_t stripe_off;
	loff_t this_stripe;
	loff_t swidth;
	u32 magic = lsm->lsm_magic;

        if (file_size == OBD_OBJECT_EOF)
                return OBD_OBJECT_EOF;

        LASSERT(lsm_op_find(magic) != NULL);
        lsm_op_find(magic)->lsm_stripe_by_index(lsm, &stripeno, &file_size,
                                                &swidth);

	/* lov_do_div64(a, b) returns a % b, and a = a / b */
	stripe_off = lov_do_div64(file_size, swidth);

	this_stripe = (loff_t)stripeno * ssize;
        if (stripe_off < this_stripe) {
                /* Move to end of previous stripe, or zero */
                if (file_size > 0) {
                        file_size--;
                        stripe_off = ssize;
                } else {
                        stripe_off = 0;
                }
        } else {
                stripe_off -= this_stripe;

                if (stripe_off >= ssize) {
                        /* Clamp to end of this stripe */
                        stripe_off = ssize;
                }
        }

        return (file_size * ssize + stripe_off);
}
Example #4
0
/* we have an offset in file backed by an lov and want to find out where
 * that offset lands in our given stripe of the file.  for the easy
 * case where the offset is within the stripe, we just have to scale the
 * offset down to make it relative to the stripe instead of the lov.
 *
 * the harder case is what to do when the offset doesn't intersect the
 * stripe.  callers will want start offsets clamped ahead to the start
 * of the nearest stripe in the file.  end offsets similarly clamped to the
 * nearest ending byte of a stripe in the file:
 *
 * all this function does is move offsets to the nearest region of the
 * stripe, and it does its work "mod" the full length of all the stripes.
 * consider a file with 3 stripes:
 *
 *             S                                              E
 * ---------------------------------------------------------------------
 * |    0    |     1     |     2     |    0    |     1     |     2     |
 * ---------------------------------------------------------------------
 *
 * to find stripe 1's offsets for S and E, it divides by the full stripe
 * width and does its math in the context of a single set of stripes:
 *
 *             S         E
 * -----------------------------------
 * |    0    |     1     |     2     |
 * -----------------------------------
 *
 * it'll notice that E is outside stripe 1 and clamp it to the end of the
 * stripe, then multiply it back out by lov_off to give the real offsets in
 * the stripe:
 *
 *   S                   E
 * ---------------------------------------------------------------------
 * |    1    |     1     |     1     |    1    |     1     |     1     |
 * ---------------------------------------------------------------------
 *
 * it would have done similarly and pulled S forward to the start of a 1
 * stripe if, say, S had landed in a 0 stripe.
 *
 * this rounding isn't always correct.  consider an E lov offset that lands
 * on a 0 stripe, the "mod stripe width" math will pull it forward to the
 * start of a 1 stripe, when in fact it wanted to be rounded back to the end
 * of a previous 1 stripe.  this logic is handled by callers and this is why:
 *
 * this function returns < 0 when the offset was "before" the stripe and
 * was moved forward to the start of the stripe in question;  0 when it
 * 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, loff_t lov_off, int stripeno,
		      loff_t *obdoff)
{
	unsigned long ssize  = lsm->lsm_stripe_size;
	loff_t stripe_off;
	loff_t this_stripe;
	loff_t swidth;
	u32 magic = lsm->lsm_magic;
        int ret = 0;

        if (lov_off == OBD_OBJECT_EOF) {
                *obdoff = OBD_OBJECT_EOF;
                return 0;
        }

        LASSERT(lsm_op_find(magic) != NULL);
        lsm_op_find(magic)->lsm_stripe_by_index(lsm, &stripeno, &lov_off,
                                                &swidth);

	/* lov_do_div64(a, b) returns a % b, and a = a / b */
	stripe_off = lov_do_div64(lov_off, swidth);

	this_stripe = (loff_t)stripeno * ssize;
        if (stripe_off < this_stripe) {
                stripe_off = 0;
                ret = -1;
        } else {
                stripe_off -= this_stripe;

                if (stripe_off >= ssize) {
                        stripe_off = ssize;
                        ret = 1;
                }
        }

        *obdoff = lov_off * ssize + stripe_off;
        return ret;
}