Lines Matching refs:rbd_dev

277 	struct rbd_device	*rbd_dev;  member
439 static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth);
451 static bool __rbd_is_lock_owner(struct rbd_device *rbd_dev) in __rbd_is_lock_owner() argument
453 return rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED || in __rbd_is_lock_owner()
454 rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING; in __rbd_is_lock_owner()
457 static bool rbd_is_lock_owner(struct rbd_device *rbd_dev) in rbd_is_lock_owner() argument
461 down_read(&rbd_dev->lock_rwsem); in rbd_is_lock_owner()
462 is_lock_owner = __rbd_is_lock_owner(rbd_dev); in rbd_is_lock_owner()
463 up_read(&rbd_dev->lock_rwsem); in rbd_is_lock_owner()
519 void rbd_warn(struct rbd_device *rbd_dev, const char *fmt, ...) in rbd_warn() argument
528 if (!rbd_dev) in rbd_warn()
530 else if (rbd_dev->disk) in rbd_warn()
532 RBD_DRV_NAME, rbd_dev->disk->disk_name, &vaf); in rbd_warn()
533 else if (rbd_dev->spec && rbd_dev->spec->image_name) in rbd_warn()
535 RBD_DRV_NAME, rbd_dev->spec->image_name, &vaf); in rbd_warn()
536 else if (rbd_dev->spec && rbd_dev->spec->image_id) in rbd_warn()
538 RBD_DRV_NAME, rbd_dev->spec->image_id, &vaf); in rbd_warn()
541 RBD_DRV_NAME, rbd_dev, &vaf); in rbd_warn()
558 static void rbd_dev_remove_parent(struct rbd_device *rbd_dev);
560 static int rbd_dev_refresh(struct rbd_device *rbd_dev);
561 static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev);
562 static int rbd_dev_header_info(struct rbd_device *rbd_dev);
563 static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev);
564 static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev,
566 static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
568 static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id,
573 struct rbd_device *rbd_dev = bdev->bd_disk->private_data; in rbd_open() local
576 spin_lock_irq(&rbd_dev->lock); in rbd_open()
577 if (test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags)) in rbd_open()
580 rbd_dev->open_count++; in rbd_open()
581 spin_unlock_irq(&rbd_dev->lock); in rbd_open()
585 (void) get_device(&rbd_dev->dev); in rbd_open()
592 struct rbd_device *rbd_dev = disk->private_data; in rbd_release() local
595 spin_lock_irq(&rbd_dev->lock); in rbd_release()
596 open_count_before = rbd_dev->open_count--; in rbd_release()
597 spin_unlock_irq(&rbd_dev->lock); in rbd_release()
600 put_device(&rbd_dev->dev); in rbd_release()
603 static int rbd_ioctl_set_ro(struct rbd_device *rbd_dev, unsigned long arg) in rbd_ioctl_set_ro() argument
611 if (rbd_dev->spec->snap_id != CEPH_NOSNAP && !ro) in rbd_ioctl_set_ro()
621 struct rbd_device *rbd_dev = bdev->bd_disk->private_data; in rbd_ioctl() local
626 ret = rbd_ioctl_set_ro(rbd_dev, arg); in rbd_ioctl()
996 static void rbd_init_layout(struct rbd_device *rbd_dev) in rbd_init_layout() argument
998 if (rbd_dev->header.stripe_unit == 0 || in rbd_init_layout()
999 rbd_dev->header.stripe_count == 0) { in rbd_init_layout()
1000 rbd_dev->header.stripe_unit = rbd_obj_bytes(&rbd_dev->header); in rbd_init_layout()
1001 rbd_dev->header.stripe_count = 1; in rbd_init_layout()
1004 rbd_dev->layout.stripe_unit = rbd_dev->header.stripe_unit; in rbd_init_layout()
1005 rbd_dev->layout.stripe_count = rbd_dev->header.stripe_count; in rbd_init_layout()
1006 rbd_dev->layout.object_size = rbd_obj_bytes(&rbd_dev->header); in rbd_init_layout()
1007 rbd_dev->layout.pool_id = rbd_dev->header.data_pool_id == CEPH_NOPOOL ? in rbd_init_layout()
1008 rbd_dev->spec->pool_id : rbd_dev->header.data_pool_id; in rbd_init_layout()
1009 RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL); in rbd_init_layout()
1016 static int rbd_header_from_disk(struct rbd_device *rbd_dev, in rbd_header_from_disk() argument
1019 struct rbd_image_header *header = &rbd_dev->header; in rbd_header_from_disk()
1087 rbd_init_layout(rbd_dev); in rbd_header_from_disk()
1113 static const char *_rbd_dev_v1_snap_name(struct rbd_device *rbd_dev, u32 which) in _rbd_dev_v1_snap_name() argument
1117 rbd_assert(which < rbd_dev->header.snapc->num_snaps); in _rbd_dev_v1_snap_name()
1121 snap_name = rbd_dev->header.snap_names; in _rbd_dev_v1_snap_name()
1152 static u32 rbd_dev_snap_index(struct rbd_device *rbd_dev, u64 snap_id) in rbd_dev_snap_index() argument
1154 struct ceph_snap_context *snapc = rbd_dev->header.snapc; in rbd_dev_snap_index()
1163 static const char *rbd_dev_v1_snap_name(struct rbd_device *rbd_dev, in rbd_dev_v1_snap_name() argument
1169 which = rbd_dev_snap_index(rbd_dev, snap_id); in rbd_dev_v1_snap_name()
1173 snap_name = _rbd_dev_v1_snap_name(rbd_dev, which); in rbd_dev_v1_snap_name()
1177 static const char *rbd_snap_name(struct rbd_device *rbd_dev, u64 snap_id) in rbd_snap_name() argument
1182 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_snap_name()
1183 if (rbd_dev->image_format == 1) in rbd_snap_name()
1184 return rbd_dev_v1_snap_name(rbd_dev, snap_id); in rbd_snap_name()
1186 return rbd_dev_v2_snap_name(rbd_dev, snap_id); in rbd_snap_name()
1189 static int rbd_snap_size(struct rbd_device *rbd_dev, u64 snap_id, in rbd_snap_size() argument
1192 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_snap_size()
1194 *snap_size = rbd_dev->header.image_size; in rbd_snap_size()
1195 } else if (rbd_dev->image_format == 1) { in rbd_snap_size()
1198 which = rbd_dev_snap_index(rbd_dev, snap_id); in rbd_snap_size()
1202 *snap_size = rbd_dev->header.snap_sizes[which]; in rbd_snap_size()
1207 ret = _rbd_dev_v2_snap_size(rbd_dev, snap_id, NULL, &size); in rbd_snap_size()
1216 static int rbd_snap_features(struct rbd_device *rbd_dev, u64 snap_id, in rbd_snap_features() argument
1219 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_snap_features()
1221 *snap_features = rbd_dev->header.features; in rbd_snap_features()
1222 } else if (rbd_dev->image_format == 1) { in rbd_snap_features()
1228 ret = _rbd_dev_v2_snap_features(rbd_dev, snap_id, &features); in rbd_snap_features()
1237 static int rbd_dev_mapping_set(struct rbd_device *rbd_dev) in rbd_dev_mapping_set() argument
1239 u64 snap_id = rbd_dev->spec->snap_id; in rbd_dev_mapping_set()
1244 ret = rbd_snap_size(rbd_dev, snap_id, &size); in rbd_dev_mapping_set()
1247 ret = rbd_snap_features(rbd_dev, snap_id, &features); in rbd_dev_mapping_set()
1251 rbd_dev->mapping.size = size; in rbd_dev_mapping_set()
1252 rbd_dev->mapping.features = features; in rbd_dev_mapping_set()
1257 static void rbd_dev_mapping_clear(struct rbd_device *rbd_dev) in rbd_dev_mapping_clear() argument
1259 rbd_dev->mapping.size = 0; in rbd_dev_mapping_clear()
1260 rbd_dev->mapping.features = 0; in rbd_dev_mapping_clear()
1399 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_is_entire() local
1402 obj_req->ex.oe_len == rbd_dev->layout.object_size; in rbd_obj_is_entire()
1407 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_is_tail() local
1410 rbd_dev->layout.object_size; in rbd_obj_is_tail()
1477 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_osd_req_create() local
1478 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_osd_req_create()
1480 const char *name_format = rbd_dev->image_format == 1 ? in rbd_osd_req_create()
1496 ceph_oloc_copy(&req->r_base_oloc, &rbd_dev->header_oloc); in rbd_osd_req_create()
1497 req->r_base_oloc.pool = rbd_dev->layout.pool_id; in rbd_osd_req_create()
1500 rbd_dev->header.object_prefix, obj_req->ex.oe_objno)) in rbd_osd_req_create()
1572 static void rbd_dev_unparent(struct rbd_device *rbd_dev) in rbd_dev_unparent() argument
1574 rbd_dev_remove_parent(rbd_dev); in rbd_dev_unparent()
1575 rbd_spec_put(rbd_dev->parent_spec); in rbd_dev_unparent()
1576 rbd_dev->parent_spec = NULL; in rbd_dev_unparent()
1577 rbd_dev->parent_overlap = 0; in rbd_dev_unparent()
1586 static void rbd_dev_parent_put(struct rbd_device *rbd_dev) in rbd_dev_parent_put() argument
1590 if (!rbd_dev->parent_spec) in rbd_dev_parent_put()
1593 counter = atomic_dec_return_safe(&rbd_dev->parent_ref); in rbd_dev_parent_put()
1600 rbd_dev_unparent(rbd_dev); in rbd_dev_parent_put()
1602 rbd_warn(rbd_dev, "parent reference underflow"); in rbd_dev_parent_put()
1613 static bool rbd_dev_parent_get(struct rbd_device *rbd_dev) in rbd_dev_parent_get() argument
1617 if (!rbd_dev->parent_spec) in rbd_dev_parent_get()
1620 down_read(&rbd_dev->header_rwsem); in rbd_dev_parent_get()
1621 if (rbd_dev->parent_overlap) in rbd_dev_parent_get()
1622 counter = atomic_inc_return_safe(&rbd_dev->parent_ref); in rbd_dev_parent_get()
1623 up_read(&rbd_dev->header_rwsem); in rbd_dev_parent_get()
1626 rbd_warn(rbd_dev, "parent reference overflow"); in rbd_dev_parent_get()
1637 struct rbd_device *rbd_dev, in rbd_img_request_create() argument
1647 img_request->rbd_dev = rbd_dev; in rbd_img_request_create()
1650 img_request->snap_id = rbd_dev->spec->snap_id; in rbd_img_request_create()
1654 if (rbd_dev_parent_get(rbd_dev)) in rbd_img_request_create()
1661 dout("%s: rbd_dev %p %s -> img %p\n", __func__, rbd_dev, in rbd_img_request_create()
1682 rbd_dev_parent_put(img_request->rbd_dev); in rbd_img_request_destroy()
1718 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_calc_img_extents() local
1721 if (!rbd_dev->parent_overlap) in rbd_obj_calc_img_extents()
1724 ret = ceph_extent_to_file(&rbd_dev->layout, obj_req->ex.oe_objno, in rbd_obj_calc_img_extents()
1726 entire ? rbd_dev->layout.object_size : in rbd_obj_calc_img_extents()
1734 rbd_dev->parent_overlap); in rbd_obj_calc_img_extents()
1800 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in __rbd_obj_setup_write() local
1804 rbd_dev->layout.object_size, in __rbd_obj_setup_write()
1805 rbd_dev->layout.object_size); in __rbd_obj_setup_write()
2008 ret = ceph_file_to_extents(&img_req->rbd_dev->layout, in rbd_img_fill_request_nocopy()
2039 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_img_fill_request() local
2045 !rbd_layout_is_fancy(&rbd_dev->layout)) in rbd_img_fill_request()
2060 ret = ceph_file_to_extents(&rbd_dev->layout, in rbd_img_fill_request()
2084 ret = ceph_iterate_extents(&rbd_dev->layout, in rbd_img_fill_request()
2257 child_img_req = rbd_img_request_create(img_req->rbd_dev->parent, in rbd_obj_read_from_parent()
2300 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_handle_read() local
2304 rbd_dev->parent_overlap && !obj_req->tried_parent) { in rbd_obj_handle_read()
2442 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_handle_write_guard() local
2447 rbd_dev->parent_overlap); in rbd_obj_handle_write_guard()
2557 rbd_warn(img_req->rbd_dev, in rbd_obj_end_request()
2628 static struct rbd_client_id rbd_get_cid(struct rbd_device *rbd_dev) in rbd_get_cid() argument
2632 mutex_lock(&rbd_dev->watch_mutex); in rbd_get_cid()
2633 cid.gid = ceph_client_gid(rbd_dev->rbd_client->client); in rbd_get_cid()
2634 cid.handle = rbd_dev->watch_cookie; in rbd_get_cid()
2635 mutex_unlock(&rbd_dev->watch_mutex); in rbd_get_cid()
2642 static void rbd_set_owner_cid(struct rbd_device *rbd_dev, in rbd_set_owner_cid() argument
2645 dout("%s rbd_dev %p %llu-%llu -> %llu-%llu\n", __func__, rbd_dev, in rbd_set_owner_cid()
2646 rbd_dev->owner_cid.gid, rbd_dev->owner_cid.handle, in rbd_set_owner_cid()
2648 rbd_dev->owner_cid = *cid; /* struct */ in rbd_set_owner_cid()
2651 static void format_lock_cookie(struct rbd_device *rbd_dev, char *buf) in format_lock_cookie() argument
2653 mutex_lock(&rbd_dev->watch_mutex); in format_lock_cookie()
2654 sprintf(buf, "%s %llu", RBD_LOCK_COOKIE_PREFIX, rbd_dev->watch_cookie); in format_lock_cookie()
2655 mutex_unlock(&rbd_dev->watch_mutex); in format_lock_cookie()
2658 static void __rbd_lock(struct rbd_device *rbd_dev, const char *cookie) in __rbd_lock() argument
2660 struct rbd_client_id cid = rbd_get_cid(rbd_dev); in __rbd_lock()
2662 strcpy(rbd_dev->lock_cookie, cookie); in __rbd_lock()
2663 rbd_set_owner_cid(rbd_dev, &cid); in __rbd_lock()
2664 queue_work(rbd_dev->task_wq, &rbd_dev->acquired_lock_work); in __rbd_lock()
2670 static int rbd_lock(struct rbd_device *rbd_dev) in rbd_lock() argument
2672 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_lock()
2676 WARN_ON(__rbd_is_lock_owner(rbd_dev) || in rbd_lock()
2677 rbd_dev->lock_cookie[0] != '\0'); in rbd_lock()
2679 format_lock_cookie(rbd_dev, cookie); in rbd_lock()
2680 ret = ceph_cls_lock(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in rbd_lock()
2686 rbd_dev->lock_state = RBD_LOCK_STATE_LOCKED; in rbd_lock()
2687 __rbd_lock(rbd_dev, cookie); in rbd_lock()
2694 static void rbd_unlock(struct rbd_device *rbd_dev) in rbd_unlock() argument
2696 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_unlock()
2699 WARN_ON(!__rbd_is_lock_owner(rbd_dev) || in rbd_unlock()
2700 rbd_dev->lock_cookie[0] == '\0'); in rbd_unlock()
2702 ret = ceph_cls_unlock(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in rbd_unlock()
2703 RBD_LOCK_NAME, rbd_dev->lock_cookie); in rbd_unlock()
2705 rbd_warn(rbd_dev, "failed to unlock: %d", ret); in rbd_unlock()
2708 rbd_dev->lock_state = RBD_LOCK_STATE_UNLOCKED; in rbd_unlock()
2709 rbd_dev->lock_cookie[0] = '\0'; in rbd_unlock()
2710 rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); in rbd_unlock()
2711 queue_work(rbd_dev->task_wq, &rbd_dev->released_lock_work); in rbd_unlock()
2714 static int __rbd_notify_op_lock(struct rbd_device *rbd_dev, in __rbd_notify_op_lock() argument
2719 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_notify_op_lock()
2720 struct rbd_client_id cid = rbd_get_cid(rbd_dev); in __rbd_notify_op_lock()
2725 dout("%s rbd_dev %p notify_op %d\n", __func__, rbd_dev, notify_op); in __rbd_notify_op_lock()
2733 return ceph_osdc_notify(osdc, &rbd_dev->header_oid, in __rbd_notify_op_lock()
2734 &rbd_dev->header_oloc, buf, buf_size, in __rbd_notify_op_lock()
2738 static void rbd_notify_op_lock(struct rbd_device *rbd_dev, in rbd_notify_op_lock() argument
2744 __rbd_notify_op_lock(rbd_dev, notify_op, &reply_pages, &reply_len); in rbd_notify_op_lock()
2750 struct rbd_device *rbd_dev = container_of(work, struct rbd_device, in rbd_notify_acquired_lock() local
2753 rbd_notify_op_lock(rbd_dev, RBD_NOTIFY_OP_ACQUIRED_LOCK); in rbd_notify_acquired_lock()
2758 struct rbd_device *rbd_dev = container_of(work, struct rbd_device, in rbd_notify_released_lock() local
2761 rbd_notify_op_lock(rbd_dev, RBD_NOTIFY_OP_RELEASED_LOCK); in rbd_notify_released_lock()
2764 static int rbd_request_lock(struct rbd_device *rbd_dev) in rbd_request_lock() argument
2771 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_request_lock()
2773 ret = __rbd_notify_op_lock(rbd_dev, RBD_NOTIFY_OP_REQUEST_LOCK, in rbd_request_lock()
2776 rbd_warn(rbd_dev, "failed to request lock: %d", ret); in rbd_request_lock()
2798 rbd_warn(rbd_dev, in rbd_request_lock()
2808 rbd_warn(rbd_dev, in rbd_request_lock()
2819 rbd_warn(rbd_dev, "no lock owners detected"); in rbd_request_lock()
2832 static void wake_requests(struct rbd_device *rbd_dev, bool wake_all) in wake_requests() argument
2834 dout("%s rbd_dev %p wake_all %d\n", __func__, rbd_dev, wake_all); in wake_requests()
2836 cancel_delayed_work(&rbd_dev->lock_dwork); in wake_requests()
2838 wake_up_all(&rbd_dev->lock_waitq); in wake_requests()
2840 wake_up(&rbd_dev->lock_waitq); in wake_requests()
2843 static int get_lock_owner_info(struct rbd_device *rbd_dev, in get_lock_owner_info() argument
2846 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in get_lock_owner_info()
2851 dout("%s rbd_dev %p\n", __func__, rbd_dev); in get_lock_owner_info()
2853 ret = ceph_cls_lock_info(osdc, &rbd_dev->header_oid, in get_lock_owner_info()
2854 &rbd_dev->header_oloc, RBD_LOCK_NAME, in get_lock_owner_info()
2860 dout("%s rbd_dev %p no lockers detected\n", __func__, rbd_dev); in get_lock_owner_info()
2865 rbd_warn(rbd_dev, "locked by external mechanism, tag %s", in get_lock_owner_info()
2872 rbd_warn(rbd_dev, "shared lock type detected"); in get_lock_owner_info()
2879 rbd_warn(rbd_dev, "locked by external mechanism, cookie %s", in get_lock_owner_info()
2890 static int find_watcher(struct rbd_device *rbd_dev, in find_watcher() argument
2893 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in find_watcher()
2900 ret = ceph_osdc_list_watchers(osdc, &rbd_dev->header_oid, in find_watcher()
2901 &rbd_dev->header_oloc, &watchers, in find_watcher()
2917 rbd_dev, cid.gid, cid.handle); in find_watcher()
2918 rbd_set_owner_cid(rbd_dev, &cid); in find_watcher()
2924 dout("%s rbd_dev %p no watchers\n", __func__, rbd_dev); in find_watcher()
2934 static int rbd_try_lock(struct rbd_device *rbd_dev) in rbd_try_lock() argument
2936 struct ceph_client *client = rbd_dev->rbd_client->client; in rbd_try_lock()
2942 ret = rbd_lock(rbd_dev); in rbd_try_lock()
2947 ret = get_lock_owner_info(rbd_dev, &lockers, &num_lockers); in rbd_try_lock()
2954 ret = find_watcher(rbd_dev, lockers); in rbd_try_lock()
2961 rbd_warn(rbd_dev, "%s%llu seems dead, breaking lock", in rbd_try_lock()
2967 rbd_warn(rbd_dev, "blacklist of %s%llu failed: %d", in rbd_try_lock()
2972 ret = ceph_cls_break_lock(&client->osdc, &rbd_dev->header_oid, in rbd_try_lock()
2973 &rbd_dev->header_oloc, RBD_LOCK_NAME, in rbd_try_lock()
2991 static enum rbd_lock_state rbd_try_acquire_lock(struct rbd_device *rbd_dev, in rbd_try_acquire_lock() argument
2996 down_read(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
2997 dout("%s rbd_dev %p read lock_state %d\n", __func__, rbd_dev, in rbd_try_acquire_lock()
2998 rbd_dev->lock_state); in rbd_try_acquire_lock()
2999 if (__rbd_is_lock_owner(rbd_dev)) { in rbd_try_acquire_lock()
3000 lock_state = rbd_dev->lock_state; in rbd_try_acquire_lock()
3001 up_read(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
3005 up_read(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
3006 down_write(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
3007 dout("%s rbd_dev %p write lock_state %d\n", __func__, rbd_dev, in rbd_try_acquire_lock()
3008 rbd_dev->lock_state); in rbd_try_acquire_lock()
3009 if (!__rbd_is_lock_owner(rbd_dev)) { in rbd_try_acquire_lock()
3010 *pret = rbd_try_lock(rbd_dev); in rbd_try_acquire_lock()
3012 rbd_warn(rbd_dev, "failed to acquire lock: %d", *pret); in rbd_try_acquire_lock()
3015 lock_state = rbd_dev->lock_state; in rbd_try_acquire_lock()
3016 up_write(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
3022 struct rbd_device *rbd_dev = container_of(to_delayed_work(work), in rbd_acquire_lock() local
3027 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_acquire_lock()
3029 lock_state = rbd_try_acquire_lock(rbd_dev, &ret); in rbd_acquire_lock()
3032 wake_requests(rbd_dev, true); in rbd_acquire_lock()
3034 rbd_dev, lock_state, ret); in rbd_acquire_lock()
3038 ret = rbd_request_lock(rbd_dev); in rbd_acquire_lock()
3042 rbd_warn(rbd_dev, "peer will not release lock"); in rbd_acquire_lock()
3048 if (!(rbd_dev->disk->flags & GENHD_FL_UP)) { in rbd_acquire_lock()
3049 set_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags); in rbd_acquire_lock()
3051 wake_requests(rbd_dev, false); in rbd_acquire_lock()
3054 rbd_warn(rbd_dev, "error requesting lock: %d", ret); in rbd_acquire_lock()
3055 mod_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, in rbd_acquire_lock()
3063 rbd_dev); in rbd_acquire_lock()
3064 mod_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, in rbd_acquire_lock()
3072 static bool rbd_release_lock(struct rbd_device *rbd_dev) in rbd_release_lock() argument
3074 dout("%s rbd_dev %p read lock_state %d\n", __func__, rbd_dev, in rbd_release_lock()
3075 rbd_dev->lock_state); in rbd_release_lock()
3076 if (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED) in rbd_release_lock()
3079 rbd_dev->lock_state = RBD_LOCK_STATE_RELEASING; in rbd_release_lock()
3080 downgrade_write(&rbd_dev->lock_rwsem); in rbd_release_lock()
3087 ceph_osdc_sync(&rbd_dev->rbd_client->client->osdc); in rbd_release_lock()
3088 up_read(&rbd_dev->lock_rwsem); in rbd_release_lock()
3090 down_write(&rbd_dev->lock_rwsem); in rbd_release_lock()
3091 dout("%s rbd_dev %p write lock_state %d\n", __func__, rbd_dev, in rbd_release_lock()
3092 rbd_dev->lock_state); in rbd_release_lock()
3093 if (rbd_dev->lock_state != RBD_LOCK_STATE_RELEASING) in rbd_release_lock()
3096 rbd_unlock(rbd_dev); in rbd_release_lock()
3104 cancel_delayed_work(&rbd_dev->lock_dwork); in rbd_release_lock()
3110 struct rbd_device *rbd_dev = container_of(work, struct rbd_device, in rbd_release_lock_work() local
3113 down_write(&rbd_dev->lock_rwsem); in rbd_release_lock_work()
3114 rbd_release_lock(rbd_dev); in rbd_release_lock_work()
3115 up_write(&rbd_dev->lock_rwsem); in rbd_release_lock_work()
3118 static void rbd_handle_acquired_lock(struct rbd_device *rbd_dev, u8 struct_v, in rbd_handle_acquired_lock() argument
3128 dout("%s rbd_dev %p cid %llu-%llu\n", __func__, rbd_dev, cid.gid, in rbd_handle_acquired_lock()
3131 down_write(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
3132 if (rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { in rbd_handle_acquired_lock()
3137 up_write(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
3141 rbd_set_owner_cid(rbd_dev, &cid); in rbd_handle_acquired_lock()
3142 downgrade_write(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
3144 down_read(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
3147 if (!__rbd_is_lock_owner(rbd_dev)) in rbd_handle_acquired_lock()
3148 wake_requests(rbd_dev, false); in rbd_handle_acquired_lock()
3149 up_read(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
3152 static void rbd_handle_released_lock(struct rbd_device *rbd_dev, u8 struct_v, in rbd_handle_released_lock() argument
3162 dout("%s rbd_dev %p cid %llu-%llu\n", __func__, rbd_dev, cid.gid, in rbd_handle_released_lock()
3165 down_write(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
3166 if (!rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { in rbd_handle_released_lock()
3168 __func__, rbd_dev, cid.gid, cid.handle, in rbd_handle_released_lock()
3169 rbd_dev->owner_cid.gid, rbd_dev->owner_cid.handle); in rbd_handle_released_lock()
3170 up_write(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
3174 rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); in rbd_handle_released_lock()
3175 downgrade_write(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
3177 down_read(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
3180 if (!__rbd_is_lock_owner(rbd_dev)) in rbd_handle_released_lock()
3181 wake_requests(rbd_dev, false); in rbd_handle_released_lock()
3182 up_read(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
3189 static int rbd_handle_request_lock(struct rbd_device *rbd_dev, u8 struct_v, in rbd_handle_request_lock() argument
3192 struct rbd_client_id my_cid = rbd_get_cid(rbd_dev); in rbd_handle_request_lock()
3201 dout("%s rbd_dev %p cid %llu-%llu\n", __func__, rbd_dev, cid.gid, in rbd_handle_request_lock()
3206 down_read(&rbd_dev->lock_rwsem); in rbd_handle_request_lock()
3207 if (__rbd_is_lock_owner(rbd_dev)) { in rbd_handle_request_lock()
3208 if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED && in rbd_handle_request_lock()
3209 rbd_cid_equal(&rbd_dev->owner_cid, &rbd_empty_cid)) in rbd_handle_request_lock()
3218 if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED) { in rbd_handle_request_lock()
3219 if (!rbd_dev->opts->exclusive) { in rbd_handle_request_lock()
3221 __func__, rbd_dev); in rbd_handle_request_lock()
3222 queue_work(rbd_dev->task_wq, in rbd_handle_request_lock()
3223 &rbd_dev->unlock_work); in rbd_handle_request_lock()
3232 up_read(&rbd_dev->lock_rwsem); in rbd_handle_request_lock()
3236 static void __rbd_acknowledge_notify(struct rbd_device *rbd_dev, in __rbd_acknowledge_notify() argument
3239 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_acknowledge_notify()
3255 ret = ceph_osdc_notify_ack(osdc, &rbd_dev->header_oid, in __rbd_acknowledge_notify()
3256 &rbd_dev->header_oloc, notify_id, cookie, in __rbd_acknowledge_notify()
3259 rbd_warn(rbd_dev, "acknowledge_notify failed: %d", ret); in __rbd_acknowledge_notify()
3262 static void rbd_acknowledge_notify(struct rbd_device *rbd_dev, u64 notify_id, in rbd_acknowledge_notify() argument
3265 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_acknowledge_notify()
3266 __rbd_acknowledge_notify(rbd_dev, notify_id, cookie, NULL); in rbd_acknowledge_notify()
3269 static void rbd_acknowledge_notify_result(struct rbd_device *rbd_dev, in rbd_acknowledge_notify_result() argument
3272 dout("%s rbd_dev %p result %d\n", __func__, rbd_dev, result); in rbd_acknowledge_notify_result()
3273 __rbd_acknowledge_notify(rbd_dev, notify_id, cookie, &result); in rbd_acknowledge_notify_result()
3279 struct rbd_device *rbd_dev = arg; in rbd_watch_cb() local
3288 __func__, rbd_dev, cookie, notify_id, data_len); in rbd_watch_cb()
3293 rbd_warn(rbd_dev, "failed to decode NotifyMessage: %d", in rbd_watch_cb()
3305 dout("%s rbd_dev %p notify_op %u\n", __func__, rbd_dev, notify_op); in rbd_watch_cb()
3308 rbd_handle_acquired_lock(rbd_dev, struct_v, &p); in rbd_watch_cb()
3309 rbd_acknowledge_notify(rbd_dev, notify_id, cookie); in rbd_watch_cb()
3312 rbd_handle_released_lock(rbd_dev, struct_v, &p); in rbd_watch_cb()
3313 rbd_acknowledge_notify(rbd_dev, notify_id, cookie); in rbd_watch_cb()
3316 ret = rbd_handle_request_lock(rbd_dev, struct_v, &p); in rbd_watch_cb()
3318 rbd_acknowledge_notify_result(rbd_dev, notify_id, in rbd_watch_cb()
3321 rbd_acknowledge_notify(rbd_dev, notify_id, cookie); in rbd_watch_cb()
3324 ret = rbd_dev_refresh(rbd_dev); in rbd_watch_cb()
3326 rbd_warn(rbd_dev, "refresh failed: %d", ret); in rbd_watch_cb()
3328 rbd_acknowledge_notify(rbd_dev, notify_id, cookie); in rbd_watch_cb()
3331 if (rbd_is_lock_owner(rbd_dev)) in rbd_watch_cb()
3332 rbd_acknowledge_notify_result(rbd_dev, notify_id, in rbd_watch_cb()
3335 rbd_acknowledge_notify(rbd_dev, notify_id, cookie); in rbd_watch_cb()
3340 static void __rbd_unregister_watch(struct rbd_device *rbd_dev);
3344 struct rbd_device *rbd_dev = arg; in rbd_watch_errcb() local
3346 rbd_warn(rbd_dev, "encountered watch error: %d", err); in rbd_watch_errcb()
3348 down_write(&rbd_dev->lock_rwsem); in rbd_watch_errcb()
3349 rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); in rbd_watch_errcb()
3350 up_write(&rbd_dev->lock_rwsem); in rbd_watch_errcb()
3352 mutex_lock(&rbd_dev->watch_mutex); in rbd_watch_errcb()
3353 if (rbd_dev->watch_state == RBD_WATCH_STATE_REGISTERED) { in rbd_watch_errcb()
3354 __rbd_unregister_watch(rbd_dev); in rbd_watch_errcb()
3355 rbd_dev->watch_state = RBD_WATCH_STATE_ERROR; in rbd_watch_errcb()
3357 queue_delayed_work(rbd_dev->task_wq, &rbd_dev->watch_dwork, 0); in rbd_watch_errcb()
3359 mutex_unlock(&rbd_dev->watch_mutex); in rbd_watch_errcb()
3365 static int __rbd_register_watch(struct rbd_device *rbd_dev) in __rbd_register_watch() argument
3367 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_register_watch()
3370 rbd_assert(!rbd_dev->watch_handle); in __rbd_register_watch()
3371 dout("%s rbd_dev %p\n", __func__, rbd_dev); in __rbd_register_watch()
3373 handle = ceph_osdc_watch(osdc, &rbd_dev->header_oid, in __rbd_register_watch()
3374 &rbd_dev->header_oloc, rbd_watch_cb, in __rbd_register_watch()
3375 rbd_watch_errcb, rbd_dev); in __rbd_register_watch()
3379 rbd_dev->watch_handle = handle; in __rbd_register_watch()
3386 static void __rbd_unregister_watch(struct rbd_device *rbd_dev) in __rbd_unregister_watch() argument
3388 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_unregister_watch()
3391 rbd_assert(rbd_dev->watch_handle); in __rbd_unregister_watch()
3392 dout("%s rbd_dev %p\n", __func__, rbd_dev); in __rbd_unregister_watch()
3394 ret = ceph_osdc_unwatch(osdc, rbd_dev->watch_handle); in __rbd_unregister_watch()
3396 rbd_warn(rbd_dev, "failed to unwatch: %d", ret); in __rbd_unregister_watch()
3398 rbd_dev->watch_handle = NULL; in __rbd_unregister_watch()
3401 static int rbd_register_watch(struct rbd_device *rbd_dev) in rbd_register_watch() argument
3405 mutex_lock(&rbd_dev->watch_mutex); in rbd_register_watch()
3406 rbd_assert(rbd_dev->watch_state == RBD_WATCH_STATE_UNREGISTERED); in rbd_register_watch()
3407 ret = __rbd_register_watch(rbd_dev); in rbd_register_watch()
3411 rbd_dev->watch_state = RBD_WATCH_STATE_REGISTERED; in rbd_register_watch()
3412 rbd_dev->watch_cookie = rbd_dev->watch_handle->linger_id; in rbd_register_watch()
3415 mutex_unlock(&rbd_dev->watch_mutex); in rbd_register_watch()
3419 static void cancel_tasks_sync(struct rbd_device *rbd_dev) in cancel_tasks_sync() argument
3421 dout("%s rbd_dev %p\n", __func__, rbd_dev); in cancel_tasks_sync()
3423 cancel_work_sync(&rbd_dev->acquired_lock_work); in cancel_tasks_sync()
3424 cancel_work_sync(&rbd_dev->released_lock_work); in cancel_tasks_sync()
3425 cancel_delayed_work_sync(&rbd_dev->lock_dwork); in cancel_tasks_sync()
3426 cancel_work_sync(&rbd_dev->unlock_work); in cancel_tasks_sync()
3429 static void rbd_unregister_watch(struct rbd_device *rbd_dev) in rbd_unregister_watch() argument
3431 WARN_ON(waitqueue_active(&rbd_dev->lock_waitq)); in rbd_unregister_watch()
3432 cancel_tasks_sync(rbd_dev); in rbd_unregister_watch()
3434 mutex_lock(&rbd_dev->watch_mutex); in rbd_unregister_watch()
3435 if (rbd_dev->watch_state == RBD_WATCH_STATE_REGISTERED) in rbd_unregister_watch()
3436 __rbd_unregister_watch(rbd_dev); in rbd_unregister_watch()
3437 rbd_dev->watch_state = RBD_WATCH_STATE_UNREGISTERED; in rbd_unregister_watch()
3438 mutex_unlock(&rbd_dev->watch_mutex); in rbd_unregister_watch()
3440 cancel_delayed_work_sync(&rbd_dev->watch_dwork); in rbd_unregister_watch()
3441 ceph_osdc_flush_notifies(&rbd_dev->rbd_client->client->osdc); in rbd_unregister_watch()
3447 static void rbd_reacquire_lock(struct rbd_device *rbd_dev) in rbd_reacquire_lock() argument
3449 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_reacquire_lock()
3453 WARN_ON(rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED); in rbd_reacquire_lock()
3455 format_lock_cookie(rbd_dev, cookie); in rbd_reacquire_lock()
3456 ret = ceph_cls_set_cookie(osdc, &rbd_dev->header_oid, in rbd_reacquire_lock()
3457 &rbd_dev->header_oloc, RBD_LOCK_NAME, in rbd_reacquire_lock()
3458 CEPH_CLS_LOCK_EXCLUSIVE, rbd_dev->lock_cookie, in rbd_reacquire_lock()
3462 rbd_warn(rbd_dev, "failed to update lock cookie: %d", in rbd_reacquire_lock()
3469 if (rbd_release_lock(rbd_dev)) in rbd_reacquire_lock()
3470 queue_delayed_work(rbd_dev->task_wq, in rbd_reacquire_lock()
3471 &rbd_dev->lock_dwork, 0); in rbd_reacquire_lock()
3473 __rbd_lock(rbd_dev, cookie); in rbd_reacquire_lock()
3479 struct rbd_device *rbd_dev = container_of(to_delayed_work(work), in rbd_reregister_watch() local
3483 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_reregister_watch()
3485 mutex_lock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
3486 if (rbd_dev->watch_state != RBD_WATCH_STATE_ERROR) { in rbd_reregister_watch()
3487 mutex_unlock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
3491 ret = __rbd_register_watch(rbd_dev); in rbd_reregister_watch()
3493 rbd_warn(rbd_dev, "failed to reregister watch: %d", ret); in rbd_reregister_watch()
3495 set_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags); in rbd_reregister_watch()
3496 wake_requests(rbd_dev, true); in rbd_reregister_watch()
3498 queue_delayed_work(rbd_dev->task_wq, in rbd_reregister_watch()
3499 &rbd_dev->watch_dwork, in rbd_reregister_watch()
3502 mutex_unlock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
3506 rbd_dev->watch_state = RBD_WATCH_STATE_REGISTERED; in rbd_reregister_watch()
3507 rbd_dev->watch_cookie = rbd_dev->watch_handle->linger_id; in rbd_reregister_watch()
3508 mutex_unlock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
3510 down_write(&rbd_dev->lock_rwsem); in rbd_reregister_watch()
3511 if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED) in rbd_reregister_watch()
3512 rbd_reacquire_lock(rbd_dev); in rbd_reregister_watch()
3513 up_write(&rbd_dev->lock_rwsem); in rbd_reregister_watch()
3515 ret = rbd_dev_refresh(rbd_dev); in rbd_reregister_watch()
3517 rbd_warn(rbd_dev, "reregistration refresh failed: %d", ret); in rbd_reregister_watch()
3524 static int rbd_obj_method_sync(struct rbd_device *rbd_dev, in rbd_obj_method_sync() argument
3533 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_obj_method_sync()
3580 static int rbd_wait_state_locked(struct rbd_device *rbd_dev, bool may_acquire) in rbd_wait_state_locked() argument
3586 if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) in rbd_wait_state_locked()
3589 if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED) in rbd_wait_state_locked()
3593 rbd_warn(rbd_dev, "exclusive lock required"); in rbd_wait_state_locked()
3602 dout("%s rbd_dev %p queueing lock_dwork\n", __func__, rbd_dev); in rbd_wait_state_locked()
3603 queue_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); in rbd_wait_state_locked()
3604 prepare_to_wait_exclusive(&rbd_dev->lock_waitq, &wait, in rbd_wait_state_locked()
3606 up_read(&rbd_dev->lock_rwsem); in rbd_wait_state_locked()
3608 rbd_dev->opts->lock_timeout)); in rbd_wait_state_locked()
3609 down_read(&rbd_dev->lock_rwsem); in rbd_wait_state_locked()
3610 if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) { in rbd_wait_state_locked()
3615 rbd_warn(rbd_dev, "timed out waiting for lock"); in rbd_wait_state_locked()
3619 } while (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED); in rbd_wait_state_locked()
3621 finish_wait(&rbd_dev->lock_waitq, &wait); in rbd_wait_state_locked()
3628 struct rbd_device *rbd_dev = rq->q->queuedata; in rbd_queue_workfn() local
3664 rbd_dev->spec->snap_id == CEPH_NOSNAP); in rbd_queue_workfn()
3672 if (!test_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags)) { in rbd_queue_workfn()
3674 rbd_assert(rbd_dev->spec->snap_id != CEPH_NOSNAP); in rbd_queue_workfn()
3680 rbd_warn(rbd_dev, "bad request range (%llu~%llu)", offset, in rbd_queue_workfn()
3688 down_read(&rbd_dev->header_rwsem); in rbd_queue_workfn()
3689 mapping_size = rbd_dev->mapping.size; in rbd_queue_workfn()
3691 snapc = rbd_dev->header.snapc; in rbd_queue_workfn()
3694 up_read(&rbd_dev->header_rwsem); in rbd_queue_workfn()
3697 rbd_warn(rbd_dev, "beyond EOD (%llu~%llu > %llu)", offset, in rbd_queue_workfn()
3704 (rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK) && in rbd_queue_workfn()
3705 (op_type != OBJ_OP_READ || rbd_dev->opts->lock_on_read); in rbd_queue_workfn()
3707 down_read(&rbd_dev->lock_rwsem); in rbd_queue_workfn()
3708 result = rbd_wait_state_locked(rbd_dev, in rbd_queue_workfn()
3709 !rbd_dev->opts->exclusive); in rbd_queue_workfn()
3714 img_request = rbd_img_request_create(rbd_dev, op_type, snapc); in rbd_queue_workfn()
3732 up_read(&rbd_dev->lock_rwsem); in rbd_queue_workfn()
3739 up_read(&rbd_dev->lock_rwsem); in rbd_queue_workfn()
3742 rbd_warn(rbd_dev, "%s %llx at %llx result %d", in rbd_queue_workfn()
3759 static void rbd_free_disk(struct rbd_device *rbd_dev) in rbd_free_disk() argument
3761 blk_cleanup_queue(rbd_dev->disk->queue); in rbd_free_disk()
3762 blk_mq_free_tag_set(&rbd_dev->tag_set); in rbd_free_disk()
3763 put_disk(rbd_dev->disk); in rbd_free_disk()
3764 rbd_dev->disk = NULL; in rbd_free_disk()
3767 static int rbd_obj_read_sync(struct rbd_device *rbd_dev, in rbd_obj_read_sync() argument
3773 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_obj_read_sync()
3816 static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) in rbd_dev_v1_header_info() argument
3843 ret = rbd_obj_read_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v1_header_info()
3844 &rbd_dev->header_oloc, ondisk, size); in rbd_dev_v1_header_info()
3849 rbd_warn(rbd_dev, "short header read (want %zd got %d)", in rbd_dev_v1_header_info()
3855 rbd_warn(rbd_dev, "invalid header"); in rbd_dev_v1_header_info()
3864 ret = rbd_header_from_disk(rbd_dev, ondisk); in rbd_dev_v1_header_info()
3875 static void rbd_exists_validate(struct rbd_device *rbd_dev) in rbd_exists_validate() argument
3879 if (!test_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags)) in rbd_exists_validate()
3882 snap_id = rbd_dev->spec->snap_id; in rbd_exists_validate()
3886 if (rbd_dev_snap_index(rbd_dev, snap_id) == BAD_SNAP_INDEX) in rbd_exists_validate()
3887 clear_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); in rbd_exists_validate()
3890 static void rbd_dev_update_size(struct rbd_device *rbd_dev) in rbd_dev_update_size() argument
3899 if (test_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags) && in rbd_dev_update_size()
3900 !test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags)) { in rbd_dev_update_size()
3901 size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE; in rbd_dev_update_size()
3903 set_capacity(rbd_dev->disk, size); in rbd_dev_update_size()
3904 revalidate_disk(rbd_dev->disk); in rbd_dev_update_size()
3908 static int rbd_dev_refresh(struct rbd_device *rbd_dev) in rbd_dev_refresh() argument
3913 down_write(&rbd_dev->header_rwsem); in rbd_dev_refresh()
3914 mapping_size = rbd_dev->mapping.size; in rbd_dev_refresh()
3916 ret = rbd_dev_header_info(rbd_dev); in rbd_dev_refresh()
3924 if (rbd_dev->parent) { in rbd_dev_refresh()
3925 ret = rbd_dev_v2_parent_info(rbd_dev); in rbd_dev_refresh()
3930 if (rbd_dev->spec->snap_id == CEPH_NOSNAP) { in rbd_dev_refresh()
3931 rbd_dev->mapping.size = rbd_dev->header.image_size; in rbd_dev_refresh()
3934 rbd_exists_validate(rbd_dev); in rbd_dev_refresh()
3938 up_write(&rbd_dev->header_rwsem); in rbd_dev_refresh()
3939 if (!ret && mapping_size != rbd_dev->mapping.size) in rbd_dev_refresh()
3940 rbd_dev_update_size(rbd_dev); in rbd_dev_refresh()
3959 static int rbd_init_disk(struct rbd_device *rbd_dev) in rbd_init_disk() argument
3964 rbd_dev->layout.object_size * rbd_dev->layout.stripe_count; in rbd_init_disk()
3975 rbd_dev->dev_id); in rbd_init_disk()
3976 disk->major = rbd_dev->major; in rbd_init_disk()
3977 disk->first_minor = rbd_dev->minor; in rbd_init_disk()
3981 disk->private_data = rbd_dev; in rbd_init_disk()
3983 memset(&rbd_dev->tag_set, 0, sizeof(rbd_dev->tag_set)); in rbd_init_disk()
3984 rbd_dev->tag_set.ops = &rbd_mq_ops; in rbd_init_disk()
3985 rbd_dev->tag_set.queue_depth = rbd_dev->opts->queue_depth; in rbd_init_disk()
3986 rbd_dev->tag_set.numa_node = NUMA_NO_NODE; in rbd_init_disk()
3987 rbd_dev->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_SG_MERGE; in rbd_init_disk()
3988 rbd_dev->tag_set.nr_hw_queues = 1; in rbd_init_disk()
3989 rbd_dev->tag_set.cmd_size = sizeof(struct work_struct); in rbd_init_disk()
3991 err = blk_mq_alloc_tag_set(&rbd_dev->tag_set); in rbd_init_disk()
3995 q = blk_mq_init_queue(&rbd_dev->tag_set); in rbd_init_disk()
4011 if (rbd_dev->opts->trim) { in rbd_init_disk()
4018 if (!ceph_test_opt(rbd_dev->rbd_client->client, NOCRC)) in rbd_init_disk()
4027 q->queuedata = rbd_dev; in rbd_init_disk()
4029 rbd_dev->disk = disk; in rbd_init_disk()
4033 blk_mq_free_tag_set(&rbd_dev->tag_set); in rbd_init_disk()
4051 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_size_show() local
4054 (unsigned long long)rbd_dev->mapping.size); in rbd_size_show()
4064 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_features_show() local
4067 (unsigned long long)rbd_dev->mapping.features); in rbd_features_show()
4073 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_major_show() local
4075 if (rbd_dev->major) in rbd_major_show()
4076 return sprintf(buf, "%d\n", rbd_dev->major); in rbd_major_show()
4084 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_minor_show() local
4086 return sprintf(buf, "%d\n", rbd_dev->minor); in rbd_minor_show()
4092 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_client_addr_show() local
4094 ceph_client_addr(rbd_dev->rbd_client->client); in rbd_client_addr_show()
4103 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_client_id_show() local
4106 ceph_client_gid(rbd_dev->rbd_client->client)); in rbd_client_id_show()
4112 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_cluster_fsid_show() local
4114 return sprintf(buf, "%pU\n", &rbd_dev->rbd_client->client->fsid); in rbd_cluster_fsid_show()
4120 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_config_info_show() local
4122 return sprintf(buf, "%s\n", rbd_dev->config_info); in rbd_config_info_show()
4128 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_pool_show() local
4130 return sprintf(buf, "%s\n", rbd_dev->spec->pool_name); in rbd_pool_show()
4136 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_pool_id_show() local
4139 (unsigned long long) rbd_dev->spec->pool_id); in rbd_pool_id_show()
4145 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_pool_ns_show() local
4147 return sprintf(buf, "%s\n", rbd_dev->spec->pool_ns ?: ""); in rbd_pool_ns_show()
4153 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_name_show() local
4155 if (rbd_dev->spec->image_name) in rbd_name_show()
4156 return sprintf(buf, "%s\n", rbd_dev->spec->image_name); in rbd_name_show()
4164 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_image_id_show() local
4166 return sprintf(buf, "%s\n", rbd_dev->spec->image_id); in rbd_image_id_show()
4177 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_snap_show() local
4179 return sprintf(buf, "%s\n", rbd_dev->spec->snap_name); in rbd_snap_show()
4185 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_snap_id_show() local
4187 return sprintf(buf, "%llu\n", rbd_dev->spec->snap_id); in rbd_snap_id_show()
4199 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_parent_show() local
4202 if (!rbd_dev->parent) in rbd_parent_show()
4205 for ( ; rbd_dev->parent; rbd_dev = rbd_dev->parent) { in rbd_parent_show()
4206 struct rbd_spec *spec = rbd_dev->parent_spec; in rbd_parent_show()
4219 rbd_dev->parent_overlap); in rbd_parent_show()
4230 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_image_refresh() local
4233 ret = rbd_dev_refresh(rbd_dev); in rbd_image_refresh()
4337 static void rbd_dev_free(struct rbd_device *rbd_dev) in rbd_dev_free() argument
4339 WARN_ON(rbd_dev->watch_state != RBD_WATCH_STATE_UNREGISTERED); in rbd_dev_free()
4340 WARN_ON(rbd_dev->lock_state != RBD_LOCK_STATE_UNLOCKED); in rbd_dev_free()
4342 ceph_oid_destroy(&rbd_dev->header_oid); in rbd_dev_free()
4343 ceph_oloc_destroy(&rbd_dev->header_oloc); in rbd_dev_free()
4344 kfree(rbd_dev->config_info); in rbd_dev_free()
4346 rbd_put_client(rbd_dev->rbd_client); in rbd_dev_free()
4347 rbd_spec_put(rbd_dev->spec); in rbd_dev_free()
4348 kfree(rbd_dev->opts); in rbd_dev_free()
4349 kfree(rbd_dev); in rbd_dev_free()
4354 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_dev_release() local
4355 bool need_put = !!rbd_dev->opts; in rbd_dev_release()
4358 destroy_workqueue(rbd_dev->task_wq); in rbd_dev_release()
4359 ida_simple_remove(&rbd_dev_id_ida, rbd_dev->dev_id); in rbd_dev_release()
4362 rbd_dev_free(rbd_dev); in rbd_dev_release()
4376 struct rbd_device *rbd_dev; in __rbd_dev_create() local
4378 rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL); in __rbd_dev_create()
4379 if (!rbd_dev) in __rbd_dev_create()
4382 spin_lock_init(&rbd_dev->lock); in __rbd_dev_create()
4383 INIT_LIST_HEAD(&rbd_dev->node); in __rbd_dev_create()
4384 init_rwsem(&rbd_dev->header_rwsem); in __rbd_dev_create()
4386 rbd_dev->header.data_pool_id = CEPH_NOPOOL; in __rbd_dev_create()
4387 ceph_oid_init(&rbd_dev->header_oid); in __rbd_dev_create()
4388 rbd_dev->header_oloc.pool = spec->pool_id; in __rbd_dev_create()
4391 rbd_dev->header_oloc.pool_ns = in __rbd_dev_create()
4396 mutex_init(&rbd_dev->watch_mutex); in __rbd_dev_create()
4397 rbd_dev->watch_state = RBD_WATCH_STATE_UNREGISTERED; in __rbd_dev_create()
4398 INIT_DELAYED_WORK(&rbd_dev->watch_dwork, rbd_reregister_watch); in __rbd_dev_create()
4400 init_rwsem(&rbd_dev->lock_rwsem); in __rbd_dev_create()
4401 rbd_dev->lock_state = RBD_LOCK_STATE_UNLOCKED; in __rbd_dev_create()
4402 INIT_WORK(&rbd_dev->acquired_lock_work, rbd_notify_acquired_lock); in __rbd_dev_create()
4403 INIT_WORK(&rbd_dev->released_lock_work, rbd_notify_released_lock); in __rbd_dev_create()
4404 INIT_DELAYED_WORK(&rbd_dev->lock_dwork, rbd_acquire_lock); in __rbd_dev_create()
4405 INIT_WORK(&rbd_dev->unlock_work, rbd_release_lock_work); in __rbd_dev_create()
4406 init_waitqueue_head(&rbd_dev->lock_waitq); in __rbd_dev_create()
4408 rbd_dev->dev.bus = &rbd_bus_type; in __rbd_dev_create()
4409 rbd_dev->dev.type = &rbd_device_type; in __rbd_dev_create()
4410 rbd_dev->dev.parent = &rbd_root_dev; in __rbd_dev_create()
4411 device_initialize(&rbd_dev->dev); in __rbd_dev_create()
4413 rbd_dev->rbd_client = rbdc; in __rbd_dev_create()
4414 rbd_dev->spec = spec; in __rbd_dev_create()
4416 return rbd_dev; in __rbd_dev_create()
4426 struct rbd_device *rbd_dev; in rbd_dev_create() local
4428 rbd_dev = __rbd_dev_create(rbdc, spec); in rbd_dev_create()
4429 if (!rbd_dev) in rbd_dev_create()
4432 rbd_dev->opts = opts; in rbd_dev_create()
4435 rbd_dev->dev_id = ida_simple_get(&rbd_dev_id_ida, 0, in rbd_dev_create()
4438 if (rbd_dev->dev_id < 0) in rbd_dev_create()
4441 sprintf(rbd_dev->name, RBD_DRV_NAME "%d", rbd_dev->dev_id); in rbd_dev_create()
4442 rbd_dev->task_wq = alloc_ordered_workqueue("%s-tasks", WQ_MEM_RECLAIM, in rbd_dev_create()
4443 rbd_dev->name); in rbd_dev_create()
4444 if (!rbd_dev->task_wq) in rbd_dev_create()
4450 dout("%s rbd_dev %p dev_id %d\n", __func__, rbd_dev, rbd_dev->dev_id); in rbd_dev_create()
4451 return rbd_dev; in rbd_dev_create()
4454 ida_simple_remove(&rbd_dev_id_ida, rbd_dev->dev_id); in rbd_dev_create()
4456 rbd_dev_free(rbd_dev); in rbd_dev_create()
4460 static void rbd_dev_destroy(struct rbd_device *rbd_dev) in rbd_dev_destroy() argument
4462 if (rbd_dev) in rbd_dev_destroy()
4463 put_device(&rbd_dev->dev); in rbd_dev_destroy()
4471 static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, in _rbd_dev_v2_snap_size() argument
4481 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in _rbd_dev_v2_snap_size()
4482 &rbd_dev->header_oloc, "get_size", in _rbd_dev_v2_snap_size()
4504 static int rbd_dev_v2_image_size(struct rbd_device *rbd_dev) in rbd_dev_v2_image_size() argument
4506 return _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, in rbd_dev_v2_image_size()
4507 &rbd_dev->header.obj_order, in rbd_dev_v2_image_size()
4508 &rbd_dev->header.image_size); in rbd_dev_v2_image_size()
4511 static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) in rbd_dev_v2_object_prefix() argument
4521 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_object_prefix()
4522 &rbd_dev->header_oloc, "get_object_prefix", in rbd_dev_v2_object_prefix()
4529 rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p, in rbd_dev_v2_object_prefix()
4533 if (IS_ERR(rbd_dev->header.object_prefix)) { in rbd_dev_v2_object_prefix()
4534 ret = PTR_ERR(rbd_dev->header.object_prefix); in rbd_dev_v2_object_prefix()
4535 rbd_dev->header.object_prefix = NULL; in rbd_dev_v2_object_prefix()
4537 dout(" object_prefix = %s\n", rbd_dev->header.object_prefix); in rbd_dev_v2_object_prefix()
4545 static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, in _rbd_dev_v2_snap_features() argument
4556 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in _rbd_dev_v2_snap_features()
4557 &rbd_dev->header_oloc, "get_features", in _rbd_dev_v2_snap_features()
4568 rbd_warn(rbd_dev, "image uses unsupported features: 0x%llx", in _rbd_dev_v2_snap_features()
4583 static int rbd_dev_v2_features(struct rbd_device *rbd_dev) in rbd_dev_v2_features() argument
4585 return _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP, in rbd_dev_v2_features()
4586 &rbd_dev->header.features); in rbd_dev_v2_features()
4634 static int __get_parent_info(struct rbd_device *rbd_dev, in __get_parent_info() argument
4639 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __get_parent_info()
4644 ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in __get_parent_info()
4656 ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in __get_parent_info()
4677 static int __get_parent_info_legacy(struct rbd_device *rbd_dev, in __get_parent_info_legacy() argument
4682 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __get_parent_info_legacy()
4687 ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in __get_parent_info_legacy()
4712 static int get_parent_info(struct rbd_device *rbd_dev, in get_parent_info() argument
4730 ceph_encode_64(&p, rbd_dev->spec->snap_id); in get_parent_info()
4731 ret = __get_parent_info(rbd_dev, req_page, reply_page, pii); in get_parent_info()
4733 ret = __get_parent_info_legacy(rbd_dev, req_page, reply_page, in get_parent_info()
4741 static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) in rbd_dev_v2_parent_info() argument
4751 ret = get_parent_info(rbd_dev, &pii); in rbd_dev_v2_parent_info()
4773 if (rbd_dev->parent_overlap) { in rbd_dev_v2_parent_info()
4774 rbd_dev->parent_overlap = 0; in rbd_dev_v2_parent_info()
4775 rbd_dev_parent_put(rbd_dev); in rbd_dev_v2_parent_info()
4777 rbd_dev->disk->disk_name); in rbd_dev_v2_parent_info()
4797 if (!rbd_dev->parent_spec) { in rbd_dev_v2_parent_info()
4807 rbd_dev->parent_spec = parent_spec; in rbd_dev_v2_parent_info()
4818 if (rbd_dev->parent_overlap) in rbd_dev_v2_parent_info()
4819 rbd_warn(rbd_dev, in rbd_dev_v2_parent_info()
4823 rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); in rbd_dev_v2_parent_info()
4826 rbd_dev->parent_overlap = pii.overlap; in rbd_dev_v2_parent_info()
4837 static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) in rbd_dev_v2_striping_info() argument
4847 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_striping_info()
4848 &rbd_dev->header_oloc, "get_stripe_unit_count", in rbd_dev_v2_striping_info()
4857 rbd_dev->header.stripe_unit = ceph_decode_64(&p); in rbd_dev_v2_striping_info()
4858 rbd_dev->header.stripe_count = ceph_decode_64(&p); in rbd_dev_v2_striping_info()
4862 static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev) in rbd_dev_v2_data_pool() argument
4867 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_data_pool()
4868 &rbd_dev->header_oloc, "get_data_pool", in rbd_dev_v2_data_pool()
4875 rbd_dev->header.data_pool_id = le64_to_cpu(data_pool_id); in rbd_dev_v2_data_pool()
4876 WARN_ON(rbd_dev->header.data_pool_id == CEPH_NOPOOL); in rbd_dev_v2_data_pool()
4880 static char *rbd_dev_image_name(struct rbd_device *rbd_dev) in rbd_dev_image_name() argument
4893 rbd_assert(!rbd_dev->spec->image_name); in rbd_dev_image_name()
4895 len = strlen(rbd_dev->spec->image_id); in rbd_dev_image_name()
4903 ceph_encode_string(&p, end, rbd_dev->spec->image_id, (u32)len); in rbd_dev_image_name()
4911 ret = rbd_obj_method_sync(rbd_dev, &oid, &rbd_dev->header_oloc, in rbd_dev_image_name()
4931 static u64 rbd_v1_snap_id_by_name(struct rbd_device *rbd_dev, const char *name) in rbd_v1_snap_id_by_name() argument
4933 struct ceph_snap_context *snapc = rbd_dev->header.snapc; in rbd_v1_snap_id_by_name()
4939 snap_name = rbd_dev->header.snap_names; in rbd_v1_snap_id_by_name()
4949 static u64 rbd_v2_snap_id_by_name(struct rbd_device *rbd_dev, const char *name) in rbd_v2_snap_id_by_name() argument
4951 struct ceph_snap_context *snapc = rbd_dev->header.snapc; in rbd_v2_snap_id_by_name()
4960 snap_name = rbd_dev_v2_snap_name(rbd_dev, snap_id); in rbd_v2_snap_id_by_name()
4978 static u64 rbd_snap_id_by_name(struct rbd_device *rbd_dev, const char *name) in rbd_snap_id_by_name() argument
4980 if (rbd_dev->image_format == 1) in rbd_snap_id_by_name()
4981 return rbd_v1_snap_id_by_name(rbd_dev, name); in rbd_snap_id_by_name()
4983 return rbd_v2_snap_id_by_name(rbd_dev, name); in rbd_snap_id_by_name()
4989 static int rbd_spec_fill_snap_id(struct rbd_device *rbd_dev) in rbd_spec_fill_snap_id() argument
4991 struct rbd_spec *spec = rbd_dev->spec; in rbd_spec_fill_snap_id()
5000 snap_id = rbd_snap_id_by_name(rbd_dev, spec->snap_name); in rbd_spec_fill_snap_id()
5018 static int rbd_spec_fill_names(struct rbd_device *rbd_dev) in rbd_spec_fill_names() argument
5020 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_spec_fill_names()
5021 struct rbd_spec *spec = rbd_dev->spec; in rbd_spec_fill_names()
5035 rbd_warn(rbd_dev, "no pool with id %llu", spec->pool_id); in rbd_spec_fill_names()
5044 image_name = rbd_dev_image_name(rbd_dev); in rbd_spec_fill_names()
5046 rbd_warn(rbd_dev, "unable to get image name"); in rbd_spec_fill_names()
5050 snap_name = rbd_snap_name(rbd_dev, spec->snap_id); in rbd_spec_fill_names()
5068 static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev) in rbd_dev_v2_snap_context() argument
5092 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_snap_context()
5093 &rbd_dev->header_oloc, "get_snapcontext", in rbd_dev_v2_snap_context()
5129 ceph_put_snap_context(rbd_dev->header.snapc); in rbd_dev_v2_snap_context()
5130 rbd_dev->header.snapc = snapc; in rbd_dev_v2_snap_context()
5140 static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, in rbd_dev_v2_snap_name() argument
5157 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_snap_name()
5158 &rbd_dev->header_oloc, "get_snapshot_name", in rbd_dev_v2_snap_name()
5180 static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev) in rbd_dev_v2_header_info() argument
5182 bool first_time = rbd_dev->header.object_prefix == NULL; in rbd_dev_v2_header_info()
5185 ret = rbd_dev_v2_image_size(rbd_dev); in rbd_dev_v2_header_info()
5190 ret = rbd_dev_v2_header_onetime(rbd_dev); in rbd_dev_v2_header_info()
5195 ret = rbd_dev_v2_snap_context(rbd_dev); in rbd_dev_v2_header_info()
5197 kfree(rbd_dev->header.object_prefix); in rbd_dev_v2_header_info()
5198 rbd_dev->header.object_prefix = NULL; in rbd_dev_v2_header_info()
5204 static int rbd_dev_header_info(struct rbd_device *rbd_dev) in rbd_dev_header_info() argument
5206 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_dev_header_info()
5208 if (rbd_dev->image_format == 1) in rbd_dev_header_info()
5209 return rbd_dev_v1_header_info(rbd_dev); in rbd_dev_header_info()
5211 return rbd_dev_v2_header_info(rbd_dev); in rbd_dev_header_info()
5417 static void rbd_dev_image_unlock(struct rbd_device *rbd_dev) in rbd_dev_image_unlock() argument
5419 down_write(&rbd_dev->lock_rwsem); in rbd_dev_image_unlock()
5420 if (__rbd_is_lock_owner(rbd_dev)) in rbd_dev_image_unlock()
5421 rbd_unlock(rbd_dev); in rbd_dev_image_unlock()
5422 up_write(&rbd_dev->lock_rwsem); in rbd_dev_image_unlock()
5425 static int rbd_add_acquire_lock(struct rbd_device *rbd_dev) in rbd_add_acquire_lock() argument
5429 if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK)) { in rbd_add_acquire_lock()
5430 rbd_warn(rbd_dev, "exclusive-lock feature is not enabled"); in rbd_add_acquire_lock()
5435 down_read(&rbd_dev->lock_rwsem); in rbd_add_acquire_lock()
5436 ret = rbd_wait_state_locked(rbd_dev, true); in rbd_add_acquire_lock()
5437 up_read(&rbd_dev->lock_rwsem); in rbd_add_acquire_lock()
5439 rbd_warn(rbd_dev, "failed to acquire exclusive lock"); in rbd_add_acquire_lock()
5460 static int rbd_dev_image_id(struct rbd_device *rbd_dev) in rbd_dev_image_id() argument
5474 if (rbd_dev->spec->image_id) { in rbd_dev_image_id()
5475 rbd_dev->image_format = *rbd_dev->spec->image_id ? 2 : 1; in rbd_dev_image_id()
5485 rbd_dev->spec->image_name); in rbd_dev_image_id()
5502 ret = rbd_obj_method_sync(rbd_dev, &oid, &rbd_dev->header_oloc, in rbd_dev_image_id()
5510 rbd_dev->image_format = 1; in rbd_dev_image_id()
5518 rbd_dev->image_format = 2; in rbd_dev_image_id()
5522 rbd_dev->spec->image_id = image_id; in rbd_dev_image_id()
5535 static void rbd_dev_unprobe(struct rbd_device *rbd_dev) in rbd_dev_unprobe() argument
5539 rbd_dev_parent_put(rbd_dev); in rbd_dev_unprobe()
5543 header = &rbd_dev->header; in rbd_dev_unprobe()
5551 static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev) in rbd_dev_v2_header_onetime() argument
5555 ret = rbd_dev_v2_object_prefix(rbd_dev); in rbd_dev_v2_header_onetime()
5563 ret = rbd_dev_v2_features(rbd_dev); in rbd_dev_v2_header_onetime()
5569 if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) { in rbd_dev_v2_header_onetime()
5570 ret = rbd_dev_v2_striping_info(rbd_dev); in rbd_dev_v2_header_onetime()
5575 if (rbd_dev->header.features & RBD_FEATURE_DATA_POOL) { in rbd_dev_v2_header_onetime()
5576 ret = rbd_dev_v2_data_pool(rbd_dev); in rbd_dev_v2_header_onetime()
5581 rbd_init_layout(rbd_dev); in rbd_dev_v2_header_onetime()
5585 rbd_dev->header.features = 0; in rbd_dev_v2_header_onetime()
5586 kfree(rbd_dev->header.object_prefix); in rbd_dev_v2_header_onetime()
5587 rbd_dev->header.object_prefix = NULL; in rbd_dev_v2_header_onetime()
5596 static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) in rbd_dev_probe_parent() argument
5601 if (!rbd_dev->parent_spec) in rbd_dev_probe_parent()
5610 parent = __rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec); in rbd_dev_probe_parent()
5620 __rbd_get_client(rbd_dev->rbd_client); in rbd_dev_probe_parent()
5621 rbd_spec_get(rbd_dev->parent_spec); in rbd_dev_probe_parent()
5627 rbd_dev->parent = parent; in rbd_dev_probe_parent()
5628 atomic_set(&rbd_dev->parent_ref, 1); in rbd_dev_probe_parent()
5632 rbd_dev_unparent(rbd_dev); in rbd_dev_probe_parent()
5637 static void rbd_dev_device_release(struct rbd_device *rbd_dev) in rbd_dev_device_release() argument
5639 clear_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); in rbd_dev_device_release()
5640 rbd_dev_mapping_clear(rbd_dev); in rbd_dev_device_release()
5641 rbd_free_disk(rbd_dev); in rbd_dev_device_release()
5643 unregister_blkdev(rbd_dev->major, rbd_dev->name); in rbd_dev_device_release()
5650 static int rbd_dev_device_setup(struct rbd_device *rbd_dev) in rbd_dev_device_setup() argument
5657 ret = register_blkdev(0, rbd_dev->name); in rbd_dev_device_setup()
5661 rbd_dev->major = ret; in rbd_dev_device_setup()
5662 rbd_dev->minor = 0; in rbd_dev_device_setup()
5664 rbd_dev->major = rbd_major; in rbd_dev_device_setup()
5665 rbd_dev->minor = rbd_dev_id_to_minor(rbd_dev->dev_id); in rbd_dev_device_setup()
5670 ret = rbd_init_disk(rbd_dev); in rbd_dev_device_setup()
5674 ret = rbd_dev_mapping_set(rbd_dev); in rbd_dev_device_setup()
5678 set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE); in rbd_dev_device_setup()
5679 set_disk_ro(rbd_dev->disk, rbd_dev->opts->read_only); in rbd_dev_device_setup()
5681 ret = dev_set_name(&rbd_dev->dev, "%d", rbd_dev->dev_id); in rbd_dev_device_setup()
5685 set_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); in rbd_dev_device_setup()
5686 up_write(&rbd_dev->header_rwsem); in rbd_dev_device_setup()
5690 rbd_dev_mapping_clear(rbd_dev); in rbd_dev_device_setup()
5692 rbd_free_disk(rbd_dev); in rbd_dev_device_setup()
5695 unregister_blkdev(rbd_dev->major, rbd_dev->name); in rbd_dev_device_setup()
5697 up_write(&rbd_dev->header_rwsem); in rbd_dev_device_setup()
5701 static int rbd_dev_header_name(struct rbd_device *rbd_dev) in rbd_dev_header_name() argument
5703 struct rbd_spec *spec = rbd_dev->spec; in rbd_dev_header_name()
5708 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_dev_header_name()
5709 if (rbd_dev->image_format == 1) in rbd_dev_header_name()
5710 ret = ceph_oid_aprintf(&rbd_dev->header_oid, GFP_KERNEL, "%s%s", in rbd_dev_header_name()
5713 ret = ceph_oid_aprintf(&rbd_dev->header_oid, GFP_KERNEL, "%s%s", in rbd_dev_header_name()
5719 static void rbd_dev_image_release(struct rbd_device *rbd_dev) in rbd_dev_image_release() argument
5721 rbd_dev_unprobe(rbd_dev); in rbd_dev_image_release()
5722 if (rbd_dev->opts) in rbd_dev_image_release()
5723 rbd_unregister_watch(rbd_dev); in rbd_dev_image_release()
5724 rbd_dev->image_format = 0; in rbd_dev_image_release()
5725 kfree(rbd_dev->spec->image_id); in rbd_dev_image_release()
5726 rbd_dev->spec->image_id = NULL; in rbd_dev_image_release()
5735 static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth) in rbd_dev_image_probe() argument
5745 ret = rbd_dev_image_id(rbd_dev); in rbd_dev_image_probe()
5749 ret = rbd_dev_header_name(rbd_dev); in rbd_dev_image_probe()
5754 ret = rbd_register_watch(rbd_dev); in rbd_dev_image_probe()
5758 rbd_dev->spec->pool_name, in rbd_dev_image_probe()
5759 rbd_dev->spec->pool_ns ?: "", in rbd_dev_image_probe()
5760 rbd_dev->spec->pool_ns ? "/" : "", in rbd_dev_image_probe()
5761 rbd_dev->spec->image_name); in rbd_dev_image_probe()
5766 ret = rbd_dev_header_info(rbd_dev); in rbd_dev_image_probe()
5777 ret = rbd_spec_fill_snap_id(rbd_dev); in rbd_dev_image_probe()
5779 ret = rbd_spec_fill_names(rbd_dev); in rbd_dev_image_probe()
5783 rbd_dev->spec->pool_name, in rbd_dev_image_probe()
5784 rbd_dev->spec->pool_ns ?: "", in rbd_dev_image_probe()
5785 rbd_dev->spec->pool_ns ? "/" : "", in rbd_dev_image_probe()
5786 rbd_dev->spec->image_name, in rbd_dev_image_probe()
5787 rbd_dev->spec->snap_name); in rbd_dev_image_probe()
5791 if (rbd_dev->header.features & RBD_FEATURE_LAYERING) { in rbd_dev_image_probe()
5792 ret = rbd_dev_v2_parent_info(rbd_dev); in rbd_dev_image_probe()
5800 if (!depth && rbd_dev->parent_spec) in rbd_dev_image_probe()
5801 rbd_warn(rbd_dev, in rbd_dev_image_probe()
5805 ret = rbd_dev_probe_parent(rbd_dev, depth); in rbd_dev_image_probe()
5810 rbd_dev->image_format, rbd_dev->header_oid.name); in rbd_dev_image_probe()
5814 rbd_dev_unprobe(rbd_dev); in rbd_dev_image_probe()
5817 rbd_unregister_watch(rbd_dev); in rbd_dev_image_probe()
5819 rbd_dev->image_format = 0; in rbd_dev_image_probe()
5820 kfree(rbd_dev->spec->image_id); in rbd_dev_image_probe()
5821 rbd_dev->spec->image_id = NULL; in rbd_dev_image_probe()
5829 struct rbd_device *rbd_dev = NULL; in do_rbd_add() local
5859 rbd_dev = rbd_dev_create(rbdc, spec, rbd_opts); in do_rbd_add()
5860 if (!rbd_dev) { in do_rbd_add()
5868 rbd_dev->config_info = kstrdup(buf, GFP_KERNEL); in do_rbd_add()
5869 if (!rbd_dev->config_info) { in do_rbd_add()
5874 down_write(&rbd_dev->header_rwsem); in do_rbd_add()
5875 rc = rbd_dev_image_probe(rbd_dev, 0); in do_rbd_add()
5877 up_write(&rbd_dev->header_rwsem); in do_rbd_add()
5882 if (rbd_dev->spec->snap_id != CEPH_NOSNAP) in do_rbd_add()
5883 rbd_dev->opts->read_only = true; in do_rbd_add()
5885 rc = rbd_dev_device_setup(rbd_dev); in do_rbd_add()
5889 if (rbd_dev->opts->exclusive) { in do_rbd_add()
5890 rc = rbd_add_acquire_lock(rbd_dev); in do_rbd_add()
5897 rc = device_add(&rbd_dev->dev); in do_rbd_add()
5901 add_disk(rbd_dev->disk); in do_rbd_add()
5903 blk_put_queue(rbd_dev->disk->queue); in do_rbd_add()
5906 list_add_tail(&rbd_dev->node, &rbd_dev_list); in do_rbd_add()
5909 pr_info("%s: capacity %llu features 0x%llx\n", rbd_dev->disk->disk_name, in do_rbd_add()
5910 (unsigned long long)get_capacity(rbd_dev->disk) << SECTOR_SHIFT, in do_rbd_add()
5911 rbd_dev->header.features); in do_rbd_add()
5918 rbd_dev_image_unlock(rbd_dev); in do_rbd_add()
5920 rbd_dev_device_release(rbd_dev); in do_rbd_add()
5922 rbd_dev_image_release(rbd_dev); in do_rbd_add()
5924 rbd_dev_destroy(rbd_dev); in do_rbd_add()
5950 static void rbd_dev_remove_parent(struct rbd_device *rbd_dev) in rbd_dev_remove_parent() argument
5952 while (rbd_dev->parent) { in rbd_dev_remove_parent()
5953 struct rbd_device *first = rbd_dev; in rbd_dev_remove_parent()
5981 struct rbd_device *rbd_dev = NULL; in do_rbd_remove() local
6008 rbd_dev = list_entry(tmp, struct rbd_device, node); in do_rbd_remove()
6009 if (rbd_dev->dev_id == dev_id) { in do_rbd_remove()
6015 spin_lock_irq(&rbd_dev->lock); in do_rbd_remove()
6016 if (rbd_dev->open_count && !force) in do_rbd_remove()
6020 &rbd_dev->flags); in do_rbd_remove()
6021 spin_unlock_irq(&rbd_dev->lock); in do_rbd_remove()
6032 blk_mq_freeze_queue(rbd_dev->disk->queue); in do_rbd_remove()
6033 blk_set_queue_dying(rbd_dev->disk->queue); in do_rbd_remove()
6036 del_gendisk(rbd_dev->disk); in do_rbd_remove()
6038 list_del_init(&rbd_dev->node); in do_rbd_remove()
6040 device_del(&rbd_dev->dev); in do_rbd_remove()
6042 rbd_dev_image_unlock(rbd_dev); in do_rbd_remove()
6043 rbd_dev_device_release(rbd_dev); in do_rbd_remove()
6044 rbd_dev_image_release(rbd_dev); in do_rbd_remove()
6045 rbd_dev_destroy(rbd_dev); in do_rbd_remove()