• Ilya Dryomov's avatar
    rbd: handle parent_overlap on writes correctly · 9638556a
    Ilya Dryomov authored
    The following check in rbd_img_obj_request_submit()
    
        rbd_dev->parent_overlap <= obj_request->img_offset
    
    allows the fall through to the non-layered write case even if both
    parent_overlap and obj_request->img_offset belong to the same RADOS
    object.  This leads to data corruption, because the area to the left of
    parent_overlap ends up unconditionally zero-filled instead of being
    populated with parent data.  Suppose we want to write 1M to offset 6M
    of image bar, which is a clone of foo@snap; object_size is 4M,
    parent_overlap is 5M:
    
        rbd_data.<id>.0000000000000001
         ---------------------|----------------------|------------
        | should be copyup'ed | should be zeroed out | write ...
         ---------------------|----------------------|------------
       4M                    5M                     6M
                        parent_overlap    obj_request->img_offset
    
    4..5M should be copyup'ed from foo, yet it is zero-filled, just like
    5..6M is.
    
    Given that the only striping mode kernel client currently supports is
    chunking (i.e. stripe_unit == object_size, stripe_count == 1), round
    parent_overlap up to the next object boundary for the purposes of the
    overlap check.
    
    Cc: stable@vger.kernel.org # 3.10+
    Signed-off-by: default avatarIlya Dryomov <ilya.dryomov@inktank.com>
    Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
    9638556a
rbd.c 142 KB