]> Pileus Git - ~andy/linux/blobdiff - drivers/block/rbd.c
rbd: flush dcache after zeroing page data
[~andy/linux] / drivers / block / rbd.c
index c8eb9cb77d361e3757da02955c81f0112cc7f586..cb728a01a19f2c5981fe98896ae42612c2798f06 100644 (file)
@@ -497,7 +497,7 @@ static int rbd_open(struct block_device *bdev, fmode_t mode)
        return 0;
 }
 
-static int rbd_release(struct gendisk *disk, fmode_t mode)
+static void rbd_release(struct gendisk *disk, fmode_t mode)
 {
        struct rbd_device *rbd_dev = disk->private_data;
        unsigned long open_count_before;
@@ -510,8 +510,6 @@ static int rbd_release(struct gendisk *disk, fmode_t mode)
        mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
        put_device(&rbd_dev->dev);
        mutex_unlock(&ctl_mutex);
-
-       return 0;
 }
 
 static const struct block_device_operations rbd_bd_ops = {
@@ -1128,6 +1126,7 @@ static void zero_bio_chain(struct bio *chain, int start_ofs)
                                buf = bvec_kmap_irq(bv, &flags);
                                memset(buf + remainder, 0,
                                       bv->bv_len - remainder);
+                               flush_dcache_page(bv->bv_page);
                                bvec_kunmap_irq(buf, &flags);
                        }
                        pos += bv->bv_len;
@@ -1155,11 +1154,12 @@ static void zero_pages(struct page **pages, u64 offset, u64 end)
                unsigned long flags;
                void *kaddr;
 
-               page_offset = (size_t)(offset & ~PAGE_MASK);
-               length = min(PAGE_SIZE - page_offset, (size_t)(end - offset));
+               page_offset = offset & ~PAGE_MASK;
+               length = min_t(size_t, PAGE_SIZE - page_offset, end - offset);
                local_irq_save(flags);
                kaddr = kmap_atomic(*page);
                memset(kaddr + page_offset, 0, length);
+               flush_dcache_page(*page);
                kunmap_atomic(kaddr);
                local_irq_restore(flags);
 
@@ -1200,7 +1200,7 @@ static struct bio *bio_clone_range(struct bio *bio_src,
        /* Find first affected segment... */
 
        resid = offset;
-       __bio_for_each_segment(bv, bio_src, idx, 0) {
+       bio_for_each_segment(bv, bio_src, idx) {
                if (resid < bv->bv_len)
                        break;
                resid -= bv->bv_len;
@@ -2537,6 +2537,7 @@ static void rbd_img_obj_exists_callback(struct rbd_obj_request *obj_request)
         */
        orig_request = obj_request->obj_request;
        obj_request->obj_request = NULL;
+       rbd_obj_request_put(orig_request);
        rbd_assert(orig_request);
        rbd_assert(orig_request->img_request);
 
@@ -2557,7 +2558,6 @@ static void rbd_img_obj_exists_callback(struct rbd_obj_request *obj_request)
        if (!rbd_dev->parent_overlap) {
                struct ceph_osd_client *osdc;
 
-               rbd_obj_request_put(orig_request);
                osdc = &rbd_dev->rbd_client->client->osdc;
                result = rbd_obj_request_submit(osdc, orig_request);
                if (!result)
@@ -2587,7 +2587,6 @@ static void rbd_img_obj_exists_callback(struct rbd_obj_request *obj_request)
 out:
        if (orig_request->result)
                rbd_obj_request_complete(orig_request);
-       rbd_obj_request_put(orig_request);
 }
 
 static int rbd_img_obj_exists_submit(struct rbd_obj_request *obj_request)