diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/block/rbd.c | 101 |
1 files changed, 10 insertions, 91 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 65cc424359b0..148ab944378d 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
| @@ -183,10 +183,6 @@ static LIST_HEAD(rbd_client_list); /* clients */ | |||
| 183 | 183 | ||
| 184 | static int __rbd_init_snaps_header(struct rbd_device *rbd_dev); | 184 | static int __rbd_init_snaps_header(struct rbd_device *rbd_dev); |
| 185 | static void rbd_dev_release(struct device *dev); | 185 | static void rbd_dev_release(struct device *dev); |
| 186 | static ssize_t rbd_snap_rollback(struct device *dev, | ||
| 187 | struct device_attribute *attr, | ||
| 188 | const char *buf, | ||
| 189 | size_t size); | ||
| 190 | static ssize_t rbd_snap_add(struct device *dev, | 186 | static ssize_t rbd_snap_add(struct device *dev, |
| 191 | struct device_attribute *attr, | 187 | struct device_attribute *attr, |
| 192 | const char *buf, | 188 | const char *buf, |
| @@ -461,6 +457,10 @@ static int rbd_header_from_disk(struct rbd_image_header *header, | |||
| 461 | u32 snap_count = le32_to_cpu(ondisk->snap_count); | 457 | u32 snap_count = le32_to_cpu(ondisk->snap_count); |
| 462 | int ret = -ENOMEM; | 458 | int ret = -ENOMEM; |
| 463 | 459 | ||
| 460 | if (memcmp(ondisk, RBD_HEADER_TEXT, sizeof(RBD_HEADER_TEXT))) { | ||
| 461 | return -ENXIO; | ||
| 462 | } | ||
| 463 | |||
| 464 | init_rwsem(&header->snap_rwsem); | 464 | init_rwsem(&header->snap_rwsem); |
| 465 | header->snap_names_len = le64_to_cpu(ondisk->snap_names_len); | 465 | header->snap_names_len = le64_to_cpu(ondisk->snap_names_len); |
| 466 | header->snapc = kmalloc(sizeof(struct ceph_snap_context) + | 466 | header->snapc = kmalloc(sizeof(struct ceph_snap_context) + |
| @@ -1356,32 +1356,6 @@ fail: | |||
| 1356 | } | 1356 | } |
| 1357 | 1357 | ||
| 1358 | /* | 1358 | /* |
| 1359 | * Request sync osd rollback | ||
| 1360 | */ | ||
| 1361 | static int rbd_req_sync_rollback_obj(struct rbd_device *dev, | ||
| 1362 | u64 snapid, | ||
| 1363 | const char *obj) | ||
| 1364 | { | ||
| 1365 | struct ceph_osd_req_op *ops; | ||
| 1366 | int ret = rbd_create_rw_ops(&ops, 1, CEPH_OSD_OP_ROLLBACK, 0); | ||
| 1367 | if (ret < 0) | ||
| 1368 | return ret; | ||
| 1369 | |||
| 1370 | ops[0].snap.snapid = snapid; | ||
| 1371 | |||
| 1372 | ret = rbd_req_sync_op(dev, NULL, | ||
| 1373 | CEPH_NOSNAP, | ||
| 1374 | 0, | ||
| 1375 | CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, | ||
| 1376 | ops, | ||
| 1377 | 1, obj, 0, 0, NULL, NULL, NULL); | ||
| 1378 | |||
| 1379 | rbd_destroy_ops(ops); | ||
| 1380 | |||
| 1381 | return ret; | ||
| 1382 | } | ||
| 1383 | |||
| 1384 | /* | ||
| 1385 | * Request sync osd read | 1359 | * Request sync osd read |
| 1386 | */ | 1360 | */ |
| 1387 | static int rbd_req_sync_exec(struct rbd_device *dev, | 1361 | static int rbd_req_sync_exec(struct rbd_device *dev, |
| @@ -1610,8 +1584,13 @@ static int rbd_read_header(struct rbd_device *rbd_dev, | |||
| 1610 | goto out_dh; | 1584 | goto out_dh; |
| 1611 | 1585 | ||
| 1612 | rc = rbd_header_from_disk(header, dh, snap_count, GFP_KERNEL); | 1586 | rc = rbd_header_from_disk(header, dh, snap_count, GFP_KERNEL); |
| 1613 | if (rc < 0) | 1587 | if (rc < 0) { |
| 1588 | if (rc == -ENXIO) { | ||
| 1589 | pr_warning("unrecognized header format" | ||
| 1590 | " for image %s", rbd_dev->obj); | ||
| 1591 | } | ||
| 1614 | goto out_dh; | 1592 | goto out_dh; |
| 1593 | } | ||
| 1615 | 1594 | ||
| 1616 | if (snap_count != header->total_snaps) { | 1595 | if (snap_count != header->total_snaps) { |
| 1617 | snap_count = header->total_snaps; | 1596 | snap_count = header->total_snaps; |
| @@ -1882,7 +1861,6 @@ static DEVICE_ATTR(name, S_IRUGO, rbd_name_show, NULL); | |||
| 1882 | static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh); | 1861 | static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh); |
| 1883 | static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL); | 1862 | static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL); |
| 1884 | static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add); | 1863 | static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add); |
| 1885 | static DEVICE_ATTR(rollback_snap, S_IWUSR, NULL, rbd_snap_rollback); | ||
| 1886 | 1864 | ||
| 1887 | static struct attribute *rbd_attrs[] = { | 1865 | static struct attribute *rbd_attrs[] = { |
| 1888 | &dev_attr_size.attr, | 1866 | &dev_attr_size.attr, |
| @@ -1893,7 +1871,6 @@ static struct attribute *rbd_attrs[] = { | |||
| 1893 | &dev_attr_current_snap.attr, | 1871 | &dev_attr_current_snap.attr, |
| 1894 | &dev_attr_refresh.attr, | 1872 | &dev_attr_refresh.attr, |
| 1895 | &dev_attr_create_snap.attr, | 1873 | &dev_attr_create_snap.attr, |
| 1896 | &dev_attr_rollback_snap.attr, | ||
| 1897 | NULL | 1874 | NULL |
| 1898 | }; | 1875 | }; |
| 1899 | 1876 | ||
| @@ -2424,64 +2401,6 @@ err_unlock: | |||
| 2424 | return ret; | 2401 | return ret; |
| 2425 | } | 2402 | } |
| 2426 | 2403 | ||
| 2427 | static ssize_t rbd_snap_rollback(struct device *dev, | ||
| 2428 | struct device_attribute *attr, | ||
| 2429 | const char *buf, | ||
| 2430 | size_t count) | ||
| 2431 | { | ||
| 2432 | struct rbd_device *rbd_dev = dev_to_rbd(dev); | ||
| 2433 | int ret; | ||
| 2434 | u64 snapid; | ||
| 2435 | u64 cur_ofs; | ||
| 2436 | char *seg_name = NULL; | ||
| 2437 | char *snap_name = kmalloc(count + 1, GFP_KERNEL); | ||
| 2438 | ret = -ENOMEM; | ||
| 2439 | if (!snap_name) | ||
| 2440 | return ret; | ||
| 2441 | |||
| 2442 | /* parse snaps add command */ | ||
| 2443 | snprintf(snap_name, count, "%s", buf); | ||
| 2444 | seg_name = kmalloc(RBD_MAX_SEG_NAME_LEN + 1, GFP_NOIO); | ||
| 2445 | if (!seg_name) | ||
| 2446 | goto done; | ||
| 2447 | |||
| 2448 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
| 2449 | |||
| 2450 | ret = snap_by_name(&rbd_dev->header, snap_name, &snapid, NULL); | ||
| 2451 | if (ret < 0) | ||
| 2452 | goto done_unlock; | ||
| 2453 | |||
| 2454 | dout("snapid=%lld\n", snapid); | ||
| 2455 | |||
| 2456 | cur_ofs = 0; | ||
| 2457 | while (cur_ofs < rbd_dev->header.image_size) { | ||
| 2458 | cur_ofs += rbd_get_segment(&rbd_dev->header, | ||
| 2459 | rbd_dev->obj, | ||
| 2460 | cur_ofs, (u64)-1, | ||
| 2461 | seg_name, NULL); | ||
| 2462 | dout("seg_name=%s\n", seg_name); | ||
| 2463 | |||
| 2464 | ret = rbd_req_sync_rollback_obj(rbd_dev, snapid, seg_name); | ||
| 2465 | if (ret < 0) | ||
| 2466 | pr_warning("could not roll back obj %s err=%d\n", | ||
| 2467 | seg_name, ret); | ||
| 2468 | } | ||
| 2469 | |||
| 2470 | ret = __rbd_update_snaps(rbd_dev); | ||
| 2471 | if (ret < 0) | ||
| 2472 | goto done_unlock; | ||
| 2473 | |||
| 2474 | ret = count; | ||
| 2475 | |||
| 2476 | done_unlock: | ||
| 2477 | mutex_unlock(&ctl_mutex); | ||
| 2478 | done: | ||
| 2479 | kfree(seg_name); | ||
| 2480 | kfree(snap_name); | ||
| 2481 | |||
| 2482 | return ret; | ||
| 2483 | } | ||
| 2484 | |||
| 2485 | static struct bus_attribute rbd_bus_attrs[] = { | 2404 | static struct bus_attribute rbd_bus_attrs[] = { |
| 2486 | __ATTR(add, S_IWUSR, NULL, rbd_add), | 2405 | __ATTR(add, S_IWUSR, NULL, rbd_add), |
| 2487 | __ATTR(remove, S_IWUSR, NULL, rbd_remove), | 2406 | __ATTR(remove, S_IWUSR, NULL, rbd_remove), |
