Merge branch 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git...
[pandora-kernel.git] / drivers / block / rbd.c
index 2c09102..fe3c324 100644 (file)
@@ -629,6 +629,14 @@ static int rbd_get_num_segments(struct rbd_image_header *header,
        return end_seg - start_seg + 1;
 }
 
+/*
+ * returns the size of an object in the image
+ */
+static u64 rbd_obj_bytes(struct rbd_image_header *header)
+{
+       return 1 << header->obj_order;
+}
+
 /*
  * bio helpers
  */
@@ -1253,6 +1261,35 @@ fail:
        return ret;
 }
 
+/*
+ * Request sync osd unwatch
+ */
+static int rbd_req_sync_unwatch(struct rbd_device *dev,
+                               const char *obj)
+{
+       struct ceph_osd_req_op *ops;
+
+       int ret = rbd_create_rw_ops(&ops, 1, CEPH_OSD_OP_WATCH, 0);
+       if (ret < 0)
+               return ret;
+
+       ops[0].watch.ver = 0;
+       ops[0].watch.cookie = cpu_to_le64(dev->watch_event->cookie);
+       ops[0].watch.flag = 0;
+
+       ret = rbd_req_sync_op(dev, NULL,
+                             CEPH_NOSNAP,
+                             0,
+                             CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK,
+                             ops,
+                             1, obj, 0, 0, NULL, NULL, NULL);
+
+       rbd_destroy_ops(ops);
+       ceph_osdc_cancel_event(dev->watch_event);
+       dev->watch_event = NULL;
+       return ret;
+}
+
 struct rbd_notify_info {
        struct rbd_device *dev;
 };
@@ -1736,6 +1773,13 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
        q = blk_init_queue(rbd_rq_fn, &rbd_dev->lock);
        if (!q)
                goto out_disk;
+
+       /* set io sizes to object size */
+       blk_queue_max_hw_sectors(q, rbd_obj_bytes(&rbd_dev->header) / 512ULL);
+       blk_queue_max_segment_size(q, rbd_obj_bytes(&rbd_dev->header));
+       blk_queue_io_min(q, rbd_obj_bytes(&rbd_dev->header));
+       blk_queue_io_opt(q, rbd_obj_bytes(&rbd_dev->header));
+
        blk_queue_merge_bvec(q, rbd_merge_bvec);
        disk->queue = q;
 
@@ -2290,7 +2334,7 @@ static void rbd_dev_release(struct device *dev)
                ceph_osdc_unregister_linger_request(&rbd_dev->client->osdc,
                                                    rbd_dev->watch_request);
        if (rbd_dev->watch_event)
-               ceph_osdc_cancel_event(rbd_dev->watch_event);
+               rbd_req_sync_unwatch(rbd_dev, rbd_dev->obj_md_name);
 
        rbd_put_client(rbd_dev);