> Actually, it looks like that calculation is wrong.. I also added
>
>       *oxoff += (stripeno % su_per_object) * su;

Looks like this update fixes the object offset for multiple stripes  
per object, but 'oxlen' needs adjusted. With the current calculation:

- oxlen = min(plen, offset % su)

A length of zero is calculated when offset equals stripe unit.  
Consider osize=128, stripe unit = 64, stripe count = 2. A write  
request of

length, offset
4096, 0

gives:
ono = 0, oxoff = 0, oxlen = 64
ono = 1, oxoff = 0, oxlen = 64
ono = 0, oxoff = 64, oxlen = 0 <-- infinite loop wrt to calling context

So, assuming that object size is a multiple of stripe unit, we really  
want the minimum between the total request and the remaining space in  
the current stripe:

- oxlen = min(plen, su - (offset % su))

I put a path in against ceph-client/unstable @

http://code.noahdesu.com/git/linux26-dev.git ceph/unstable-for-sage

-n

-------------

diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c
index 5a5520c..d62e111 100644
--- a/fs/ceph/osdmap.c
+++ b/fs/ceph/osdmap.c
@@ -731,7 +731,7 @@ void ceph_calc_file_object_mapping(struct  
ceph_file_layout *layout,
         u32 sc = le32_to_cpu(layout->fl_stripe_count);
         u32 bl, stripeno, stripepos, objsetno;
         u32 su_per_object;
-       u64 t;
+       u64 t, su_offset;

         dout("mapping %llu~%llu  osize %u fl_su %u\n", off, *plen,
              osize, su);
@@ -755,10 +755,15 @@ void ceph_calc_file_object_mapping(struct  
ceph_file_layout *layout,

         /* *oxoff = *off % layout->fl_stripe_unit;  # offset in su */
         t = off;
-       *oxoff = do_div(t, su);
-       *oxoff += (stripeno % su_per_object) * su;
-
-       *oxlen = min_t(u64, *plen, su - *oxoff);
+       su_offset = do_div(t, su);
+       *oxoff = su_offset + (stripeno % su_per_object) * su;
+
+       /*
+        * Calculate the length of the extent being written to the  
selected
+        * object. This is the minimum of the full length requested  
(plen) or
+        * the remainder of the current stripe being written to.
+        */
+       *oxlen = min_t(u64, *plen, su - su_offset);
         *plen = *oxlen;

         dout(" obj extent %llu~%llu\n", *oxoff, *oxlen);


------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Ceph-devel mailing list
Ceph-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ceph-devel

Reply via email to