aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/rbd.c72
1 files changed, 29 insertions, 43 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 013c7a549fb6..65665c9c42c6 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -141,7 +141,7 @@ struct rbd_request {
141struct rbd_snap { 141struct rbd_snap {
142 struct device dev; 142 struct device dev;
143 const char *name; 143 const char *name;
144 size_t size; 144 u64 size;
145 struct list_head node; 145 struct list_head node;
146 u64 id; 146 u64 id;
147}; 147};
@@ -175,8 +175,7 @@ struct rbd_device {
175 /* protects updating the header */ 175 /* protects updating the header */
176 struct rw_semaphore header_rwsem; 176 struct rw_semaphore header_rwsem;
177 char snap_name[RBD_MAX_SNAP_NAME_LEN]; 177 char snap_name[RBD_MAX_SNAP_NAME_LEN];
178 u32 cur_snap; /* index+1 of current snapshot within snap context 178 u64 snap_id; /* current snapshot id */
179 0 - for the head */
180 int read_only; 179 int read_only;
181 180
182 struct list_head node; 181 struct list_head node;
@@ -241,7 +240,7 @@ static void rbd_put_dev(struct rbd_device *rbd_dev)
241 put_device(&rbd_dev->dev); 240 put_device(&rbd_dev->dev);
242} 241}
243 242
244static int __rbd_update_snaps(struct rbd_device *rbd_dev); 243static int __rbd_refresh_header(struct rbd_device *rbd_dev);
245 244
246static int rbd_open(struct block_device *bdev, fmode_t mode) 245static int rbd_open(struct block_device *bdev, fmode_t mode)
247{ 246{
@@ -450,7 +449,9 @@ static void rbd_client_release(struct kref *kref)
450 struct rbd_client *rbdc = container_of(kref, struct rbd_client, kref); 449 struct rbd_client *rbdc = container_of(kref, struct rbd_client, kref);
451 450
452 dout("rbd_release_client %p\n", rbdc); 451 dout("rbd_release_client %p\n", rbdc);
452 spin_lock(&rbd_client_list_lock);
453 list_del(&rbdc->node); 453 list_del(&rbdc->node);
454 spin_unlock(&rbd_client_list_lock);
454 455
455 ceph_destroy_client(rbdc->client); 456 ceph_destroy_client(rbdc->client);
456 kfree(rbdc->rbd_opts); 457 kfree(rbdc->rbd_opts);
@@ -463,9 +464,7 @@ static void rbd_client_release(struct kref *kref)
463 */ 464 */
464static void rbd_put_client(struct rbd_device *rbd_dev) 465static void rbd_put_client(struct rbd_device *rbd_dev)
465{ 466{
466 spin_lock(&rbd_client_list_lock);
467 kref_put(&rbd_dev->rbd_client->kref, rbd_client_release); 467 kref_put(&rbd_dev->rbd_client->kref, rbd_client_release);
468 spin_unlock(&rbd_client_list_lock);
469 rbd_dev->rbd_client = NULL; 468 rbd_dev->rbd_client = NULL;
470} 469}
471 470
@@ -487,16 +486,18 @@ static void rbd_coll_release(struct kref *kref)
487 */ 486 */
488static int rbd_header_from_disk(struct rbd_image_header *header, 487static int rbd_header_from_disk(struct rbd_image_header *header,
489 struct rbd_image_header_ondisk *ondisk, 488 struct rbd_image_header_ondisk *ondisk,
490 int allocated_snaps, 489 u32 allocated_snaps,
491 gfp_t gfp_flags) 490 gfp_t gfp_flags)
492{ 491{
493 int i; 492 u32 i, snap_count;
494 u32 snap_count;
495 493
496 if (memcmp(ondisk, RBD_HEADER_TEXT, sizeof(RBD_HEADER_TEXT))) 494 if (memcmp(ondisk, RBD_HEADER_TEXT, sizeof(RBD_HEADER_TEXT)))
497 return -ENXIO; 495 return -ENXIO;
498 496
499 snap_count = le32_to_cpu(ondisk->snap_count); 497 snap_count = le32_to_cpu(ondisk->snap_count);
498 if (snap_count > (UINT_MAX - sizeof(struct ceph_snap_context))
499 / sizeof (*ondisk))
500 return -EINVAL;
500 header->snapc = kmalloc(sizeof(struct ceph_snap_context) + 501 header->snapc = kmalloc(sizeof(struct ceph_snap_context) +
501 snap_count * sizeof (*ondisk), 502 snap_count * sizeof (*ondisk),
502 gfp_flags); 503 gfp_flags);
@@ -506,11 +507,11 @@ static int rbd_header_from_disk(struct rbd_image_header *header,
506 header->snap_names_len = le64_to_cpu(ondisk->snap_names_len); 507 header->snap_names_len = le64_to_cpu(ondisk->snap_names_len);
507 if (snap_count) { 508 if (snap_count) {
508 header->snap_names = kmalloc(header->snap_names_len, 509 header->snap_names = kmalloc(header->snap_names_len,
509 GFP_KERNEL); 510 gfp_flags);
510 if (!header->snap_names) 511 if (!header->snap_names)
511 goto err_snapc; 512 goto err_snapc;
512 header->snap_sizes = kmalloc(snap_count * sizeof(u64), 513 header->snap_sizes = kmalloc(snap_count * sizeof(u64),
513 GFP_KERNEL); 514 gfp_flags);
514 if (!header->snap_sizes) 515 if (!header->snap_sizes)
515 goto err_names; 516 goto err_names;
516 } else { 517 } else {
@@ -552,21 +553,6 @@ err_snapc:
552 return -ENOMEM; 553 return -ENOMEM;
553} 554}
554 555
555static int snap_index(struct rbd_image_header *header, int snap_num)
556{
557 return header->total_snaps - snap_num;
558}
559
560static u64 cur_snap_id(struct rbd_device *rbd_dev)
561{
562 struct rbd_image_header *header = &rbd_dev->header;
563
564 if (!rbd_dev->cur_snap)
565 return 0;
566
567 return header->snapc->snaps[snap_index(header, rbd_dev->cur_snap)];
568}
569
570static int snap_by_name(struct rbd_image_header *header, const char *snap_name, 556static int snap_by_name(struct rbd_image_header *header, const char *snap_name,
571 u64 *seq, u64 *size) 557 u64 *seq, u64 *size)
572{ 558{
@@ -605,7 +591,7 @@ static int rbd_header_set_snap(struct rbd_device *dev, u64 *size)
605 snapc->seq = header->snap_seq; 591 snapc->seq = header->snap_seq;
606 else 592 else
607 snapc->seq = 0; 593 snapc->seq = 0;
608 dev->cur_snap = 0; 594 dev->snap_id = CEPH_NOSNAP;
609 dev->read_only = 0; 595 dev->read_only = 0;
610 if (size) 596 if (size)
611 *size = header->image_size; 597 *size = header->image_size;
@@ -613,8 +599,7 @@ static int rbd_header_set_snap(struct rbd_device *dev, u64 *size)
613 ret = snap_by_name(header, dev->snap_name, &snapc->seq, size); 599 ret = snap_by_name(header, dev->snap_name, &snapc->seq, size);
614 if (ret < 0) 600 if (ret < 0)
615 goto done; 601 goto done;
616 602 dev->snap_id = snapc->seq;
617 dev->cur_snap = header->total_snaps - ret;
618 dev->read_only = 1; 603 dev->read_only = 1;
619 } 604 }
620 605
@@ -935,7 +920,6 @@ static int rbd_do_request(struct request *rq,
935 layout->fl_stripe_unit = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER); 920 layout->fl_stripe_unit = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER);
936 layout->fl_stripe_count = cpu_to_le32(1); 921 layout->fl_stripe_count = cpu_to_le32(1);
937 layout->fl_object_size = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER); 922 layout->fl_object_size = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER);
938 layout->fl_pg_preferred = cpu_to_le32(-1);
939 layout->fl_pg_pool = cpu_to_le32(dev->poolid); 923 layout->fl_pg_pool = cpu_to_le32(dev->poolid);
940 ceph_calc_raw_layout(osdc, layout, snapid, ofs, &len, &bno, 924 ceph_calc_raw_layout(osdc, layout, snapid, ofs, &len, &bno,
941 req, ops); 925 req, ops);
@@ -1168,7 +1152,7 @@ static int rbd_req_read(struct request *rq,
1168 int coll_index) 1152 int coll_index)
1169{ 1153{
1170 return rbd_do_op(rq, rbd_dev, NULL, 1154 return rbd_do_op(rq, rbd_dev, NULL,
1171 (snapid ? snapid : CEPH_NOSNAP), 1155 snapid,
1172 CEPH_OSD_OP_READ, 1156 CEPH_OSD_OP_READ,
1173 CEPH_OSD_FLAG_READ, 1157 CEPH_OSD_FLAG_READ,
1174 2, 1158 2,
@@ -1187,7 +1171,7 @@ static int rbd_req_sync_read(struct rbd_device *dev,
1187 u64 *ver) 1171 u64 *ver)
1188{ 1172{
1189 return rbd_req_sync_op(dev, NULL, 1173 return rbd_req_sync_op(dev, NULL,
1190 (snapid ? snapid : CEPH_NOSNAP), 1174 snapid,
1191 CEPH_OSD_OP_READ, 1175 CEPH_OSD_OP_READ,
1192 CEPH_OSD_FLAG_READ, 1176 CEPH_OSD_FLAG_READ,
1193 NULL, 1177 NULL,
@@ -1238,7 +1222,7 @@ static void rbd_watch_cb(u64 ver, u64 notify_id, u8 opcode, void *data)
1238 dout("rbd_watch_cb %s notify_id=%lld opcode=%d\n", dev->obj_md_name, 1222 dout("rbd_watch_cb %s notify_id=%lld opcode=%d\n", dev->obj_md_name,
1239 notify_id, (int)opcode); 1223 notify_id, (int)opcode);
1240 mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); 1224 mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
1241 rc = __rbd_update_snaps(dev); 1225 rc = __rbd_refresh_header(dev);
1242 mutex_unlock(&ctl_mutex); 1226 mutex_unlock(&ctl_mutex);
1243 if (rc) 1227 if (rc)
1244 pr_warning(RBD_DRV_NAME "%d got notification but failed to " 1228 pr_warning(RBD_DRV_NAME "%d got notification but failed to "
@@ -1521,7 +1505,7 @@ static void rbd_rq_fn(struct request_queue *q)
1521 coll, cur_seg); 1505 coll, cur_seg);
1522 else 1506 else
1523 rbd_req_read(rq, rbd_dev, 1507 rbd_req_read(rq, rbd_dev,
1524 cur_snap_id(rbd_dev), 1508 rbd_dev->snap_id,
1525 ofs, 1509 ofs,
1526 op_size, bio, 1510 op_size, bio,
1527 coll, cur_seg); 1511 coll, cur_seg);
@@ -1592,7 +1576,7 @@ static int rbd_read_header(struct rbd_device *rbd_dev,
1592{ 1576{
1593 ssize_t rc; 1577 ssize_t rc;
1594 struct rbd_image_header_ondisk *dh; 1578 struct rbd_image_header_ondisk *dh;
1595 int snap_count = 0; 1579 u32 snap_count = 0;
1596 u64 ver; 1580 u64 ver;
1597 size_t len; 1581 size_t len;
1598 1582
@@ -1656,7 +1640,7 @@ static int rbd_header_add_snap(struct rbd_device *dev,
1656 struct ceph_mon_client *monc; 1640 struct ceph_mon_client *monc;
1657 1641
1658 /* we should create a snapshot only if we're pointing at the head */ 1642 /* we should create a snapshot only if we're pointing at the head */
1659 if (dev->cur_snap) 1643 if (dev->snap_id != CEPH_NOSNAP)
1660 return -EINVAL; 1644 return -EINVAL;
1661 1645
1662 monc = &dev->rbd_client->client->monc; 1646 monc = &dev->rbd_client->client->monc;
@@ -1683,7 +1667,9 @@ static int rbd_header_add_snap(struct rbd_device *dev,
1683 if (ret < 0) 1667 if (ret < 0)
1684 return ret; 1668 return ret;
1685 1669
1686 dev->header.snapc->seq = new_snapid; 1670 down_write(&dev->header_rwsem);
1671 dev->header.snapc->seq = new_snapid;
1672 up_write(&dev->header_rwsem);
1687 1673
1688 return 0; 1674 return 0;
1689bad: 1675bad:
@@ -1703,7 +1689,7 @@ static void __rbd_remove_all_snaps(struct rbd_device *rbd_dev)
1703/* 1689/*
1704 * only read the first part of the ondisk header, without the snaps info 1690 * only read the first part of the ondisk header, without the snaps info
1705 */ 1691 */
1706static int __rbd_update_snaps(struct rbd_device *rbd_dev) 1692static int __rbd_refresh_header(struct rbd_device *rbd_dev)
1707{ 1693{
1708 int ret; 1694 int ret;
1709 struct rbd_image_header h; 1695 struct rbd_image_header h;
@@ -1890,7 +1876,7 @@ static ssize_t rbd_image_refresh(struct device *dev,
1890 1876
1891 mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); 1877 mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
1892 1878
1893 rc = __rbd_update_snaps(rbd_dev); 1879 rc = __rbd_refresh_header(rbd_dev);
1894 if (rc < 0) 1880 if (rc < 0)
1895 ret = rc; 1881 ret = rc;
1896 1882
@@ -1949,7 +1935,7 @@ static ssize_t rbd_snap_size_show(struct device *dev,
1949{ 1935{
1950 struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev); 1936 struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
1951 1937
1952 return sprintf(buf, "%zd\n", snap->size); 1938 return sprintf(buf, "%llu\n", (unsigned long long)snap->size);
1953} 1939}
1954 1940
1955static ssize_t rbd_snap_id_show(struct device *dev, 1941static ssize_t rbd_snap_id_show(struct device *dev,
@@ -1958,7 +1944,7 @@ static ssize_t rbd_snap_id_show(struct device *dev,
1958{ 1944{
1959 struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev); 1945 struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
1960 1946
1961 return sprintf(buf, "%llu\n", (unsigned long long) snap->id); 1947 return sprintf(buf, "%llu\n", (unsigned long long)snap->id);
1962} 1948}
1963 1949
1964static DEVICE_ATTR(snap_size, S_IRUGO, rbd_snap_size_show, NULL); 1950static DEVICE_ATTR(snap_size, S_IRUGO, rbd_snap_size_show, NULL);
@@ -2173,7 +2159,7 @@ static int rbd_init_watch_dev(struct rbd_device *rbd_dev)
2173 rbd_dev->header.obj_version); 2159 rbd_dev->header.obj_version);
2174 if (ret == -ERANGE) { 2160 if (ret == -ERANGE) {
2175 mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); 2161 mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
2176 rc = __rbd_update_snaps(rbd_dev); 2162 rc = __rbd_refresh_header(rbd_dev);
2177 mutex_unlock(&ctl_mutex); 2163 mutex_unlock(&ctl_mutex);
2178 if (rc < 0) 2164 if (rc < 0)
2179 return rc; 2165 return rc;
@@ -2558,7 +2544,7 @@ static ssize_t rbd_snap_add(struct device *dev,
2558 if (ret < 0) 2544 if (ret < 0)
2559 goto err_unlock; 2545 goto err_unlock;
2560 2546
2561 ret = __rbd_update_snaps(rbd_dev); 2547 ret = __rbd_refresh_header(rbd_dev);
2562 if (ret < 0) 2548 if (ret < 0)
2563 goto err_unlock; 2549 goto err_unlock;
2564 2550