aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/rbd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/rbd.c')
-rw-r--r--drivers/block/rbd.c101
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
184static int __rbd_init_snaps_header(struct rbd_device *rbd_dev); 184static int __rbd_init_snaps_header(struct rbd_device *rbd_dev);
185static void rbd_dev_release(struct device *dev); 185static void rbd_dev_release(struct device *dev);
186static ssize_t rbd_snap_rollback(struct device *dev,
187 struct device_attribute *attr,
188 const char *buf,
189 size_t size);
190static ssize_t rbd_snap_add(struct device *dev, 186static 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 */
1361static 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 */
1387static int rbd_req_sync_exec(struct rbd_device *dev, 1361static 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);
1882static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh); 1861static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh);
1883static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL); 1862static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL);
1884static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add); 1863static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add);
1885static DEVICE_ATTR(rollback_snap, S_IWUSR, NULL, rbd_snap_rollback);
1886 1864
1887static struct attribute *rbd_attrs[] = { 1865static 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
2427static 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
2476done_unlock:
2477 mutex_unlock(&ctl_mutex);
2478done:
2479 kfree(seg_name);
2480 kfree(snap_name);
2481
2482 return ret;
2483}
2484
2485static struct bus_attribute rbd_bus_attrs[] = { 2404static 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),