Lines Matching refs:rbd_dev

331 	struct rbd_device	*rbd_dev;  member
501 static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth);
513 static bool rbd_is_ro(struct rbd_device *rbd_dev) in rbd_is_ro() argument
515 return test_bit(RBD_DEV_FLAG_READONLY, &rbd_dev->flags); in rbd_is_ro()
518 static bool rbd_is_snap(struct rbd_device *rbd_dev) in rbd_is_snap() argument
520 return rbd_dev->spec->snap_id != CEPH_NOSNAP; in rbd_is_snap()
523 static bool __rbd_is_lock_owner(struct rbd_device *rbd_dev) in __rbd_is_lock_owner() argument
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_QUIESCING; in __rbd_is_lock_owner()
531 static bool rbd_is_lock_owner(struct rbd_device *rbd_dev) in rbd_is_lock_owner() argument
535 down_read(&rbd_dev->lock_rwsem); in rbd_is_lock_owner()
536 is_lock_owner = __rbd_is_lock_owner(rbd_dev); in rbd_is_lock_owner()
537 up_read(&rbd_dev->lock_rwsem); in rbd_is_lock_owner()
593 void rbd_warn(struct rbd_device *rbd_dev, const char *fmt, ...) in rbd_warn() argument
602 if (!rbd_dev) in rbd_warn()
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()
615 RBD_DRV_NAME, rbd_dev, &vaf); in rbd_warn()
632 static void rbd_dev_remove_parent(struct rbd_device *rbd_dev);
634 static int rbd_dev_refresh(struct rbd_device *rbd_dev);
635 static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev,
637 static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev,
639 static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
641 static int rbd_dev_v2_get_flags(struct rbd_device *rbd_dev);
664 struct rbd_device *rbd_dev = disk->private_data; in rbd_open() local
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()
676 (void) get_device(&rbd_dev->dev); in rbd_open()
683 struct rbd_device *rbd_dev = disk->private_data; in rbd_release() local
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()
981 static void rbd_init_layout(struct rbd_device *rbd_dev) in rbd_init_layout() argument
983 if (rbd_dev->header.stripe_unit == 0 || in rbd_init_layout()
984 rbd_dev->header.stripe_count == 0) { in rbd_init_layout()
985 rbd_dev->header.stripe_unit = rbd_obj_bytes(&rbd_dev->header); in rbd_init_layout()
986 rbd_dev->header.stripe_count = 1; in rbd_init_layout()
989 rbd_dev->layout.stripe_unit = rbd_dev->header.stripe_unit; in rbd_init_layout()
990 rbd_dev->layout.stripe_count = rbd_dev->header.stripe_count; in rbd_init_layout()
991 rbd_dev->layout.object_size = rbd_obj_bytes(&rbd_dev->header); in rbd_init_layout()
992 rbd_dev->layout.pool_id = rbd_dev->header.data_pool_id == CEPH_NOPOOL ? in rbd_init_layout()
993 rbd_dev->spec->pool_id : rbd_dev->header.data_pool_id; in rbd_init_layout()
994 RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL); in rbd_init_layout()
1102 static const char *_rbd_dev_v1_snap_name(struct rbd_device *rbd_dev, u32 which) in _rbd_dev_v1_snap_name() argument
1106 rbd_assert(which < rbd_dev->header.snapc->num_snaps); in _rbd_dev_v1_snap_name()
1110 snap_name = rbd_dev->header.snap_names; in _rbd_dev_v1_snap_name()
1141 static u32 rbd_dev_snap_index(struct rbd_device *rbd_dev, u64 snap_id) in rbd_dev_snap_index() argument
1143 struct ceph_snap_context *snapc = rbd_dev->header.snapc; in rbd_dev_snap_index()
1152 static const char *rbd_dev_v1_snap_name(struct rbd_device *rbd_dev, in rbd_dev_v1_snap_name() argument
1158 which = rbd_dev_snap_index(rbd_dev, snap_id); in rbd_dev_v1_snap_name()
1162 snap_name = _rbd_dev_v1_snap_name(rbd_dev, which); in rbd_dev_v1_snap_name()
1166 static const char *rbd_snap_name(struct rbd_device *rbd_dev, u64 snap_id) in rbd_snap_name() argument
1171 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_snap_name()
1172 if (rbd_dev->image_format == 1) in rbd_snap_name()
1173 return rbd_dev_v1_snap_name(rbd_dev, snap_id); in rbd_snap_name()
1175 return rbd_dev_v2_snap_name(rbd_dev, snap_id); in rbd_snap_name()
1178 static int rbd_snap_size(struct rbd_device *rbd_dev, u64 snap_id, in rbd_snap_size() argument
1181 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_snap_size()
1183 *snap_size = rbd_dev->header.image_size; in rbd_snap_size()
1184 } else if (rbd_dev->image_format == 1) { in rbd_snap_size()
1187 which = rbd_dev_snap_index(rbd_dev, snap_id); in rbd_snap_size()
1191 *snap_size = rbd_dev->header.snap_sizes[which]; in rbd_snap_size()
1196 ret = _rbd_dev_v2_snap_size(rbd_dev, snap_id, NULL, &size); in rbd_snap_size()
1205 static int rbd_dev_mapping_set(struct rbd_device *rbd_dev) in rbd_dev_mapping_set() argument
1207 u64 snap_id = rbd_dev->spec->snap_id; in rbd_dev_mapping_set()
1211 ret = rbd_snap_size(rbd_dev, snap_id, &size); in rbd_dev_mapping_set()
1215 rbd_dev->mapping.size = size; in rbd_dev_mapping_set()
1219 static void rbd_dev_mapping_clear(struct rbd_device *rbd_dev) in rbd_dev_mapping_clear() argument
1221 rbd_dev->mapping.size = 0; in rbd_dev_mapping_clear()
1323 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_is_entire() local
1326 obj_req->ex.oe_len == rbd_dev->layout.object_size; in rbd_obj_is_entire()
1331 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_is_tail() local
1334 rbd_dev->layout.object_size; in rbd_obj_is_tail()
1410 struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev; in rbd_osd_format_read() local
1411 struct ceph_options *opt = rbd_dev->rbd_client->client->options; in rbd_osd_format_read()
1430 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in __rbd_obj_add_osd_request() local
1431 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_obj_add_osd_request()
1433 const char *name_format = rbd_dev->image_format == 1 ? in __rbd_obj_add_osd_request()
1449 ceph_oloc_copy(&req->r_base_oloc, &rbd_dev->header_oloc); in __rbd_obj_add_osd_request()
1450 req->r_base_oloc.pool = rbd_dev->layout.pool_id; in __rbd_obj_add_osd_request()
1453 rbd_dev->header.object_prefix, in __rbd_obj_add_osd_request()
1530 static void rbd_dev_unparent(struct rbd_device *rbd_dev) in rbd_dev_unparent() argument
1532 rbd_dev_remove_parent(rbd_dev); in rbd_dev_unparent()
1533 rbd_spec_put(rbd_dev->parent_spec); in rbd_dev_unparent()
1534 rbd_dev->parent_spec = NULL; in rbd_dev_unparent()
1535 rbd_dev->parent_overlap = 0; in rbd_dev_unparent()
1544 static void rbd_dev_parent_put(struct rbd_device *rbd_dev) in rbd_dev_parent_put() argument
1548 if (!rbd_dev->parent_spec) in rbd_dev_parent_put()
1551 counter = atomic_dec_return_safe(&rbd_dev->parent_ref); in rbd_dev_parent_put()
1558 rbd_dev_unparent(rbd_dev); in rbd_dev_parent_put()
1560 rbd_warn(rbd_dev, "parent reference underflow"); in rbd_dev_parent_put()
1571 static bool rbd_dev_parent_get(struct rbd_device *rbd_dev) in rbd_dev_parent_get() argument
1575 if (!rbd_dev->parent_spec) in rbd_dev_parent_get()
1578 if (rbd_dev->parent_overlap) in rbd_dev_parent_get()
1579 counter = atomic_inc_return_safe(&rbd_dev->parent_ref); in rbd_dev_parent_get()
1582 rbd_warn(rbd_dev, "parent reference overflow"); in rbd_dev_parent_get()
1588 struct rbd_device *rbd_dev, in rbd_img_request_init() argument
1593 img_request->rbd_dev = rbd_dev; in rbd_img_request_init()
1608 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_img_capture_header() local
1610 lockdep_assert_held(&rbd_dev->header_rwsem); in rbd_img_capture_header()
1613 img_req->snap_id = rbd_dev->spec->snap_id; in rbd_img_capture_header()
1615 if (rbd_dev_parent_get(rbd_dev)) in rbd_img_capture_header()
1631 rbd_dev_parent_put(img_request->rbd_dev); in rbd_img_request_destroy()
1644 static void __rbd_object_map_index(struct rbd_device *rbd_dev, u64 objno, in __rbd_object_map_index() argument
1649 rbd_assert(objno < rbd_dev->object_map_size); in __rbd_object_map_index()
1654 static u8 __rbd_object_map_get(struct rbd_device *rbd_dev, u64 objno) in __rbd_object_map_get() argument
1659 lockdep_assert_held(&rbd_dev->object_map_lock); in __rbd_object_map_get()
1660 __rbd_object_map_index(rbd_dev, objno, &index, &shift); in __rbd_object_map_get()
1661 return (rbd_dev->object_map[index] >> shift) & OBJ_MASK; in __rbd_object_map_get()
1664 static void __rbd_object_map_set(struct rbd_device *rbd_dev, u64 objno, u8 val) in __rbd_object_map_set() argument
1670 lockdep_assert_held(&rbd_dev->object_map_lock); in __rbd_object_map_set()
1673 __rbd_object_map_index(rbd_dev, objno, &index, &shift); in __rbd_object_map_set()
1674 p = &rbd_dev->object_map[index]; in __rbd_object_map_set()
1678 static u8 rbd_object_map_get(struct rbd_device *rbd_dev, u64 objno) in rbd_object_map_get() argument
1682 spin_lock(&rbd_dev->object_map_lock); in rbd_object_map_get()
1683 state = __rbd_object_map_get(rbd_dev, objno); in rbd_object_map_get()
1684 spin_unlock(&rbd_dev->object_map_lock); in rbd_object_map_get()
1688 static bool use_object_map(struct rbd_device *rbd_dev) in use_object_map() argument
1698 if (!rbd_is_snap(rbd_dev) && rbd_is_ro(rbd_dev)) in use_object_map()
1701 return ((rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP) && in use_object_map()
1702 !(rbd_dev->object_map_flags & RBD_FLAG_OBJECT_MAP_INVALID)); in use_object_map()
1705 static bool rbd_object_map_may_exist(struct rbd_device *rbd_dev, u64 objno) in rbd_object_map_may_exist() argument
1710 if (!use_object_map(rbd_dev)) in rbd_object_map_may_exist()
1713 state = rbd_object_map_get(rbd_dev, objno); in rbd_object_map_may_exist()
1717 static void rbd_object_map_name(struct rbd_device *rbd_dev, u64 snap_id, in rbd_object_map_name() argument
1722 rbd_dev->spec->image_id); in rbd_object_map_name()
1725 rbd_dev->spec->image_id, snap_id); in rbd_object_map_name()
1728 static int rbd_object_map_lock(struct rbd_device *rbd_dev) in rbd_object_map_lock() argument
1730 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_object_map_lock()
1739 rbd_object_map_name(rbd_dev, CEPH_NOSNAP, &oid); in rbd_object_map_lock()
1742 ret = ceph_cls_lock(osdc, &oid, &rbd_dev->header_oloc, RBD_LOCK_NAME, in rbd_object_map_lock()
1748 rbd_warn(rbd_dev, "failed to lock object map: %d", ret); in rbd_object_map_lock()
1752 ret = ceph_cls_lock_info(osdc, &oid, &rbd_dev->header_oloc, in rbd_object_map_lock()
1759 rbd_warn(rbd_dev, "failed to get object map lockers: %d", ret); in rbd_object_map_lock()
1767 rbd_warn(rbd_dev, "breaking object map lock owned by %s%llu", in rbd_object_map_lock()
1770 ret = ceph_cls_break_lock(osdc, &oid, &rbd_dev->header_oloc, in rbd_object_map_lock()
1778 rbd_warn(rbd_dev, "failed to break object map lock: %d", ret); in rbd_object_map_lock()
1786 static void rbd_object_map_unlock(struct rbd_device *rbd_dev) in rbd_object_map_unlock() argument
1788 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_object_map_unlock()
1792 rbd_object_map_name(rbd_dev, CEPH_NOSNAP, &oid); in rbd_object_map_unlock()
1794 ret = ceph_cls_unlock(osdc, &oid, &rbd_dev->header_oloc, RBD_LOCK_NAME, in rbd_object_map_unlock()
1797 rbd_warn(rbd_dev, "failed to unlock object map: %d", ret); in rbd_object_map_unlock()
1825 static int __rbd_object_map_load(struct rbd_device *rbd_dev) in __rbd_object_map_load() argument
1827 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_object_map_load()
1838 rbd_assert(!rbd_dev->object_map && !rbd_dev->object_map_size); in __rbd_object_map_load()
1840 num_objects = ceph_get_num_objects(&rbd_dev->layout, in __rbd_object_map_load()
1841 rbd_dev->mapping.size); in __rbd_object_map_load()
1850 rbd_object_map_name(rbd_dev, rbd_dev->spec->snap_id, &oid); in __rbd_object_map_load()
1851 ret = ceph_osdc_call(osdc, &oid, &rbd_dev->header_oloc, in __rbd_object_map_load()
1864 rbd_warn(rbd_dev, "object map size mismatch: %llu vs %llu", in __rbd_object_map_load()
1875 rbd_dev->object_map = kvmalloc(object_map_bytes, GFP_KERNEL); in __rbd_object_map_load()
1876 if (!rbd_dev->object_map) { in __rbd_object_map_load()
1881 rbd_dev->object_map_size = object_map_size; in __rbd_object_map_load()
1882 ceph_copy_from_page_vector(pages, rbd_dev->object_map, in __rbd_object_map_load()
1890 static void rbd_object_map_free(struct rbd_device *rbd_dev) in rbd_object_map_free() argument
1892 kvfree(rbd_dev->object_map); in rbd_object_map_free()
1893 rbd_dev->object_map = NULL; in rbd_object_map_free()
1894 rbd_dev->object_map_size = 0; in rbd_object_map_free()
1897 static int rbd_object_map_load(struct rbd_device *rbd_dev) in rbd_object_map_load() argument
1901 ret = __rbd_object_map_load(rbd_dev); in rbd_object_map_load()
1905 ret = rbd_dev_v2_get_flags(rbd_dev); in rbd_object_map_load()
1907 rbd_object_map_free(rbd_dev); in rbd_object_map_load()
1911 if (rbd_dev->object_map_flags & RBD_FLAG_OBJECT_MAP_INVALID) in rbd_object_map_load()
1912 rbd_warn(rbd_dev, "object map is invalid"); in rbd_object_map_load()
1917 static int rbd_object_map_open(struct rbd_device *rbd_dev) in rbd_object_map_open() argument
1921 ret = rbd_object_map_lock(rbd_dev); in rbd_object_map_open()
1925 ret = rbd_object_map_load(rbd_dev); in rbd_object_map_open()
1927 rbd_object_map_unlock(rbd_dev); in rbd_object_map_open()
1934 static void rbd_object_map_close(struct rbd_device *rbd_dev) in rbd_object_map_close() argument
1936 rbd_object_map_free(rbd_dev); in rbd_object_map_close()
1937 rbd_object_map_unlock(rbd_dev); in rbd_object_map_close()
1953 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_object_map_update_finish() local
1985 spin_lock(&rbd_dev->object_map_lock); in rbd_object_map_update_finish()
1986 state = __rbd_object_map_get(rbd_dev, objno); in rbd_object_map_update_finish()
1989 __rbd_object_map_set(rbd_dev, objno, new_state); in rbd_object_map_update_finish()
1990 spin_unlock(&rbd_dev->object_map_lock); in rbd_object_map_update_finish()
2007 static bool update_needed(struct rbd_device *rbd_dev, u64 objno, u8 new_state) in update_needed() argument
2009 u8 state = rbd_object_map_get(rbd_dev, objno); in update_needed()
2060 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_object_map_update() local
2061 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_object_map_update()
2068 if (!update_needed(rbd_dev, obj_req->ex.oe_objno, new_state)) in rbd_object_map_update()
2082 rbd_object_map_name(rbd_dev, snap_id, &req->r_base_oid); in rbd_object_map_update()
2083 ceph_oloc_copy(&req->r_base_oloc, &rbd_dev->header_oloc); in rbd_object_map_update()
2138 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_calc_img_extents() local
2141 if (!rbd_dev->parent_overlap) in rbd_obj_calc_img_extents()
2144 ret = ceph_extent_to_file(&rbd_dev->layout, obj_req->ex.oe_objno, in rbd_obj_calc_img_extents()
2146 entire ? rbd_dev->layout.object_size : in rbd_obj_calc_img_extents()
2154 rbd_dev->parent_overlap); in rbd_obj_calc_img_extents()
2229 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in __rbd_osd_setup_write_ops() local
2232 if (!use_object_map(rbd_dev) || in __rbd_osd_setup_write_ops()
2235 rbd_dev->layout.object_size, in __rbd_osd_setup_write_ops()
2236 rbd_dev->layout.object_size, in __rbd_osd_setup_write_ops()
2237 rbd_dev->opts->alloc_hint_flags); in __rbd_osd_setup_write_ops()
2287 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_init_discard() local
2299 if (rbd_dev->opts->alloc_size != rbd_dev->layout.object_size || in rbd_obj_init_discard()
2301 off = round_up(obj_req->ex.oe_off, rbd_dev->opts->alloc_size); in rbd_obj_init_discard()
2303 rbd_dev->opts->alloc_size); in rbd_obj_init_discard()
2380 if (!use_object_map(img_req->rbd_dev) || in count_write_ops()
2512 ret = ceph_file_to_extents(&img_req->rbd_dev->layout, in rbd_img_fill_request_nocopy()
2543 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_img_fill_request() local
2549 !rbd_layout_is_fancy(&rbd_dev->layout)) in rbd_img_fill_request()
2564 ret = ceph_file_to_extents(&rbd_dev->layout, in rbd_img_fill_request()
2588 ret = ceph_iterate_extents(&rbd_dev->layout, in rbd_img_fill_request()
2759 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_may_exist() local
2761 if (rbd_object_map_may_exist(rbd_dev, obj_req->ex.oe_objno)) { in rbd_obj_may_exist()
2796 struct rbd_device *parent = img_req->rbd_dev->parent; in rbd_obj_read_from_parent()
2851 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_advance_read() local
2873 if (*result == -ENOENT && rbd_dev->parent_overlap) { in rbd_obj_advance_read()
2928 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_write_is_noop() local
2930 if (rbd_object_map_may_exist(rbd_dev, obj_req->ex.oe_objno)) in rbd_obj_write_is_noop()
2950 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_write_pre_object_map() local
2953 if (!(rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) in rbd_obj_write_pre_object_map()
3109 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_copyup_read_parent() local
3114 rbd_dev->parent_overlap); in rbd_obj_copyup_read_parent()
3134 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_copyup_object_maps() local
3142 if (!(rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) in rbd_obj_copyup_object_maps()
3149 if ((rbd_dev->header.features & RBD_FEATURE_FAST_DIFF) && in rbd_obj_copyup_object_maps()
3210 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_advance_copyup() local
3252 rbd_warn(rbd_dev, "snap object map update failed: %d", in rbd_obj_advance_copyup()
3284 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_write_post_object_map() local
3287 if (!(rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) in rbd_obj_write_post_object_map()
3299 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_advance_write() local
3322 rbd_warn(rbd_dev, "pre object map update failed: %d", in rbd_obj_advance_write()
3359 rbd_warn(rbd_dev, "copyup failed: %d", *result); in rbd_obj_advance_write()
3373 rbd_warn(rbd_dev, "post object map update failed: %d", in rbd_obj_advance_write()
3388 struct rbd_device *rbd_dev = img_req->rbd_dev; in __rbd_obj_handle_request() local
3400 rbd_warn(rbd_dev, "%s at objno %llu %llu~%llu result %d", in __rbd_obj_handle_request()
3419 struct rbd_device *rbd_dev = img_req->rbd_dev; in need_exclusive_lock() local
3421 if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK)) in need_exclusive_lock()
3424 if (rbd_is_ro(rbd_dev)) in need_exclusive_lock()
3428 if (rbd_dev->opts->lock_on_read || in need_exclusive_lock()
3429 (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) in need_exclusive_lock()
3437 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_lock_add_request() local
3440 lockdep_assert_held(&rbd_dev->lock_rwsem); in rbd_lock_add_request()
3441 locked = rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED; in rbd_lock_add_request()
3442 spin_lock(&rbd_dev->lock_lists_lock); in rbd_lock_add_request()
3445 list_add_tail(&img_req->lock_item, &rbd_dev->acquiring_list); in rbd_lock_add_request()
3447 list_add_tail(&img_req->lock_item, &rbd_dev->running_list); in rbd_lock_add_request()
3448 spin_unlock(&rbd_dev->lock_lists_lock); in rbd_lock_add_request()
3454 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_lock_del_request() local
3457 lockdep_assert_held(&rbd_dev->lock_rwsem); in rbd_lock_del_request()
3458 spin_lock(&rbd_dev->lock_lists_lock); in rbd_lock_del_request()
3460 rbd_assert(!list_empty(&rbd_dev->running_list)); in rbd_lock_del_request()
3462 need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_QUIESCING && in rbd_lock_del_request()
3463 list_empty(&rbd_dev->running_list)); in rbd_lock_del_request()
3465 spin_unlock(&rbd_dev->lock_lists_lock); in rbd_lock_del_request()
3467 complete(&rbd_dev->quiescing_wait); in rbd_lock_del_request()
3472 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_img_exclusive_lock() local
3484 dout("%s rbd_dev %p queueing lock_dwork\n", __func__, rbd_dev); in rbd_img_exclusive_lock()
3485 queue_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); in rbd_img_exclusive_lock()
3491 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_img_object_requests() local
3496 __rbd_is_lock_owner(rbd_dev)); in rbd_img_object_requests()
3500 down_read(&rbd_dev->header_rwsem); in rbd_img_object_requests()
3501 img_req->snapc = ceph_get_snap_context(rbd_dev->header.snapc); in rbd_img_object_requests()
3502 up_read(&rbd_dev->header_rwsem); in rbd_img_object_requests()
3566 struct rbd_device *rbd_dev = img_req->rbd_dev; in __rbd_img_handle_request() local
3570 down_read(&rbd_dev->lock_rwsem); in __rbd_img_handle_request()
3576 up_read(&rbd_dev->lock_rwsem); in __rbd_img_handle_request()
3585 rbd_warn(rbd_dev, "%s%s result %d", in __rbd_img_handle_request()
3622 static struct rbd_client_id rbd_get_cid(struct rbd_device *rbd_dev) in rbd_get_cid() argument
3626 mutex_lock(&rbd_dev->watch_mutex); in rbd_get_cid()
3627 cid.gid = ceph_client_gid(rbd_dev->rbd_client->client); in rbd_get_cid()
3628 cid.handle = rbd_dev->watch_cookie; in rbd_get_cid()
3629 mutex_unlock(&rbd_dev->watch_mutex); in rbd_get_cid()
3636 static void rbd_set_owner_cid(struct rbd_device *rbd_dev, in rbd_set_owner_cid() argument
3639 dout("%s rbd_dev %p %llu-%llu -> %llu-%llu\n", __func__, rbd_dev, in rbd_set_owner_cid()
3640 rbd_dev->owner_cid.gid, rbd_dev->owner_cid.handle, in rbd_set_owner_cid()
3642 rbd_dev->owner_cid = *cid; /* struct */ in rbd_set_owner_cid()
3645 static void format_lock_cookie(struct rbd_device *rbd_dev, char *buf) in format_lock_cookie() argument
3647 mutex_lock(&rbd_dev->watch_mutex); in format_lock_cookie()
3648 sprintf(buf, "%s %llu", RBD_LOCK_COOKIE_PREFIX, rbd_dev->watch_cookie); in format_lock_cookie()
3649 mutex_unlock(&rbd_dev->watch_mutex); in format_lock_cookie()
3652 static void __rbd_lock(struct rbd_device *rbd_dev, const char *cookie) in __rbd_lock() argument
3654 struct rbd_client_id cid = rbd_get_cid(rbd_dev); in __rbd_lock()
3656 rbd_dev->lock_state = RBD_LOCK_STATE_LOCKED; in __rbd_lock()
3657 strcpy(rbd_dev->lock_cookie, cookie); in __rbd_lock()
3658 rbd_set_owner_cid(rbd_dev, &cid); in __rbd_lock()
3659 queue_work(rbd_dev->task_wq, &rbd_dev->acquired_lock_work); in __rbd_lock()
3665 static int rbd_lock(struct rbd_device *rbd_dev) in rbd_lock() argument
3667 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_lock()
3671 WARN_ON(__rbd_is_lock_owner(rbd_dev) || in rbd_lock()
3672 rbd_dev->lock_cookie[0] != '\0'); in rbd_lock()
3674 format_lock_cookie(rbd_dev, cookie); in rbd_lock()
3675 ret = ceph_cls_lock(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in rbd_lock()
3681 __rbd_lock(rbd_dev, cookie); in rbd_lock()
3688 static void rbd_unlock(struct rbd_device *rbd_dev) in rbd_unlock() argument
3690 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_unlock()
3693 WARN_ON(!__rbd_is_lock_owner(rbd_dev) || in rbd_unlock()
3694 rbd_dev->lock_cookie[0] == '\0'); in rbd_unlock()
3696 ret = ceph_cls_unlock(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in rbd_unlock()
3697 RBD_LOCK_NAME, rbd_dev->lock_cookie); in rbd_unlock()
3699 rbd_warn(rbd_dev, "failed to unlock header: %d", ret); in rbd_unlock()
3702 rbd_dev->lock_state = RBD_LOCK_STATE_UNLOCKED; in rbd_unlock()
3703 rbd_dev->lock_cookie[0] = '\0'; in rbd_unlock()
3704 rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); in rbd_unlock()
3705 queue_work(rbd_dev->task_wq, &rbd_dev->released_lock_work); in rbd_unlock()
3708 static int __rbd_notify_op_lock(struct rbd_device *rbd_dev, in __rbd_notify_op_lock() argument
3713 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_notify_op_lock()
3714 struct rbd_client_id cid = rbd_get_cid(rbd_dev); in __rbd_notify_op_lock()
3719 dout("%s rbd_dev %p notify_op %d\n", __func__, rbd_dev, notify_op); in __rbd_notify_op_lock()
3727 return ceph_osdc_notify(osdc, &rbd_dev->header_oid, in __rbd_notify_op_lock()
3728 &rbd_dev->header_oloc, buf, buf_size, in __rbd_notify_op_lock()
3732 static void rbd_notify_op_lock(struct rbd_device *rbd_dev, in rbd_notify_op_lock() argument
3735 __rbd_notify_op_lock(rbd_dev, notify_op, NULL, NULL); in rbd_notify_op_lock()
3740 struct rbd_device *rbd_dev = container_of(work, struct rbd_device, in rbd_notify_acquired_lock() local
3743 rbd_notify_op_lock(rbd_dev, RBD_NOTIFY_OP_ACQUIRED_LOCK); in rbd_notify_acquired_lock()
3748 struct rbd_device *rbd_dev = container_of(work, struct rbd_device, in rbd_notify_released_lock() local
3751 rbd_notify_op_lock(rbd_dev, RBD_NOTIFY_OP_RELEASED_LOCK); in rbd_notify_released_lock()
3754 static int rbd_request_lock(struct rbd_device *rbd_dev) in rbd_request_lock() argument
3761 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_request_lock()
3763 ret = __rbd_notify_op_lock(rbd_dev, RBD_NOTIFY_OP_REQUEST_LOCK, in rbd_request_lock()
3766 rbd_warn(rbd_dev, "failed to request lock: %d", ret); in rbd_request_lock()
3788 rbd_warn(rbd_dev, in rbd_request_lock()
3798 rbd_warn(rbd_dev, in rbd_request_lock()
3809 rbd_warn(rbd_dev, "no lock owners detected"); in rbd_request_lock()
3826 static void wake_lock_waiters(struct rbd_device *rbd_dev, int result) in wake_lock_waiters() argument
3830 dout("%s rbd_dev %p result %d\n", __func__, rbd_dev, result); in wake_lock_waiters()
3831 lockdep_assert_held_write(&rbd_dev->lock_rwsem); in wake_lock_waiters()
3833 cancel_delayed_work(&rbd_dev->lock_dwork); in wake_lock_waiters()
3834 if (!completion_done(&rbd_dev->acquire_wait)) { in wake_lock_waiters()
3835 rbd_assert(list_empty(&rbd_dev->acquiring_list) && in wake_lock_waiters()
3836 list_empty(&rbd_dev->running_list)); in wake_lock_waiters()
3837 rbd_dev->acquire_err = result; in wake_lock_waiters()
3838 complete_all(&rbd_dev->acquire_wait); in wake_lock_waiters()
3842 while (!list_empty(&rbd_dev->acquiring_list)) { in wake_lock_waiters()
3843 img_req = list_first_entry(&rbd_dev->acquiring_list, in wake_lock_waiters()
3849 &rbd_dev->running_list); in wake_lock_waiters()
3872 static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev) in get_lock_owner_info() argument
3874 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in get_lock_owner_info()
3882 ret = ceph_cls_lock_info(osdc, &rbd_dev->header_oid, in get_lock_owner_info()
3883 &rbd_dev->header_oloc, RBD_LOCK_NAME, in get_lock_owner_info()
3886 rbd_warn(rbd_dev, "failed to get header lockers: %d", ret); in get_lock_owner_info()
3891 dout("%s rbd_dev %p no lockers detected\n", __func__, rbd_dev); in get_lock_owner_info()
3897 rbd_warn(rbd_dev, "locked by external mechanism, tag %s", in get_lock_owner_info()
3903 rbd_warn(rbd_dev, "incompatible lock type detected"); in get_lock_owner_info()
3911 rbd_warn(rbd_dev, "locked by external mechanism, cookie %s", in get_lock_owner_info()
3916 rbd_warn(rbd_dev, "locker has a blank address"); in get_lock_owner_info()
3921 __func__, rbd_dev, ENTITY_NAME(lockers[0].id.name), in get_lock_owner_info()
3935 static int find_watcher(struct rbd_device *rbd_dev, in find_watcher() argument
3938 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in find_watcher()
3945 ret = ceph_osdc_list_watchers(osdc, &rbd_dev->header_oid, in find_watcher()
3946 &rbd_dev->header_oloc, &watchers, in find_watcher()
3949 rbd_warn(rbd_dev, "failed to get watchers: %d", ret); in find_watcher()
3968 rbd_dev, cid.gid, cid.handle); in find_watcher()
3969 rbd_set_owner_cid(rbd_dev, &cid); in find_watcher()
3975 dout("%s rbd_dev %p no watchers\n", __func__, rbd_dev); in find_watcher()
3985 static int rbd_try_lock(struct rbd_device *rbd_dev) in rbd_try_lock() argument
3987 struct ceph_client *client = rbd_dev->rbd_client->client; in rbd_try_lock()
3994 ret = rbd_lock(rbd_dev); in rbd_try_lock()
3998 rbd_warn(rbd_dev, "failed to lock header: %d", ret); in rbd_try_lock()
4003 locker = get_lock_owner_info(rbd_dev); in rbd_try_lock()
4012 ret = find_watcher(rbd_dev, locker); in rbd_try_lock()
4016 refreshed_locker = get_lock_owner_info(rbd_dev); in rbd_try_lock()
4026 rbd_warn(rbd_dev, "breaking header lock owned by %s%llu", in rbd_try_lock()
4032 rbd_warn(rbd_dev, "failed to blocklist %s%llu: %d", in rbd_try_lock()
4037 ret = ceph_cls_break_lock(&client->osdc, &rbd_dev->header_oid, in rbd_try_lock()
4038 &rbd_dev->header_oloc, RBD_LOCK_NAME, in rbd_try_lock()
4041 rbd_warn(rbd_dev, "failed to break header lock: %d", in rbd_try_lock()
4057 static int rbd_post_acquire_action(struct rbd_device *rbd_dev) in rbd_post_acquire_action() argument
4061 ret = rbd_dev_refresh(rbd_dev); in rbd_post_acquire_action()
4065 if (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP) { in rbd_post_acquire_action()
4066 ret = rbd_object_map_open(rbd_dev); in rbd_post_acquire_action()
4080 static int rbd_try_acquire_lock(struct rbd_device *rbd_dev) in rbd_try_acquire_lock() argument
4084 down_read(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4085 dout("%s rbd_dev %p read lock_state %d\n", __func__, rbd_dev, in rbd_try_acquire_lock()
4086 rbd_dev->lock_state); in rbd_try_acquire_lock()
4087 if (__rbd_is_lock_owner(rbd_dev)) { in rbd_try_acquire_lock()
4088 up_read(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4092 up_read(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4093 down_write(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4094 dout("%s rbd_dev %p write lock_state %d\n", __func__, rbd_dev, in rbd_try_acquire_lock()
4095 rbd_dev->lock_state); in rbd_try_acquire_lock()
4096 if (__rbd_is_lock_owner(rbd_dev)) { in rbd_try_acquire_lock()
4097 up_write(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4101 ret = rbd_try_lock(rbd_dev); in rbd_try_acquire_lock()
4103 rbd_warn(rbd_dev, "failed to acquire lock: %d", ret); in rbd_try_acquire_lock()
4107 up_write(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4111 rbd_assert(rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED); in rbd_try_acquire_lock()
4112 rbd_assert(list_empty(&rbd_dev->running_list)); in rbd_try_acquire_lock()
4114 ret = rbd_post_acquire_action(rbd_dev); in rbd_try_acquire_lock()
4116 rbd_warn(rbd_dev, "post-acquire action failed: %d", ret); in rbd_try_acquire_lock()
4122 rbd_unlock(rbd_dev); in rbd_try_acquire_lock()
4126 wake_lock_waiters(rbd_dev, ret); in rbd_try_acquire_lock()
4127 up_write(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4133 struct rbd_device *rbd_dev = container_of(to_delayed_work(work), in rbd_acquire_lock() local
4137 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_acquire_lock()
4139 ret = rbd_try_acquire_lock(rbd_dev); in rbd_acquire_lock()
4141 dout("%s rbd_dev %p ret %d - done\n", __func__, rbd_dev, ret); in rbd_acquire_lock()
4145 ret = rbd_request_lock(rbd_dev); in rbd_acquire_lock()
4149 rbd_warn(rbd_dev, "peer will not release lock"); in rbd_acquire_lock()
4150 down_write(&rbd_dev->lock_rwsem); in rbd_acquire_lock()
4151 wake_lock_waiters(rbd_dev, ret); in rbd_acquire_lock()
4152 up_write(&rbd_dev->lock_rwsem); in rbd_acquire_lock()
4154 rbd_warn(rbd_dev, "error requesting lock: %d", ret); in rbd_acquire_lock()
4155 mod_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, in rbd_acquire_lock()
4163 rbd_dev); in rbd_acquire_lock()
4164 mod_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, in rbd_acquire_lock()
4169 static bool rbd_quiesce_lock(struct rbd_device *rbd_dev) in rbd_quiesce_lock() argument
4171 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_quiesce_lock()
4172 lockdep_assert_held_write(&rbd_dev->lock_rwsem); in rbd_quiesce_lock()
4174 if (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED) in rbd_quiesce_lock()
4180 rbd_dev->lock_state = RBD_LOCK_STATE_QUIESCING; in rbd_quiesce_lock()
4181 rbd_assert(!completion_done(&rbd_dev->quiescing_wait)); in rbd_quiesce_lock()
4182 if (list_empty(&rbd_dev->running_list)) in rbd_quiesce_lock()
4185 up_write(&rbd_dev->lock_rwsem); in rbd_quiesce_lock()
4186 wait_for_completion(&rbd_dev->quiescing_wait); in rbd_quiesce_lock()
4188 down_write(&rbd_dev->lock_rwsem); in rbd_quiesce_lock()
4189 if (rbd_dev->lock_state != RBD_LOCK_STATE_QUIESCING) in rbd_quiesce_lock()
4192 rbd_assert(list_empty(&rbd_dev->running_list)); in rbd_quiesce_lock()
4196 static void rbd_pre_release_action(struct rbd_device *rbd_dev) in rbd_pre_release_action() argument
4198 if (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP) in rbd_pre_release_action()
4199 rbd_object_map_close(rbd_dev); in rbd_pre_release_action()
4202 static void __rbd_release_lock(struct rbd_device *rbd_dev) in __rbd_release_lock() argument
4204 rbd_assert(list_empty(&rbd_dev->running_list)); in __rbd_release_lock()
4206 rbd_pre_release_action(rbd_dev); in __rbd_release_lock()
4207 rbd_unlock(rbd_dev); in __rbd_release_lock()
4213 static void rbd_release_lock(struct rbd_device *rbd_dev) in rbd_release_lock() argument
4215 if (!rbd_quiesce_lock(rbd_dev)) in rbd_release_lock()
4218 __rbd_release_lock(rbd_dev); in rbd_release_lock()
4227 cancel_delayed_work(&rbd_dev->lock_dwork); in rbd_release_lock()
4232 struct rbd_device *rbd_dev = container_of(work, struct rbd_device, in rbd_release_lock_work() local
4235 down_write(&rbd_dev->lock_rwsem); in rbd_release_lock_work()
4236 rbd_release_lock(rbd_dev); in rbd_release_lock_work()
4237 up_write(&rbd_dev->lock_rwsem); in rbd_release_lock_work()
4240 static void maybe_kick_acquire(struct rbd_device *rbd_dev) in maybe_kick_acquire() argument
4244 dout("%s rbd_dev %p\n", __func__, rbd_dev); in maybe_kick_acquire()
4245 if (__rbd_is_lock_owner(rbd_dev)) in maybe_kick_acquire()
4248 spin_lock(&rbd_dev->lock_lists_lock); in maybe_kick_acquire()
4249 have_requests = !list_empty(&rbd_dev->acquiring_list); in maybe_kick_acquire()
4250 spin_unlock(&rbd_dev->lock_lists_lock); in maybe_kick_acquire()
4251 if (have_requests || delayed_work_pending(&rbd_dev->lock_dwork)) { in maybe_kick_acquire()
4252 dout("%s rbd_dev %p kicking lock_dwork\n", __func__, rbd_dev); in maybe_kick_acquire()
4253 mod_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); in maybe_kick_acquire()
4257 static void rbd_handle_acquired_lock(struct rbd_device *rbd_dev, u8 struct_v, in rbd_handle_acquired_lock() argument
4267 dout("%s rbd_dev %p cid %llu-%llu\n", __func__, rbd_dev, cid.gid, in rbd_handle_acquired_lock()
4270 down_write(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
4271 if (rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { in rbd_handle_acquired_lock()
4273 __func__, rbd_dev, cid.gid, cid.handle); in rbd_handle_acquired_lock()
4275 rbd_set_owner_cid(rbd_dev, &cid); in rbd_handle_acquired_lock()
4277 downgrade_write(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
4279 down_read(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
4282 maybe_kick_acquire(rbd_dev); in rbd_handle_acquired_lock()
4283 up_read(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
4286 static void rbd_handle_released_lock(struct rbd_device *rbd_dev, u8 struct_v, in rbd_handle_released_lock() argument
4296 dout("%s rbd_dev %p cid %llu-%llu\n", __func__, rbd_dev, cid.gid, in rbd_handle_released_lock()
4299 down_write(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
4300 if (!rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { in rbd_handle_released_lock()
4302 __func__, rbd_dev, cid.gid, cid.handle, in rbd_handle_released_lock()
4303 rbd_dev->owner_cid.gid, rbd_dev->owner_cid.handle); in rbd_handle_released_lock()
4305 rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); in rbd_handle_released_lock()
4307 downgrade_write(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
4309 down_read(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
4312 maybe_kick_acquire(rbd_dev); in rbd_handle_released_lock()
4313 up_read(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
4320 static int rbd_handle_request_lock(struct rbd_device *rbd_dev, u8 struct_v, in rbd_handle_request_lock() argument
4323 struct rbd_client_id my_cid = rbd_get_cid(rbd_dev); in rbd_handle_request_lock()
4332 dout("%s rbd_dev %p cid %llu-%llu\n", __func__, rbd_dev, cid.gid, in rbd_handle_request_lock()
4337 down_read(&rbd_dev->lock_rwsem); in rbd_handle_request_lock()
4338 if (__rbd_is_lock_owner(rbd_dev)) { in rbd_handle_request_lock()
4339 if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED && in rbd_handle_request_lock()
4340 rbd_cid_equal(&rbd_dev->owner_cid, &rbd_empty_cid)) in rbd_handle_request_lock()
4349 if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED) { in rbd_handle_request_lock()
4350 if (!rbd_dev->opts->exclusive) { in rbd_handle_request_lock()
4352 __func__, rbd_dev); in rbd_handle_request_lock()
4353 queue_work(rbd_dev->task_wq, in rbd_handle_request_lock()
4354 &rbd_dev->unlock_work); in rbd_handle_request_lock()
4363 up_read(&rbd_dev->lock_rwsem); in rbd_handle_request_lock()
4367 static void __rbd_acknowledge_notify(struct rbd_device *rbd_dev, in __rbd_acknowledge_notify() argument
4370 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_acknowledge_notify()
4386 ret = ceph_osdc_notify_ack(osdc, &rbd_dev->header_oid, in __rbd_acknowledge_notify()
4387 &rbd_dev->header_oloc, notify_id, cookie, in __rbd_acknowledge_notify()
4390 rbd_warn(rbd_dev, "acknowledge_notify failed: %d", ret); in __rbd_acknowledge_notify()
4393 static void rbd_acknowledge_notify(struct rbd_device *rbd_dev, u64 notify_id, in rbd_acknowledge_notify() argument
4396 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_acknowledge_notify()
4397 __rbd_acknowledge_notify(rbd_dev, notify_id, cookie, NULL); in rbd_acknowledge_notify()
4400 static void rbd_acknowledge_notify_result(struct rbd_device *rbd_dev, in rbd_acknowledge_notify_result() argument
4403 dout("%s rbd_dev %p result %d\n", __func__, rbd_dev, result); in rbd_acknowledge_notify_result()
4404 __rbd_acknowledge_notify(rbd_dev, notify_id, cookie, &result); in rbd_acknowledge_notify_result()
4410 struct rbd_device *rbd_dev = arg; in rbd_watch_cb() local
4419 __func__, rbd_dev, cookie, notify_id, data_len); in rbd_watch_cb()
4424 rbd_warn(rbd_dev, "failed to decode NotifyMessage: %d", in rbd_watch_cb()
4436 dout("%s rbd_dev %p notify_op %u\n", __func__, rbd_dev, notify_op); in rbd_watch_cb()
4439 rbd_handle_acquired_lock(rbd_dev, struct_v, &p); in rbd_watch_cb()
4440 rbd_acknowledge_notify(rbd_dev, notify_id, cookie); in rbd_watch_cb()
4443 rbd_handle_released_lock(rbd_dev, struct_v, &p); in rbd_watch_cb()
4444 rbd_acknowledge_notify(rbd_dev, notify_id, cookie); in rbd_watch_cb()
4447 ret = rbd_handle_request_lock(rbd_dev, struct_v, &p); in rbd_watch_cb()
4449 rbd_acknowledge_notify_result(rbd_dev, notify_id, in rbd_watch_cb()
4452 rbd_acknowledge_notify(rbd_dev, notify_id, cookie); in rbd_watch_cb()
4455 ret = rbd_dev_refresh(rbd_dev); in rbd_watch_cb()
4457 rbd_warn(rbd_dev, "refresh failed: %d", ret); in rbd_watch_cb()
4459 rbd_acknowledge_notify(rbd_dev, notify_id, cookie); in rbd_watch_cb()
4462 if (rbd_is_lock_owner(rbd_dev)) in rbd_watch_cb()
4463 rbd_acknowledge_notify_result(rbd_dev, notify_id, in rbd_watch_cb()
4466 rbd_acknowledge_notify(rbd_dev, notify_id, cookie); in rbd_watch_cb()
4471 static void __rbd_unregister_watch(struct rbd_device *rbd_dev);
4475 struct rbd_device *rbd_dev = arg; in rbd_watch_errcb() local
4477 rbd_warn(rbd_dev, "encountered watch error: %d", err); in rbd_watch_errcb()
4479 down_write(&rbd_dev->lock_rwsem); in rbd_watch_errcb()
4480 rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); in rbd_watch_errcb()
4481 up_write(&rbd_dev->lock_rwsem); in rbd_watch_errcb()
4483 mutex_lock(&rbd_dev->watch_mutex); in rbd_watch_errcb()
4484 if (rbd_dev->watch_state == RBD_WATCH_STATE_REGISTERED) { in rbd_watch_errcb()
4485 __rbd_unregister_watch(rbd_dev); in rbd_watch_errcb()
4486 rbd_dev->watch_state = RBD_WATCH_STATE_ERROR; in rbd_watch_errcb()
4488 queue_delayed_work(rbd_dev->task_wq, &rbd_dev->watch_dwork, 0); in rbd_watch_errcb()
4490 mutex_unlock(&rbd_dev->watch_mutex); in rbd_watch_errcb()
4496 static int __rbd_register_watch(struct rbd_device *rbd_dev) in __rbd_register_watch() argument
4498 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_register_watch()
4501 rbd_assert(!rbd_dev->watch_handle); in __rbd_register_watch()
4502 dout("%s rbd_dev %p\n", __func__, rbd_dev); in __rbd_register_watch()
4504 handle = ceph_osdc_watch(osdc, &rbd_dev->header_oid, in __rbd_register_watch()
4505 &rbd_dev->header_oloc, rbd_watch_cb, in __rbd_register_watch()
4506 rbd_watch_errcb, rbd_dev); in __rbd_register_watch()
4510 rbd_dev->watch_handle = handle; in __rbd_register_watch()
4517 static void __rbd_unregister_watch(struct rbd_device *rbd_dev) in __rbd_unregister_watch() argument
4519 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_unregister_watch()
4522 rbd_assert(rbd_dev->watch_handle); in __rbd_unregister_watch()
4523 dout("%s rbd_dev %p\n", __func__, rbd_dev); in __rbd_unregister_watch()
4525 ret = ceph_osdc_unwatch(osdc, rbd_dev->watch_handle); in __rbd_unregister_watch()
4527 rbd_warn(rbd_dev, "failed to unwatch: %d", ret); in __rbd_unregister_watch()
4529 rbd_dev->watch_handle = NULL; in __rbd_unregister_watch()
4532 static int rbd_register_watch(struct rbd_device *rbd_dev) in rbd_register_watch() argument
4536 mutex_lock(&rbd_dev->watch_mutex); in rbd_register_watch()
4537 rbd_assert(rbd_dev->watch_state == RBD_WATCH_STATE_UNREGISTERED); in rbd_register_watch()
4538 ret = __rbd_register_watch(rbd_dev); in rbd_register_watch()
4542 rbd_dev->watch_state = RBD_WATCH_STATE_REGISTERED; in rbd_register_watch()
4543 rbd_dev->watch_cookie = rbd_dev->watch_handle->linger_id; in rbd_register_watch()
4546 mutex_unlock(&rbd_dev->watch_mutex); in rbd_register_watch()
4550 static void cancel_tasks_sync(struct rbd_device *rbd_dev) in cancel_tasks_sync() argument
4552 dout("%s rbd_dev %p\n", __func__, rbd_dev); in cancel_tasks_sync()
4554 cancel_work_sync(&rbd_dev->acquired_lock_work); in cancel_tasks_sync()
4555 cancel_work_sync(&rbd_dev->released_lock_work); in cancel_tasks_sync()
4556 cancel_delayed_work_sync(&rbd_dev->lock_dwork); in cancel_tasks_sync()
4557 cancel_work_sync(&rbd_dev->unlock_work); in cancel_tasks_sync()
4564 static void rbd_unregister_watch(struct rbd_device *rbd_dev) in rbd_unregister_watch() argument
4566 cancel_tasks_sync(rbd_dev); in rbd_unregister_watch()
4568 mutex_lock(&rbd_dev->watch_mutex); in rbd_unregister_watch()
4569 if (rbd_dev->watch_state == RBD_WATCH_STATE_REGISTERED) in rbd_unregister_watch()
4570 __rbd_unregister_watch(rbd_dev); in rbd_unregister_watch()
4571 rbd_dev->watch_state = RBD_WATCH_STATE_UNREGISTERED; in rbd_unregister_watch()
4572 mutex_unlock(&rbd_dev->watch_mutex); in rbd_unregister_watch()
4574 cancel_delayed_work_sync(&rbd_dev->watch_dwork); in rbd_unregister_watch()
4575 ceph_osdc_flush_notifies(&rbd_dev->rbd_client->client->osdc); in rbd_unregister_watch()
4581 static void rbd_reacquire_lock(struct rbd_device *rbd_dev) in rbd_reacquire_lock() argument
4583 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_reacquire_lock()
4587 if (!rbd_quiesce_lock(rbd_dev)) in rbd_reacquire_lock()
4590 format_lock_cookie(rbd_dev, cookie); in rbd_reacquire_lock()
4591 ret = ceph_cls_set_cookie(osdc, &rbd_dev->header_oid, in rbd_reacquire_lock()
4592 &rbd_dev->header_oloc, RBD_LOCK_NAME, in rbd_reacquire_lock()
4593 CEPH_CLS_LOCK_EXCLUSIVE, rbd_dev->lock_cookie, in rbd_reacquire_lock()
4597 rbd_warn(rbd_dev, "failed to update lock cookie: %d", in rbd_reacquire_lock()
4600 if (rbd_dev->opts->exclusive) in rbd_reacquire_lock()
4601 rbd_warn(rbd_dev, in rbd_reacquire_lock()
4608 __rbd_release_lock(rbd_dev); in rbd_reacquire_lock()
4609 queue_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); in rbd_reacquire_lock()
4611 __rbd_lock(rbd_dev, cookie); in rbd_reacquire_lock()
4612 wake_lock_waiters(rbd_dev, 0); in rbd_reacquire_lock()
4618 struct rbd_device *rbd_dev = container_of(to_delayed_work(work), in rbd_reregister_watch() local
4622 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_reregister_watch()
4624 mutex_lock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
4625 if (rbd_dev->watch_state != RBD_WATCH_STATE_ERROR) { in rbd_reregister_watch()
4626 mutex_unlock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
4630 ret = __rbd_register_watch(rbd_dev); in rbd_reregister_watch()
4632 rbd_warn(rbd_dev, "failed to reregister watch: %d", ret); in rbd_reregister_watch()
4634 queue_delayed_work(rbd_dev->task_wq, in rbd_reregister_watch()
4635 &rbd_dev->watch_dwork, in rbd_reregister_watch()
4637 mutex_unlock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
4641 mutex_unlock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
4642 down_write(&rbd_dev->lock_rwsem); in rbd_reregister_watch()
4643 wake_lock_waiters(rbd_dev, ret); in rbd_reregister_watch()
4644 up_write(&rbd_dev->lock_rwsem); in rbd_reregister_watch()
4648 rbd_dev->watch_state = RBD_WATCH_STATE_REGISTERED; in rbd_reregister_watch()
4649 rbd_dev->watch_cookie = rbd_dev->watch_handle->linger_id; in rbd_reregister_watch()
4650 mutex_unlock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
4652 down_write(&rbd_dev->lock_rwsem); in rbd_reregister_watch()
4653 if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED) in rbd_reregister_watch()
4654 rbd_reacquire_lock(rbd_dev); in rbd_reregister_watch()
4655 up_write(&rbd_dev->lock_rwsem); in rbd_reregister_watch()
4657 ret = rbd_dev_refresh(rbd_dev); in rbd_reregister_watch()
4659 rbd_warn(rbd_dev, "reregistration refresh failed: %d", ret); in rbd_reregister_watch()
4666 static int rbd_obj_method_sync(struct rbd_device *rbd_dev, in rbd_obj_method_sync() argument
4675 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_obj_method_sync()
4723 struct rbd_device *rbd_dev = img_request->rbd_dev; in rbd_queue_workfn() local
4740 down_read(&rbd_dev->header_rwsem); in rbd_queue_workfn()
4741 mapping_size = rbd_dev->mapping.size; in rbd_queue_workfn()
4743 up_read(&rbd_dev->header_rwsem); in rbd_queue_workfn()
4746 rbd_warn(rbd_dev, "beyond EOD (%llu~%llu > %llu)", offset, in rbd_queue_workfn()
4752 dout("%s rbd_dev %p img_req %p %s %llu~%llu\n", __func__, rbd_dev, in rbd_queue_workfn()
4769 rbd_warn(rbd_dev, "%s %llx at %llx result %d", in rbd_queue_workfn()
4777 struct rbd_device *rbd_dev = hctx->queue->queuedata; in rbd_queue_rq() local
4795 rbd_warn(rbd_dev, "unknown req_op %d", req_op(bd->rq)); in rbd_queue_rq()
4799 rbd_img_request_init(img_req, rbd_dev, op_type); in rbd_queue_rq()
4802 if (rbd_is_ro(rbd_dev)) { in rbd_queue_rq()
4803 rbd_warn(rbd_dev, "%s on read-only mapping", in rbd_queue_rq()
4807 rbd_assert(!rbd_is_snap(rbd_dev)); in rbd_queue_rq()
4815 static void rbd_free_disk(struct rbd_device *rbd_dev) in rbd_free_disk() argument
4817 put_disk(rbd_dev->disk); in rbd_free_disk()
4818 blk_mq_free_tag_set(&rbd_dev->tag_set); in rbd_free_disk()
4819 rbd_dev->disk = NULL; in rbd_free_disk()
4822 static int rbd_obj_read_sync(struct rbd_device *rbd_dev, in rbd_obj_read_sync() argument
4828 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_obj_read_sync()
4871 static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev, in rbd_dev_v1_header_info() argument
4900 ret = rbd_obj_read_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v1_header_info()
4901 &rbd_dev->header_oloc, ondisk, size); in rbd_dev_v1_header_info()
4906 rbd_warn(rbd_dev, "short header read (want %zd got %d)", in rbd_dev_v1_header_info()
4912 rbd_warn(rbd_dev, "invalid header"); in rbd_dev_v1_header_info()
4928 static void rbd_dev_update_size(struct rbd_device *rbd_dev) in rbd_dev_update_size() argument
4937 if (test_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags) && in rbd_dev_update_size()
4938 !test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags)) { in rbd_dev_update_size()
4939 size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE; in rbd_dev_update_size()
4941 set_capacity_and_notify(rbd_dev->disk, size); in rbd_dev_update_size()
4949 static int rbd_init_disk(struct rbd_device *rbd_dev) in rbd_init_disk() argument
4953 rbd_dev->layout.object_size * rbd_dev->layout.stripe_count; in rbd_init_disk()
4957 .io_min = rbd_dev->opts->alloc_size, in rbd_init_disk()
4963 memset(&rbd_dev->tag_set, 0, sizeof(rbd_dev->tag_set)); in rbd_init_disk()
4964 rbd_dev->tag_set.ops = &rbd_mq_ops; in rbd_init_disk()
4965 rbd_dev->tag_set.queue_depth = rbd_dev->opts->queue_depth; in rbd_init_disk()
4966 rbd_dev->tag_set.numa_node = NUMA_NO_NODE; in rbd_init_disk()
4967 rbd_dev->tag_set.nr_hw_queues = num_present_cpus(); in rbd_init_disk()
4968 rbd_dev->tag_set.cmd_size = sizeof(struct rbd_img_request); in rbd_init_disk()
4970 err = blk_mq_alloc_tag_set(&rbd_dev->tag_set); in rbd_init_disk()
4974 if (rbd_dev->opts->trim) { in rbd_init_disk()
4975 lim.discard_granularity = rbd_dev->opts->alloc_size; in rbd_init_disk()
4980 if (!ceph_test_opt(rbd_dev->rbd_client->client, NOCRC)) in rbd_init_disk()
4983 disk = blk_mq_alloc_disk(&rbd_dev->tag_set, &lim, rbd_dev); in rbd_init_disk()
4990 rbd_dev->dev_id); in rbd_init_disk()
4991 disk->major = rbd_dev->major; in rbd_init_disk()
4992 disk->first_minor = rbd_dev->minor; in rbd_init_disk()
4998 disk->private_data = rbd_dev; in rbd_init_disk()
4999 rbd_dev->disk = disk; in rbd_init_disk()
5003 blk_mq_free_tag_set(&rbd_dev->tag_set); in rbd_init_disk()
5019 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_size_show() local
5022 (unsigned long long)rbd_dev->mapping.size); in rbd_size_show()
5028 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_features_show() local
5030 return sprintf(buf, "0x%016llx\n", rbd_dev->header.features); in rbd_features_show()
5036 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_major_show() local
5038 if (rbd_dev->major) in rbd_major_show()
5039 return sprintf(buf, "%d\n", rbd_dev->major); in rbd_major_show()
5047 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_minor_show() local
5049 return sprintf(buf, "%d\n", rbd_dev->minor); in rbd_minor_show()
5055 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_client_addr_show() local
5057 ceph_client_addr(rbd_dev->rbd_client->client); in rbd_client_addr_show()
5066 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_client_id_show() local
5069 ceph_client_gid(rbd_dev->rbd_client->client)); in rbd_client_id_show()
5075 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_cluster_fsid_show() local
5077 return sprintf(buf, "%pU\n", &rbd_dev->rbd_client->client->fsid); in rbd_cluster_fsid_show()
5083 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_config_info_show() local
5088 return sprintf(buf, "%s\n", rbd_dev->config_info); in rbd_config_info_show()
5094 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_pool_show() local
5096 return sprintf(buf, "%s\n", rbd_dev->spec->pool_name); in rbd_pool_show()
5102 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_pool_id_show() local
5105 (unsigned long long) rbd_dev->spec->pool_id); in rbd_pool_id_show()
5111 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_pool_ns_show() local
5113 return sprintf(buf, "%s\n", rbd_dev->spec->pool_ns ?: ""); in rbd_pool_ns_show()
5119 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_name_show() local
5121 if (rbd_dev->spec->image_name) in rbd_name_show()
5122 return sprintf(buf, "%s\n", rbd_dev->spec->image_name); in rbd_name_show()
5130 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_image_id_show() local
5132 return sprintf(buf, "%s\n", rbd_dev->spec->image_id); in rbd_image_id_show()
5143 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_snap_show() local
5145 return sprintf(buf, "%s\n", rbd_dev->spec->snap_name); in rbd_snap_show()
5151 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_snap_id_show() local
5153 return sprintf(buf, "%llu\n", rbd_dev->spec->snap_id); in rbd_snap_id_show()
5165 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_parent_show() local
5168 if (!rbd_dev->parent) in rbd_parent_show()
5171 for ( ; rbd_dev->parent; rbd_dev = rbd_dev->parent) { in rbd_parent_show()
5172 struct rbd_spec *spec = rbd_dev->parent_spec; in rbd_parent_show()
5185 rbd_dev->parent_overlap); in rbd_parent_show()
5196 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_image_refresh() local
5202 ret = rbd_dev_refresh(rbd_dev); in rbd_image_refresh()
5306 static void rbd_dev_free(struct rbd_device *rbd_dev) in rbd_dev_free() argument
5308 WARN_ON(rbd_dev->watch_state != RBD_WATCH_STATE_UNREGISTERED); in rbd_dev_free()
5309 WARN_ON(rbd_dev->lock_state != RBD_LOCK_STATE_UNLOCKED); in rbd_dev_free()
5311 ceph_oid_destroy(&rbd_dev->header_oid); in rbd_dev_free()
5312 ceph_oloc_destroy(&rbd_dev->header_oloc); in rbd_dev_free()
5313 kfree(rbd_dev->config_info); in rbd_dev_free()
5315 rbd_put_client(rbd_dev->rbd_client); in rbd_dev_free()
5316 rbd_spec_put(rbd_dev->spec); in rbd_dev_free()
5317 kfree(rbd_dev->opts); in rbd_dev_free()
5318 kfree(rbd_dev); in rbd_dev_free()
5323 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_dev_release() local
5324 bool need_put = !!rbd_dev->opts; in rbd_dev_release()
5327 destroy_workqueue(rbd_dev->task_wq); in rbd_dev_release()
5328 ida_free(&rbd_dev_id_ida, rbd_dev->dev_id); in rbd_dev_release()
5331 rbd_dev_free(rbd_dev); in rbd_dev_release()
5344 struct rbd_device *rbd_dev; in __rbd_dev_create() local
5346 rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL); in __rbd_dev_create()
5347 if (!rbd_dev) in __rbd_dev_create()
5350 spin_lock_init(&rbd_dev->lock); in __rbd_dev_create()
5351 INIT_LIST_HEAD(&rbd_dev->node); in __rbd_dev_create()
5352 init_rwsem(&rbd_dev->header_rwsem); in __rbd_dev_create()
5354 rbd_dev->header.data_pool_id = CEPH_NOPOOL; in __rbd_dev_create()
5355 ceph_oid_init(&rbd_dev->header_oid); in __rbd_dev_create()
5356 rbd_dev->header_oloc.pool = spec->pool_id; in __rbd_dev_create()
5359 rbd_dev->header_oloc.pool_ns = in __rbd_dev_create()
5364 mutex_init(&rbd_dev->watch_mutex); in __rbd_dev_create()
5365 rbd_dev->watch_state = RBD_WATCH_STATE_UNREGISTERED; in __rbd_dev_create()
5366 INIT_DELAYED_WORK(&rbd_dev->watch_dwork, rbd_reregister_watch); in __rbd_dev_create()
5368 init_rwsem(&rbd_dev->lock_rwsem); in __rbd_dev_create()
5369 rbd_dev->lock_state = RBD_LOCK_STATE_UNLOCKED; in __rbd_dev_create()
5370 INIT_WORK(&rbd_dev->acquired_lock_work, rbd_notify_acquired_lock); in __rbd_dev_create()
5371 INIT_WORK(&rbd_dev->released_lock_work, rbd_notify_released_lock); in __rbd_dev_create()
5372 INIT_DELAYED_WORK(&rbd_dev->lock_dwork, rbd_acquire_lock); in __rbd_dev_create()
5373 INIT_WORK(&rbd_dev->unlock_work, rbd_release_lock_work); in __rbd_dev_create()
5374 spin_lock_init(&rbd_dev->lock_lists_lock); in __rbd_dev_create()
5375 INIT_LIST_HEAD(&rbd_dev->acquiring_list); in __rbd_dev_create()
5376 INIT_LIST_HEAD(&rbd_dev->running_list); in __rbd_dev_create()
5377 init_completion(&rbd_dev->acquire_wait); in __rbd_dev_create()
5378 init_completion(&rbd_dev->quiescing_wait); in __rbd_dev_create()
5380 spin_lock_init(&rbd_dev->object_map_lock); in __rbd_dev_create()
5382 rbd_dev->dev.bus = &rbd_bus_type; in __rbd_dev_create()
5383 rbd_dev->dev.type = &rbd_device_type; in __rbd_dev_create()
5384 rbd_dev->dev.parent = &rbd_root_dev; in __rbd_dev_create()
5385 device_initialize(&rbd_dev->dev); in __rbd_dev_create()
5387 return rbd_dev; in __rbd_dev_create()
5397 struct rbd_device *rbd_dev; in rbd_dev_create() local
5399 rbd_dev = __rbd_dev_create(spec); in rbd_dev_create()
5400 if (!rbd_dev) in rbd_dev_create()
5404 rbd_dev->dev_id = ida_alloc_max(&rbd_dev_id_ida, in rbd_dev_create()
5407 if (rbd_dev->dev_id < 0) in rbd_dev_create()
5410 sprintf(rbd_dev->name, RBD_DRV_NAME "%d", rbd_dev->dev_id); in rbd_dev_create()
5411 rbd_dev->task_wq = alloc_ordered_workqueue("%s-tasks", WQ_MEM_RECLAIM, in rbd_dev_create()
5412 rbd_dev->name); in rbd_dev_create()
5413 if (!rbd_dev->task_wq) in rbd_dev_create()
5419 rbd_dev->rbd_client = rbdc; in rbd_dev_create()
5420 rbd_dev->spec = spec; in rbd_dev_create()
5421 rbd_dev->opts = opts; in rbd_dev_create()
5423 dout("%s rbd_dev %p dev_id %d\n", __func__, rbd_dev, rbd_dev->dev_id); in rbd_dev_create()
5424 return rbd_dev; in rbd_dev_create()
5427 ida_free(&rbd_dev_id_ida, rbd_dev->dev_id); in rbd_dev_create()
5429 rbd_dev_free(rbd_dev); in rbd_dev_create()
5433 static void rbd_dev_destroy(struct rbd_device *rbd_dev) in rbd_dev_destroy() argument
5435 if (rbd_dev) in rbd_dev_destroy()
5436 put_device(&rbd_dev->dev); in rbd_dev_destroy()
5444 static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, in _rbd_dev_v2_snap_size() argument
5454 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in _rbd_dev_v2_snap_size()
5455 &rbd_dev->header_oloc, "get_size", in _rbd_dev_v2_snap_size()
5477 static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev, in rbd_dev_v2_object_prefix() argument
5492 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_object_prefix()
5493 &rbd_dev->header_oloc, "get_object_prefix", in rbd_dev_v2_object_prefix()
5516 static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, in _rbd_dev_v2_snap_features() argument
5533 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in _rbd_dev_v2_snap_features()
5534 &rbd_dev->header_oloc, "get_features", in _rbd_dev_v2_snap_features()
5545 rbd_warn(rbd_dev, "image uses unsupported features: 0x%llx", in _rbd_dev_v2_snap_features()
5567 static int rbd_dev_v2_get_flags(struct rbd_device *rbd_dev) in rbd_dev_v2_get_flags() argument
5569 __le64 snapid = cpu_to_le64(rbd_dev->spec->snap_id); in rbd_dev_v2_get_flags()
5573 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_get_flags()
5574 &rbd_dev->header_oloc, "get_flags", in rbd_dev_v2_get_flags()
5582 rbd_dev->object_map_flags = le64_to_cpu(flags); in rbd_dev_v2_get_flags()
5639 static int __get_parent_info(struct rbd_device *rbd_dev, in __get_parent_info() argument
5644 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __get_parent_info()
5649 ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in __get_parent_info()
5661 ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in __get_parent_info()
5685 static int __get_parent_info_legacy(struct rbd_device *rbd_dev, in __get_parent_info_legacy() argument
5690 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __get_parent_info_legacy()
5695 ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in __get_parent_info_legacy()
5723 static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev, in rbd_dev_v2_parent_info() argument
5741 ceph_encode_64(&p, rbd_dev->spec->snap_id); in rbd_dev_v2_parent_info()
5742 ret = __get_parent_info(rbd_dev, req_page, reply_page, pii); in rbd_dev_v2_parent_info()
5744 ret = __get_parent_info_legacy(rbd_dev, req_page, reply_page, in rbd_dev_v2_parent_info()
5752 static int rbd_dev_setup_parent(struct rbd_device *rbd_dev) in rbd_dev_setup_parent() argument
5762 ret = rbd_dev_v2_parent_info(rbd_dev, &pii); in rbd_dev_setup_parent()
5791 rbd_assert(!rbd_dev->parent_spec); in rbd_dev_setup_parent()
5792 rbd_dev->parent_spec = parent_spec; in rbd_dev_setup_parent()
5800 rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); in rbd_dev_setup_parent()
5801 rbd_dev->parent_overlap = pii.overlap; in rbd_dev_setup_parent()
5811 static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev, in rbd_dev_v2_striping_info() argument
5821 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_striping_info()
5822 &rbd_dev->header_oloc, "get_stripe_unit_count", in rbd_dev_v2_striping_info()
5838 static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev, s64 *data_pool_id) in rbd_dev_v2_data_pool() argument
5843 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_data_pool()
5844 &rbd_dev->header_oloc, "get_data_pool", in rbd_dev_v2_data_pool()
5860 static char *rbd_dev_image_name(struct rbd_device *rbd_dev) in rbd_dev_image_name() argument
5873 rbd_assert(!rbd_dev->spec->image_name); in rbd_dev_image_name()
5875 len = strlen(rbd_dev->spec->image_id); in rbd_dev_image_name()
5883 ceph_encode_string(&p, end, rbd_dev->spec->image_id, (u32)len); in rbd_dev_image_name()
5891 ret = rbd_obj_method_sync(rbd_dev, &oid, &rbd_dev->header_oloc, in rbd_dev_image_name()
5911 static u64 rbd_v1_snap_id_by_name(struct rbd_device *rbd_dev, const char *name) in rbd_v1_snap_id_by_name() argument
5913 struct ceph_snap_context *snapc = rbd_dev->header.snapc; in rbd_v1_snap_id_by_name()
5919 snap_name = rbd_dev->header.snap_names; in rbd_v1_snap_id_by_name()
5929 static u64 rbd_v2_snap_id_by_name(struct rbd_device *rbd_dev, const char *name) in rbd_v2_snap_id_by_name() argument
5931 struct ceph_snap_context *snapc = rbd_dev->header.snapc; in rbd_v2_snap_id_by_name()
5940 snap_name = rbd_dev_v2_snap_name(rbd_dev, snap_id); in rbd_v2_snap_id_by_name()
5958 static u64 rbd_snap_id_by_name(struct rbd_device *rbd_dev, const char *name) in rbd_snap_id_by_name() argument
5960 if (rbd_dev->image_format == 1) in rbd_snap_id_by_name()
5961 return rbd_v1_snap_id_by_name(rbd_dev, name); in rbd_snap_id_by_name()
5963 return rbd_v2_snap_id_by_name(rbd_dev, name); in rbd_snap_id_by_name()
5969 static int rbd_spec_fill_snap_id(struct rbd_device *rbd_dev) in rbd_spec_fill_snap_id() argument
5971 struct rbd_spec *spec = rbd_dev->spec; in rbd_spec_fill_snap_id()
5980 snap_id = rbd_snap_id_by_name(rbd_dev, spec->snap_name); in rbd_spec_fill_snap_id()
5998 static int rbd_spec_fill_names(struct rbd_device *rbd_dev) in rbd_spec_fill_names() argument
6000 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_spec_fill_names()
6001 struct rbd_spec *spec = rbd_dev->spec; in rbd_spec_fill_names()
6015 rbd_warn(rbd_dev, "no pool with id %llu", spec->pool_id); in rbd_spec_fill_names()
6024 image_name = rbd_dev_image_name(rbd_dev); in rbd_spec_fill_names()
6026 rbd_warn(rbd_dev, "unable to get image name"); in rbd_spec_fill_names()
6030 snap_name = rbd_snap_name(rbd_dev, spec->snap_id); in rbd_spec_fill_names()
6048 static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, in rbd_dev_v2_snap_context() argument
6073 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_snap_context()
6074 &rbd_dev->header_oloc, "get_snapcontext", in rbd_dev_v2_snap_context()
6119 static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, in rbd_dev_v2_snap_name() argument
6136 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_snap_name()
6137 &rbd_dev->header_oloc, "get_snapshot_name", in rbd_dev_v2_snap_name()
6159 static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev, in rbd_dev_v2_header_info() argument
6165 ret = _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, in rbd_dev_v2_header_info()
6172 ret = rbd_dev_v2_header_onetime(rbd_dev, header); in rbd_dev_v2_header_info()
6177 ret = rbd_dev_v2_snap_context(rbd_dev, &header->snapc); in rbd_dev_v2_header_info()
6184 static int rbd_dev_header_info(struct rbd_device *rbd_dev, in rbd_dev_header_info() argument
6188 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_dev_header_info()
6191 if (rbd_dev->image_format == 1) in rbd_dev_header_info()
6192 return rbd_dev_v1_header_info(rbd_dev, header, first_time); in rbd_dev_header_info()
6194 return rbd_dev_v2_header_info(rbd_dev, header, first_time); in rbd_dev_header_info()
6540 static void rbd_dev_image_unlock(struct rbd_device *rbd_dev) in rbd_dev_image_unlock() argument
6542 down_write(&rbd_dev->lock_rwsem); in rbd_dev_image_unlock()
6543 if (__rbd_is_lock_owner(rbd_dev)) in rbd_dev_image_unlock()
6544 __rbd_release_lock(rbd_dev); in rbd_dev_image_unlock()
6545 up_write(&rbd_dev->lock_rwsem); in rbd_dev_image_unlock()
6553 static int rbd_add_acquire_lock(struct rbd_device *rbd_dev) in rbd_add_acquire_lock() argument
6557 if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK)) { in rbd_add_acquire_lock()
6558 if (!rbd_dev->opts->exclusive && !rbd_dev->opts->lock_on_read) in rbd_add_acquire_lock()
6561 rbd_warn(rbd_dev, "exclusive-lock feature is not enabled"); in rbd_add_acquire_lock()
6565 if (rbd_is_ro(rbd_dev)) in rbd_add_acquire_lock()
6568 rbd_assert(!rbd_is_lock_owner(rbd_dev)); in rbd_add_acquire_lock()
6569 queue_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); in rbd_add_acquire_lock()
6570 ret = wait_for_completion_killable_timeout(&rbd_dev->acquire_wait, in rbd_add_acquire_lock()
6571 ceph_timeout_jiffies(rbd_dev->opts->lock_timeout)); in rbd_add_acquire_lock()
6573 ret = rbd_dev->acquire_err; in rbd_add_acquire_lock()
6575 cancel_delayed_work_sync(&rbd_dev->lock_dwork); in rbd_add_acquire_lock()
6579 rbd_warn(rbd_dev, "failed to acquire lock: %ld", ret); in rbd_add_acquire_lock()
6601 static int rbd_dev_image_id(struct rbd_device *rbd_dev) in rbd_dev_image_id() argument
6615 if (rbd_dev->spec->image_id) { in rbd_dev_image_id()
6616 rbd_dev->image_format = *rbd_dev->spec->image_id ? 2 : 1; in rbd_dev_image_id()
6626 rbd_dev->spec->image_name); in rbd_dev_image_id()
6642 ret = rbd_obj_method_sync(rbd_dev, &oid, &rbd_dev->header_oloc, in rbd_dev_image_id()
6650 rbd_dev->image_format = 1; in rbd_dev_image_id()
6658 rbd_dev->image_format = 2; in rbd_dev_image_id()
6662 rbd_dev->spec->image_id = image_id; in rbd_dev_image_id()
6675 static void rbd_dev_unprobe(struct rbd_device *rbd_dev) in rbd_dev_unprobe() argument
6677 rbd_dev_parent_put(rbd_dev); in rbd_dev_unprobe()
6678 rbd_object_map_free(rbd_dev); in rbd_dev_unprobe()
6679 rbd_dev_mapping_clear(rbd_dev); in rbd_dev_unprobe()
6683 rbd_image_header_cleanup(&rbd_dev->header); in rbd_dev_unprobe()
6686 static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev, in rbd_dev_v2_header_onetime() argument
6691 ret = rbd_dev_v2_object_prefix(rbd_dev, &header->object_prefix); in rbd_dev_v2_header_onetime()
6699 ret = _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP, in rbd_dev_v2_header_onetime()
6700 rbd_is_ro(rbd_dev), &header->features); in rbd_dev_v2_header_onetime()
6707 ret = rbd_dev_v2_striping_info(rbd_dev, &header->stripe_unit, in rbd_dev_v2_header_onetime()
6714 ret = rbd_dev_v2_data_pool(rbd_dev, &header->data_pool_id); in rbd_dev_v2_header_onetime()
6727 static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) in rbd_dev_probe_parent() argument
6732 if (!rbd_dev->parent_spec) in rbd_dev_probe_parent()
6741 parent = __rbd_dev_create(rbd_dev->parent_spec); in rbd_dev_probe_parent()
6751 parent->rbd_client = __rbd_get_client(rbd_dev->rbd_client); in rbd_dev_probe_parent()
6752 parent->spec = rbd_spec_get(rbd_dev->parent_spec); in rbd_dev_probe_parent()
6760 rbd_dev->parent = parent; in rbd_dev_probe_parent()
6761 atomic_set(&rbd_dev->parent_ref, 1); in rbd_dev_probe_parent()
6765 rbd_dev_unparent(rbd_dev); in rbd_dev_probe_parent()
6770 static void rbd_dev_device_release(struct rbd_device *rbd_dev) in rbd_dev_device_release() argument
6772 clear_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); in rbd_dev_device_release()
6773 rbd_free_disk(rbd_dev); in rbd_dev_device_release()
6775 unregister_blkdev(rbd_dev->major, rbd_dev->name); in rbd_dev_device_release()
6782 static int rbd_dev_device_setup(struct rbd_device *rbd_dev) in rbd_dev_device_setup() argument
6789 ret = register_blkdev(0, rbd_dev->name); in rbd_dev_device_setup()
6793 rbd_dev->major = ret; in rbd_dev_device_setup()
6794 rbd_dev->minor = 0; in rbd_dev_device_setup()
6796 rbd_dev->major = rbd_major; in rbd_dev_device_setup()
6797 rbd_dev->minor = rbd_dev_id_to_minor(rbd_dev->dev_id); in rbd_dev_device_setup()
6802 ret = rbd_init_disk(rbd_dev); in rbd_dev_device_setup()
6806 set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE); in rbd_dev_device_setup()
6807 set_disk_ro(rbd_dev->disk, rbd_is_ro(rbd_dev)); in rbd_dev_device_setup()
6809 ret = dev_set_name(&rbd_dev->dev, "%d", rbd_dev->dev_id); in rbd_dev_device_setup()
6813 set_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); in rbd_dev_device_setup()
6814 up_write(&rbd_dev->header_rwsem); in rbd_dev_device_setup()
6818 rbd_free_disk(rbd_dev); in rbd_dev_device_setup()
6821 unregister_blkdev(rbd_dev->major, rbd_dev->name); in rbd_dev_device_setup()
6823 up_write(&rbd_dev->header_rwsem); in rbd_dev_device_setup()
6827 static int rbd_dev_header_name(struct rbd_device *rbd_dev) in rbd_dev_header_name() argument
6829 struct rbd_spec *spec = rbd_dev->spec; in rbd_dev_header_name()
6834 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_dev_header_name()
6835 if (rbd_dev->image_format == 1) in rbd_dev_header_name()
6836 ret = ceph_oid_aprintf(&rbd_dev->header_oid, GFP_KERNEL, "%s%s", in rbd_dev_header_name()
6839 ret = ceph_oid_aprintf(&rbd_dev->header_oid, GFP_KERNEL, "%s%s", in rbd_dev_header_name()
6845 static void rbd_print_dne(struct rbd_device *rbd_dev, bool is_snap) in rbd_print_dne() argument
6849 rbd_dev->spec->pool_name, in rbd_print_dne()
6850 rbd_dev->spec->pool_ns ?: "", in rbd_print_dne()
6851 rbd_dev->spec->pool_ns ? "/" : "", in rbd_print_dne()
6852 rbd_dev->spec->image_name); in rbd_print_dne()
6855 rbd_dev->spec->pool_name, in rbd_print_dne()
6856 rbd_dev->spec->pool_ns ?: "", in rbd_print_dne()
6857 rbd_dev->spec->pool_ns ? "/" : "", in rbd_print_dne()
6858 rbd_dev->spec->image_name, in rbd_print_dne()
6859 rbd_dev->spec->snap_name); in rbd_print_dne()
6863 static void rbd_dev_image_release(struct rbd_device *rbd_dev) in rbd_dev_image_release() argument
6865 if (!rbd_is_ro(rbd_dev)) in rbd_dev_image_release()
6866 rbd_unregister_watch(rbd_dev); in rbd_dev_image_release()
6868 rbd_dev_unprobe(rbd_dev); in rbd_dev_image_release()
6869 rbd_dev->image_format = 0; in rbd_dev_image_release()
6870 kfree(rbd_dev->spec->image_id); in rbd_dev_image_release()
6871 rbd_dev->spec->image_id = NULL; in rbd_dev_image_release()
6883 static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth) in rbd_dev_image_probe() argument
6885 bool need_watch = !rbd_is_ro(rbd_dev); in rbd_dev_image_probe()
6894 ret = rbd_dev_image_id(rbd_dev); in rbd_dev_image_probe()
6898 ret = rbd_dev_header_name(rbd_dev); in rbd_dev_image_probe()
6903 ret = rbd_register_watch(rbd_dev); in rbd_dev_image_probe()
6906 rbd_print_dne(rbd_dev, false); in rbd_dev_image_probe()
6912 down_write(&rbd_dev->header_rwsem); in rbd_dev_image_probe()
6914 ret = rbd_dev_header_info(rbd_dev, &rbd_dev->header, true); in rbd_dev_image_probe()
6917 rbd_print_dne(rbd_dev, false); in rbd_dev_image_probe()
6921 rbd_init_layout(rbd_dev); in rbd_dev_image_probe()
6930 ret = rbd_spec_fill_snap_id(rbd_dev); in rbd_dev_image_probe()
6932 ret = rbd_spec_fill_names(rbd_dev); in rbd_dev_image_probe()
6935 rbd_print_dne(rbd_dev, true); in rbd_dev_image_probe()
6939 ret = rbd_dev_mapping_set(rbd_dev); in rbd_dev_image_probe()
6943 if (rbd_is_snap(rbd_dev) && in rbd_dev_image_probe()
6944 (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) { in rbd_dev_image_probe()
6945 ret = rbd_object_map_load(rbd_dev); in rbd_dev_image_probe()
6950 if (rbd_dev->header.features & RBD_FEATURE_LAYERING) { in rbd_dev_image_probe()
6951 ret = rbd_dev_setup_parent(rbd_dev); in rbd_dev_image_probe()
6956 ret = rbd_dev_probe_parent(rbd_dev, depth); in rbd_dev_image_probe()
6961 rbd_dev->image_format, rbd_dev->header_oid.name); in rbd_dev_image_probe()
6966 up_write(&rbd_dev->header_rwsem); in rbd_dev_image_probe()
6968 rbd_unregister_watch(rbd_dev); in rbd_dev_image_probe()
6969 rbd_dev_unprobe(rbd_dev); in rbd_dev_image_probe()
6971 rbd_dev->image_format = 0; in rbd_dev_image_probe()
6972 kfree(rbd_dev->spec->image_id); in rbd_dev_image_probe()
6973 rbd_dev->spec->image_id = NULL; in rbd_dev_image_probe()
6977 static void rbd_dev_update_header(struct rbd_device *rbd_dev, in rbd_dev_update_header() argument
6980 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_dev_update_header()
6981 rbd_assert(rbd_dev->header.object_prefix); /* !first_time */ in rbd_dev_update_header()
6983 if (rbd_dev->header.image_size != header->image_size) { in rbd_dev_update_header()
6984 rbd_dev->header.image_size = header->image_size; in rbd_dev_update_header()
6986 if (!rbd_is_snap(rbd_dev)) { in rbd_dev_update_header()
6987 rbd_dev->mapping.size = header->image_size; in rbd_dev_update_header()
6988 rbd_dev_update_size(rbd_dev); in rbd_dev_update_header()
6992 ceph_put_snap_context(rbd_dev->header.snapc); in rbd_dev_update_header()
6993 rbd_dev->header.snapc = header->snapc; in rbd_dev_update_header()
6996 if (rbd_dev->image_format == 1) { in rbd_dev_update_header()
6997 kfree(rbd_dev->header.snap_names); in rbd_dev_update_header()
6998 rbd_dev->header.snap_names = header->snap_names; in rbd_dev_update_header()
7001 kfree(rbd_dev->header.snap_sizes); in rbd_dev_update_header()
7002 rbd_dev->header.snap_sizes = header->snap_sizes; in rbd_dev_update_header()
7007 static void rbd_dev_update_parent(struct rbd_device *rbd_dev, in rbd_dev_update_parent() argument
7024 if (rbd_dev->parent_overlap) { in rbd_dev_update_parent()
7025 rbd_dev->parent_overlap = 0; in rbd_dev_update_parent()
7026 rbd_dev_parent_put(rbd_dev); in rbd_dev_update_parent()
7028 rbd_dev->disk->disk_name); in rbd_dev_update_parent()
7031 rbd_assert(rbd_dev->parent_spec); in rbd_dev_update_parent()
7037 if (!pii->overlap && rbd_dev->parent_overlap) in rbd_dev_update_parent()
7038 rbd_warn(rbd_dev, in rbd_dev_update_parent()
7040 rbd_dev->parent_overlap = pii->overlap; in rbd_dev_update_parent()
7044 static int rbd_dev_refresh(struct rbd_device *rbd_dev) in rbd_dev_refresh() argument
7050 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_dev_refresh()
7052 ret = rbd_dev_header_info(rbd_dev, &header, false); in rbd_dev_refresh()
7060 if (rbd_dev->parent) { in rbd_dev_refresh()
7061 ret = rbd_dev_v2_parent_info(rbd_dev, &pii); in rbd_dev_refresh()
7066 down_write(&rbd_dev->header_rwsem); in rbd_dev_refresh()
7067 rbd_dev_update_header(rbd_dev, &header); in rbd_dev_refresh()
7068 if (rbd_dev->parent) in rbd_dev_refresh()
7069 rbd_dev_update_parent(rbd_dev, &pii); in rbd_dev_refresh()
7070 up_write(&rbd_dev->header_rwsem); in rbd_dev_refresh()
7080 struct rbd_device *rbd_dev = NULL; in do_rbd_add() local
7113 rbd_dev = rbd_dev_create(rbdc, spec, rbd_opts); in do_rbd_add()
7114 if (!rbd_dev) { in do_rbd_add()
7123 if (rbd_dev->opts->read_only || in do_rbd_add()
7124 strcmp(rbd_dev->spec->snap_name, RBD_SNAP_HEAD_NAME)) in do_rbd_add()
7125 __set_bit(RBD_DEV_FLAG_READONLY, &rbd_dev->flags); in do_rbd_add()
7127 rbd_dev->config_info = kstrdup(buf, GFP_KERNEL); in do_rbd_add()
7128 if (!rbd_dev->config_info) { in do_rbd_add()
7133 rc = rbd_dev_image_probe(rbd_dev, 0); in do_rbd_add()
7137 if (rbd_dev->opts->alloc_size > rbd_dev->layout.object_size) { in do_rbd_add()
7138 rbd_warn(rbd_dev, "alloc_size adjusted to %u", in do_rbd_add()
7139 rbd_dev->layout.object_size); in do_rbd_add()
7140 rbd_dev->opts->alloc_size = rbd_dev->layout.object_size; in do_rbd_add()
7143 rc = rbd_dev_device_setup(rbd_dev); in do_rbd_add()
7147 rc = rbd_add_acquire_lock(rbd_dev); in do_rbd_add()
7153 rc = device_add(&rbd_dev->dev); in do_rbd_add()
7157 rc = device_add_disk(&rbd_dev->dev, rbd_dev->disk, NULL); in do_rbd_add()
7162 list_add_tail(&rbd_dev->node, &rbd_dev_list); in do_rbd_add()
7165 pr_info("%s: capacity %llu features 0x%llx\n", rbd_dev->disk->disk_name, in do_rbd_add()
7166 (unsigned long long)get_capacity(rbd_dev->disk) << SECTOR_SHIFT, in do_rbd_add()
7167 rbd_dev->header.features); in do_rbd_add()
7174 rbd_free_disk(rbd_dev); in do_rbd_add()
7176 rbd_dev_image_unlock(rbd_dev); in do_rbd_add()
7177 rbd_dev_device_release(rbd_dev); in do_rbd_add()
7179 rbd_dev_image_release(rbd_dev); in do_rbd_add()
7181 rbd_dev_destroy(rbd_dev); in do_rbd_add()
7204 static void rbd_dev_remove_parent(struct rbd_device *rbd_dev) in rbd_dev_remove_parent() argument
7206 while (rbd_dev->parent) { in rbd_dev_remove_parent()
7207 struct rbd_device *first = rbd_dev; in rbd_dev_remove_parent()
7233 struct rbd_device *rbd_dev = NULL; in do_rbd_remove() local
7260 list_for_each_entry(rbd_dev, &rbd_dev_list, node) { in do_rbd_remove()
7261 if (rbd_dev->dev_id == dev_id) { in do_rbd_remove()
7267 spin_lock_irq(&rbd_dev->lock); in do_rbd_remove()
7268 if (rbd_dev->open_count && !force) in do_rbd_remove()
7271 &rbd_dev->flags)) in do_rbd_remove()
7273 spin_unlock_irq(&rbd_dev->lock); in do_rbd_remove()
7284 unsigned int memflags = blk_mq_freeze_queue(rbd_dev->disk->queue); in do_rbd_remove()
7286 blk_mark_disk_dead(rbd_dev->disk); in do_rbd_remove()
7287 blk_mq_unfreeze_queue(rbd_dev->disk->queue, memflags); in do_rbd_remove()
7290 del_gendisk(rbd_dev->disk); in do_rbd_remove()
7292 list_del_init(&rbd_dev->node); in do_rbd_remove()
7294 device_del(&rbd_dev->dev); in do_rbd_remove()
7296 rbd_dev_image_unlock(rbd_dev); in do_rbd_remove()
7297 rbd_dev_device_release(rbd_dev); in do_rbd_remove()
7298 rbd_dev_image_release(rbd_dev); in do_rbd_remove()
7299 rbd_dev_destroy(rbd_dev); in do_rbd_remove()