diff options
Diffstat (limited to 'drivers/block/rbd.c')
-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), |