Lines Matching +full:dout +full:- +full:default +full:- +full:2
3 rbd.c -- Export ceph rados objects as a Linux block device
27 Documentation/ABI/testing/sysfs-bus-rbd
43 #include <linux/blk-mq.h>
58 * -EINVAL without updating it.
70 return -EINVAL; in atomic_inc_return_safe()
73 /* Decrement the counter. Return the resulting value, or -EINVAL */
84 return -EINVAL; in atomic_dec_return_safe()
96 (NAME_MAX - (sizeof (RBD_SNAP_DEV_NAME_PREFIX) - 1))
100 #define RBD_SNAP_HEAD_NAME "-"
105 #define RBD_IMAGE_NAME_LEN_MAX (PAGE_SIZE - sizeof (__le32) - 1)
117 #define RBD_FEATURE_EXCLUSIVE_LOCK (1ULL<<2)
144 * block device image metadata (in-memory version)
170 * user-mapped image, the names are supplied and the id's associated
175 * non-null if the image it represents is a child in a layered
190 const char *pool_ns; /* NULL if default, never "" */
233 #define RBD_OBJ_FLAG_COPYUP_ZEROS (1U << 2)
252 * . v v (deep-copyup .
352 list_for_each_entry(oreq, &(ireq)->object_extents, ex.oe_item)
354 list_for_each_entry_safe(oreq, n, &(ireq)->object_extents, ex.oe_item)
388 u32 image_format; /* Either 1 or 2 */
455 * Flag bits for rbd_dev->flags:
456 * - REMOVING (which is coupled with rbd_dev->open_count) is protected
457 * by rbd_dev->lock
462 RBD_DEV_FLAG_READONLY, /* -o ro or snapshot */
473 /* Slab caches for frequently-allocated structures */
488 * single-major requires >= 0.75 version of userspace rbd utility.
492 MODULE_PARM_DESC(single_major, "Use a single major number for all rbd devices (default: true)");
515 return test_bit(RBD_DEV_FLAG_READONLY, &rbd_dev->flags); in rbd_is_ro()
520 return rbd_dev->spec->snap_id != CEPH_NOSNAP; in rbd_is_snap()
525 lockdep_assert_held(&rbd_dev->lock_rwsem); in __rbd_is_lock_owner()
527 return rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED || in __rbd_is_lock_owner()
528 rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING; in __rbd_is_lock_owner()
535 down_read(&rbd_dev->lock_rwsem); in rbd_is_lock_owner()
537 up_read(&rbd_dev->lock_rwsem); in rbd_is_lock_owner()
569 return attr->mode; in rbd_bus_is_visible()
592 static __printf(2, 3)
604 else if (rbd_dev->disk) in rbd_warn()
606 RBD_DRV_NAME, rbd_dev->disk->disk_name, &vaf); in rbd_warn()
607 else if (rbd_dev->spec && rbd_dev->spec->image_name) in rbd_warn()
609 RBD_DRV_NAME, rbd_dev->spec->image_name, &vaf); in rbd_warn()
610 else if (rbd_dev->spec && rbd_dev->spec->image_id) in rbd_warn()
612 RBD_DRV_NAME, rbd_dev->spec->image_id, &vaf); in rbd_warn()
651 rbd_assert(pending->num_pending > 0); in pending_result_dec()
653 if (*result && !pending->result) in pending_result_dec()
654 pending->result = *result; in pending_result_dec()
655 if (--pending->num_pending) in pending_result_dec()
658 *result = pending->result; in pending_result_dec()
664 struct rbd_device *rbd_dev = bdev->bd_disk->private_data; in rbd_open()
667 spin_lock_irq(&rbd_dev->lock); in rbd_open()
668 if (test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags)) in rbd_open()
671 rbd_dev->open_count++; in rbd_open()
672 spin_unlock_irq(&rbd_dev->lock); in rbd_open()
674 return -ENOENT; in rbd_open()
676 (void) get_device(&rbd_dev->dev); in rbd_open()
683 struct rbd_device *rbd_dev = disk->private_data; in rbd_release()
686 spin_lock_irq(&rbd_dev->lock); in rbd_release()
687 open_count_before = rbd_dev->open_count--; in rbd_release()
688 spin_unlock_irq(&rbd_dev->lock); in rbd_release()
691 put_device(&rbd_dev->dev); in rbd_release()
699 return -EFAULT; in rbd_ioctl_set_ro()
702 * Both images mapped read-only and snapshots can't be marked in rbd_ioctl_set_ro()
703 * read-write. in rbd_ioctl_set_ro()
707 return -EROFS; in rbd_ioctl_set_ro()
713 return -ENOTTY; in rbd_ioctl_set_ro()
719 struct rbd_device *rbd_dev = bdev->bd_disk->private_data; in rbd_ioctl()
726 default: in rbd_ioctl()
727 ret = -ENOTTY; in rbd_ioctl()
758 int ret = -ENOMEM; in rbd_client_create()
760 dout("%s:\n", __func__); in rbd_client_create()
765 kref_init(&rbdc->kref); in rbd_client_create()
766 INIT_LIST_HEAD(&rbdc->node); in rbd_client_create()
768 rbdc->client = ceph_create_client(ceph_opts, rbdc); in rbd_client_create()
769 if (IS_ERR(rbdc->client)) in rbd_client_create()
771 ceph_opts = NULL; /* Now rbdc->client is responsible for ceph_opts */ in rbd_client_create()
773 ret = ceph_open_session(rbdc->client); in rbd_client_create()
778 list_add_tail(&rbdc->node, &rbd_client_list); in rbd_client_create()
781 dout("%s: rbdc %p\n", __func__, rbdc); in rbd_client_create()
785 ceph_destroy_client(rbdc->client); in rbd_client_create()
791 dout("%s: error %d\n", __func__, ret); in rbd_client_create()
798 kref_get(&rbdc->kref); in __rbd_get_client()
812 if (ceph_opts->flags & CEPH_OPT_NOSHARE) in rbd_client_find()
817 if (!ceph_compare_options(ceph_opts, client_node->client)) { in rbd_client_find()
914 default: in obj_op_name()
928 dout("%s: rbdc %p\n", __func__, rbdc); in rbd_client_release()
930 list_del(&rbdc->node); in rbd_client_release()
933 ceph_destroy_client(rbdc->client); in rbd_client_release()
944 kref_put(&rbdc->kref, rbd_client_release); in rbd_put_client()
963 * Using an existing client. Make sure ->pg_pools is up to in rbd_get_client()
966 ret = ceph_wait_for_latest_osdmap(rbdc->client, in rbd_get_client()
967 rbdc->client->options->mount_timeout); in rbd_get_client()
983 return image_format == 1 || image_format == 2; in rbd_image_format_valid()
992 if (memcmp(&ondisk->text, RBD_HEADER_TEXT, sizeof (RBD_HEADER_TEXT))) in rbd_dev_ondisk_valid()
995 /* The bio layer requires at least sector-sized I/O */ in rbd_dev_ondisk_valid()
997 if (ondisk->options.order < SECTOR_SHIFT) in rbd_dev_ondisk_valid()
1002 if (ondisk->options.order > 8 * sizeof (int) - 1) in rbd_dev_ondisk_valid()
1009 snap_count = le32_to_cpu(ondisk->snap_count); in rbd_dev_ondisk_valid()
1010 size = SIZE_MAX - sizeof (struct ceph_snap_context); in rbd_dev_ondisk_valid()
1018 size -= snap_count * sizeof (__le64); in rbd_dev_ondisk_valid()
1019 if ((u64) size < le64_to_cpu(ondisk->snap_names_len)) in rbd_dev_ondisk_valid()
1030 return 1U << header->obj_order; in rbd_obj_bytes()
1035 if (rbd_dev->header.stripe_unit == 0 || in rbd_init_layout()
1036 rbd_dev->header.stripe_count == 0) { in rbd_init_layout()
1037 rbd_dev->header.stripe_unit = rbd_obj_bytes(&rbd_dev->header); in rbd_init_layout()
1038 rbd_dev->header.stripe_count = 1; in rbd_init_layout()
1041 rbd_dev->layout.stripe_unit = rbd_dev->header.stripe_unit; in rbd_init_layout()
1042 rbd_dev->layout.stripe_count = rbd_dev->header.stripe_count; in rbd_init_layout()
1043 rbd_dev->layout.object_size = rbd_obj_bytes(&rbd_dev->header); in rbd_init_layout()
1044 rbd_dev->layout.pool_id = rbd_dev->header.data_pool_id == CEPH_NOPOOL ? in rbd_init_layout()
1045 rbd_dev->spec->pool_id : rbd_dev->header.data_pool_id; in rbd_init_layout()
1046 RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL); in rbd_init_layout()
1051 kfree(header->object_prefix); in rbd_image_header_cleanup()
1052 ceph_put_snap_context(header->snapc); in rbd_image_header_cleanup()
1053 kfree(header->snap_sizes); in rbd_image_header_cleanup()
1054 kfree(header->snap_names); in rbd_image_header_cleanup()
1061 * on-disk header.
1072 int ret = -ENOMEM; in rbd_header_from_disk()
1078 object_prefix = kstrndup(ondisk->object_prefix, in rbd_header_from_disk()
1079 sizeof(ondisk->object_prefix), in rbd_header_from_disk()
1082 return -ENOMEM; in rbd_header_from_disk()
1087 snap_count = le32_to_cpu(ondisk->snap_count); in rbd_header_from_disk()
1091 snapc->seq = le64_to_cpu(ondisk->snap_seq); in rbd_header_from_disk()
1094 u64 snap_names_len = le64_to_cpu(ondisk->snap_names_len); in rbd_header_from_disk()
1106 sizeof(*header->snap_sizes), in rbd_header_from_disk()
1120 memcpy(snap_names, &ondisk->snaps[snap_count], snap_names_len); in rbd_header_from_disk()
1121 snaps = ondisk->snaps; in rbd_header_from_disk()
1123 snapc->snaps[i] = le64_to_cpu(snaps[i].id); in rbd_header_from_disk()
1131 header->object_prefix = object_prefix; in rbd_header_from_disk()
1132 header->obj_order = ondisk->options.order; in rbd_header_from_disk()
1137 header->image_size = le64_to_cpu(ondisk->image_size); in rbd_header_from_disk()
1138 header->snapc = snapc; in rbd_header_from_disk()
1139 header->snap_names = snap_names; in rbd_header_from_disk()
1140 header->snap_sizes = snap_sizes; in rbd_header_from_disk()
1144 ret = -EIO; in rbd_header_from_disk()
1158 rbd_assert(which < rbd_dev->header.snapc->num_snaps); in _rbd_dev_v1_snap_name()
1162 snap_name = rbd_dev->header.snap_names; in _rbd_dev_v1_snap_name()
1163 while (which--) in _rbd_dev_v1_snap_name()
1180 return snap_id1 == snap_id2 ? 0 : -1; in snapid_compare_reverse()
1195 struct ceph_snap_context *snapc = rbd_dev->header.snapc; in rbd_dev_snap_index()
1198 found = bsearch(&snap_id, &snapc->snaps, snapc->num_snaps, in rbd_dev_snap_index()
1201 return found ? (u32)(found - &snapc->snaps[0]) : BAD_SNAP_INDEX; in rbd_dev_snap_index()
1212 return ERR_PTR(-ENOENT); in rbd_dev_v1_snap_name()
1215 return snap_name ? snap_name : ERR_PTR(-ENOMEM); in rbd_dev_v1_snap_name()
1223 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_snap_name()
1224 if (rbd_dev->image_format == 1) in rbd_snap_name()
1233 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_snap_size()
1235 *snap_size = rbd_dev->header.image_size; in rbd_snap_size()
1236 } else if (rbd_dev->image_format == 1) { in rbd_snap_size()
1241 return -ENOENT; in rbd_snap_size()
1243 *snap_size = rbd_dev->header.snap_sizes[which]; in rbd_snap_size()
1259 u64 snap_id = rbd_dev->spec->snap_id; in rbd_dev_mapping_set()
1267 rbd_dev->mapping.size = size; in rbd_dev_mapping_set()
1273 rbd_dev->mapping.size = 0; in rbd_dev_mapping_clear()
1282 memset(buf, 0, bv->bv_len); in zero_bvec()
1283 flush_dcache_page(bv->bv_page); in zero_bvec()
1316 dout("%s %p data buf %u~%u\n", __func__, obj_req, off, bytes); in rbd_obj_zero_range()
1318 switch (obj_req->img_request->data_type) { in rbd_obj_zero_range()
1320 zero_bios(&obj_req->bio_pos, off, bytes); in rbd_obj_zero_range()
1324 zero_bvecs(&obj_req->bvec_pos, off, bytes); in rbd_obj_zero_range()
1326 default: in rbd_obj_zero_range()
1335 dout("%s: obj %p (was %d)\n", __func__, obj_request, in rbd_obj_request_put()
1336 kref_read(&obj_request->kref)); in rbd_obj_request_put()
1337 kref_put(&obj_request->kref, rbd_obj_request_destroy); in rbd_obj_request_put()
1343 rbd_assert(obj_request->img_request == NULL); in rbd_img_obj_request_add()
1346 obj_request->img_request = img_request; in rbd_img_obj_request_add()
1347 dout("%s: img %p obj %p\n", __func__, img_request, obj_request); in rbd_img_obj_request_add()
1353 dout("%s: img %p obj %p\n", __func__, img_request, obj_request); in rbd_img_obj_request_del()
1354 list_del(&obj_request->ex.oe_item); in rbd_img_obj_request_del()
1355 rbd_assert(obj_request->img_request == img_request); in rbd_img_obj_request_del()
1361 struct rbd_obj_request *obj_req = osd_req->r_priv; in rbd_osd_submit()
1363 dout("%s osd_req %p for obj_req %p objno %llu %llu~%llu\n", in rbd_osd_submit()
1364 __func__, osd_req, obj_req, obj_req->ex.oe_objno, in rbd_osd_submit()
1365 obj_req->ex.oe_off, obj_req->ex.oe_len); in rbd_osd_submit()
1366 ceph_osdc_start_request(osd_req->r_osdc, osd_req, false); in rbd_osd_submit()
1370 * The default/initial value for all image request flags is 0. Each
1376 set_bit(IMG_REQ_LAYERED, &img_request->flags); in img_request_layered_set()
1381 return test_bit(IMG_REQ_LAYERED, &img_request->flags) != 0; in img_request_layered_test()
1386 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_is_entire()
1388 return !obj_req->ex.oe_off && in rbd_obj_is_entire()
1389 obj_req->ex.oe_len == rbd_dev->layout.object_size; in rbd_obj_is_entire()
1394 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_is_tail()
1396 return obj_req->ex.oe_off + obj_req->ex.oe_len == in rbd_obj_is_tail()
1397 rbd_dev->layout.object_size; in rbd_obj_is_tail()
1405 rbd_assert(obj_req->img_request->snapc); in rbd_obj_set_copyup_enabled()
1407 if (obj_req->img_request->op_type == OBJ_OP_DISCARD) { in rbd_obj_set_copyup_enabled()
1408 dout("%s %p objno %llu discard\n", __func__, obj_req, in rbd_obj_set_copyup_enabled()
1409 obj_req->ex.oe_objno); in rbd_obj_set_copyup_enabled()
1413 if (!obj_req->num_img_extents) { in rbd_obj_set_copyup_enabled()
1414 dout("%s %p objno %llu not overlapping\n", __func__, obj_req, in rbd_obj_set_copyup_enabled()
1415 obj_req->ex.oe_objno); in rbd_obj_set_copyup_enabled()
1420 !obj_req->img_request->snapc->num_snaps) { in rbd_obj_set_copyup_enabled()
1421 dout("%s %p objno %llu entire\n", __func__, obj_req, in rbd_obj_set_copyup_enabled()
1422 obj_req->ex.oe_objno); in rbd_obj_set_copyup_enabled()
1426 obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ENABLED; in rbd_obj_set_copyup_enabled()
1431 return ceph_file_extents_bytes(obj_req->img_extents, in rbd_obj_img_extents_bytes()
1432 obj_req->num_img_extents); in rbd_obj_img_extents_bytes()
1437 switch (img_req->op_type) { in rbd_img_is_write()
1444 default: in rbd_img_is_write()
1451 struct rbd_obj_request *obj_req = osd_req->r_priv; in rbd_osd_req_callback()
1454 dout("%s osd_req %p result %d for obj_req %p\n", __func__, osd_req, in rbd_osd_req_callback()
1455 osd_req->r_result, obj_req); in rbd_osd_req_callback()
1462 if (osd_req->r_result > 0 && rbd_img_is_write(obj_req->img_request)) in rbd_osd_req_callback()
1465 result = osd_req->r_result; in rbd_osd_req_callback()
1472 struct rbd_obj_request *obj_request = osd_req->r_priv; in rbd_osd_format_read()
1473 struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev; in rbd_osd_format_read()
1474 struct ceph_options *opt = rbd_dev->rbd_client->client->options; in rbd_osd_format_read()
1476 osd_req->r_flags = CEPH_OSD_FLAG_READ | opt->read_from_replica; in rbd_osd_format_read()
1477 osd_req->r_snapid = obj_request->img_request->snap_id; in rbd_osd_format_read()
1482 struct rbd_obj_request *obj_request = osd_req->r_priv; in rbd_osd_format_write()
1484 osd_req->r_flags = CEPH_OSD_FLAG_WRITE; in rbd_osd_format_write()
1485 ktime_get_real_ts64(&osd_req->r_mtime); in rbd_osd_format_write()
1486 osd_req->r_data_offset = obj_request->ex.oe_off; in rbd_osd_format_write()
1493 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in __rbd_obj_add_osd_request()
1494 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_obj_add_osd_request()
1496 const char *name_format = rbd_dev->image_format == 1 ? in __rbd_obj_add_osd_request()
1502 return ERR_PTR(-ENOMEM); in __rbd_obj_add_osd_request()
1504 list_add_tail(&req->r_private_item, &obj_req->osd_reqs); in __rbd_obj_add_osd_request()
1505 req->r_callback = rbd_osd_req_callback; in __rbd_obj_add_osd_request()
1506 req->r_priv = obj_req; in __rbd_obj_add_osd_request()
1512 ceph_oloc_copy(&req->r_base_oloc, &rbd_dev->header_oloc); in __rbd_obj_add_osd_request()
1513 req->r_base_oloc.pool = rbd_dev->layout.pool_id; in __rbd_obj_add_osd_request()
1515 ret = ceph_oid_aprintf(&req->r_base_oid, GFP_NOIO, name_format, in __rbd_obj_add_osd_request()
1516 rbd_dev->header.object_prefix, in __rbd_obj_add_osd_request()
1517 obj_req->ex.oe_objno); in __rbd_obj_add_osd_request()
1527 rbd_assert(obj_req->img_request->snapc); in rbd_obj_add_osd_request()
1528 return __rbd_obj_add_osd_request(obj_req, obj_req->img_request->snapc, in rbd_obj_add_osd_request()
1540 ceph_object_extent_init(&obj_request->ex); in rbd_obj_request_create()
1541 INIT_LIST_HEAD(&obj_request->osd_reqs); in rbd_obj_request_create()
1542 mutex_init(&obj_request->state_mutex); in rbd_obj_request_create()
1543 kref_init(&obj_request->kref); in rbd_obj_request_create()
1545 dout("%s %p\n", __func__, obj_request); in rbd_obj_request_create()
1557 dout("%s: obj %p\n", __func__, obj_request); in rbd_obj_request_destroy()
1559 while (!list_empty(&obj_request->osd_reqs)) { in rbd_obj_request_destroy()
1560 osd_req = list_first_entry(&obj_request->osd_reqs, in rbd_obj_request_destroy()
1562 list_del_init(&osd_req->r_private_item); in rbd_obj_request_destroy()
1566 switch (obj_request->img_request->data_type) { in rbd_obj_request_destroy()
1572 kfree(obj_request->bvec_pos.bvecs); in rbd_obj_request_destroy()
1574 default: in rbd_obj_request_destroy()
1578 kfree(obj_request->img_extents); in rbd_obj_request_destroy()
1579 if (obj_request->copyup_bvecs) { in rbd_obj_request_destroy()
1580 for (i = 0; i < obj_request->copyup_bvec_count; i++) { in rbd_obj_request_destroy()
1581 if (obj_request->copyup_bvecs[i].bv_page) in rbd_obj_request_destroy()
1582 __free_page(obj_request->copyup_bvecs[i].bv_page); in rbd_obj_request_destroy()
1584 kfree(obj_request->copyup_bvecs); in rbd_obj_request_destroy()
1596 rbd_spec_put(rbd_dev->parent_spec); in rbd_dev_unparent()
1597 rbd_dev->parent_spec = NULL; in rbd_dev_unparent()
1598 rbd_dev->parent_overlap = 0; in rbd_dev_unparent()
1603 * image's parent fields can be safely torn down--after there are no
1604 * more in-flight requests to the parent image. When the last
1611 if (!rbd_dev->parent_spec) in rbd_dev_parent_put()
1614 counter = atomic_dec_return_safe(&rbd_dev->parent_ref); in rbd_dev_parent_put()
1627 * If an image has a non-zero parent overlap, get a reference to its
1630 * Returns true if the rbd device has a parent with a non-zero
1638 if (!rbd_dev->parent_spec) in rbd_dev_parent_get()
1641 if (rbd_dev->parent_overlap) in rbd_dev_parent_get()
1642 counter = atomic_inc_return_safe(&rbd_dev->parent_ref); in rbd_dev_parent_get()
1656 img_request->rbd_dev = rbd_dev; in rbd_img_request_init()
1657 img_request->op_type = op_type; in rbd_img_request_init()
1659 INIT_LIST_HEAD(&img_request->lock_item); in rbd_img_request_init()
1660 INIT_LIST_HEAD(&img_request->object_extents); in rbd_img_request_init()
1661 mutex_init(&img_request->state_mutex); in rbd_img_request_init()
1671 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_img_capture_header()
1673 lockdep_assert_held(&rbd_dev->header_rwsem); in rbd_img_capture_header()
1676 img_req->snap_id = rbd_dev->spec->snap_id; in rbd_img_capture_header()
1687 dout("%s: img %p\n", __func__, img_request); in rbd_img_request_destroy()
1689 WARN_ON(!list_empty(&img_request->lock_item)); in rbd_img_request_destroy()
1694 rbd_dev_parent_put(img_request->rbd_dev); in rbd_img_request_destroy()
1697 ceph_put_snap_context(img_request->snapc); in rbd_img_request_destroy()
1699 if (test_bit(IMG_REQ_CHILD, &img_request->flags)) in rbd_img_request_destroy()
1703 #define BITS_PER_OBJ 2
1705 #define OBJ_MASK ((1 << BITS_PER_OBJ) - 1)
1712 rbd_assert(objno < rbd_dev->object_map_size); in __rbd_object_map_index()
1714 *shift = (OBJS_PER_BYTE - off - 1) * BITS_PER_OBJ; in __rbd_object_map_index()
1722 lockdep_assert_held(&rbd_dev->object_map_lock); in __rbd_object_map_get()
1724 return (rbd_dev->object_map[index] >> shift) & OBJ_MASK; in __rbd_object_map_get()
1733 lockdep_assert_held(&rbd_dev->object_map_lock); in __rbd_object_map_set()
1737 p = &rbd_dev->object_map[index]; in __rbd_object_map_set()
1745 spin_lock(&rbd_dev->object_map_lock); in rbd_object_map_get()
1747 spin_unlock(&rbd_dev->object_map_lock); in rbd_object_map_get()
1754 * An image mapped read-only can't use the object map -- it isn't in use_object_map()
1764 return ((rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP) && in use_object_map()
1765 !(rbd_dev->object_map_flags & RBD_FLAG_OBJECT_MAP_INVALID)); in use_object_map()
1772 /* fall back to default logic if object map is disabled or invalid */ in rbd_object_map_may_exist()
1785 rbd_dev->spec->image_id); in rbd_object_map_name()
1788 rbd_dev->spec->image_id, snap_id); in rbd_object_map_name()
1793 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_object_map_lock()
1805 ret = ceph_cls_lock(osdc, &oid, &rbd_dev->header_oloc, RBD_LOCK_NAME, in rbd_object_map_lock()
1807 if (ret != -EBUSY || broke_lock) { in rbd_object_map_lock()
1808 if (ret == -EEXIST) in rbd_object_map_lock()
1815 ret = ceph_cls_lock_info(osdc, &oid, &rbd_dev->header_oloc, in rbd_object_map_lock()
1819 if (ret == -ENOENT) in rbd_object_map_lock()
1833 ret = ceph_cls_break_lock(osdc, &oid, &rbd_dev->header_oloc, in rbd_object_map_lock()
1838 if (ret == -ENOENT) in rbd_object_map_lock()
1851 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_object_map_unlock()
1857 ret = ceph_cls_unlock(osdc, &oid, &rbd_dev->header_oloc, RBD_LOCK_NAME, in rbd_object_map_unlock()
1859 if (ret && ret != -ENOENT) in rbd_object_map_unlock()
1885 return -EINVAL; in decode_object_map_header()
1890 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_object_map_load()
1901 rbd_assert(!rbd_dev->object_map && !rbd_dev->object_map_size); in __rbd_object_map_load()
1903 num_objects = ceph_get_num_objects(&rbd_dev->layout, in __rbd_object_map_load()
1904 rbd_dev->mapping.size); in __rbd_object_map_load()
1913 rbd_object_map_name(rbd_dev, rbd_dev->spec->snap_id, &oid); in __rbd_object_map_load()
1914 ret = ceph_osdc_call(osdc, &oid, &rbd_dev->header_oloc, in __rbd_object_map_load()
1929 ret = -EINVAL; in __rbd_object_map_load()
1934 ret = -EINVAL; in __rbd_object_map_load()
1938 rbd_dev->object_map = kvmalloc(object_map_bytes, GFP_KERNEL); in __rbd_object_map_load()
1939 if (!rbd_dev->object_map) { in __rbd_object_map_load()
1940 ret = -ENOMEM; in __rbd_object_map_load()
1944 rbd_dev->object_map_size = object_map_size; in __rbd_object_map_load()
1945 ceph_copy_from_page_vector(pages, rbd_dev->object_map, in __rbd_object_map_load()
1955 kvfree(rbd_dev->object_map); in rbd_object_map_free()
1956 rbd_dev->object_map = NULL; in rbd_object_map_free()
1957 rbd_dev->object_map_size = 0; in rbd_object_map_free()
1974 if (rbd_dev->object_map_flags & RBD_FLAG_OBJECT_MAP_INVALID) in rbd_object_map_load()
2016 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_object_map_update_finish()
2023 if (osd_req->r_result) in rbd_object_map_update_finish()
2024 return osd_req->r_result; in rbd_object_map_update_finish()
2029 if (osd_req->r_num_ops == 1) in rbd_object_map_update_finish()
2033 * Update in-memory HEAD object map. in rbd_object_map_update_finish()
2035 rbd_assert(osd_req->r_num_ops == 2); in rbd_object_map_update_finish()
2037 rbd_assert(osd_data->type == CEPH_OSD_DATA_TYPE_PAGES); in rbd_object_map_update_finish()
2039 p = page_address(osd_data->pages[0]); in rbd_object_map_update_finish()
2041 rbd_assert(objno == obj_req->ex.oe_objno); in rbd_object_map_update_finish()
2048 spin_lock(&rbd_dev->object_map_lock); in rbd_object_map_update_finish()
2053 spin_unlock(&rbd_dev->object_map_lock); in rbd_object_map_update_finish()
2060 struct rbd_obj_request *obj_req = osd_req->r_priv; in rbd_object_map_callback()
2063 dout("%s osd_req %p result %d for obj_req %p\n", __func__, osd_req, in rbd_object_map_callback()
2064 osd_req->r_result, obj_req); in rbd_object_map_callback()
2109 osd_req_op_cls_request_data_pages(req, which, pages, p - start, 0, in rbd_cls_object_map_update()
2116 * 0 - object map update sent
2117 * 1 - object map update isn't needed
2118 * <0 - error
2123 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_object_map_update()
2124 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_object_map_update()
2131 if (!update_needed(rbd_dev, obj_req->ex.oe_objno, new_state)) in rbd_object_map_update()
2139 return -ENOMEM; in rbd_object_map_update()
2141 list_add_tail(&req->r_private_item, &obj_req->osd_reqs); in rbd_object_map_update()
2142 req->r_callback = rbd_object_map_callback; in rbd_object_map_update()
2143 req->r_priv = obj_req; in rbd_object_map_update()
2145 rbd_object_map_name(rbd_dev, snap_id, &req->r_base_oid); in rbd_object_map_update()
2146 ceph_oloc_copy(&req->r_base_oloc, &rbd_dev->header_oloc); in rbd_object_map_update()
2147 req->r_flags = CEPH_OSD_FLAG_WRITE; in rbd_object_map_update()
2148 ktime_get_real_ts64(&req->r_mtime); in rbd_object_map_update()
2161 ret = rbd_cls_object_map_update(req, which, obj_req->ex.oe_objno, in rbd_object_map_update()
2180 while (cnt && img_extents[cnt - 1].fe_off >= overlap) in prune_extents()
2181 cnt--; in prune_extents()
2184 struct ceph_file_extent *ex = &img_extents[cnt - 1]; in prune_extents()
2187 if (ex->fe_off + ex->fe_len > overlap) in prune_extents()
2188 ex->fe_len = overlap - ex->fe_off; in prune_extents()
2201 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_calc_img_extents()
2204 if (!rbd_dev->parent_overlap) in rbd_obj_calc_img_extents()
2207 ret = ceph_extent_to_file(&rbd_dev->layout, obj_req->ex.oe_objno, in rbd_obj_calc_img_extents()
2208 entire ? 0 : obj_req->ex.oe_off, in rbd_obj_calc_img_extents()
2209 entire ? rbd_dev->layout.object_size : in rbd_obj_calc_img_extents()
2210 obj_req->ex.oe_len, in rbd_obj_calc_img_extents()
2211 &obj_req->img_extents, in rbd_obj_calc_img_extents()
2212 &obj_req->num_img_extents); in rbd_obj_calc_img_extents()
2216 prune_extents(obj_req->img_extents, &obj_req->num_img_extents, in rbd_obj_calc_img_extents()
2217 rbd_dev->parent_overlap); in rbd_obj_calc_img_extents()
2223 struct rbd_obj_request *obj_req = osd_req->r_priv; in rbd_osd_setup_data()
2225 switch (obj_req->img_request->data_type) { in rbd_osd_setup_data()
2228 &obj_req->bio_pos, in rbd_osd_setup_data()
2229 obj_req->ex.oe_len); in rbd_osd_setup_data()
2233 rbd_assert(obj_req->bvec_pos.iter.bi_size == in rbd_osd_setup_data()
2234 obj_req->ex.oe_len); in rbd_osd_setup_data()
2235 rbd_assert(obj_req->bvec_idx == obj_req->bvec_count); in rbd_osd_setup_data()
2237 &obj_req->bvec_pos); in rbd_osd_setup_data()
2239 default: in rbd_osd_setup_data()
2270 struct rbd_obj_request *obj_req = osd_req->r_priv; in rbd_osd_setup_copyup()
2277 osd_req_op_cls_request_data_bvecs(osd_req, which, obj_req->copyup_bvecs, in rbd_osd_setup_copyup()
2278 obj_req->copyup_bvec_count, bytes); in rbd_osd_setup_copyup()
2284 obj_req->read_state = RBD_OBJ_READ_START; in rbd_obj_init_read()
2291 struct rbd_obj_request *obj_req = osd_req->r_priv; in __rbd_osd_setup_write_ops()
2292 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in __rbd_osd_setup_write_ops()
2296 !(obj_req->flags & RBD_OBJ_FLAG_MAY_EXIST)) { in __rbd_osd_setup_write_ops()
2298 rbd_dev->layout.object_size, in __rbd_osd_setup_write_ops()
2299 rbd_dev->layout.object_size, in __rbd_osd_setup_write_ops()
2300 rbd_dev->opts->alloc_hint_flags); in __rbd_osd_setup_write_ops()
2309 obj_req->ex.oe_off, obj_req->ex.oe_len, 0, 0); in __rbd_osd_setup_write_ops()
2322 obj_req->write_state = RBD_OBJ_WRITE_START; in rbd_obj_init_write()
2335 struct rbd_obj_request *obj_req = osd_req->r_priv; in __rbd_osd_setup_discard_ops()
2337 if (rbd_obj_is_entire(obj_req) && !obj_req->num_img_extents) { in __rbd_osd_setup_discard_ops()
2338 rbd_assert(obj_req->flags & RBD_OBJ_FLAG_DELETION); in __rbd_osd_setup_discard_ops()
2343 obj_req->ex.oe_off, obj_req->ex.oe_len, in __rbd_osd_setup_discard_ops()
2350 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_init_discard()
2362 if (rbd_dev->opts->alloc_size != rbd_dev->layout.object_size || in rbd_obj_init_discard()
2364 off = round_up(obj_req->ex.oe_off, rbd_dev->opts->alloc_size); in rbd_obj_init_discard()
2365 next_off = round_down(obj_req->ex.oe_off + obj_req->ex.oe_len, in rbd_obj_init_discard()
2366 rbd_dev->opts->alloc_size); in rbd_obj_init_discard()
2370 dout("%s %p %llu~%llu -> %llu~%llu\n", __func__, in rbd_obj_init_discard()
2371 obj_req, obj_req->ex.oe_off, obj_req->ex.oe_len, in rbd_obj_init_discard()
2372 off, next_off - off); in rbd_obj_init_discard()
2373 obj_req->ex.oe_off = off; in rbd_obj_init_discard()
2374 obj_req->ex.oe_len = next_off - off; in rbd_obj_init_discard()
2382 obj_req->flags |= RBD_OBJ_FLAG_NOOP_FOR_NONEXISTENT; in rbd_obj_init_discard()
2383 if (rbd_obj_is_entire(obj_req) && !obj_req->num_img_extents) in rbd_obj_init_discard()
2384 obj_req->flags |= RBD_OBJ_FLAG_DELETION; in rbd_obj_init_discard()
2386 obj_req->write_state = RBD_OBJ_WRITE_START; in rbd_obj_init_discard()
2393 struct rbd_obj_request *obj_req = osd_req->r_priv; in __rbd_osd_setup_zeroout_ops()
2397 if (obj_req->num_img_extents) { in __rbd_osd_setup_zeroout_ops()
2398 if (!(obj_req->flags & RBD_OBJ_FLAG_COPYUP_ENABLED)) in __rbd_osd_setup_zeroout_ops()
2403 rbd_assert(obj_req->flags & RBD_OBJ_FLAG_DELETION); in __rbd_osd_setup_zeroout_ops()
2414 obj_req->ex.oe_off, obj_req->ex.oe_len, in __rbd_osd_setup_zeroout_ops()
2427 if (!obj_req->num_img_extents) { in rbd_obj_init_zeroout()
2428 obj_req->flags |= RBD_OBJ_FLAG_NOOP_FOR_NONEXISTENT; in rbd_obj_init_zeroout()
2430 obj_req->flags |= RBD_OBJ_FLAG_DELETION; in rbd_obj_init_zeroout()
2433 obj_req->write_state = RBD_OBJ_WRITE_START; in rbd_obj_init_zeroout()
2439 struct rbd_img_request *img_req = obj_req->img_request; in count_write_ops()
2441 switch (img_req->op_type) { in count_write_ops()
2443 if (!use_object_map(img_req->rbd_dev) || in count_write_ops()
2444 !(obj_req->flags & RBD_OBJ_FLAG_MAY_EXIST)) in count_write_ops()
2445 return 2; /* setallochint + write/writefull */ in count_write_ops()
2451 if (rbd_obj_is_entire(obj_req) && obj_req->num_img_extents && in count_write_ops()
2452 !(obj_req->flags & RBD_OBJ_FLAG_COPYUP_ENABLED)) in count_write_ops()
2453 return 2; /* create + truncate */ in count_write_ops()
2456 default: in count_write_ops()
2464 struct rbd_obj_request *obj_req = osd_req->r_priv; in rbd_osd_setup_write_ops()
2466 switch (obj_req->img_request->op_type) { in rbd_osd_setup_write_ops()
2476 default: in rbd_osd_setup_write_ops()
2492 switch (img_req->op_type) { in __rbd_img_fill_request()
2505 default: in __rbd_img_fill_request()
2516 img_req->state = RBD_IMG_START; in __rbd_img_fill_request()
2544 return &obj_req->ex; in alloc_object_extent()
2550 * because ->set_pos_fn() should be called only once per object.
2556 return l->stripe_unit != l->object_size; in rbd_layout_is_fancy()
2567 img_req->data_type = fctx->pos_type; in rbd_img_fill_request_nocopy()
2573 fctx->iter = *fctx->pos; in rbd_img_fill_request_nocopy()
2575 ret = ceph_file_to_extents(&img_req->rbd_dev->layout, in rbd_img_fill_request_nocopy()
2578 &img_req->object_extents, in rbd_img_fill_request_nocopy()
2580 fctx->set_pos_fn, &fctx->iter); in rbd_img_fill_request_nocopy()
2593 * @fctx->pos data buffer.
2597 * different chunks of @fctx->pos data buffer.
2599 * @fctx->pos data buffer is assumed to be large enough.
2606 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_img_fill_request()
2611 if (fctx->pos_type == OBJ_REQUEST_NODATA || in rbd_img_fill_request()
2612 !rbd_layout_is_fancy(&rbd_dev->layout)) in rbd_img_fill_request()
2616 img_req->data_type = OBJ_REQUEST_OWN_BVECS; in rbd_img_fill_request()
2619 * Create object requests and determine ->bvec_count for each object in rbd_img_fill_request()
2620 * request. Note that ->bvec_count sum over all object requests may in rbd_img_fill_request()
2625 fctx->iter = *fctx->pos; in rbd_img_fill_request()
2627 ret = ceph_file_to_extents(&rbd_dev->layout, in rbd_img_fill_request()
2630 &img_req->object_extents, in rbd_img_fill_request()
2632 fctx->count_fn, &fctx->iter); in rbd_img_fill_request()
2638 obj_req->bvec_pos.bvecs = kmalloc_array(obj_req->bvec_count, in rbd_img_fill_request()
2639 sizeof(*obj_req->bvec_pos.bvecs), in rbd_img_fill_request()
2641 if (!obj_req->bvec_pos.bvecs) in rbd_img_fill_request()
2642 return -ENOMEM; in rbd_img_fill_request()
2649 fctx->iter = *fctx->pos; in rbd_img_fill_request()
2651 ret = ceph_iterate_extents(&rbd_dev->layout, in rbd_img_fill_request()
2654 &img_req->object_extents, in rbd_img_fill_request()
2655 fctx->copy_fn, &fctx->iter); in rbd_img_fill_request()
2682 dout("%s objno %llu bytes %u\n", __func__, ex->oe_objno, bytes); in set_bio_pos()
2683 obj_req->bio_pos = *it; in set_bio_pos()
2693 dout("%s objno %llu bytes %u\n", __func__, ex->oe_objno, bytes); in count_bio_bvecs()
2695 obj_req->bvec_count++; in count_bio_bvecs()
2706 dout("%s objno %llu bytes %u\n", __func__, ex->oe_objno, bytes); in copy_bio_bvecs()
2708 obj_req->bvec_pos.bvecs[obj_req->bvec_idx++] = bv; in copy_bio_bvecs()
2709 obj_req->bvec_pos.iter.bi_size += bv.bv_len; in copy_bio_bvecs()
2734 struct ceph_bio_iter it = { .bio = bio, .iter = bio->bi_iter }; in rbd_img_fill_from_bio()
2745 obj_req->bvec_pos = *it; in set_bvec_pos()
2746 ceph_bvec_iter_shorten(&obj_req->bvec_pos, bytes); in set_bvec_pos()
2757 obj_req->bvec_count++; in count_bvecs()
2768 obj_req->bvec_pos.bvecs[obj_req->bvec_idx++] = bv; in copy_bvecs()
2769 obj_req->bvec_pos.iter.bi_size += bv.bv_len; in copy_bvecs()
2810 rbd_img_handle_request(img_req, img_req->work_result); in rbd_img_handle_request_work()
2815 INIT_WORK(&img_req->work, rbd_img_handle_request_work); in rbd_img_schedule()
2816 img_req->work_result = result; in rbd_img_schedule()
2817 queue_work(rbd_wq, &img_req->work); in rbd_img_schedule()
2822 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_may_exist()
2824 if (rbd_object_map_may_exist(rbd_dev, obj_req->ex.oe_objno)) { in rbd_obj_may_exist()
2825 obj_req->flags |= RBD_OBJ_FLAG_MAY_EXIST; in rbd_obj_may_exist()
2829 dout("%s %p objno %llu assuming dne\n", __func__, obj_req, in rbd_obj_may_exist()
2830 obj_req->ex.oe_objno); in rbd_obj_may_exist()
2844 obj_req->ex.oe_off, obj_req->ex.oe_len, 0, 0); in rbd_obj_read_object()
2858 struct rbd_img_request *img_req = obj_req->img_request; in rbd_obj_read_from_parent()
2859 struct rbd_device *parent = img_req->rbd_dev->parent; in rbd_obj_read_from_parent()
2865 return -ENOMEM; in rbd_obj_read_from_parent()
2868 __set_bit(IMG_REQ_CHILD, &child_img_req->flags); in rbd_obj_read_from_parent()
2869 child_img_req->obj_request = obj_req; in rbd_obj_read_from_parent()
2871 down_read(&parent->header_rwsem); in rbd_obj_read_from_parent()
2873 up_read(&parent->header_rwsem); in rbd_obj_read_from_parent()
2875 dout("%s child_img_req %p for obj_req %p\n", __func__, child_img_req, in rbd_obj_read_from_parent()
2879 switch (img_req->data_type) { in rbd_obj_read_from_parent()
2882 obj_req->img_extents, in rbd_obj_read_from_parent()
2883 obj_req->num_img_extents, in rbd_obj_read_from_parent()
2884 &obj_req->bio_pos); in rbd_obj_read_from_parent()
2889 obj_req->img_extents, in rbd_obj_read_from_parent()
2890 obj_req->num_img_extents, in rbd_obj_read_from_parent()
2891 &obj_req->bvec_pos); in rbd_obj_read_from_parent()
2893 default: in rbd_obj_read_from_parent()
2898 obj_req->img_extents, in rbd_obj_read_from_parent()
2899 obj_req->num_img_extents, in rbd_obj_read_from_parent()
2900 obj_req->copyup_bvecs); in rbd_obj_read_from_parent()
2914 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_advance_read()
2918 switch (obj_req->read_state) { in rbd_obj_advance_read()
2923 *result = -ENOENT; in rbd_obj_advance_read()
2924 obj_req->read_state = RBD_OBJ_READ_OBJECT; in rbd_obj_advance_read()
2933 obj_req->read_state = RBD_OBJ_READ_OBJECT; in rbd_obj_advance_read()
2936 if (*result == -ENOENT && rbd_dev->parent_overlap) { in rbd_obj_advance_read()
2943 if (obj_req->num_img_extents) { in rbd_obj_advance_read()
2949 obj_req->read_state = RBD_OBJ_READ_PARENT; in rbd_obj_advance_read()
2955 * -ENOENT means a hole in the image -- zero-fill the entire in rbd_obj_advance_read()
2956 * length of the request. A short read also implies zero-fill in rbd_obj_advance_read()
2959 if (*result == -ENOENT) { in rbd_obj_advance_read()
2960 rbd_obj_zero_range(obj_req, 0, obj_req->ex.oe_len); in rbd_obj_advance_read()
2963 if (*result < obj_req->ex.oe_len) in rbd_obj_advance_read()
2965 obj_req->ex.oe_len - *result); in rbd_obj_advance_read()
2967 rbd_assert(*result == obj_req->ex.oe_len); in rbd_obj_advance_read()
2973 * The parent image is read only up to the overlap -- zero-fill in rbd_obj_advance_read()
2979 if (obj_overlap < obj_req->ex.oe_len) in rbd_obj_advance_read()
2981 obj_req->ex.oe_len - obj_overlap); in rbd_obj_advance_read()
2984 default: in rbd_obj_advance_read()
2991 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_write_is_noop()
2993 if (rbd_object_map_may_exist(rbd_dev, obj_req->ex.oe_objno)) in rbd_obj_write_is_noop()
2994 obj_req->flags |= RBD_OBJ_FLAG_MAY_EXIST; in rbd_obj_write_is_noop()
2996 if (!(obj_req->flags & RBD_OBJ_FLAG_MAY_EXIST) && in rbd_obj_write_is_noop()
2997 (obj_req->flags & RBD_OBJ_FLAG_NOOP_FOR_NONEXISTENT)) { in rbd_obj_write_is_noop()
2998 dout("%s %p noop for nonexistent\n", __func__, obj_req); in rbd_obj_write_is_noop()
3007 * 0 - object map update sent
3008 * 1 - object map update isn't needed
3009 * <0 - error
3013 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_write_pre_object_map()
3016 if (!(rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) in rbd_obj_write_pre_object_map()
3019 if (obj_req->flags & RBD_OBJ_FLAG_DELETION) in rbd_obj_write_pre_object_map()
3034 if (obj_req->flags & RBD_OBJ_FLAG_COPYUP_ENABLED) in rbd_obj_write_object()
3041 if (obj_req->flags & RBD_OBJ_FLAG_COPYUP_ENABLED) { in rbd_obj_write_object()
3084 dout("%s obj_req %p bytes %u\n", __func__, obj_req, bytes); in rbd_obj_copyup_empty_snapc()
3113 dout("%s obj_req %p bytes %u\n", __func__, obj_req, bytes); in rbd_obj_copyup_current_snapc()
3143 rbd_assert(!obj_req->copyup_bvecs); in setup_copyup_bvecs()
3144 obj_req->copyup_bvec_count = calc_pages_for(0, obj_overlap); in setup_copyup_bvecs()
3145 obj_req->copyup_bvecs = kcalloc(obj_req->copyup_bvec_count, in setup_copyup_bvecs()
3146 sizeof(*obj_req->copyup_bvecs), in setup_copyup_bvecs()
3148 if (!obj_req->copyup_bvecs) in setup_copyup_bvecs()
3149 return -ENOMEM; in setup_copyup_bvecs()
3151 for (i = 0; i < obj_req->copyup_bvec_count; i++) { in setup_copyup_bvecs()
3154 obj_req->copyup_bvecs[i].bv_page = alloc_page(GFP_NOIO); in setup_copyup_bvecs()
3155 if (!obj_req->copyup_bvecs[i].bv_page) in setup_copyup_bvecs()
3156 return -ENOMEM; in setup_copyup_bvecs()
3158 obj_req->copyup_bvecs[i].bv_offset = 0; in setup_copyup_bvecs()
3159 obj_req->copyup_bvecs[i].bv_len = len; in setup_copyup_bvecs()
3160 obj_overlap -= len; in setup_copyup_bvecs()
3174 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_copyup_read_parent()
3177 rbd_assert(obj_req->num_img_extents); in rbd_obj_copyup_read_parent()
3178 prune_extents(obj_req->img_extents, &obj_req->num_img_extents, in rbd_obj_copyup_read_parent()
3179 rbd_dev->parent_overlap); in rbd_obj_copyup_read_parent()
3180 if (!obj_req->num_img_extents) { in rbd_obj_copyup_read_parent()
3183 * image has been flattened). Re-submit the original write in rbd_obj_copyup_read_parent()
3184 * request -- pass MODS_ONLY since the copyup isn't needed in rbd_obj_copyup_read_parent()
3199 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_copyup_object_maps()
3200 struct ceph_snap_context *snapc = obj_req->img_request->snapc; in rbd_obj_copyup_object_maps()
3205 rbd_assert(!obj_req->pending.result && !obj_req->pending.num_pending); in rbd_obj_copyup_object_maps()
3207 if (!(rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) in rbd_obj_copyup_object_maps()
3210 if (obj_req->flags & RBD_OBJ_FLAG_COPYUP_ZEROS) in rbd_obj_copyup_object_maps()
3213 for (i = 0; i < snapc->num_snaps; i++) { in rbd_obj_copyup_object_maps()
3214 if ((rbd_dev->header.features & RBD_FEATURE_FAST_DIFF) && in rbd_obj_copyup_object_maps()
3215 i + 1 < snapc->num_snaps) in rbd_obj_copyup_object_maps()
3220 ret = rbd_object_map_update(obj_req, snapc->snaps[i], in rbd_obj_copyup_object_maps()
3223 obj_req->pending.result = ret; in rbd_obj_copyup_object_maps()
3228 obj_req->pending.num_pending++; in rbd_obj_copyup_object_maps()
3237 rbd_assert(!obj_req->pending.result && !obj_req->pending.num_pending); in rbd_obj_copyup_write_object()
3240 * Only send non-zero copyup data to save some I/O and network in rbd_obj_copyup_write_object()
3241 * bandwidth -- zero copyup data is equivalent to the object not in rbd_obj_copyup_write_object()
3244 if (obj_req->flags & RBD_OBJ_FLAG_COPYUP_ZEROS) in rbd_obj_copyup_write_object()
3247 if (obj_req->img_request->snapc->num_snaps && bytes > 0) { in rbd_obj_copyup_write_object()
3250 * deep-copyup the object through all existing snapshots. in rbd_obj_copyup_write_object()
3256 obj_req->pending.result = ret; in rbd_obj_copyup_write_object()
3260 obj_req->pending.num_pending++; in rbd_obj_copyup_write_object()
3266 obj_req->pending.result = ret; in rbd_obj_copyup_write_object()
3270 obj_req->pending.num_pending++; in rbd_obj_copyup_write_object()
3275 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_advance_copyup()
3279 switch (obj_req->copyup_state) { in rbd_obj_advance_copyup()
3288 if (obj_req->num_img_extents) in rbd_obj_advance_copyup()
3289 obj_req->copyup_state = RBD_OBJ_COPYUP_READ_PARENT; in rbd_obj_advance_copyup()
3291 obj_req->copyup_state = RBD_OBJ_COPYUP_WRITE_OBJECT; in rbd_obj_advance_copyup()
3297 if (is_zero_bvecs(obj_req->copyup_bvecs, in rbd_obj_advance_copyup()
3299 dout("%s %p detected zeros\n", __func__, obj_req); in rbd_obj_advance_copyup()
3300 obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ZEROS; in rbd_obj_advance_copyup()
3304 if (!obj_req->pending.num_pending) { in rbd_obj_advance_copyup()
3305 *result = obj_req->pending.result; in rbd_obj_advance_copyup()
3306 obj_req->copyup_state = RBD_OBJ_COPYUP_OBJECT_MAPS; in rbd_obj_advance_copyup()
3309 obj_req->copyup_state = __RBD_OBJ_COPYUP_OBJECT_MAPS; in rbd_obj_advance_copyup()
3312 if (!pending_result_dec(&obj_req->pending, result)) in rbd_obj_advance_copyup()
3323 if (!obj_req->pending.num_pending) { in rbd_obj_advance_copyup()
3324 *result = obj_req->pending.result; in rbd_obj_advance_copyup()
3325 obj_req->copyup_state = RBD_OBJ_COPYUP_WRITE_OBJECT; in rbd_obj_advance_copyup()
3328 obj_req->copyup_state = __RBD_OBJ_COPYUP_WRITE_OBJECT; in rbd_obj_advance_copyup()
3331 if (!pending_result_dec(&obj_req->pending, result)) in rbd_obj_advance_copyup()
3336 default: in rbd_obj_advance_copyup()
3343 * 0 - object map update sent
3344 * 1 - object map update isn't needed
3345 * <0 - error
3349 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_write_post_object_map()
3352 if (!(rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) in rbd_obj_write_post_object_map()
3355 if (!(obj_req->flags & RBD_OBJ_FLAG_DELETION)) in rbd_obj_write_post_object_map()
3364 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_advance_write()
3368 switch (obj_req->write_state) { in rbd_obj_advance_write()
3381 obj_req->write_state = RBD_OBJ_WRITE_PRE_OBJECT_MAP; in rbd_obj_advance_write()
3396 obj_req->write_state = RBD_OBJ_WRITE_OBJECT; in rbd_obj_advance_write()
3399 if (*result == -ENOENT) { in rbd_obj_advance_write()
3400 if (obj_req->flags & RBD_OBJ_FLAG_COPYUP_ENABLED) { in rbd_obj_advance_write()
3402 obj_req->copyup_state = RBD_OBJ_COPYUP_START; in rbd_obj_advance_write()
3403 obj_req->write_state = __RBD_OBJ_WRITE_COPYUP; in rbd_obj_advance_write()
3407 * On a non-existent object: in rbd_obj_advance_write()
3408 * delete - -ENOENT, truncate/zero - 0 in rbd_obj_advance_write()
3410 if (obj_req->flags & RBD_OBJ_FLAG_DELETION) in rbd_obj_advance_write()
3416 obj_req->write_state = RBD_OBJ_WRITE_COPYUP; in rbd_obj_advance_write()
3432 obj_req->write_state = RBD_OBJ_WRITE_POST_OBJECT_MAP; in rbd_obj_advance_write()
3441 default: in rbd_obj_advance_write()
3452 struct rbd_img_request *img_req = obj_req->img_request; in __rbd_obj_handle_request()
3453 struct rbd_device *rbd_dev = img_req->rbd_dev; in __rbd_obj_handle_request()
3456 mutex_lock(&obj_req->state_mutex); in __rbd_obj_handle_request()
3461 mutex_unlock(&obj_req->state_mutex); in __rbd_obj_handle_request()
3466 obj_op_name(img_req->op_type), obj_req->ex.oe_objno, in __rbd_obj_handle_request()
3467 obj_req->ex.oe_off, obj_req->ex.oe_len, *result); in __rbd_obj_handle_request()
3473 * This is open-coded in rbd_img_handle_request() to avoid parent chain
3479 rbd_img_handle_request(obj_req->img_request, result); in rbd_obj_handle_request()
3484 struct rbd_device *rbd_dev = img_req->rbd_dev; in need_exclusive_lock()
3486 if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK)) in need_exclusive_lock()
3492 rbd_assert(!test_bit(IMG_REQ_CHILD, &img_req->flags)); in need_exclusive_lock()
3493 if (rbd_dev->opts->lock_on_read || in need_exclusive_lock()
3494 (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) in need_exclusive_lock()
3502 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_lock_add_request()
3505 lockdep_assert_held(&rbd_dev->lock_rwsem); in rbd_lock_add_request()
3506 locked = rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED; in rbd_lock_add_request()
3507 spin_lock(&rbd_dev->lock_lists_lock); in rbd_lock_add_request()
3508 rbd_assert(list_empty(&img_req->lock_item)); in rbd_lock_add_request()
3510 list_add_tail(&img_req->lock_item, &rbd_dev->acquiring_list); in rbd_lock_add_request()
3512 list_add_tail(&img_req->lock_item, &rbd_dev->running_list); in rbd_lock_add_request()
3513 spin_unlock(&rbd_dev->lock_lists_lock); in rbd_lock_add_request()
3519 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_lock_del_request()
3522 lockdep_assert_held(&rbd_dev->lock_rwsem); in rbd_lock_del_request()
3523 spin_lock(&rbd_dev->lock_lists_lock); in rbd_lock_del_request()
3524 rbd_assert(!list_empty(&img_req->lock_item)); in rbd_lock_del_request()
3525 list_del_init(&img_req->lock_item); in rbd_lock_del_request()
3526 need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING && in rbd_lock_del_request()
3527 list_empty(&rbd_dev->running_list)); in rbd_lock_del_request()
3528 spin_unlock(&rbd_dev->lock_lists_lock); in rbd_lock_del_request()
3530 complete(&rbd_dev->releasing_wait); in rbd_lock_del_request()
3535 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_img_exclusive_lock()
3543 if (rbd_dev->opts->exclusive) { in rbd_img_exclusive_lock()
3545 return -EROFS; in rbd_img_exclusive_lock()
3552 dout("%s rbd_dev %p queueing lock_dwork\n", __func__, rbd_dev); in rbd_img_exclusive_lock()
3553 queue_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); in rbd_img_exclusive_lock()
3559 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_img_object_requests()
3562 rbd_assert(!img_req->pending.result && !img_req->pending.num_pending); in rbd_img_object_requests()
3567 rbd_assert(!img_req->snapc); in rbd_img_object_requests()
3568 down_read(&rbd_dev->header_rwsem); in rbd_img_object_requests()
3569 img_req->snapc = ceph_get_snap_context(rbd_dev->header.snapc); in rbd_img_object_requests()
3570 up_read(&rbd_dev->header_rwsem); in rbd_img_object_requests()
3578 img_req->pending.result = result; in rbd_img_object_requests()
3582 img_req->pending.num_pending++; in rbd_img_object_requests()
3592 switch (img_req->state) { in rbd_img_advance()
3601 img_req->state = RBD_IMG_EXCLUSIVE_LOCK; in rbd_img_advance()
3610 if (!img_req->pending.num_pending) { in rbd_img_advance()
3611 *result = img_req->pending.result; in rbd_img_advance()
3612 img_req->state = RBD_IMG_OBJECT_REQUESTS; in rbd_img_advance()
3615 img_req->state = __RBD_IMG_OBJECT_REQUESTS; in rbd_img_advance()
3618 if (!pending_result_dec(&img_req->pending, result)) in rbd_img_advance()
3623 default: in rbd_img_advance()
3634 struct rbd_device *rbd_dev = img_req->rbd_dev; in __rbd_img_handle_request()
3638 down_read(&rbd_dev->lock_rwsem); in __rbd_img_handle_request()
3639 mutex_lock(&img_req->state_mutex); in __rbd_img_handle_request()
3643 mutex_unlock(&img_req->state_mutex); in __rbd_img_handle_request()
3644 up_read(&rbd_dev->lock_rwsem); in __rbd_img_handle_request()
3646 mutex_lock(&img_req->state_mutex); in __rbd_img_handle_request()
3648 mutex_unlock(&img_req->state_mutex); in __rbd_img_handle_request()
3654 test_bit(IMG_REQ_CHILD, &img_req->flags) ? "child " : "", in __rbd_img_handle_request()
3655 obj_op_name(img_req->op_type), *result); in __rbd_img_handle_request()
3666 if (test_bit(IMG_REQ_CHILD, &img_req->flags)) { in rbd_img_handle_request()
3667 struct rbd_obj_request *obj_req = img_req->obj_request; in rbd_img_handle_request()
3671 img_req = obj_req->img_request; in rbd_img_handle_request()
3687 return lhs->gid == rhs->gid && lhs->handle == rhs->handle; in rbd_cid_equal()
3694 mutex_lock(&rbd_dev->watch_mutex); in rbd_get_cid()
3695 cid.gid = ceph_client_gid(rbd_dev->rbd_client->client); in rbd_get_cid()
3696 cid.handle = rbd_dev->watch_cookie; in rbd_get_cid()
3697 mutex_unlock(&rbd_dev->watch_mutex); in rbd_get_cid()
3707 dout("%s rbd_dev %p %llu-%llu -> %llu-%llu\n", __func__, rbd_dev, in rbd_set_owner_cid()
3708 rbd_dev->owner_cid.gid, rbd_dev->owner_cid.handle, in rbd_set_owner_cid()
3709 cid->gid, cid->handle); in rbd_set_owner_cid()
3710 rbd_dev->owner_cid = *cid; /* struct */ in rbd_set_owner_cid()
3715 mutex_lock(&rbd_dev->watch_mutex); in format_lock_cookie()
3716 sprintf(buf, "%s %llu", RBD_LOCK_COOKIE_PREFIX, rbd_dev->watch_cookie); in format_lock_cookie()
3717 mutex_unlock(&rbd_dev->watch_mutex); in format_lock_cookie()
3724 rbd_dev->lock_state = RBD_LOCK_STATE_LOCKED; in __rbd_lock()
3725 strcpy(rbd_dev->lock_cookie, cookie); in __rbd_lock()
3727 queue_work(rbd_dev->task_wq, &rbd_dev->acquired_lock_work); in __rbd_lock()
3735 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_lock()
3740 rbd_dev->lock_cookie[0] != '\0'); in rbd_lock()
3743 ret = ceph_cls_lock(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in rbd_lock()
3746 if (ret && ret != -EEXIST) in rbd_lock()
3758 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_unlock()
3762 rbd_dev->lock_cookie[0] == '\0'); in rbd_unlock()
3764 ret = ceph_cls_unlock(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in rbd_unlock()
3765 RBD_LOCK_NAME, rbd_dev->lock_cookie); in rbd_unlock()
3766 if (ret && ret != -ENOENT) in rbd_unlock()
3770 rbd_dev->lock_state = RBD_LOCK_STATE_UNLOCKED; in rbd_unlock()
3771 rbd_dev->lock_cookie[0] = '\0'; in rbd_unlock()
3773 queue_work(rbd_dev->task_wq, &rbd_dev->released_lock_work); in rbd_unlock()
3781 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_notify_op_lock()
3787 dout("%s rbd_dev %p notify_op %d\n", __func__, rbd_dev, notify_op); in __rbd_notify_op_lock()
3790 ceph_start_encoding(&p, 2, 1, buf_size - CEPH_ENCODING_START_BLK_LEN); in __rbd_notify_op_lock()
3795 return ceph_osdc_notify(osdc, &rbd_dev->header_oid, in __rbd_notify_op_lock()
3796 &rbd_dev->header_oloc, buf, buf_size, in __rbd_notify_op_lock()
3829 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_request_lock()
3833 if (ret && ret != -ETIMEDOUT) { in rbd_request_lock()
3844 while (n--) { in rbd_request_lock()
3858 ret = -EIO; in rbd_request_lock()
3878 ret = -ETIMEDOUT; in rbd_request_lock()
3886 ret = -EINVAL; in rbd_request_lock()
3898 dout("%s rbd_dev %p result %d\n", __func__, rbd_dev, result); in wake_lock_waiters()
3899 lockdep_assert_held_write(&rbd_dev->lock_rwsem); in wake_lock_waiters()
3901 cancel_delayed_work(&rbd_dev->lock_dwork); in wake_lock_waiters()
3902 if (!completion_done(&rbd_dev->acquire_wait)) { in wake_lock_waiters()
3903 rbd_assert(list_empty(&rbd_dev->acquiring_list) && in wake_lock_waiters()
3904 list_empty(&rbd_dev->running_list)); in wake_lock_waiters()
3905 rbd_dev->acquire_err = result; in wake_lock_waiters()
3906 complete_all(&rbd_dev->acquire_wait); in wake_lock_waiters()
3910 list_for_each_entry(img_req, &rbd_dev->acquiring_list, lock_item) { in wake_lock_waiters()
3911 mutex_lock(&img_req->state_mutex); in wake_lock_waiters()
3912 rbd_assert(img_req->state == RBD_IMG_EXCLUSIVE_LOCK); in wake_lock_waiters()
3914 mutex_unlock(&img_req->state_mutex); in wake_lock_waiters()
3917 list_splice_tail_init(&rbd_dev->acquiring_list, &rbd_dev->running_list); in wake_lock_waiters()
3923 return lhs->id.name.type == rhs->id.name.type && in locker_equal()
3924 lhs->id.name.num == rhs->id.name.num && in locker_equal()
3925 !strcmp(lhs->id.cookie, rhs->id.cookie) && in locker_equal()
3926 ceph_addr_equal_no_type(&lhs->info.addr, &rhs->info.addr); in locker_equal()
3937 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in get_lock_owner_info()
3944 dout("%s rbd_dev %p\n", __func__, rbd_dev); in get_lock_owner_info()
3946 ret = ceph_cls_lock_info(osdc, &rbd_dev->header_oid, in get_lock_owner_info()
3947 &rbd_dev->header_oloc, RBD_LOCK_NAME, in get_lock_owner_info()
3955 dout("%s rbd_dev %p no lockers detected\n", __func__, rbd_dev); in get_lock_owner_info()
3986 return ERR_PTR(-EBUSY); in get_lock_owner_info()
3992 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in find_watcher()
3999 ret = ceph_osdc_list_watchers(osdc, &rbd_dev->header_oid, in find_watcher()
4000 &rbd_dev->header_oloc, &watchers, in find_watcher()
4007 sscanf(locker->id.cookie, RBD_LOCK_COOKIE_PREFIX " %llu", &cookie); in find_watcher()
4010 * Ignore addr->type while comparing. This mimics in find_watcher()
4014 &locker->info.addr) && in find_watcher()
4021 dout("%s rbd_dev %p found cid %llu-%llu\n", __func__, in find_watcher()
4029 dout("%s rbd_dev %p no watchers\n", __func__, rbd_dev); in find_watcher()
4041 struct ceph_client *client = rbd_dev->rbd_client->client; in rbd_try_lock()
4051 if (ret != -EBUSY) { in rbd_try_lock()
4081 ENTITY_NAME(locker->id.name)); in rbd_try_lock()
4083 ret = ceph_monc_blocklist_add(&client->monc, in rbd_try_lock()
4084 &locker->info.addr); in rbd_try_lock()
4087 ENTITY_NAME(locker->id.name), ret); in rbd_try_lock()
4091 ret = ceph_cls_break_lock(&client->osdc, &rbd_dev->header_oid, in rbd_try_lock()
4092 &rbd_dev->header_oloc, RBD_LOCK_NAME, in rbd_try_lock()
4093 locker->id.cookie, &locker->id.name); in rbd_try_lock()
4094 if (ret && ret != -ENOENT) { in rbd_try_lock()
4119 if (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP) { in rbd_post_acquire_action()
4130 * 0 - lock acquired
4131 * 1 - caller should call rbd_request_lock()
4132 * <0 - error
4138 down_read(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4139 dout("%s rbd_dev %p read lock_state %d\n", __func__, rbd_dev, in rbd_try_acquire_lock()
4140 rbd_dev->lock_state); in rbd_try_acquire_lock()
4142 up_read(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4146 up_read(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4147 down_write(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4148 dout("%s rbd_dev %p write lock_state %d\n", __func__, rbd_dev, in rbd_try_acquire_lock()
4149 rbd_dev->lock_state); in rbd_try_acquire_lock()
4151 up_write(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4161 up_write(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4165 rbd_assert(rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED); in rbd_try_acquire_lock()
4166 rbd_assert(list_empty(&rbd_dev->running_list)); in rbd_try_acquire_lock()
4170 rbd_warn(rbd_dev, "post-acquire action failed: %d", ret); in rbd_try_acquire_lock()
4181 up_write(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4191 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_acquire_lock()
4195 dout("%s rbd_dev %p ret %d - done\n", __func__, rbd_dev, ret); in rbd_acquire_lock()
4200 if (ret == -ETIMEDOUT) { in rbd_acquire_lock()
4202 } else if (ret == -EROFS) { in rbd_acquire_lock()
4204 down_write(&rbd_dev->lock_rwsem); in rbd_acquire_lock()
4206 up_write(&rbd_dev->lock_rwsem); in rbd_acquire_lock()
4209 mod_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, in rbd_acquire_lock()
4216 dout("%s rbd_dev %p requeuing lock_dwork\n", __func__, in rbd_acquire_lock()
4218 mod_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, in rbd_acquire_lock()
4219 msecs_to_jiffies(2 * RBD_NOTIFY_TIMEOUT * MSEC_PER_SEC)); in rbd_acquire_lock()
4225 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_quiesce_lock()
4226 lockdep_assert_held_write(&rbd_dev->lock_rwsem); in rbd_quiesce_lock()
4228 if (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED) in rbd_quiesce_lock()
4232 * Ensure that all in-flight IO is flushed. in rbd_quiesce_lock()
4234 rbd_dev->lock_state = RBD_LOCK_STATE_RELEASING; in rbd_quiesce_lock()
4235 rbd_assert(!completion_done(&rbd_dev->releasing_wait)); in rbd_quiesce_lock()
4236 if (list_empty(&rbd_dev->running_list)) in rbd_quiesce_lock()
4239 up_write(&rbd_dev->lock_rwsem); in rbd_quiesce_lock()
4240 wait_for_completion(&rbd_dev->releasing_wait); in rbd_quiesce_lock()
4242 down_write(&rbd_dev->lock_rwsem); in rbd_quiesce_lock()
4243 if (rbd_dev->lock_state != RBD_LOCK_STATE_RELEASING) in rbd_quiesce_lock()
4246 rbd_assert(list_empty(&rbd_dev->running_list)); in rbd_quiesce_lock()
4252 if (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP) in rbd_pre_release_action()
4258 rbd_assert(list_empty(&rbd_dev->running_list)); in __rbd_release_lock()
4275 * Give others a chance to grab the lock - we would re-acquire in rbd_release_lock()
4281 cancel_delayed_work(&rbd_dev->lock_dwork); in rbd_release_lock()
4289 down_write(&rbd_dev->lock_rwsem); in rbd_release_lock_work()
4291 up_write(&rbd_dev->lock_rwsem); in rbd_release_lock_work()
4298 dout("%s rbd_dev %p\n", __func__, rbd_dev); in maybe_kick_acquire()
4302 spin_lock(&rbd_dev->lock_lists_lock); in maybe_kick_acquire()
4303 have_requests = !list_empty(&rbd_dev->acquiring_list); in maybe_kick_acquire()
4304 spin_unlock(&rbd_dev->lock_lists_lock); in maybe_kick_acquire()
4305 if (have_requests || delayed_work_pending(&rbd_dev->lock_dwork)) { in maybe_kick_acquire()
4306 dout("%s rbd_dev %p kicking lock_dwork\n", __func__, rbd_dev); in maybe_kick_acquire()
4307 mod_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); in maybe_kick_acquire()
4316 if (struct_v >= 2) { in rbd_handle_acquired_lock()
4321 dout("%s rbd_dev %p cid %llu-%llu\n", __func__, rbd_dev, cid.gid, in rbd_handle_acquired_lock()
4324 down_write(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
4325 if (rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { in rbd_handle_acquired_lock()
4326 dout("%s rbd_dev %p cid %llu-%llu == owner_cid\n", in rbd_handle_acquired_lock()
4331 downgrade_write(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
4333 down_read(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
4337 up_read(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
4345 if (struct_v >= 2) { in rbd_handle_released_lock()
4350 dout("%s rbd_dev %p cid %llu-%llu\n", __func__, rbd_dev, cid.gid, in rbd_handle_released_lock()
4353 down_write(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
4354 if (!rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { in rbd_handle_released_lock()
4355 dout("%s rbd_dev %p cid %llu-%llu != owner_cid %llu-%llu\n", in rbd_handle_released_lock()
4357 rbd_dev->owner_cid.gid, rbd_dev->owner_cid.handle); in rbd_handle_released_lock()
4361 downgrade_write(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
4363 down_read(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
4367 up_read(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
4381 if (struct_v >= 2) { in rbd_handle_request_lock()
4386 dout("%s rbd_dev %p cid %llu-%llu\n", __func__, rbd_dev, cid.gid, in rbd_handle_request_lock()
4391 down_read(&rbd_dev->lock_rwsem); in rbd_handle_request_lock()
4393 if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED && in rbd_handle_request_lock()
4394 rbd_cid_equal(&rbd_dev->owner_cid, &rbd_empty_cid)) in rbd_handle_request_lock()
4403 if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED) { in rbd_handle_request_lock()
4404 if (!rbd_dev->opts->exclusive) { in rbd_handle_request_lock()
4405 dout("%s rbd_dev %p queueing unlock_work\n", in rbd_handle_request_lock()
4407 queue_work(rbd_dev->task_wq, in rbd_handle_request_lock()
4408 &rbd_dev->unlock_work); in rbd_handle_request_lock()
4411 result = -EROFS; in rbd_handle_request_lock()
4417 up_read(&rbd_dev->lock_rwsem); in rbd_handle_request_lock()
4424 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_acknowledge_notify()
4434 buf_size - CEPH_ENCODING_START_BLK_LEN); in __rbd_acknowledge_notify()
4440 ret = ceph_osdc_notify_ack(osdc, &rbd_dev->header_oid, in __rbd_acknowledge_notify()
4441 &rbd_dev->header_oloc, notify_id, cookie, in __rbd_acknowledge_notify()
4450 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_acknowledge_notify()
4457 dout("%s rbd_dev %p result %d\n", __func__, rbd_dev, result); in rbd_acknowledge_notify_result()
4472 dout("%s rbd_dev %p cookie %llu notify_id %llu data_len %zu\n", in rbd_watch_cb()
4490 dout("%s rbd_dev %p notify_op %u\n", __func__, rbd_dev, notify_op); in rbd_watch_cb()
4515 default: in rbd_watch_cb()
4518 cookie, -EOPNOTSUPP); in rbd_watch_cb()
4533 down_write(&rbd_dev->lock_rwsem); in rbd_watch_errcb()
4535 up_write(&rbd_dev->lock_rwsem); in rbd_watch_errcb()
4537 mutex_lock(&rbd_dev->watch_mutex); in rbd_watch_errcb()
4538 if (rbd_dev->watch_state == RBD_WATCH_STATE_REGISTERED) { in rbd_watch_errcb()
4540 rbd_dev->watch_state = RBD_WATCH_STATE_ERROR; in rbd_watch_errcb()
4542 queue_delayed_work(rbd_dev->task_wq, &rbd_dev->watch_dwork, 0); in rbd_watch_errcb()
4544 mutex_unlock(&rbd_dev->watch_mutex); in rbd_watch_errcb()
4552 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_register_watch()
4555 rbd_assert(!rbd_dev->watch_handle); in __rbd_register_watch()
4556 dout("%s rbd_dev %p\n", __func__, rbd_dev); in __rbd_register_watch()
4558 handle = ceph_osdc_watch(osdc, &rbd_dev->header_oid, in __rbd_register_watch()
4559 &rbd_dev->header_oloc, rbd_watch_cb, in __rbd_register_watch()
4564 rbd_dev->watch_handle = handle; in __rbd_register_watch()
4573 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_unregister_watch()
4576 rbd_assert(rbd_dev->watch_handle); in __rbd_unregister_watch()
4577 dout("%s rbd_dev %p\n", __func__, rbd_dev); in __rbd_unregister_watch()
4579 ret = ceph_osdc_unwatch(osdc, rbd_dev->watch_handle); in __rbd_unregister_watch()
4583 rbd_dev->watch_handle = NULL; in __rbd_unregister_watch()
4590 mutex_lock(&rbd_dev->watch_mutex); in rbd_register_watch()
4591 rbd_assert(rbd_dev->watch_state == RBD_WATCH_STATE_UNREGISTERED); in rbd_register_watch()
4596 rbd_dev->watch_state = RBD_WATCH_STATE_REGISTERED; in rbd_register_watch()
4597 rbd_dev->watch_cookie = rbd_dev->watch_handle->linger_id; in rbd_register_watch()
4600 mutex_unlock(&rbd_dev->watch_mutex); in rbd_register_watch()
4606 dout("%s rbd_dev %p\n", __func__, rbd_dev); in cancel_tasks_sync()
4608 cancel_work_sync(&rbd_dev->acquired_lock_work); in cancel_tasks_sync()
4609 cancel_work_sync(&rbd_dev->released_lock_work); in cancel_tasks_sync()
4610 cancel_delayed_work_sync(&rbd_dev->lock_dwork); in cancel_tasks_sync()
4611 cancel_work_sync(&rbd_dev->unlock_work); in cancel_tasks_sync()
4622 mutex_lock(&rbd_dev->watch_mutex); in rbd_unregister_watch()
4623 if (rbd_dev->watch_state == RBD_WATCH_STATE_REGISTERED) in rbd_unregister_watch()
4625 rbd_dev->watch_state = RBD_WATCH_STATE_UNREGISTERED; in rbd_unregister_watch()
4626 mutex_unlock(&rbd_dev->watch_mutex); in rbd_unregister_watch()
4628 cancel_delayed_work_sync(&rbd_dev->watch_dwork); in rbd_unregister_watch()
4629 ceph_osdc_flush_notifies(&rbd_dev->rbd_client->client->osdc); in rbd_unregister_watch()
4637 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_reacquire_lock()
4645 ret = ceph_cls_set_cookie(osdc, &rbd_dev->header_oid, in rbd_reacquire_lock()
4646 &rbd_dev->header_oloc, RBD_LOCK_NAME, in rbd_reacquire_lock()
4647 CEPH_CLS_LOCK_EXCLUSIVE, rbd_dev->lock_cookie, in rbd_reacquire_lock()
4650 if (ret != -EOPNOTSUPP) in rbd_reacquire_lock()
4659 queue_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); in rbd_reacquire_lock()
4672 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_reregister_watch()
4674 mutex_lock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
4675 if (rbd_dev->watch_state != RBD_WATCH_STATE_ERROR) { in rbd_reregister_watch()
4676 mutex_unlock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
4683 if (ret != -EBLOCKLISTED && ret != -ENOENT) { in rbd_reregister_watch()
4684 queue_delayed_work(rbd_dev->task_wq, in rbd_reregister_watch()
4685 &rbd_dev->watch_dwork, in rbd_reregister_watch()
4687 mutex_unlock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
4691 mutex_unlock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
4692 down_write(&rbd_dev->lock_rwsem); in rbd_reregister_watch()
4694 up_write(&rbd_dev->lock_rwsem); in rbd_reregister_watch()
4698 rbd_dev->watch_state = RBD_WATCH_STATE_REGISTERED; in rbd_reregister_watch()
4699 rbd_dev->watch_cookie = rbd_dev->watch_handle->linger_id; in rbd_reregister_watch()
4700 mutex_unlock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
4702 down_write(&rbd_dev->lock_rwsem); in rbd_reregister_watch()
4703 if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED) in rbd_reregister_watch()
4705 up_write(&rbd_dev->lock_rwsem); in rbd_reregister_watch()
4725 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_obj_method_sync()
4733 * also supply outbound data--parameters for the object in rbd_obj_method_sync()
4739 return -E2BIG; in rbd_obj_method_sync()
4743 return -ENOMEM; in rbd_obj_method_sync()
4752 return -ENOMEM; in rbd_obj_method_sync()
4773 struct rbd_device *rbd_dev = img_request->rbd_dev; in rbd_queue_workfn()
4774 enum obj_operation_type op_type = img_request->op_type; in rbd_queue_workfn()
4781 /* Ignore/skip any zero-length requests */ in rbd_queue_workfn()
4783 dout("%s: zero-length request\n", __func__); in rbd_queue_workfn()
4790 down_read(&rbd_dev->header_rwsem); in rbd_queue_workfn()
4791 mapping_size = rbd_dev->mapping.size; in rbd_queue_workfn()
4793 up_read(&rbd_dev->header_rwsem); in rbd_queue_workfn()
4798 result = -EIO; in rbd_queue_workfn()
4802 dout("%s rbd_dev %p img_req %p %s %llu~%llu\n", __func__, rbd_dev, in rbd_queue_workfn()
4809 rq->bio); in rbd_queue_workfn()
4827 struct rbd_device *rbd_dev = hctx->queue->queuedata; in rbd_queue_rq()
4828 struct rbd_img_request *img_req = blk_mq_rq_to_pdu(bd->rq); in rbd_queue_rq()
4831 switch (req_op(bd->rq)) { in rbd_queue_rq()
4844 default: in rbd_queue_rq()
4845 rbd_warn(rbd_dev, "unknown req_op %d", req_op(bd->rq)); in rbd_queue_rq()
4853 rbd_warn(rbd_dev, "%s on read-only mapping", in rbd_queue_rq()
4854 obj_op_name(img_req->op_type)); in rbd_queue_rq()
4860 INIT_WORK(&img_req->work, rbd_queue_workfn); in rbd_queue_rq()
4861 queue_work(rbd_wq, &img_req->work); in rbd_queue_rq()
4867 blk_cleanup_queue(rbd_dev->disk->queue); in rbd_free_disk()
4868 blk_mq_free_tag_set(&rbd_dev->tag_set); in rbd_free_disk()
4869 put_disk(rbd_dev->disk); in rbd_free_disk()
4870 rbd_dev->disk = NULL; in rbd_free_disk()
4879 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_obj_read_sync()
4887 return -ENOMEM; in rbd_obj_read_sync()
4889 ceph_oid_copy(&req->r_base_oid, oid); in rbd_obj_read_sync()
4890 ceph_oloc_copy(&req->r_base_oloc, oloc); in rbd_obj_read_sync()
4891 req->r_flags = CEPH_OSD_FLAG_READ; in rbd_obj_read_sync()
4919 * return, the rbd_dev->header field will contain up-to-date
4933 * The complete header will include an array of its 64-bit in rbd_dev_v1_header_info()
4935 * a contiguous block of NUL-terminated strings. Note that in rbd_dev_v1_header_info()
4937 * it in, in which case we re-read it. in rbd_dev_v1_header_info()
4949 return -ENOMEM; in rbd_dev_v1_header_info()
4951 ret = rbd_obj_read_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v1_header_info()
4952 &rbd_dev->header_oloc, ondisk, size); in rbd_dev_v1_header_info()
4956 ret = -ENXIO; in rbd_dev_v1_header_info()
4962 ret = -ENXIO; in rbd_dev_v1_header_info()
4967 names_size = le64_to_cpu(ondisk->snap_names_len); in rbd_dev_v1_header_info()
4969 snap_count = le32_to_cpu(ondisk->snap_count); in rbd_dev_v1_header_info()
4984 * If EXISTS is not set, rbd_dev->disk may be NULL, so don't in rbd_dev_update_size()
4988 if (test_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags) && in rbd_dev_update_size()
4989 !test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags)) { in rbd_dev_update_size()
4990 size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE; in rbd_dev_update_size()
4991 dout("setting size to %llu sectors", (unsigned long long)size); in rbd_dev_update_size()
4992 set_capacity(rbd_dev->disk, size); in rbd_dev_update_size()
4993 revalidate_disk_size(rbd_dev->disk, true); in rbd_dev_update_size()
5006 rbd_dev->layout.object_size * rbd_dev->layout.stripe_count; in rbd_init_disk()
5014 return -ENOMEM; in rbd_init_disk()
5016 snprintf(disk->disk_name, sizeof(disk->disk_name), RBD_DRV_NAME "%d", in rbd_init_disk()
5017 rbd_dev->dev_id); in rbd_init_disk()
5018 disk->major = rbd_dev->major; in rbd_init_disk()
5019 disk->first_minor = rbd_dev->minor; in rbd_init_disk()
5021 disk->flags |= GENHD_FL_EXT_DEVT; in rbd_init_disk()
5022 disk->fops = &rbd_bd_ops; in rbd_init_disk()
5023 disk->private_data = rbd_dev; in rbd_init_disk()
5025 memset(&rbd_dev->tag_set, 0, sizeof(rbd_dev->tag_set)); in rbd_init_disk()
5026 rbd_dev->tag_set.ops = &rbd_mq_ops; in rbd_init_disk()
5027 rbd_dev->tag_set.queue_depth = rbd_dev->opts->queue_depth; in rbd_init_disk()
5028 rbd_dev->tag_set.numa_node = NUMA_NO_NODE; in rbd_init_disk()
5029 rbd_dev->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; in rbd_init_disk()
5030 rbd_dev->tag_set.nr_hw_queues = num_present_cpus(); in rbd_init_disk()
5031 rbd_dev->tag_set.cmd_size = sizeof(struct rbd_img_request); in rbd_init_disk()
5033 err = blk_mq_alloc_tag_set(&rbd_dev->tag_set); in rbd_init_disk()
5037 q = blk_mq_init_queue(&rbd_dev->tag_set); in rbd_init_disk()
5044 /* QUEUE_FLAG_ADD_RANDOM is off by default for blk-mq */ in rbd_init_disk()
5047 q->limits.max_sectors = queue_max_hw_sectors(q); in rbd_init_disk()
5050 blk_queue_io_min(q, rbd_dev->opts->alloc_size); in rbd_init_disk()
5051 blk_queue_io_opt(q, rbd_dev->opts->alloc_size); in rbd_init_disk()
5053 if (rbd_dev->opts->trim) { in rbd_init_disk()
5055 q->limits.discard_granularity = rbd_dev->opts->alloc_size; in rbd_init_disk()
5060 if (!ceph_test_opt(rbd_dev->rbd_client->client, NOCRC)) in rbd_init_disk()
5068 disk->queue = q; in rbd_init_disk()
5069 q->queuedata = rbd_dev; in rbd_init_disk()
5071 rbd_dev->disk = disk; in rbd_init_disk()
5075 blk_mq_free_tag_set(&rbd_dev->tag_set); in rbd_init_disk()
5096 (unsigned long long)rbd_dev->mapping.size); in rbd_size_show()
5104 return sprintf(buf, "0x%016llx\n", rbd_dev->header.features); in rbd_features_show()
5112 if (rbd_dev->major) in rbd_major_show()
5113 return sprintf(buf, "%d\n", rbd_dev->major); in rbd_major_show()
5123 return sprintf(buf, "%d\n", rbd_dev->minor); in rbd_minor_show()
5131 ceph_client_addr(rbd_dev->rbd_client->client); in rbd_client_addr_show()
5133 return sprintf(buf, "%pISpc/%u\n", &client_addr->in_addr, in rbd_client_addr_show()
5134 le32_to_cpu(client_addr->nonce)); in rbd_client_addr_show()
5143 ceph_client_gid(rbd_dev->rbd_client->client)); in rbd_client_id_show()
5151 return sprintf(buf, "%pU\n", &rbd_dev->rbd_client->client->fsid); in rbd_cluster_fsid_show()
5160 return -EPERM; in rbd_config_info_show()
5162 return sprintf(buf, "%s\n", rbd_dev->config_info); in rbd_config_info_show()
5170 return sprintf(buf, "%s\n", rbd_dev->spec->pool_name); in rbd_pool_show()
5179 (unsigned long long) rbd_dev->spec->pool_id); in rbd_pool_id_show()
5187 return sprintf(buf, "%s\n", rbd_dev->spec->pool_ns ?: ""); in rbd_pool_ns_show()
5195 if (rbd_dev->spec->image_name) in rbd_name_show()
5196 return sprintf(buf, "%s\n", rbd_dev->spec->image_name); in rbd_name_show()
5206 return sprintf(buf, "%s\n", rbd_dev->spec->image_id); in rbd_image_id_show()
5210 * Shows the name of the currently-mapped snapshot (or
5219 return sprintf(buf, "%s\n", rbd_dev->spec->snap_name); in rbd_snap_show()
5227 return sprintf(buf, "%llu\n", rbd_dev->spec->snap_id); in rbd_snap_id_show()
5242 if (!rbd_dev->parent) in rbd_parent_show()
5245 for ( ; rbd_dev->parent; rbd_dev = rbd_dev->parent) { in rbd_parent_show()
5246 struct rbd_spec *spec = rbd_dev->parent_spec; in rbd_parent_show()
5255 spec->pool_id, spec->pool_name, in rbd_parent_show()
5256 spec->pool_ns ?: "", in rbd_parent_show()
5257 spec->image_id, spec->image_name ?: "(unknown)", in rbd_parent_show()
5258 spec->snap_id, spec->snap_name, in rbd_parent_show()
5259 rbd_dev->parent_overlap); in rbd_parent_show()
5274 return -EPERM; in rbd_image_refresh()
5341 kref_get(&spec->kref); in rbd_spec_get()
5350 kref_put(&spec->kref, rbd_spec_free); in rbd_spec_put()
5361 spec->pool_id = CEPH_NOPOOL; in rbd_spec_alloc()
5362 spec->snap_id = CEPH_NOSNAP; in rbd_spec_alloc()
5363 kref_init(&spec->kref); in rbd_spec_alloc()
5372 kfree(spec->pool_name); in rbd_spec_free()
5373 kfree(spec->pool_ns); in rbd_spec_free()
5374 kfree(spec->image_id); in rbd_spec_free()
5375 kfree(spec->image_name); in rbd_spec_free()
5376 kfree(spec->snap_name); in rbd_spec_free()
5382 WARN_ON(rbd_dev->watch_state != RBD_WATCH_STATE_UNREGISTERED); in rbd_dev_free()
5383 WARN_ON(rbd_dev->lock_state != RBD_LOCK_STATE_UNLOCKED); in rbd_dev_free()
5385 ceph_oid_destroy(&rbd_dev->header_oid); in rbd_dev_free()
5386 ceph_oloc_destroy(&rbd_dev->header_oloc); in rbd_dev_free()
5387 kfree(rbd_dev->config_info); in rbd_dev_free()
5389 rbd_put_client(rbd_dev->rbd_client); in rbd_dev_free()
5390 rbd_spec_put(rbd_dev->spec); in rbd_dev_free()
5391 kfree(rbd_dev->opts); in rbd_dev_free()
5398 bool need_put = !!rbd_dev->opts; in rbd_dev_release()
5401 destroy_workqueue(rbd_dev->task_wq); in rbd_dev_release()
5402 ida_simple_remove(&rbd_dev_id_ida, rbd_dev->dev_id); in rbd_dev_release()
5410 * doing something similar to dm (dm-builtin.c) is overkill. in rbd_dev_release()
5424 spin_lock_init(&rbd_dev->lock); in __rbd_dev_create()
5425 INIT_LIST_HEAD(&rbd_dev->node); in __rbd_dev_create()
5426 init_rwsem(&rbd_dev->header_rwsem); in __rbd_dev_create()
5428 rbd_dev->header.data_pool_id = CEPH_NOPOOL; in __rbd_dev_create()
5429 ceph_oid_init(&rbd_dev->header_oid); in __rbd_dev_create()
5430 rbd_dev->header_oloc.pool = spec->pool_id; in __rbd_dev_create()
5431 if (spec->pool_ns) { in __rbd_dev_create()
5432 WARN_ON(!*spec->pool_ns); in __rbd_dev_create()
5433 rbd_dev->header_oloc.pool_ns = in __rbd_dev_create()
5434 ceph_find_or_create_string(spec->pool_ns, in __rbd_dev_create()
5435 strlen(spec->pool_ns)); in __rbd_dev_create()
5438 mutex_init(&rbd_dev->watch_mutex); in __rbd_dev_create()
5439 rbd_dev->watch_state = RBD_WATCH_STATE_UNREGISTERED; in __rbd_dev_create()
5440 INIT_DELAYED_WORK(&rbd_dev->watch_dwork, rbd_reregister_watch); in __rbd_dev_create()
5442 init_rwsem(&rbd_dev->lock_rwsem); in __rbd_dev_create()
5443 rbd_dev->lock_state = RBD_LOCK_STATE_UNLOCKED; in __rbd_dev_create()
5444 INIT_WORK(&rbd_dev->acquired_lock_work, rbd_notify_acquired_lock); in __rbd_dev_create()
5445 INIT_WORK(&rbd_dev->released_lock_work, rbd_notify_released_lock); in __rbd_dev_create()
5446 INIT_DELAYED_WORK(&rbd_dev->lock_dwork, rbd_acquire_lock); in __rbd_dev_create()
5447 INIT_WORK(&rbd_dev->unlock_work, rbd_release_lock_work); in __rbd_dev_create()
5448 spin_lock_init(&rbd_dev->lock_lists_lock); in __rbd_dev_create()
5449 INIT_LIST_HEAD(&rbd_dev->acquiring_list); in __rbd_dev_create()
5450 INIT_LIST_HEAD(&rbd_dev->running_list); in __rbd_dev_create()
5451 init_completion(&rbd_dev->acquire_wait); in __rbd_dev_create()
5452 init_completion(&rbd_dev->releasing_wait); in __rbd_dev_create()
5454 spin_lock_init(&rbd_dev->object_map_lock); in __rbd_dev_create()
5456 rbd_dev->dev.bus = &rbd_bus_type; in __rbd_dev_create()
5457 rbd_dev->dev.type = &rbd_device_type; in __rbd_dev_create()
5458 rbd_dev->dev.parent = &rbd_root_dev; in __rbd_dev_create()
5459 device_initialize(&rbd_dev->dev); in __rbd_dev_create()
5478 rbd_dev->dev_id = ida_simple_get(&rbd_dev_id_ida, 0, in rbd_dev_create()
5481 if (rbd_dev->dev_id < 0) in rbd_dev_create()
5484 sprintf(rbd_dev->name, RBD_DRV_NAME "%d", rbd_dev->dev_id); in rbd_dev_create()
5485 rbd_dev->task_wq = alloc_ordered_workqueue("%s-tasks", WQ_MEM_RECLAIM, in rbd_dev_create()
5486 rbd_dev->name); in rbd_dev_create()
5487 if (!rbd_dev->task_wq) in rbd_dev_create()
5493 rbd_dev->rbd_client = rbdc; in rbd_dev_create()
5494 rbd_dev->spec = spec; in rbd_dev_create()
5495 rbd_dev->opts = opts; in rbd_dev_create()
5497 dout("%s rbd_dev %p dev_id %d\n", __func__, rbd_dev, rbd_dev->dev_id); in rbd_dev_create()
5501 ida_simple_remove(&rbd_dev_id_ida, rbd_dev->dev_id); in rbd_dev_create()
5510 put_device(&rbd_dev->dev); in rbd_dev_destroy()
5528 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in _rbd_dev_v2_snap_size()
5529 &rbd_dev->header_oloc, "get_size", in _rbd_dev_v2_snap_size()
5532 dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); in _rbd_dev_v2_snap_size()
5536 return -ERANGE; in _rbd_dev_v2_snap_size()
5540 dout(" order %u", (unsigned int)*order); in _rbd_dev_v2_snap_size()
5544 dout(" snap_id 0x%016llx snap_size = %llu\n", in _rbd_dev_v2_snap_size()
5564 return -ENOMEM; in rbd_dev_v2_object_prefix()
5566 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_object_prefix()
5567 &rbd_dev->header_oloc, "get_object_prefix", in rbd_dev_v2_object_prefix()
5569 dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); in rbd_dev_v2_object_prefix()
5583 dout(" object_prefix = %s\n", object_prefix); in rbd_dev_v2_object_prefix()
5607 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in _rbd_dev_v2_snap_features()
5608 &rbd_dev->header_oloc, "get_features", in _rbd_dev_v2_snap_features()
5611 dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); in _rbd_dev_v2_snap_features()
5615 return -ERANGE; in _rbd_dev_v2_snap_features()
5621 return -ENXIO; in _rbd_dev_v2_snap_features()
5626 dout(" snap_id 0x%016llx features = 0x%016llx incompat = 0x%016llx\n", in _rbd_dev_v2_snap_features()
5636 * object map, store them in rbd_dev->object_map_flags.
5643 __le64 snapid = cpu_to_le64(rbd_dev->spec->snap_id); in rbd_dev_v2_get_flags()
5647 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_get_flags()
5648 &rbd_dev->header_oloc, "get_flags", in rbd_dev_v2_get_flags()
5654 return -EBADMSG; in rbd_dev_v2_get_flags()
5656 rbd_dev->object_map_flags = le64_to_cpu(flags); in rbd_dev_v2_get_flags()
5672 kfree(pii->pool_ns); in rbd_parent_info_cleanup()
5673 kfree(pii->image_id); in rbd_parent_info_cleanup()
5693 ceph_decode_64_safe(p, end, pii->pool_id, e_inval); in decode_parent_image_spec()
5694 pii->pool_ns = ceph_extract_encoded_string(p, end, NULL, GFP_KERNEL); in decode_parent_image_spec()
5695 if (IS_ERR(pii->pool_ns)) { in decode_parent_image_spec()
5696 ret = PTR_ERR(pii->pool_ns); in decode_parent_image_spec()
5697 pii->pool_ns = NULL; in decode_parent_image_spec()
5700 pii->image_id = ceph_extract_encoded_string(p, end, NULL, GFP_KERNEL); in decode_parent_image_spec()
5701 if (IS_ERR(pii->image_id)) { in decode_parent_image_spec()
5702 ret = PTR_ERR(pii->image_id); in decode_parent_image_spec()
5703 pii->image_id = NULL; in decode_parent_image_spec()
5706 ceph_decode_64_safe(p, end, pii->snap_id, e_inval); in decode_parent_image_spec()
5710 return -EINVAL; in decode_parent_image_spec()
5718 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __get_parent_info()
5723 ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in __get_parent_info()
5727 return ret == -EOPNOTSUPP ? 1 : ret; in __get_parent_info()
5735 ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in __get_parent_info()
5743 ceph_decode_8_safe(&p, end, pii->has_overlap, e_inval); in __get_parent_info()
5744 if (pii->has_overlap) in __get_parent_info()
5745 ceph_decode_64_safe(&p, end, pii->overlap, e_inval); in __get_parent_info()
5747 dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", in __get_parent_info()
5748 __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id, in __get_parent_info()
5749 pii->has_overlap, pii->overlap); in __get_parent_info()
5753 return -EINVAL; in __get_parent_info()
5764 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __get_parent_info_legacy()
5769 ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in __get_parent_info_legacy()
5777 ceph_decode_64_safe(&p, end, pii->pool_id, e_inval); in __get_parent_info_legacy()
5778 pii->image_id = ceph_extract_encoded_string(&p, end, NULL, GFP_KERNEL); in __get_parent_info_legacy()
5779 if (IS_ERR(pii->image_id)) { in __get_parent_info_legacy()
5780 ret = PTR_ERR(pii->image_id); in __get_parent_info_legacy()
5781 pii->image_id = NULL; in __get_parent_info_legacy()
5784 ceph_decode_64_safe(&p, end, pii->snap_id, e_inval); in __get_parent_info_legacy()
5785 pii->has_overlap = true; in __get_parent_info_legacy()
5786 ceph_decode_64_safe(&p, end, pii->overlap, e_inval); in __get_parent_info_legacy()
5788 dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", in __get_parent_info_legacy()
5789 __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id, in __get_parent_info_legacy()
5790 pii->has_overlap, pii->overlap); in __get_parent_info_legacy()
5794 return -EINVAL; in __get_parent_info_legacy()
5806 return -ENOMEM; in rbd_dev_v2_parent_info()
5811 return -ENOMEM; in rbd_dev_v2_parent_info()
5815 ceph_encode_64(&p, rbd_dev->spec->snap_id); in rbd_dev_v2_parent_info()
5834 return -ENOMEM; in rbd_dev_setup_parent()
5845 ret = -EIO; in rbd_dev_setup_parent()
5856 parent_spec->pool_id = pii.pool_id; in rbd_dev_setup_parent()
5858 parent_spec->pool_ns = pii.pool_ns; in rbd_dev_setup_parent()
5861 parent_spec->image_id = pii.image_id; in rbd_dev_setup_parent()
5863 parent_spec->snap_id = pii.snap_id; in rbd_dev_setup_parent()
5865 rbd_assert(!rbd_dev->parent_spec); in rbd_dev_setup_parent()
5866 rbd_dev->parent_spec = parent_spec; in rbd_dev_setup_parent()
5875 rbd_dev->parent_overlap = pii.overlap; in rbd_dev_setup_parent()
5895 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_striping_info()
5896 &rbd_dev->header_oloc, "get_stripe_unit_count", in rbd_dev_v2_striping_info()
5898 dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); in rbd_dev_v2_striping_info()
5902 return -ERANGE; in rbd_dev_v2_striping_info()
5906 dout(" stripe_unit = %llu stripe_count = %llu\n", *stripe_unit, in rbd_dev_v2_striping_info()
5917 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_data_pool()
5918 &rbd_dev->header_oloc, "get_data_pool", in rbd_dev_v2_data_pool()
5921 dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); in rbd_dev_v2_data_pool()
5925 return -EBADMSG; in rbd_dev_v2_data_pool()
5928 dout(" data_pool_id = %lld\n", *data_pool_id); in rbd_dev_v2_data_pool()
5947 rbd_assert(!rbd_dev->spec->image_name); in rbd_dev_image_name()
5949 len = strlen(rbd_dev->spec->image_id); in rbd_dev_image_name()
5957 ceph_encode_string(&p, end, rbd_dev->spec->image_id, (u32)len); in rbd_dev_image_name()
5965 ret = rbd_obj_method_sync(rbd_dev, &oid, &rbd_dev->header_oloc, in rbd_dev_image_name()
5977 dout("%s: name is %s len is %zd\n", __func__, image_name, len); in rbd_dev_image_name()
5987 struct ceph_snap_context *snapc = rbd_dev->header.snapc; in rbd_v1_snap_id_by_name()
5993 snap_name = rbd_dev->header.snap_names; in rbd_v1_snap_id_by_name()
5994 while (which < snapc->num_snaps) { in rbd_v1_snap_id_by_name()
5996 return snapc->snaps[which]; in rbd_v1_snap_id_by_name()
6005 struct ceph_snap_context *snapc = rbd_dev->header.snapc; in rbd_v2_snap_id_by_name()
6010 for (which = 0; !found && which < snapc->num_snaps; which++) { in rbd_v2_snap_id_by_name()
6013 snap_id = snapc->snaps[which]; in rbd_v2_snap_id_by_name()
6016 /* ignore no-longer existing snapshots */ in rbd_v2_snap_id_by_name()
6017 if (PTR_ERR(snap_name) == -ENOENT) in rbd_v2_snap_id_by_name()
6034 if (rbd_dev->image_format == 1) in rbd_snap_id_by_name()
6045 struct rbd_spec *spec = rbd_dev->spec; in rbd_spec_fill_snap_id()
6047 rbd_assert(spec->pool_id != CEPH_NOPOOL && spec->pool_name); in rbd_spec_fill_snap_id()
6048 rbd_assert(spec->image_id && spec->image_name); in rbd_spec_fill_snap_id()
6049 rbd_assert(spec->snap_name); in rbd_spec_fill_snap_id()
6051 if (strcmp(spec->snap_name, RBD_SNAP_HEAD_NAME)) { in rbd_spec_fill_snap_id()
6054 snap_id = rbd_snap_id_by_name(rbd_dev, spec->snap_name); in rbd_spec_fill_snap_id()
6056 return -ENOENT; in rbd_spec_fill_snap_id()
6058 spec->snap_id = snap_id; in rbd_spec_fill_snap_id()
6060 spec->snap_id = CEPH_NOSNAP; in rbd_spec_fill_snap_id()
6074 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_spec_fill_names()
6075 struct rbd_spec *spec = rbd_dev->spec; in rbd_spec_fill_names()
6081 rbd_assert(spec->pool_id != CEPH_NOPOOL); in rbd_spec_fill_names()
6082 rbd_assert(spec->image_id); in rbd_spec_fill_names()
6083 rbd_assert(spec->snap_id != CEPH_NOSNAP); in rbd_spec_fill_names()
6087 pool_name = ceph_pg_pool_name_by_id(osdc->osdmap, spec->pool_id); in rbd_spec_fill_names()
6089 rbd_warn(rbd_dev, "no pool with id %llu", spec->pool_id); in rbd_spec_fill_names()
6090 return -EIO; in rbd_spec_fill_names()
6094 return -ENOMEM; in rbd_spec_fill_names()
6104 snap_name = rbd_snap_name(rbd_dev, spec->snap_id); in rbd_spec_fill_names()
6110 spec->pool_name = pool_name; in rbd_spec_fill_names()
6111 spec->image_name = image_name; in rbd_spec_fill_names()
6112 spec->snap_name = snap_name; in rbd_spec_fill_names()
6145 return -ENOMEM; in rbd_dev_v2_snap_context()
6147 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_snap_context()
6148 &rbd_dev->header_oloc, "get_snapcontext", in rbd_dev_v2_snap_context()
6150 dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); in rbd_dev_v2_snap_context()
6156 ret = -ERANGE; in rbd_dev_v2_snap_context()
6166 if (snap_count > (SIZE_MAX - sizeof (struct ceph_snap_context)) in rbd_dev_v2_snap_context()
6168 ret = -EINVAL; in rbd_dev_v2_snap_context()
6177 ret = -ENOMEM; in rbd_dev_v2_snap_context()
6180 snapc->seq = seq; in rbd_dev_v2_snap_context()
6182 snapc->snaps[i] = ceph_decode_64(&p); in rbd_dev_v2_snap_context()
6185 dout(" snap context seq = %llu, snap_count = %u\n", in rbd_dev_v2_snap_context()
6207 return ERR_PTR(-ENOMEM); in rbd_dev_v2_snap_name()
6210 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_snap_name()
6211 &rbd_dev->header_oloc, "get_snapshot_name", in rbd_dev_v2_snap_name()
6213 dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); in rbd_dev_v2_snap_name()
6225 dout(" snap_id 0x%016llx snap_name = %s\n", in rbd_dev_v2_snap_name()
6240 first_time ? &header->obj_order : NULL, in rbd_dev_v2_header_info()
6241 &header->image_size); in rbd_dev_v2_header_info()
6251 ret = rbd_dev_v2_snap_context(rbd_dev, &header->snapc); in rbd_dev_v2_header_info()
6262 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_dev_header_info()
6263 rbd_assert(!header->object_prefix && !header->snapc); in rbd_dev_header_info()
6265 if (rbd_dev->image_format == 1) in rbd_dev_header_info()
6273 * first found non-space character (if any). Returns the length of
6274 * the token (string of non-white space characters) found. Note
6294 * that a duplicate buffer is created even for a zero-length token.
6296 * Returns a pointer to the newly-allocated duplicate, or a null
6298 * the lenp argument is a non-null pointer, the length of the token
6327 struct rbd_options *opt = pctx->opts; in rbd_parse_param()
6332 ret = ceph_parse_param(param, pctx->copts, NULL); in rbd_parse_param()
6333 if (ret != -ENOPARAM) in rbd_parse_param()
6337 dout("%s fs_parse '%s' token %d\n", __func__, param->key, token); in rbd_parse_param()
6339 if (token == -ENOPARAM) in rbd_parse_param()
6341 param->key); in rbd_parse_param()
6349 opt->queue_depth = result.uint_32; in rbd_parse_param()
6355 return inval_plog(&log, "alloc_size must be a power of 2"); in rbd_parse_param()
6356 opt->alloc_size = result.uint_32; in rbd_parse_param()
6362 opt->lock_timeout = msecs_to_jiffies(result.uint_32 * 1000); in rbd_parse_param()
6365 kfree(pctx->spec->pool_ns); in rbd_parse_param()
6366 pctx->spec->pool_ns = param->string; in rbd_parse_param()
6367 param->string = NULL; in rbd_parse_param()
6372 opt->alloc_hint_flags &= in rbd_parse_param()
6377 opt->alloc_hint_flags |= in rbd_parse_param()
6379 opt->alloc_hint_flags &= in rbd_parse_param()
6383 opt->alloc_hint_flags |= in rbd_parse_param()
6385 opt->alloc_hint_flags &= in rbd_parse_param()
6388 default: in rbd_parse_param()
6393 opt->read_only = true; in rbd_parse_param()
6396 opt->read_only = false; in rbd_parse_param()
6399 opt->lock_on_read = true; in rbd_parse_param()
6402 opt->exclusive = true; in rbd_parse_param()
6405 opt->trim = false; in rbd_parse_param()
6407 default: in rbd_parse_param()
6414 return inval_plog(&log, "%s out of range", param->key); in rbd_parse_param()
6426 dout("%s '%s'\n", __func__, options); in rbd_parse_options()
6444 return -ENOMEM; in rbd_parse_options()
6462 * and the data written is passed here via a NUL-terminated buffer.
6466 * the other parameters which return dynamically-allocated
6484 * A comma-separated list of one or more monitor addresses.
6489 * A comma-separated list of ceph and/or rbd options.
6498 * provided. Snapshot mappings are always read-only.
6518 return -EINVAL; in rbd_add_parse_args()
6524 ret = -EINVAL; in rbd_add_parse_args()
6527 return -ENOMEM; in rbd_add_parse_args()
6537 pctx.spec->pool_name = dup_token(&buf, NULL); in rbd_add_parse_args()
6538 if (!pctx.spec->pool_name) in rbd_add_parse_args()
6540 if (!*pctx.spec->pool_name) { in rbd_add_parse_args()
6545 pctx.spec->image_name = dup_token(&buf, NULL); in rbd_add_parse_args()
6546 if (!pctx.spec->image_name) in rbd_add_parse_args()
6548 if (!*pctx.spec->image_name) { in rbd_add_parse_args()
6554 * Snapshot name is optional; default is to use "-" in rbd_add_parse_args()
6560 len = sizeof (RBD_SNAP_HEAD_NAME) - 1; in rbd_add_parse_args()
6562 ret = -ENAMETOOLONG; in rbd_add_parse_args()
6569 pctx.spec->snap_name = snap_name; in rbd_add_parse_args()
6581 pctx.opts->read_only = RBD_READ_ONLY_DEFAULT; in rbd_add_parse_args()
6582 pctx.opts->queue_depth = RBD_QUEUE_DEPTH_DEFAULT; in rbd_add_parse_args()
6583 pctx.opts->alloc_size = RBD_ALLOC_SIZE_DEFAULT; in rbd_add_parse_args()
6584 pctx.opts->lock_timeout = RBD_LOCK_TIMEOUT_DEFAULT; in rbd_add_parse_args()
6585 pctx.opts->lock_on_read = RBD_LOCK_ON_READ_DEFAULT; in rbd_add_parse_args()
6586 pctx.opts->exclusive = RBD_EXCLUSIVE_DEFAULT; in rbd_add_parse_args()
6587 pctx.opts->trim = RBD_TRIM_DEFAULT; in rbd_add_parse_args()
6604 ret = -ENOMEM; in rbd_add_parse_args()
6615 down_write(&rbd_dev->lock_rwsem); in rbd_dev_image_unlock()
6618 up_write(&rbd_dev->lock_rwsem); in rbd_dev_image_unlock()
6630 if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK)) { in rbd_add_acquire_lock()
6631 if (!rbd_dev->opts->exclusive && !rbd_dev->opts->lock_on_read) in rbd_add_acquire_lock()
6634 rbd_warn(rbd_dev, "exclusive-lock feature is not enabled"); in rbd_add_acquire_lock()
6635 return -EINVAL; in rbd_add_acquire_lock()
6642 queue_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); in rbd_add_acquire_lock()
6643 ret = wait_for_completion_killable_timeout(&rbd_dev->acquire_wait, in rbd_add_acquire_lock()
6644 ceph_timeout_jiffies(rbd_dev->opts->lock_timeout)); in rbd_add_acquire_lock()
6646 ret = rbd_dev->acquire_err; in rbd_add_acquire_lock()
6648 cancel_delayed_work_sync(&rbd_dev->lock_dwork); in rbd_add_acquire_lock()
6650 ret = -ETIMEDOUT; in rbd_add_acquire_lock()
6661 rbd_assert(!rbd_dev->opts->exclusive || rbd_is_lock_owner(rbd_dev)); in rbd_add_acquire_lock()
6666 * An rbd format 2 image has a unique identifier, distinct from the
6693 if (rbd_dev->spec->image_id) { in rbd_dev_image_id()
6694 rbd_dev->image_format = *rbd_dev->spec->image_id ? 2 : 1; in rbd_dev_image_id()
6700 * First, see if the format 2 image id file exists, and if in rbd_dev_image_id()
6704 rbd_dev->spec->image_name); in rbd_dev_image_id()
6708 dout("rbd id object name is %s\n", oid.name); in rbd_dev_image_id()
6714 ret = -ENOMEM; in rbd_dev_image_id()
6720 ret = rbd_obj_method_sync(rbd_dev, &oid, &rbd_dev->header_oloc, in rbd_dev_image_id()
6723 dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); in rbd_dev_image_id()
6724 if (ret == -ENOENT) { in rbd_dev_image_id()
6726 ret = image_id ? 0 : -ENOMEM; in rbd_dev_image_id()
6728 rbd_dev->image_format = 1; in rbd_dev_image_id()
6736 rbd_dev->image_format = 2; in rbd_dev_image_id()
6740 rbd_dev->spec->image_id = image_id; in rbd_dev_image_id()
6741 dout("image_id is %s\n", image_id); in rbd_dev_image_id()
6761 rbd_image_header_cleanup(&rbd_dev->header); in rbd_dev_unprobe()
6769 ret = rbd_dev_v2_object_prefix(rbd_dev, &header->object_prefix); in rbd_dev_v2_header_onetime()
6778 rbd_is_ro(rbd_dev), &header->features); in rbd_dev_v2_header_onetime()
6784 if (header->features & RBD_FEATURE_STRIPINGV2) { in rbd_dev_v2_header_onetime()
6785 ret = rbd_dev_v2_striping_info(rbd_dev, &header->stripe_unit, in rbd_dev_v2_header_onetime()
6786 &header->stripe_count); in rbd_dev_v2_header_onetime()
6791 if (header->features & RBD_FEATURE_DATA_POOL) { in rbd_dev_v2_header_onetime()
6792 ret = rbd_dev_v2_data_pool(rbd_dev, &header->data_pool_id); in rbd_dev_v2_header_onetime()
6801 * @depth is rbd_dev_image_probe() -> rbd_dev_probe_parent() ->
6810 if (!rbd_dev->parent_spec) in rbd_dev_probe_parent()
6815 ret = -EINVAL; in rbd_dev_probe_parent()
6819 parent = __rbd_dev_create(rbd_dev->parent_spec); in rbd_dev_probe_parent()
6821 ret = -ENOMEM; in rbd_dev_probe_parent()
6829 parent->rbd_client = __rbd_get_client(rbd_dev->rbd_client); in rbd_dev_probe_parent()
6830 parent->spec = rbd_spec_get(rbd_dev->parent_spec); in rbd_dev_probe_parent()
6832 __set_bit(RBD_DEV_FLAG_READONLY, &parent->flags); in rbd_dev_probe_parent()
6838 rbd_dev->parent = parent; in rbd_dev_probe_parent()
6839 atomic_set(&rbd_dev->parent_ref, 1); in rbd_dev_probe_parent()
6850 clear_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); in rbd_dev_device_release()
6853 unregister_blkdev(rbd_dev->major, rbd_dev->name); in rbd_dev_device_release()
6857 * rbd_dev->header_rwsem must be locked for write and will be unlocked
6867 ret = register_blkdev(0, rbd_dev->name); in rbd_dev_device_setup()
6871 rbd_dev->major = ret; in rbd_dev_device_setup()
6872 rbd_dev->minor = 0; in rbd_dev_device_setup()
6874 rbd_dev->major = rbd_major; in rbd_dev_device_setup()
6875 rbd_dev->minor = rbd_dev_id_to_minor(rbd_dev->dev_id); in rbd_dev_device_setup()
6884 set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE); in rbd_dev_device_setup()
6885 set_disk_ro(rbd_dev->disk, rbd_is_ro(rbd_dev)); in rbd_dev_device_setup()
6887 ret = dev_set_name(&rbd_dev->dev, "%d", rbd_dev->dev_id); in rbd_dev_device_setup()
6891 set_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); in rbd_dev_device_setup()
6892 up_write(&rbd_dev->header_rwsem); in rbd_dev_device_setup()
6899 unregister_blkdev(rbd_dev->major, rbd_dev->name); in rbd_dev_device_setup()
6901 up_write(&rbd_dev->header_rwsem); in rbd_dev_device_setup()
6907 struct rbd_spec *spec = rbd_dev->spec; in rbd_dev_header_name()
6912 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_dev_header_name()
6913 if (rbd_dev->image_format == 1) in rbd_dev_header_name()
6914 ret = ceph_oid_aprintf(&rbd_dev->header_oid, GFP_KERNEL, "%s%s", in rbd_dev_header_name()
6915 spec->image_name, RBD_SUFFIX); in rbd_dev_header_name()
6917 ret = ceph_oid_aprintf(&rbd_dev->header_oid, GFP_KERNEL, "%s%s", in rbd_dev_header_name()
6918 RBD_HEADER_PREFIX, spec->image_id); in rbd_dev_header_name()
6927 rbd_dev->spec->pool_name, in rbd_print_dne()
6928 rbd_dev->spec->pool_ns ?: "", in rbd_print_dne()
6929 rbd_dev->spec->pool_ns ? "/" : "", in rbd_print_dne()
6930 rbd_dev->spec->image_name); in rbd_print_dne()
6933 rbd_dev->spec->pool_name, in rbd_print_dne()
6934 rbd_dev->spec->pool_ns ?: "", in rbd_print_dne()
6935 rbd_dev->spec->pool_ns ? "/" : "", in rbd_print_dne()
6936 rbd_dev->spec->image_name, in rbd_print_dne()
6937 rbd_dev->spec->snap_name); in rbd_print_dne()
6947 rbd_dev->image_format = 0; in rbd_dev_image_release()
6948 kfree(rbd_dev->spec->image_id); in rbd_dev_image_release()
6949 rbd_dev->spec->image_id = NULL; in rbd_dev_image_release()
6968 * error, rbd_dev->spec->image_id will be filled in with in rbd_dev_image_probe()
6969 * a dynamically-allocated string, and rbd_dev->image_format in rbd_dev_image_probe()
6970 * will be set to either 1 or 2. in rbd_dev_image_probe()
6983 if (ret == -ENOENT) in rbd_dev_image_probe()
6990 down_write(&rbd_dev->header_rwsem); in rbd_dev_image_probe()
6992 ret = rbd_dev_header_info(rbd_dev, &rbd_dev->header, true); in rbd_dev_image_probe()
6994 if (ret == -ENOENT && !need_watch) in rbd_dev_image_probe()
7003 * id, image name and id, and snap name - need to fill snap id. in rbd_dev_image_probe()
7005 * and snap ids - need to fill in names for those ids. in rbd_dev_image_probe()
7012 if (ret == -ENOENT) in rbd_dev_image_probe()
7022 (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) { in rbd_dev_image_probe()
7028 if (rbd_dev->header.features & RBD_FEATURE_LAYERING) { in rbd_dev_image_probe()
7038 dout("discovered format %u image, header name is %s\n", in rbd_dev_image_probe()
7039 rbd_dev->image_format, rbd_dev->header_oid.name); in rbd_dev_image_probe()
7044 up_write(&rbd_dev->header_rwsem); in rbd_dev_image_probe()
7049 rbd_dev->image_format = 0; in rbd_dev_image_probe()
7050 kfree(rbd_dev->spec->image_id); in rbd_dev_image_probe()
7051 rbd_dev->spec->image_id = NULL; in rbd_dev_image_probe()
7058 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_dev_update_header()
7059 rbd_assert(rbd_dev->header.object_prefix); /* !first_time */ in rbd_dev_update_header()
7061 if (rbd_dev->header.image_size != header->image_size) { in rbd_dev_update_header()
7062 rbd_dev->header.image_size = header->image_size; in rbd_dev_update_header()
7065 rbd_dev->mapping.size = header->image_size; in rbd_dev_update_header()
7070 ceph_put_snap_context(rbd_dev->header.snapc); in rbd_dev_update_header()
7071 rbd_dev->header.snapc = header->snapc; in rbd_dev_update_header()
7072 header->snapc = NULL; in rbd_dev_update_header()
7074 if (rbd_dev->image_format == 1) { in rbd_dev_update_header()
7075 kfree(rbd_dev->header.snap_names); in rbd_dev_update_header()
7076 rbd_dev->header.snap_names = header->snap_names; in rbd_dev_update_header()
7077 header->snap_names = NULL; in rbd_dev_update_header()
7079 kfree(rbd_dev->header.snap_sizes); in rbd_dev_update_header()
7080 rbd_dev->header.snap_sizes = header->snap_sizes; in rbd_dev_update_header()
7081 header->snap_sizes = NULL; in rbd_dev_update_header()
7088 if (pii->pool_id == CEPH_NOPOOL || !pii->has_overlap) { in rbd_dev_update_parent()
7102 if (rbd_dev->parent_overlap) { in rbd_dev_update_parent()
7103 rbd_dev->parent_overlap = 0; in rbd_dev_update_parent()
7106 rbd_dev->disk->disk_name); in rbd_dev_update_parent()
7109 rbd_assert(rbd_dev->parent_spec); in rbd_dev_update_parent()
7115 if (!pii->overlap && rbd_dev->parent_overlap) in rbd_dev_update_parent()
7118 rbd_dev->parent_overlap = pii->overlap; in rbd_dev_update_parent()
7128 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_dev_refresh()
7138 if (rbd_dev->parent) { in rbd_dev_refresh()
7144 down_write(&rbd_dev->header_rwsem); in rbd_dev_refresh()
7146 if (rbd_dev->parent) in rbd_dev_refresh()
7148 up_write(&rbd_dev->header_rwsem); in rbd_dev_refresh()
7168 return -EPERM; in do_rbd_add()
7171 return -ENODEV; in do_rbd_add()
7185 rc = ceph_pg_poolid_by_name(rbdc->client->osdc.osdmap, spec->pool_name); in do_rbd_add()
7187 if (rc == -ENOENT) in do_rbd_add()
7188 pr_info("pool %s does not exist\n", spec->pool_name); in do_rbd_add()
7191 spec->pool_id = (u64)rc; in do_rbd_add()
7195 rc = -ENOMEM; in do_rbd_add()
7202 /* if we are mapping a snapshot it will be a read-only mapping */ in do_rbd_add()
7203 if (rbd_dev->opts->read_only || in do_rbd_add()
7204 strcmp(rbd_dev->spec->snap_name, RBD_SNAP_HEAD_NAME)) in do_rbd_add()
7205 __set_bit(RBD_DEV_FLAG_READONLY, &rbd_dev->flags); in do_rbd_add()
7207 rbd_dev->config_info = kstrdup(buf, GFP_KERNEL); in do_rbd_add()
7208 if (!rbd_dev->config_info) { in do_rbd_add()
7209 rc = -ENOMEM; in do_rbd_add()
7217 if (rbd_dev->opts->alloc_size > rbd_dev->layout.object_size) { in do_rbd_add()
7219 rbd_dev->layout.object_size); in do_rbd_add()
7220 rbd_dev->opts->alloc_size = rbd_dev->layout.object_size; in do_rbd_add()
7233 rc = device_add(&rbd_dev->dev); in do_rbd_add()
7237 device_add_disk(&rbd_dev->dev, rbd_dev->disk, NULL); in do_rbd_add()
7239 blk_put_queue(rbd_dev->disk->queue); in do_rbd_add()
7242 list_add_tail(&rbd_dev->node, &rbd_dev_list); in do_rbd_add()
7245 pr_info("%s: capacity %llu features 0x%llx\n", rbd_dev->disk->disk_name, in do_rbd_add()
7246 (unsigned long long)get_capacity(rbd_dev->disk) << SECTOR_SHIFT, in do_rbd_add()
7247 rbd_dev->header.features); in do_rbd_add()
7271 return -EINVAL; in add_store()
7284 while (rbd_dev->parent) { in rbd_dev_remove_parent()
7286 struct rbd_device *second = first->parent; in rbd_dev_remove_parent()
7293 while (second && (third = second->parent)) { in rbd_dev_remove_parent()
7300 first->parent = NULL; in rbd_dev_remove_parent()
7301 first->parent_overlap = 0; in rbd_dev_remove_parent()
7303 rbd_assert(first->parent_spec); in rbd_dev_remove_parent()
7304 rbd_spec_put(first->parent_spec); in rbd_dev_remove_parent()
7305 first->parent_spec = NULL; in rbd_dev_remove_parent()
7321 return -EPERM; in do_rbd_remove()
7323 dev_id = -1; in do_rbd_remove()
7328 return -EINVAL; in do_rbd_remove()
7335 return -EINVAL; in do_rbd_remove()
7339 ret = -ENOENT; in do_rbd_remove()
7343 if (rbd_dev->dev_id == dev_id) { in do_rbd_remove()
7349 spin_lock_irq(&rbd_dev->lock); in do_rbd_remove()
7350 if (rbd_dev->open_count && !force) in do_rbd_remove()
7351 ret = -EBUSY; in do_rbd_remove()
7353 &rbd_dev->flags)) in do_rbd_remove()
7354 ret = -EINPROGRESS; in do_rbd_remove()
7355 spin_unlock_irq(&rbd_dev->lock); in do_rbd_remove()
7366 blk_mq_freeze_queue(rbd_dev->disk->queue); in do_rbd_remove()
7367 blk_set_queue_dying(rbd_dev->disk->queue); in do_rbd_remove()
7370 del_gendisk(rbd_dev->disk); in do_rbd_remove()
7372 list_del_init(&rbd_dev->node); in do_rbd_remove()
7374 device_del(&rbd_dev->dev); in do_rbd_remove()
7386 return -EINVAL; in remove_store()
7427 return -ENOMEM; in rbd_slab_init()
7439 return -ENOMEM; in rbd_slab_init()
7459 return -EINVAL; in rbd_init()
7468 * rbd devices * queue depth, so leave @max_active at default. in rbd_init()
7472 rc = -ENOMEM; in rbd_init()