#define        SECTOR_SHIFT    9
 #define        SECTOR_SIZE     (1ULL << SECTOR_SHIFT)
 
+/* It might be useful to have this defined elsewhere too */
+
+#define        U64_MAX ((u64) (~0ULL))
+
 #define RBD_DRV_NAME "rbd"
 #define RBD_DRV_NAME_LONG "rbd (rados block device)"
 
 static int rbd_get_num_segments(struct rbd_image_header *header,
                                u64 ofs, u64 len)
 {
-       u64 start_seg = ofs >> header->obj_order;
-       u64 end_seg = (ofs + len - 1) >> header->obj_order;
+       u64 start_seg;
+       u64 end_seg;
+
+       if (!len)
+               return 0;
+       if (len - 1 > U64_MAX - ofs)
+               return -ERANGE;
+
+       start_seg = ofs >> header->obj_order;
+       end_seg = (ofs + len - 1) >> header->obj_order;
+
        return end_seg - start_seg + 1;
 }
 
                     size, (unsigned long long) blk_rq_pos(rq) * SECTOR_SIZE);
 
                num_segs = rbd_get_num_segments(&rbd_dev->header, ofs, size);
+               if (num_segs <= 0) {
+                       spin_lock_irq(q->queue_lock);
+                       __blk_end_request_all(rq, num_segs);
+                       ceph_put_snap_context(snapc);
+                       continue;
+               }
                coll = rbd_alloc_coll(num_segs);
                if (!coll) {
                        spin_lock_irq(q->queue_lock);