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_RELEASING; 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);
636 static int rbd_dev_header_info(struct rbd_device *rbd_dev);
637 static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev);
638 static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev,
640 static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
642 static int rbd_dev_v2_get_flags(struct rbd_device *rbd_dev);
665 struct rbd_device *rbd_dev = bdev->bd_disk->private_data; in rbd_open() local
668 spin_lock_irq(&rbd_dev->lock); in rbd_open()
669 if (test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags)) in rbd_open()
672 rbd_dev->open_count++; in rbd_open()
673 spin_unlock_irq(&rbd_dev->lock); in rbd_open()
677 (void) get_device(&rbd_dev->dev); in rbd_open()
684 struct rbd_device *rbd_dev = disk->private_data; in rbd_release() local
687 spin_lock_irq(&rbd_dev->lock); in rbd_release()
688 open_count_before = rbd_dev->open_count--; in rbd_release()
689 spin_unlock_irq(&rbd_dev->lock); in rbd_release()
692 put_device(&rbd_dev->dev); in rbd_release()
695 static int rbd_ioctl_set_ro(struct rbd_device *rbd_dev, unsigned long arg) in rbd_ioctl_set_ro() argument
707 if (rbd_is_ro(rbd_dev)) in rbd_ioctl_set_ro()
710 rbd_assert(!rbd_is_snap(rbd_dev)); in rbd_ioctl_set_ro()
720 struct rbd_device *rbd_dev = bdev->bd_disk->private_data; in rbd_ioctl() local
725 ret = rbd_ioctl_set_ro(rbd_dev, arg); in rbd_ioctl()
1034 static void rbd_init_layout(struct rbd_device *rbd_dev) in rbd_init_layout() argument
1036 if (rbd_dev->header.stripe_unit == 0 || in rbd_init_layout()
1037 rbd_dev->header.stripe_count == 0) { in rbd_init_layout()
1038 rbd_dev->header.stripe_unit = rbd_obj_bytes(&rbd_dev->header); in rbd_init_layout()
1039 rbd_dev->header.stripe_count = 1; in rbd_init_layout()
1042 rbd_dev->layout.stripe_unit = rbd_dev->header.stripe_unit; in rbd_init_layout()
1043 rbd_dev->layout.stripe_count = rbd_dev->header.stripe_count; in rbd_init_layout()
1044 rbd_dev->layout.object_size = rbd_obj_bytes(&rbd_dev->header); in rbd_init_layout()
1045 rbd_dev->layout.pool_id = rbd_dev->header.data_pool_id == CEPH_NOPOOL ? in rbd_init_layout()
1046 rbd_dev->spec->pool_id : rbd_dev->header.data_pool_id; in rbd_init_layout()
1047 RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL); in rbd_init_layout()
1054 static int rbd_header_from_disk(struct rbd_device *rbd_dev, in rbd_header_from_disk() argument
1057 struct rbd_image_header *header = &rbd_dev->header; in rbd_header_from_disk()
1125 rbd_init_layout(rbd_dev); in rbd_header_from_disk()
1151 static const char *_rbd_dev_v1_snap_name(struct rbd_device *rbd_dev, u32 which) in _rbd_dev_v1_snap_name() argument
1155 rbd_assert(which < rbd_dev->header.snapc->num_snaps); in _rbd_dev_v1_snap_name()
1159 snap_name = rbd_dev->header.snap_names; in _rbd_dev_v1_snap_name()
1190 static u32 rbd_dev_snap_index(struct rbd_device *rbd_dev, u64 snap_id) in rbd_dev_snap_index() argument
1192 struct ceph_snap_context *snapc = rbd_dev->header.snapc; in rbd_dev_snap_index()
1201 static const char *rbd_dev_v1_snap_name(struct rbd_device *rbd_dev, in rbd_dev_v1_snap_name() argument
1207 which = rbd_dev_snap_index(rbd_dev, snap_id); in rbd_dev_v1_snap_name()
1211 snap_name = _rbd_dev_v1_snap_name(rbd_dev, which); in rbd_dev_v1_snap_name()
1215 static const char *rbd_snap_name(struct rbd_device *rbd_dev, u64 snap_id) in rbd_snap_name() argument
1220 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_snap_name()
1221 if (rbd_dev->image_format == 1) in rbd_snap_name()
1222 return rbd_dev_v1_snap_name(rbd_dev, snap_id); in rbd_snap_name()
1224 return rbd_dev_v2_snap_name(rbd_dev, snap_id); in rbd_snap_name()
1227 static int rbd_snap_size(struct rbd_device *rbd_dev, u64 snap_id, in rbd_snap_size() argument
1230 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_snap_size()
1232 *snap_size = rbd_dev->header.image_size; in rbd_snap_size()
1233 } else if (rbd_dev->image_format == 1) { in rbd_snap_size()
1236 which = rbd_dev_snap_index(rbd_dev, snap_id); in rbd_snap_size()
1240 *snap_size = rbd_dev->header.snap_sizes[which]; in rbd_snap_size()
1245 ret = _rbd_dev_v2_snap_size(rbd_dev, snap_id, NULL, &size); in rbd_snap_size()
1254 static int rbd_dev_mapping_set(struct rbd_device *rbd_dev) in rbd_dev_mapping_set() argument
1256 u64 snap_id = rbd_dev->spec->snap_id; in rbd_dev_mapping_set()
1260 ret = rbd_snap_size(rbd_dev, snap_id, &size); in rbd_dev_mapping_set()
1264 rbd_dev->mapping.size = size; in rbd_dev_mapping_set()
1268 static void rbd_dev_mapping_clear(struct rbd_device *rbd_dev) in rbd_dev_mapping_clear() argument
1270 rbd_dev->mapping.size = 0; in rbd_dev_mapping_clear()
1383 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_is_entire() local
1386 obj_req->ex.oe_len == rbd_dev->layout.object_size; in rbd_obj_is_entire()
1391 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_is_tail() local
1394 rbd_dev->layout.object_size; in rbd_obj_is_tail()
1454 struct rbd_device *rbd_dev = obj_request->img_request->rbd_dev; in rbd_osd_format_read() local
1455 struct ceph_options *opt = rbd_dev->rbd_client->client->options; in rbd_osd_format_read()
1474 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in __rbd_obj_add_osd_request() local
1475 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_obj_add_osd_request()
1477 const char *name_format = rbd_dev->image_format == 1 ? in __rbd_obj_add_osd_request()
1493 ceph_oloc_copy(&req->r_base_oloc, &rbd_dev->header_oloc); in __rbd_obj_add_osd_request()
1494 req->r_base_oloc.pool = rbd_dev->layout.pool_id; in __rbd_obj_add_osd_request()
1497 rbd_dev->header.object_prefix, in __rbd_obj_add_osd_request()
1573 static void rbd_dev_unparent(struct rbd_device *rbd_dev) in rbd_dev_unparent() argument
1575 rbd_dev_remove_parent(rbd_dev); in rbd_dev_unparent()
1576 rbd_spec_put(rbd_dev->parent_spec); in rbd_dev_unparent()
1577 rbd_dev->parent_spec = NULL; in rbd_dev_unparent()
1578 rbd_dev->parent_overlap = 0; in rbd_dev_unparent()
1587 static void rbd_dev_parent_put(struct rbd_device *rbd_dev) in rbd_dev_parent_put() argument
1591 if (!rbd_dev->parent_spec) in rbd_dev_parent_put()
1594 counter = atomic_dec_return_safe(&rbd_dev->parent_ref); in rbd_dev_parent_put()
1601 rbd_dev_unparent(rbd_dev); in rbd_dev_parent_put()
1603 rbd_warn(rbd_dev, "parent reference underflow"); in rbd_dev_parent_put()
1614 static bool rbd_dev_parent_get(struct rbd_device *rbd_dev) in rbd_dev_parent_get() argument
1618 if (!rbd_dev->parent_spec) 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()
1625 rbd_warn(rbd_dev, "parent reference overflow"); in rbd_dev_parent_get()
1631 struct rbd_device *rbd_dev, in rbd_img_request_init() argument
1636 img_request->rbd_dev = rbd_dev; in rbd_img_request_init()
1646 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_img_capture_header() local
1648 lockdep_assert_held(&rbd_dev->header_rwsem); in rbd_img_capture_header()
1651 img_req->snapc = ceph_get_snap_context(rbd_dev->header.snapc); in rbd_img_capture_header()
1653 img_req->snap_id = rbd_dev->spec->snap_id; in rbd_img_capture_header()
1655 if (rbd_dev_parent_get(rbd_dev)) in rbd_img_capture_header()
1671 rbd_dev_parent_put(img_request->rbd_dev); in rbd_img_request_destroy()
1684 static void __rbd_object_map_index(struct rbd_device *rbd_dev, u64 objno, in __rbd_object_map_index() argument
1689 rbd_assert(objno < rbd_dev->object_map_size); in __rbd_object_map_index()
1694 static u8 __rbd_object_map_get(struct rbd_device *rbd_dev, u64 objno) in __rbd_object_map_get() argument
1699 lockdep_assert_held(&rbd_dev->object_map_lock); in __rbd_object_map_get()
1700 __rbd_object_map_index(rbd_dev, objno, &index, &shift); in __rbd_object_map_get()
1701 return (rbd_dev->object_map[index] >> shift) & OBJ_MASK; in __rbd_object_map_get()
1704 static void __rbd_object_map_set(struct rbd_device *rbd_dev, u64 objno, u8 val) in __rbd_object_map_set() argument
1710 lockdep_assert_held(&rbd_dev->object_map_lock); in __rbd_object_map_set()
1713 __rbd_object_map_index(rbd_dev, objno, &index, &shift); in __rbd_object_map_set()
1714 p = &rbd_dev->object_map[index]; in __rbd_object_map_set()
1718 static u8 rbd_object_map_get(struct rbd_device *rbd_dev, u64 objno) in rbd_object_map_get() argument
1722 spin_lock(&rbd_dev->object_map_lock); in rbd_object_map_get()
1723 state = __rbd_object_map_get(rbd_dev, objno); in rbd_object_map_get()
1724 spin_unlock(&rbd_dev->object_map_lock); in rbd_object_map_get()
1728 static bool use_object_map(struct rbd_device *rbd_dev) in use_object_map() argument
1738 if (!rbd_is_snap(rbd_dev) && rbd_is_ro(rbd_dev)) in use_object_map()
1741 return ((rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP) && in use_object_map()
1742 !(rbd_dev->object_map_flags & RBD_FLAG_OBJECT_MAP_INVALID)); in use_object_map()
1745 static bool rbd_object_map_may_exist(struct rbd_device *rbd_dev, u64 objno) in rbd_object_map_may_exist() argument
1750 if (!use_object_map(rbd_dev)) in rbd_object_map_may_exist()
1753 state = rbd_object_map_get(rbd_dev, objno); in rbd_object_map_may_exist()
1757 static void rbd_object_map_name(struct rbd_device *rbd_dev, u64 snap_id, in rbd_object_map_name() argument
1762 rbd_dev->spec->image_id); in rbd_object_map_name()
1765 rbd_dev->spec->image_id, snap_id); in rbd_object_map_name()
1768 static int rbd_object_map_lock(struct rbd_device *rbd_dev) in rbd_object_map_lock() argument
1770 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_object_map_lock()
1779 rbd_object_map_name(rbd_dev, CEPH_NOSNAP, &oid); in rbd_object_map_lock()
1782 ret = ceph_cls_lock(osdc, &oid, &rbd_dev->header_oloc, RBD_LOCK_NAME, in rbd_object_map_lock()
1788 rbd_warn(rbd_dev, "failed to lock object map: %d", ret); in rbd_object_map_lock()
1792 ret = ceph_cls_lock_info(osdc, &oid, &rbd_dev->header_oloc, in rbd_object_map_lock()
1799 rbd_warn(rbd_dev, "failed to get object map lockers: %d", ret); in rbd_object_map_lock()
1807 rbd_warn(rbd_dev, "breaking object map lock owned by %s%llu", in rbd_object_map_lock()
1810 ret = ceph_cls_break_lock(osdc, &oid, &rbd_dev->header_oloc, in rbd_object_map_lock()
1818 rbd_warn(rbd_dev, "failed to break object map lock: %d", ret); in rbd_object_map_lock()
1826 static void rbd_object_map_unlock(struct rbd_device *rbd_dev) in rbd_object_map_unlock() argument
1828 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_object_map_unlock()
1832 rbd_object_map_name(rbd_dev, CEPH_NOSNAP, &oid); in rbd_object_map_unlock()
1834 ret = ceph_cls_unlock(osdc, &oid, &rbd_dev->header_oloc, RBD_LOCK_NAME, in rbd_object_map_unlock()
1837 rbd_warn(rbd_dev, "failed to unlock object map: %d", ret); in rbd_object_map_unlock()
1865 static int __rbd_object_map_load(struct rbd_device *rbd_dev) in __rbd_object_map_load() argument
1867 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_object_map_load()
1878 rbd_assert(!rbd_dev->object_map && !rbd_dev->object_map_size); in __rbd_object_map_load()
1880 num_objects = ceph_get_num_objects(&rbd_dev->layout, in __rbd_object_map_load()
1881 rbd_dev->mapping.size); in __rbd_object_map_load()
1890 rbd_object_map_name(rbd_dev, rbd_dev->spec->snap_id, &oid); in __rbd_object_map_load()
1891 ret = ceph_osdc_call(osdc, &oid, &rbd_dev->header_oloc, in __rbd_object_map_load()
1904 rbd_warn(rbd_dev, "object map size mismatch: %llu vs %llu", in __rbd_object_map_load()
1915 rbd_dev->object_map = kvmalloc(object_map_bytes, GFP_KERNEL); in __rbd_object_map_load()
1916 if (!rbd_dev->object_map) { in __rbd_object_map_load()
1921 rbd_dev->object_map_size = object_map_size; in __rbd_object_map_load()
1922 ceph_copy_from_page_vector(pages, rbd_dev->object_map, in __rbd_object_map_load()
1930 static void rbd_object_map_free(struct rbd_device *rbd_dev) in rbd_object_map_free() argument
1932 kvfree(rbd_dev->object_map); in rbd_object_map_free()
1933 rbd_dev->object_map = NULL; in rbd_object_map_free()
1934 rbd_dev->object_map_size = 0; in rbd_object_map_free()
1937 static int rbd_object_map_load(struct rbd_device *rbd_dev) in rbd_object_map_load() argument
1941 ret = __rbd_object_map_load(rbd_dev); in rbd_object_map_load()
1945 ret = rbd_dev_v2_get_flags(rbd_dev); in rbd_object_map_load()
1947 rbd_object_map_free(rbd_dev); in rbd_object_map_load()
1951 if (rbd_dev->object_map_flags & RBD_FLAG_OBJECT_MAP_INVALID) in rbd_object_map_load()
1952 rbd_warn(rbd_dev, "object map is invalid"); in rbd_object_map_load()
1957 static int rbd_object_map_open(struct rbd_device *rbd_dev) in rbd_object_map_open() argument
1961 ret = rbd_object_map_lock(rbd_dev); in rbd_object_map_open()
1965 ret = rbd_object_map_load(rbd_dev); in rbd_object_map_open()
1967 rbd_object_map_unlock(rbd_dev); in rbd_object_map_open()
1974 static void rbd_object_map_close(struct rbd_device *rbd_dev) in rbd_object_map_close() argument
1976 rbd_object_map_free(rbd_dev); in rbd_object_map_close()
1977 rbd_object_map_unlock(rbd_dev); in rbd_object_map_close()
1993 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_object_map_update_finish() local
2025 spin_lock(&rbd_dev->object_map_lock); in rbd_object_map_update_finish()
2026 state = __rbd_object_map_get(rbd_dev, objno); in rbd_object_map_update_finish()
2029 __rbd_object_map_set(rbd_dev, objno, new_state); in rbd_object_map_update_finish()
2030 spin_unlock(&rbd_dev->object_map_lock); in rbd_object_map_update_finish()
2047 static bool update_needed(struct rbd_device *rbd_dev, u64 objno, u8 new_state) in update_needed() argument
2049 u8 state = rbd_object_map_get(rbd_dev, objno); in update_needed()
2100 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_object_map_update() local
2101 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_object_map_update()
2108 if (!update_needed(rbd_dev, obj_req->ex.oe_objno, new_state)) in rbd_object_map_update()
2122 rbd_object_map_name(rbd_dev, snap_id, &req->r_base_oid); in rbd_object_map_update()
2123 ceph_oloc_copy(&req->r_base_oloc, &rbd_dev->header_oloc); in rbd_object_map_update()
2178 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_calc_img_extents() local
2181 if (!rbd_dev->parent_overlap) in rbd_obj_calc_img_extents()
2184 ret = ceph_extent_to_file(&rbd_dev->layout, obj_req->ex.oe_objno, in rbd_obj_calc_img_extents()
2186 entire ? rbd_dev->layout.object_size : in rbd_obj_calc_img_extents()
2194 rbd_dev->parent_overlap); in rbd_obj_calc_img_extents()
2269 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in __rbd_osd_setup_write_ops() local
2272 if (!use_object_map(rbd_dev) || in __rbd_osd_setup_write_ops()
2275 rbd_dev->layout.object_size, in __rbd_osd_setup_write_ops()
2276 rbd_dev->layout.object_size, in __rbd_osd_setup_write_ops()
2277 rbd_dev->opts->alloc_hint_flags); in __rbd_osd_setup_write_ops()
2330 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_init_discard() local
2342 if (rbd_dev->opts->alloc_size != rbd_dev->layout.object_size || in rbd_obj_init_discard()
2344 off = round_up(obj_req->ex.oe_off, rbd_dev->opts->alloc_size); in rbd_obj_init_discard()
2346 rbd_dev->opts->alloc_size); in rbd_obj_init_discard()
2425 if (!use_object_map(img_req->rbd_dev) || in count_write_ops()
2557 ret = ceph_file_to_extents(&img_req->rbd_dev->layout, in rbd_img_fill_request_nocopy()
2588 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_img_fill_request() local
2594 !rbd_layout_is_fancy(&rbd_dev->layout)) in rbd_img_fill_request()
2609 ret = ceph_file_to_extents(&rbd_dev->layout, in rbd_img_fill_request()
2633 ret = ceph_iterate_extents(&rbd_dev->layout, in rbd_img_fill_request()
2804 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_may_exist() local
2806 if (rbd_object_map_may_exist(rbd_dev, obj_req->ex.oe_objno)) { in rbd_obj_may_exist()
2841 struct rbd_device *parent = img_req->rbd_dev->parent; in rbd_obj_read_from_parent()
2896 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_advance_read() local
2918 if (*result == -ENOENT && rbd_dev->parent_overlap) { in rbd_obj_advance_read()
2973 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_write_is_noop() local
2975 if (rbd_object_map_may_exist(rbd_dev, obj_req->ex.oe_objno)) in rbd_obj_write_is_noop()
2995 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_write_pre_object_map() local
2998 if (!(rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) in rbd_obj_write_pre_object_map()
3156 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_copyup_read_parent() local
3161 rbd_dev->parent_overlap); in rbd_obj_copyup_read_parent()
3181 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_copyup_object_maps() local
3189 if (!(rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) in rbd_obj_copyup_object_maps()
3196 if ((rbd_dev->header.features & RBD_FEATURE_FAST_DIFF) && in rbd_obj_copyup_object_maps()
3257 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_advance_copyup() local
3299 rbd_warn(rbd_dev, "snap object map update failed: %d", in rbd_obj_advance_copyup()
3331 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_write_post_object_map() local
3334 if (!(rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) in rbd_obj_write_post_object_map()
3346 struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; in rbd_obj_advance_write() local
3368 rbd_warn(rbd_dev, "pre object map update failed: %d", in rbd_obj_advance_write()
3405 rbd_warn(rbd_dev, "copyup failed: %d", *result); in rbd_obj_advance_write()
3419 rbd_warn(rbd_dev, "post object map update failed: %d", in rbd_obj_advance_write()
3434 struct rbd_device *rbd_dev = img_req->rbd_dev; in __rbd_obj_handle_request() local
3446 rbd_warn(rbd_dev, "%s at objno %llu %llu~%llu result %d", in __rbd_obj_handle_request()
3465 struct rbd_device *rbd_dev = img_req->rbd_dev; in need_exclusive_lock() local
3467 if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK)) in need_exclusive_lock()
3470 if (rbd_is_ro(rbd_dev)) in need_exclusive_lock()
3474 if (rbd_dev->opts->lock_on_read || in need_exclusive_lock()
3475 (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) in need_exclusive_lock()
3483 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_lock_add_request() local
3486 lockdep_assert_held(&rbd_dev->lock_rwsem); in rbd_lock_add_request()
3487 locked = rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED; in rbd_lock_add_request()
3488 spin_lock(&rbd_dev->lock_lists_lock); in rbd_lock_add_request()
3491 list_add_tail(&img_req->lock_item, &rbd_dev->acquiring_list); in rbd_lock_add_request()
3493 list_add_tail(&img_req->lock_item, &rbd_dev->running_list); in rbd_lock_add_request()
3494 spin_unlock(&rbd_dev->lock_lists_lock); in rbd_lock_add_request()
3500 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_lock_del_request() local
3503 lockdep_assert_held(&rbd_dev->lock_rwsem); in rbd_lock_del_request()
3504 spin_lock(&rbd_dev->lock_lists_lock); in rbd_lock_del_request()
3507 need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING && in rbd_lock_del_request()
3508 list_empty(&rbd_dev->running_list)); in rbd_lock_del_request()
3509 spin_unlock(&rbd_dev->lock_lists_lock); in rbd_lock_del_request()
3511 complete(&rbd_dev->releasing_wait); in rbd_lock_del_request()
3516 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_img_exclusive_lock() local
3524 if (rbd_dev->opts->exclusive) { in rbd_img_exclusive_lock()
3533 dout("%s rbd_dev %p queueing lock_dwork\n", __func__, rbd_dev); in rbd_img_exclusive_lock()
3534 queue_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); in rbd_img_exclusive_lock()
3560 struct rbd_device *rbd_dev = img_req->rbd_dev; in rbd_img_advance() local
3582 __rbd_is_lock_owner(rbd_dev)); in rbd_img_advance()
3609 struct rbd_device *rbd_dev = img_req->rbd_dev; in __rbd_img_handle_request() local
3613 down_read(&rbd_dev->lock_rwsem); in __rbd_img_handle_request()
3619 up_read(&rbd_dev->lock_rwsem); in __rbd_img_handle_request()
3628 rbd_warn(rbd_dev, "%s%s result %d", in __rbd_img_handle_request()
3665 static struct rbd_client_id rbd_get_cid(struct rbd_device *rbd_dev) in rbd_get_cid() argument
3669 mutex_lock(&rbd_dev->watch_mutex); in rbd_get_cid()
3670 cid.gid = ceph_client_gid(rbd_dev->rbd_client->client); in rbd_get_cid()
3671 cid.handle = rbd_dev->watch_cookie; in rbd_get_cid()
3672 mutex_unlock(&rbd_dev->watch_mutex); in rbd_get_cid()
3679 static void rbd_set_owner_cid(struct rbd_device *rbd_dev, in rbd_set_owner_cid() argument
3682 dout("%s rbd_dev %p %llu-%llu -> %llu-%llu\n", __func__, rbd_dev, in rbd_set_owner_cid()
3683 rbd_dev->owner_cid.gid, rbd_dev->owner_cid.handle, in rbd_set_owner_cid()
3685 rbd_dev->owner_cid = *cid; /* struct */ in rbd_set_owner_cid()
3688 static void format_lock_cookie(struct rbd_device *rbd_dev, char *buf) in format_lock_cookie() argument
3690 mutex_lock(&rbd_dev->watch_mutex); in format_lock_cookie()
3691 sprintf(buf, "%s %llu", RBD_LOCK_COOKIE_PREFIX, rbd_dev->watch_cookie); in format_lock_cookie()
3692 mutex_unlock(&rbd_dev->watch_mutex); in format_lock_cookie()
3695 static void __rbd_lock(struct rbd_device *rbd_dev, const char *cookie) in __rbd_lock() argument
3697 struct rbd_client_id cid = rbd_get_cid(rbd_dev); in __rbd_lock()
3699 rbd_dev->lock_state = RBD_LOCK_STATE_LOCKED; in __rbd_lock()
3700 strcpy(rbd_dev->lock_cookie, cookie); in __rbd_lock()
3701 rbd_set_owner_cid(rbd_dev, &cid); in __rbd_lock()
3702 queue_work(rbd_dev->task_wq, &rbd_dev->acquired_lock_work); in __rbd_lock()
3708 static int rbd_lock(struct rbd_device *rbd_dev) in rbd_lock() argument
3710 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_lock()
3714 WARN_ON(__rbd_is_lock_owner(rbd_dev) || in rbd_lock()
3715 rbd_dev->lock_cookie[0] != '\0'); in rbd_lock()
3717 format_lock_cookie(rbd_dev, cookie); in rbd_lock()
3718 ret = ceph_cls_lock(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in rbd_lock()
3724 __rbd_lock(rbd_dev, cookie); in rbd_lock()
3731 static void rbd_unlock(struct rbd_device *rbd_dev) in rbd_unlock() argument
3733 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_unlock()
3736 WARN_ON(!__rbd_is_lock_owner(rbd_dev) || in rbd_unlock()
3737 rbd_dev->lock_cookie[0] == '\0'); in rbd_unlock()
3739 ret = ceph_cls_unlock(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in rbd_unlock()
3740 RBD_LOCK_NAME, rbd_dev->lock_cookie); in rbd_unlock()
3742 rbd_warn(rbd_dev, "failed to unlock header: %d", ret); in rbd_unlock()
3745 rbd_dev->lock_state = RBD_LOCK_STATE_UNLOCKED; in rbd_unlock()
3746 rbd_dev->lock_cookie[0] = '\0'; in rbd_unlock()
3747 rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); in rbd_unlock()
3748 queue_work(rbd_dev->task_wq, &rbd_dev->released_lock_work); in rbd_unlock()
3751 static int __rbd_notify_op_lock(struct rbd_device *rbd_dev, in __rbd_notify_op_lock() argument
3756 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_notify_op_lock()
3757 struct rbd_client_id cid = rbd_get_cid(rbd_dev); in __rbd_notify_op_lock()
3762 dout("%s rbd_dev %p notify_op %d\n", __func__, rbd_dev, notify_op); in __rbd_notify_op_lock()
3770 return ceph_osdc_notify(osdc, &rbd_dev->header_oid, in __rbd_notify_op_lock()
3771 &rbd_dev->header_oloc, buf, buf_size, in __rbd_notify_op_lock()
3775 static void rbd_notify_op_lock(struct rbd_device *rbd_dev, in rbd_notify_op_lock() argument
3778 __rbd_notify_op_lock(rbd_dev, notify_op, NULL, NULL); in rbd_notify_op_lock()
3783 struct rbd_device *rbd_dev = container_of(work, struct rbd_device, in rbd_notify_acquired_lock() local
3786 rbd_notify_op_lock(rbd_dev, RBD_NOTIFY_OP_ACQUIRED_LOCK); in rbd_notify_acquired_lock()
3791 struct rbd_device *rbd_dev = container_of(work, struct rbd_device, in rbd_notify_released_lock() local
3794 rbd_notify_op_lock(rbd_dev, RBD_NOTIFY_OP_RELEASED_LOCK); in rbd_notify_released_lock()
3797 static int rbd_request_lock(struct rbd_device *rbd_dev) in rbd_request_lock() argument
3804 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_request_lock()
3806 ret = __rbd_notify_op_lock(rbd_dev, RBD_NOTIFY_OP_REQUEST_LOCK, in rbd_request_lock()
3809 rbd_warn(rbd_dev, "failed to request lock: %d", ret); in rbd_request_lock()
3831 rbd_warn(rbd_dev, in rbd_request_lock()
3841 rbd_warn(rbd_dev, in rbd_request_lock()
3852 rbd_warn(rbd_dev, "no lock owners detected"); in rbd_request_lock()
3869 static void wake_lock_waiters(struct rbd_device *rbd_dev, int result) in wake_lock_waiters() argument
3873 dout("%s rbd_dev %p result %d\n", __func__, rbd_dev, result); in wake_lock_waiters()
3874 lockdep_assert_held_write(&rbd_dev->lock_rwsem); in wake_lock_waiters()
3876 cancel_delayed_work(&rbd_dev->lock_dwork); in wake_lock_waiters()
3877 if (!completion_done(&rbd_dev->acquire_wait)) { in wake_lock_waiters()
3878 rbd_assert(list_empty(&rbd_dev->acquiring_list) && in wake_lock_waiters()
3879 list_empty(&rbd_dev->running_list)); in wake_lock_waiters()
3880 rbd_dev->acquire_err = result; in wake_lock_waiters()
3881 complete_all(&rbd_dev->acquire_wait); in wake_lock_waiters()
3885 list_for_each_entry(img_req, &rbd_dev->acquiring_list, lock_item) { in wake_lock_waiters()
3892 list_splice_tail_init(&rbd_dev->acquiring_list, &rbd_dev->running_list); in wake_lock_waiters()
3895 static int get_lock_owner_info(struct rbd_device *rbd_dev, in get_lock_owner_info() argument
3898 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in get_lock_owner_info()
3903 dout("%s rbd_dev %p\n", __func__, rbd_dev); in get_lock_owner_info()
3905 ret = ceph_cls_lock_info(osdc, &rbd_dev->header_oid, in get_lock_owner_info()
3906 &rbd_dev->header_oloc, RBD_LOCK_NAME, in get_lock_owner_info()
3912 dout("%s rbd_dev %p no lockers detected\n", __func__, rbd_dev); in get_lock_owner_info()
3917 rbd_warn(rbd_dev, "locked by external mechanism, tag %s", in get_lock_owner_info()
3924 rbd_warn(rbd_dev, "shared lock type detected"); in get_lock_owner_info()
3931 rbd_warn(rbd_dev, "locked by external mechanism, cookie %s", in get_lock_owner_info()
3942 static int find_watcher(struct rbd_device *rbd_dev, in find_watcher() argument
3945 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in find_watcher()
3952 ret = ceph_osdc_list_watchers(osdc, &rbd_dev->header_oid, in find_watcher()
3953 &rbd_dev->header_oloc, &watchers, in find_watcher()
3969 rbd_dev, cid.gid, cid.handle); in find_watcher()
3970 rbd_set_owner_cid(rbd_dev, &cid); in find_watcher()
3976 dout("%s rbd_dev %p no watchers\n", __func__, rbd_dev); in find_watcher()
3986 static int rbd_try_lock(struct rbd_device *rbd_dev) in rbd_try_lock() argument
3988 struct ceph_client *client = rbd_dev->rbd_client->client; in rbd_try_lock()
3994 ret = rbd_lock(rbd_dev); in rbd_try_lock()
3999 ret = get_lock_owner_info(rbd_dev, &lockers, &num_lockers); in rbd_try_lock()
4006 ret = find_watcher(rbd_dev, lockers); in rbd_try_lock()
4010 rbd_warn(rbd_dev, "breaking header lock owned by %s%llu", in rbd_try_lock()
4016 rbd_warn(rbd_dev, "blocklist of %s%llu failed: %d", in rbd_try_lock()
4021 ret = ceph_cls_break_lock(&client->osdc, &rbd_dev->header_oid, in rbd_try_lock()
4022 &rbd_dev->header_oloc, RBD_LOCK_NAME, in rbd_try_lock()
4037 static int rbd_post_acquire_action(struct rbd_device *rbd_dev) in rbd_post_acquire_action() argument
4041 if (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP) { in rbd_post_acquire_action()
4042 ret = rbd_object_map_open(rbd_dev); in rbd_post_acquire_action()
4056 static int rbd_try_acquire_lock(struct rbd_device *rbd_dev) in rbd_try_acquire_lock() argument
4060 down_read(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4061 dout("%s rbd_dev %p read lock_state %d\n", __func__, rbd_dev, in rbd_try_acquire_lock()
4062 rbd_dev->lock_state); in rbd_try_acquire_lock()
4063 if (__rbd_is_lock_owner(rbd_dev)) { in rbd_try_acquire_lock()
4064 up_read(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4068 up_read(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4069 down_write(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4070 dout("%s rbd_dev %p write lock_state %d\n", __func__, rbd_dev, in rbd_try_acquire_lock()
4071 rbd_dev->lock_state); in rbd_try_acquire_lock()
4072 if (__rbd_is_lock_owner(rbd_dev)) { in rbd_try_acquire_lock()
4073 up_write(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4077 ret = rbd_try_lock(rbd_dev); in rbd_try_acquire_lock()
4079 rbd_warn(rbd_dev, "failed to lock header: %d", ret); in rbd_try_acquire_lock()
4086 up_write(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4090 rbd_assert(rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED); in rbd_try_acquire_lock()
4091 rbd_assert(list_empty(&rbd_dev->running_list)); in rbd_try_acquire_lock()
4093 ret = rbd_post_acquire_action(rbd_dev); in rbd_try_acquire_lock()
4095 rbd_warn(rbd_dev, "post-acquire action failed: %d", ret); in rbd_try_acquire_lock()
4101 rbd_unlock(rbd_dev); in rbd_try_acquire_lock()
4105 wake_lock_waiters(rbd_dev, ret); in rbd_try_acquire_lock()
4106 up_write(&rbd_dev->lock_rwsem); in rbd_try_acquire_lock()
4112 struct rbd_device *rbd_dev = container_of(to_delayed_work(work), in rbd_acquire_lock() local
4116 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_acquire_lock()
4118 ret = rbd_try_acquire_lock(rbd_dev); in rbd_acquire_lock()
4120 dout("%s rbd_dev %p ret %d - done\n", __func__, rbd_dev, ret); in rbd_acquire_lock()
4124 ret = rbd_request_lock(rbd_dev); in rbd_acquire_lock()
4128 rbd_warn(rbd_dev, "peer will not release lock"); in rbd_acquire_lock()
4129 down_write(&rbd_dev->lock_rwsem); in rbd_acquire_lock()
4130 wake_lock_waiters(rbd_dev, ret); in rbd_acquire_lock()
4131 up_write(&rbd_dev->lock_rwsem); in rbd_acquire_lock()
4133 rbd_warn(rbd_dev, "error requesting lock: %d", ret); in rbd_acquire_lock()
4134 mod_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, in rbd_acquire_lock()
4142 rbd_dev); in rbd_acquire_lock()
4143 mod_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, in rbd_acquire_lock()
4148 static bool rbd_quiesce_lock(struct rbd_device *rbd_dev) in rbd_quiesce_lock() argument
4152 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_quiesce_lock()
4153 lockdep_assert_held_write(&rbd_dev->lock_rwsem); in rbd_quiesce_lock()
4155 if (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED) in rbd_quiesce_lock()
4161 rbd_dev->lock_state = RBD_LOCK_STATE_RELEASING; in rbd_quiesce_lock()
4162 rbd_assert(!completion_done(&rbd_dev->releasing_wait)); in rbd_quiesce_lock()
4163 need_wait = !list_empty(&rbd_dev->running_list); in rbd_quiesce_lock()
4164 downgrade_write(&rbd_dev->lock_rwsem); in rbd_quiesce_lock()
4166 wait_for_completion(&rbd_dev->releasing_wait); in rbd_quiesce_lock()
4167 up_read(&rbd_dev->lock_rwsem); in rbd_quiesce_lock()
4169 down_write(&rbd_dev->lock_rwsem); in rbd_quiesce_lock()
4170 if (rbd_dev->lock_state != RBD_LOCK_STATE_RELEASING) in rbd_quiesce_lock()
4173 rbd_assert(list_empty(&rbd_dev->running_list)); in rbd_quiesce_lock()
4177 static void rbd_pre_release_action(struct rbd_device *rbd_dev) in rbd_pre_release_action() argument
4179 if (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP) in rbd_pre_release_action()
4180 rbd_object_map_close(rbd_dev); in rbd_pre_release_action()
4183 static void __rbd_release_lock(struct rbd_device *rbd_dev) in __rbd_release_lock() argument
4185 rbd_assert(list_empty(&rbd_dev->running_list)); in __rbd_release_lock()
4187 rbd_pre_release_action(rbd_dev); in __rbd_release_lock()
4188 rbd_unlock(rbd_dev); in __rbd_release_lock()
4194 static void rbd_release_lock(struct rbd_device *rbd_dev) in rbd_release_lock() argument
4196 if (!rbd_quiesce_lock(rbd_dev)) in rbd_release_lock()
4199 __rbd_release_lock(rbd_dev); in rbd_release_lock()
4208 cancel_delayed_work(&rbd_dev->lock_dwork); in rbd_release_lock()
4213 struct rbd_device *rbd_dev = container_of(work, struct rbd_device, in rbd_release_lock_work() local
4216 down_write(&rbd_dev->lock_rwsem); in rbd_release_lock_work()
4217 rbd_release_lock(rbd_dev); in rbd_release_lock_work()
4218 up_write(&rbd_dev->lock_rwsem); in rbd_release_lock_work()
4221 static void maybe_kick_acquire(struct rbd_device *rbd_dev) in maybe_kick_acquire() argument
4225 dout("%s rbd_dev %p\n", __func__, rbd_dev); in maybe_kick_acquire()
4226 if (__rbd_is_lock_owner(rbd_dev)) in maybe_kick_acquire()
4229 spin_lock(&rbd_dev->lock_lists_lock); in maybe_kick_acquire()
4230 have_requests = !list_empty(&rbd_dev->acquiring_list); in maybe_kick_acquire()
4231 spin_unlock(&rbd_dev->lock_lists_lock); in maybe_kick_acquire()
4232 if (have_requests || delayed_work_pending(&rbd_dev->lock_dwork)) { in maybe_kick_acquire()
4233 dout("%s rbd_dev %p kicking lock_dwork\n", __func__, rbd_dev); in maybe_kick_acquire()
4234 mod_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); in maybe_kick_acquire()
4238 static void rbd_handle_acquired_lock(struct rbd_device *rbd_dev, u8 struct_v, in rbd_handle_acquired_lock() argument
4248 dout("%s rbd_dev %p cid %llu-%llu\n", __func__, rbd_dev, cid.gid, in rbd_handle_acquired_lock()
4251 down_write(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
4252 if (rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { in rbd_handle_acquired_lock()
4257 up_write(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
4261 rbd_set_owner_cid(rbd_dev, &cid); in rbd_handle_acquired_lock()
4262 downgrade_write(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
4264 down_read(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
4267 maybe_kick_acquire(rbd_dev); in rbd_handle_acquired_lock()
4268 up_read(&rbd_dev->lock_rwsem); in rbd_handle_acquired_lock()
4271 static void rbd_handle_released_lock(struct rbd_device *rbd_dev, u8 struct_v, in rbd_handle_released_lock() argument
4281 dout("%s rbd_dev %p cid %llu-%llu\n", __func__, rbd_dev, cid.gid, in rbd_handle_released_lock()
4284 down_write(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
4285 if (!rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { in rbd_handle_released_lock()
4287 __func__, rbd_dev, cid.gid, cid.handle, in rbd_handle_released_lock()
4288 rbd_dev->owner_cid.gid, rbd_dev->owner_cid.handle); in rbd_handle_released_lock()
4289 up_write(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
4293 rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); in rbd_handle_released_lock()
4294 downgrade_write(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
4296 down_read(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
4299 maybe_kick_acquire(rbd_dev); in rbd_handle_released_lock()
4300 up_read(&rbd_dev->lock_rwsem); in rbd_handle_released_lock()
4307 static int rbd_handle_request_lock(struct rbd_device *rbd_dev, u8 struct_v, in rbd_handle_request_lock() argument
4310 struct rbd_client_id my_cid = rbd_get_cid(rbd_dev); in rbd_handle_request_lock()
4319 dout("%s rbd_dev %p cid %llu-%llu\n", __func__, rbd_dev, cid.gid, in rbd_handle_request_lock()
4324 down_read(&rbd_dev->lock_rwsem); in rbd_handle_request_lock()
4325 if (__rbd_is_lock_owner(rbd_dev)) { in rbd_handle_request_lock()
4326 if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED && in rbd_handle_request_lock()
4327 rbd_cid_equal(&rbd_dev->owner_cid, &rbd_empty_cid)) in rbd_handle_request_lock()
4336 if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED) { in rbd_handle_request_lock()
4337 if (!rbd_dev->opts->exclusive) { in rbd_handle_request_lock()
4339 __func__, rbd_dev); in rbd_handle_request_lock()
4340 queue_work(rbd_dev->task_wq, in rbd_handle_request_lock()
4341 &rbd_dev->unlock_work); in rbd_handle_request_lock()
4350 up_read(&rbd_dev->lock_rwsem); in rbd_handle_request_lock()
4354 static void __rbd_acknowledge_notify(struct rbd_device *rbd_dev, in __rbd_acknowledge_notify() argument
4357 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_acknowledge_notify()
4373 ret = ceph_osdc_notify_ack(osdc, &rbd_dev->header_oid, in __rbd_acknowledge_notify()
4374 &rbd_dev->header_oloc, notify_id, cookie, in __rbd_acknowledge_notify()
4377 rbd_warn(rbd_dev, "acknowledge_notify failed: %d", ret); in __rbd_acknowledge_notify()
4380 static void rbd_acknowledge_notify(struct rbd_device *rbd_dev, u64 notify_id, in rbd_acknowledge_notify() argument
4383 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_acknowledge_notify()
4384 __rbd_acknowledge_notify(rbd_dev, notify_id, cookie, NULL); in rbd_acknowledge_notify()
4387 static void rbd_acknowledge_notify_result(struct rbd_device *rbd_dev, in rbd_acknowledge_notify_result() argument
4390 dout("%s rbd_dev %p result %d\n", __func__, rbd_dev, result); in rbd_acknowledge_notify_result()
4391 __rbd_acknowledge_notify(rbd_dev, notify_id, cookie, &result); in rbd_acknowledge_notify_result()
4397 struct rbd_device *rbd_dev = arg; in rbd_watch_cb() local
4406 __func__, rbd_dev, cookie, notify_id, data_len); in rbd_watch_cb()
4411 rbd_warn(rbd_dev, "failed to decode NotifyMessage: %d", in rbd_watch_cb()
4423 dout("%s rbd_dev %p notify_op %u\n", __func__, rbd_dev, notify_op); in rbd_watch_cb()
4426 rbd_handle_acquired_lock(rbd_dev, struct_v, &p); in rbd_watch_cb()
4427 rbd_acknowledge_notify(rbd_dev, notify_id, cookie); in rbd_watch_cb()
4430 rbd_handle_released_lock(rbd_dev, struct_v, &p); in rbd_watch_cb()
4431 rbd_acknowledge_notify(rbd_dev, notify_id, cookie); in rbd_watch_cb()
4434 ret = rbd_handle_request_lock(rbd_dev, struct_v, &p); in rbd_watch_cb()
4436 rbd_acknowledge_notify_result(rbd_dev, notify_id, in rbd_watch_cb()
4439 rbd_acknowledge_notify(rbd_dev, notify_id, cookie); in rbd_watch_cb()
4442 ret = rbd_dev_refresh(rbd_dev); in rbd_watch_cb()
4444 rbd_warn(rbd_dev, "refresh failed: %d", ret); in rbd_watch_cb()
4446 rbd_acknowledge_notify(rbd_dev, notify_id, cookie); in rbd_watch_cb()
4449 if (rbd_is_lock_owner(rbd_dev)) in rbd_watch_cb()
4450 rbd_acknowledge_notify_result(rbd_dev, notify_id, in rbd_watch_cb()
4453 rbd_acknowledge_notify(rbd_dev, notify_id, cookie); in rbd_watch_cb()
4458 static void __rbd_unregister_watch(struct rbd_device *rbd_dev);
4462 struct rbd_device *rbd_dev = arg; in rbd_watch_errcb() local
4464 rbd_warn(rbd_dev, "encountered watch error: %d", err); in rbd_watch_errcb()
4466 down_write(&rbd_dev->lock_rwsem); in rbd_watch_errcb()
4467 rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); in rbd_watch_errcb()
4468 up_write(&rbd_dev->lock_rwsem); in rbd_watch_errcb()
4470 mutex_lock(&rbd_dev->watch_mutex); in rbd_watch_errcb()
4471 if (rbd_dev->watch_state == RBD_WATCH_STATE_REGISTERED) { in rbd_watch_errcb()
4472 __rbd_unregister_watch(rbd_dev); in rbd_watch_errcb()
4473 rbd_dev->watch_state = RBD_WATCH_STATE_ERROR; in rbd_watch_errcb()
4475 queue_delayed_work(rbd_dev->task_wq, &rbd_dev->watch_dwork, 0); in rbd_watch_errcb()
4477 mutex_unlock(&rbd_dev->watch_mutex); in rbd_watch_errcb()
4483 static int __rbd_register_watch(struct rbd_device *rbd_dev) in __rbd_register_watch() argument
4485 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_register_watch()
4488 rbd_assert(!rbd_dev->watch_handle); in __rbd_register_watch()
4489 dout("%s rbd_dev %p\n", __func__, rbd_dev); in __rbd_register_watch()
4491 handle = ceph_osdc_watch(osdc, &rbd_dev->header_oid, in __rbd_register_watch()
4492 &rbd_dev->header_oloc, rbd_watch_cb, in __rbd_register_watch()
4493 rbd_watch_errcb, rbd_dev); in __rbd_register_watch()
4497 rbd_dev->watch_handle = handle; in __rbd_register_watch()
4504 static void __rbd_unregister_watch(struct rbd_device *rbd_dev) in __rbd_unregister_watch() argument
4506 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __rbd_unregister_watch()
4509 rbd_assert(rbd_dev->watch_handle); in __rbd_unregister_watch()
4510 dout("%s rbd_dev %p\n", __func__, rbd_dev); in __rbd_unregister_watch()
4512 ret = ceph_osdc_unwatch(osdc, rbd_dev->watch_handle); in __rbd_unregister_watch()
4514 rbd_warn(rbd_dev, "failed to unwatch: %d", ret); in __rbd_unregister_watch()
4516 rbd_dev->watch_handle = NULL; in __rbd_unregister_watch()
4519 static int rbd_register_watch(struct rbd_device *rbd_dev) in rbd_register_watch() argument
4523 mutex_lock(&rbd_dev->watch_mutex); in rbd_register_watch()
4524 rbd_assert(rbd_dev->watch_state == RBD_WATCH_STATE_UNREGISTERED); in rbd_register_watch()
4525 ret = __rbd_register_watch(rbd_dev); in rbd_register_watch()
4529 rbd_dev->watch_state = RBD_WATCH_STATE_REGISTERED; in rbd_register_watch()
4530 rbd_dev->watch_cookie = rbd_dev->watch_handle->linger_id; in rbd_register_watch()
4533 mutex_unlock(&rbd_dev->watch_mutex); in rbd_register_watch()
4537 static void cancel_tasks_sync(struct rbd_device *rbd_dev) in cancel_tasks_sync() argument
4539 dout("%s rbd_dev %p\n", __func__, rbd_dev); in cancel_tasks_sync()
4541 cancel_work_sync(&rbd_dev->acquired_lock_work); in cancel_tasks_sync()
4542 cancel_work_sync(&rbd_dev->released_lock_work); in cancel_tasks_sync()
4543 cancel_delayed_work_sync(&rbd_dev->lock_dwork); in cancel_tasks_sync()
4544 cancel_work_sync(&rbd_dev->unlock_work); in cancel_tasks_sync()
4551 static void rbd_unregister_watch(struct rbd_device *rbd_dev) in rbd_unregister_watch() argument
4553 cancel_tasks_sync(rbd_dev); in rbd_unregister_watch()
4555 mutex_lock(&rbd_dev->watch_mutex); in rbd_unregister_watch()
4556 if (rbd_dev->watch_state == RBD_WATCH_STATE_REGISTERED) in rbd_unregister_watch()
4557 __rbd_unregister_watch(rbd_dev); in rbd_unregister_watch()
4558 rbd_dev->watch_state = RBD_WATCH_STATE_UNREGISTERED; in rbd_unregister_watch()
4559 mutex_unlock(&rbd_dev->watch_mutex); in rbd_unregister_watch()
4561 cancel_delayed_work_sync(&rbd_dev->watch_dwork); in rbd_unregister_watch()
4562 ceph_osdc_flush_notifies(&rbd_dev->rbd_client->client->osdc); in rbd_unregister_watch()
4568 static void rbd_reacquire_lock(struct rbd_device *rbd_dev) in rbd_reacquire_lock() argument
4570 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_reacquire_lock()
4574 if (!rbd_quiesce_lock(rbd_dev)) in rbd_reacquire_lock()
4577 format_lock_cookie(rbd_dev, cookie); in rbd_reacquire_lock()
4578 ret = ceph_cls_set_cookie(osdc, &rbd_dev->header_oid, in rbd_reacquire_lock()
4579 &rbd_dev->header_oloc, RBD_LOCK_NAME, in rbd_reacquire_lock()
4580 CEPH_CLS_LOCK_EXCLUSIVE, rbd_dev->lock_cookie, in rbd_reacquire_lock()
4584 rbd_warn(rbd_dev, "failed to update lock cookie: %d", in rbd_reacquire_lock()
4591 __rbd_release_lock(rbd_dev); in rbd_reacquire_lock()
4592 queue_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); in rbd_reacquire_lock()
4594 __rbd_lock(rbd_dev, cookie); in rbd_reacquire_lock()
4595 wake_lock_waiters(rbd_dev, 0); in rbd_reacquire_lock()
4601 struct rbd_device *rbd_dev = container_of(to_delayed_work(work), in rbd_reregister_watch() local
4605 dout("%s rbd_dev %p\n", __func__, rbd_dev); in rbd_reregister_watch()
4607 mutex_lock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
4608 if (rbd_dev->watch_state != RBD_WATCH_STATE_ERROR) { in rbd_reregister_watch()
4609 mutex_unlock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
4613 ret = __rbd_register_watch(rbd_dev); in rbd_reregister_watch()
4615 rbd_warn(rbd_dev, "failed to reregister watch: %d", ret); in rbd_reregister_watch()
4617 queue_delayed_work(rbd_dev->task_wq, in rbd_reregister_watch()
4618 &rbd_dev->watch_dwork, in rbd_reregister_watch()
4620 mutex_unlock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
4624 mutex_unlock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
4625 down_write(&rbd_dev->lock_rwsem); in rbd_reregister_watch()
4626 wake_lock_waiters(rbd_dev, ret); in rbd_reregister_watch()
4627 up_write(&rbd_dev->lock_rwsem); in rbd_reregister_watch()
4631 rbd_dev->watch_state = RBD_WATCH_STATE_REGISTERED; in rbd_reregister_watch()
4632 rbd_dev->watch_cookie = rbd_dev->watch_handle->linger_id; in rbd_reregister_watch()
4633 mutex_unlock(&rbd_dev->watch_mutex); in rbd_reregister_watch()
4635 down_write(&rbd_dev->lock_rwsem); in rbd_reregister_watch()
4636 if (rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED) in rbd_reregister_watch()
4637 rbd_reacquire_lock(rbd_dev); in rbd_reregister_watch()
4638 up_write(&rbd_dev->lock_rwsem); in rbd_reregister_watch()
4640 ret = rbd_dev_refresh(rbd_dev); in rbd_reregister_watch()
4642 rbd_warn(rbd_dev, "reregistration refresh failed: %d", ret); in rbd_reregister_watch()
4649 static int rbd_obj_method_sync(struct rbd_device *rbd_dev, in rbd_obj_method_sync() argument
4658 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_obj_method_sync()
4706 struct rbd_device *rbd_dev = img_request->rbd_dev; in rbd_queue_workfn() local
4723 down_read(&rbd_dev->header_rwsem); in rbd_queue_workfn()
4724 mapping_size = rbd_dev->mapping.size; in rbd_queue_workfn()
4726 up_read(&rbd_dev->header_rwsem); in rbd_queue_workfn()
4729 rbd_warn(rbd_dev, "beyond EOD (%llu~%llu > %llu)", offset, in rbd_queue_workfn()
4735 dout("%s rbd_dev %p img_req %p %s %llu~%llu\n", __func__, rbd_dev, in rbd_queue_workfn()
4752 rbd_warn(rbd_dev, "%s %llx at %llx result %d", in rbd_queue_workfn()
4760 struct rbd_device *rbd_dev = hctx->queue->queuedata; in rbd_queue_rq() local
4778 rbd_warn(rbd_dev, "unknown req_op %d", req_op(bd->rq)); in rbd_queue_rq()
4782 rbd_img_request_init(img_req, rbd_dev, op_type); in rbd_queue_rq()
4785 if (rbd_is_ro(rbd_dev)) { in rbd_queue_rq()
4786 rbd_warn(rbd_dev, "%s on read-only mapping", in rbd_queue_rq()
4790 rbd_assert(!rbd_is_snap(rbd_dev)); in rbd_queue_rq()
4798 static void rbd_free_disk(struct rbd_device *rbd_dev) in rbd_free_disk() argument
4800 blk_cleanup_queue(rbd_dev->disk->queue); in rbd_free_disk()
4801 blk_mq_free_tag_set(&rbd_dev->tag_set); in rbd_free_disk()
4802 put_disk(rbd_dev->disk); in rbd_free_disk()
4803 rbd_dev->disk = NULL; in rbd_free_disk()
4806 static int rbd_obj_read_sync(struct rbd_device *rbd_dev, in rbd_obj_read_sync() argument
4812 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_obj_read_sync()
4855 static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) in rbd_dev_v1_header_info() argument
4882 ret = rbd_obj_read_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v1_header_info()
4883 &rbd_dev->header_oloc, ondisk, size); in rbd_dev_v1_header_info()
4888 rbd_warn(rbd_dev, "short header read (want %zd got %d)", in rbd_dev_v1_header_info()
4894 rbd_warn(rbd_dev, "invalid header"); in rbd_dev_v1_header_info()
4903 ret = rbd_header_from_disk(rbd_dev, ondisk); in rbd_dev_v1_header_info()
4910 static void rbd_dev_update_size(struct rbd_device *rbd_dev) in rbd_dev_update_size() argument
4919 if (test_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags) && in rbd_dev_update_size()
4920 !test_bit(RBD_DEV_FLAG_REMOVING, &rbd_dev->flags)) { in rbd_dev_update_size()
4921 size = (sector_t)rbd_dev->mapping.size / SECTOR_SIZE; in rbd_dev_update_size()
4923 set_capacity(rbd_dev->disk, size); in rbd_dev_update_size()
4924 revalidate_disk_size(rbd_dev->disk, true); in rbd_dev_update_size()
4928 static int rbd_dev_refresh(struct rbd_device *rbd_dev) in rbd_dev_refresh() argument
4933 down_write(&rbd_dev->header_rwsem); in rbd_dev_refresh()
4934 mapping_size = rbd_dev->mapping.size; in rbd_dev_refresh()
4936 ret = rbd_dev_header_info(rbd_dev); in rbd_dev_refresh()
4944 if (rbd_dev->parent) { in rbd_dev_refresh()
4945 ret = rbd_dev_v2_parent_info(rbd_dev); in rbd_dev_refresh()
4950 rbd_assert(!rbd_is_snap(rbd_dev)); in rbd_dev_refresh()
4951 rbd_dev->mapping.size = rbd_dev->header.image_size; in rbd_dev_refresh()
4954 up_write(&rbd_dev->header_rwsem); in rbd_dev_refresh()
4955 if (!ret && mapping_size != rbd_dev->mapping.size) in rbd_dev_refresh()
4956 rbd_dev_update_size(rbd_dev); in rbd_dev_refresh()
4965 static int rbd_init_disk(struct rbd_device *rbd_dev) in rbd_init_disk() argument
4970 rbd_dev->layout.object_size * rbd_dev->layout.stripe_count; in rbd_init_disk()
4981 rbd_dev->dev_id); in rbd_init_disk()
4982 disk->major = rbd_dev->major; in rbd_init_disk()
4983 disk->first_minor = rbd_dev->minor; in rbd_init_disk()
4987 disk->private_data = rbd_dev; in rbd_init_disk()
4989 memset(&rbd_dev->tag_set, 0, sizeof(rbd_dev->tag_set)); in rbd_init_disk()
4990 rbd_dev->tag_set.ops = &rbd_mq_ops; in rbd_init_disk()
4991 rbd_dev->tag_set.queue_depth = rbd_dev->opts->queue_depth; in rbd_init_disk()
4992 rbd_dev->tag_set.numa_node = NUMA_NO_NODE; in rbd_init_disk()
4993 rbd_dev->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; in rbd_init_disk()
4994 rbd_dev->tag_set.nr_hw_queues = num_present_cpus(); in rbd_init_disk()
4995 rbd_dev->tag_set.cmd_size = sizeof(struct rbd_img_request); in rbd_init_disk()
4997 err = blk_mq_alloc_tag_set(&rbd_dev->tag_set); in rbd_init_disk()
5001 q = blk_mq_init_queue(&rbd_dev->tag_set); in rbd_init_disk()
5014 blk_queue_io_min(q, rbd_dev->opts->alloc_size); in rbd_init_disk()
5015 blk_queue_io_opt(q, rbd_dev->opts->alloc_size); in rbd_init_disk()
5017 if (rbd_dev->opts->trim) { in rbd_init_disk()
5019 q->limits.discard_granularity = rbd_dev->opts->alloc_size; in rbd_init_disk()
5024 if (!ceph_test_opt(rbd_dev->rbd_client->client, NOCRC)) in rbd_init_disk()
5033 q->queuedata = rbd_dev; in rbd_init_disk()
5035 rbd_dev->disk = disk; in rbd_init_disk()
5039 blk_mq_free_tag_set(&rbd_dev->tag_set); in rbd_init_disk()
5057 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_size_show() local
5060 (unsigned long long)rbd_dev->mapping.size); in rbd_size_show()
5066 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_features_show() local
5068 return sprintf(buf, "0x%016llx\n", rbd_dev->header.features); in rbd_features_show()
5074 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_major_show() local
5076 if (rbd_dev->major) in rbd_major_show()
5077 return sprintf(buf, "%d\n", rbd_dev->major); in rbd_major_show()
5085 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_minor_show() local
5087 return sprintf(buf, "%d\n", rbd_dev->minor); in rbd_minor_show()
5093 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_client_addr_show() local
5095 ceph_client_addr(rbd_dev->rbd_client->client); in rbd_client_addr_show()
5104 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_client_id_show() local
5107 ceph_client_gid(rbd_dev->rbd_client->client)); in rbd_client_id_show()
5113 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_cluster_fsid_show() local
5115 return sprintf(buf, "%pU\n", &rbd_dev->rbd_client->client->fsid); in rbd_cluster_fsid_show()
5121 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_config_info_show() local
5126 return sprintf(buf, "%s\n", rbd_dev->config_info); in rbd_config_info_show()
5132 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_pool_show() local
5134 return sprintf(buf, "%s\n", rbd_dev->spec->pool_name); in rbd_pool_show()
5140 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_pool_id_show() local
5143 (unsigned long long) rbd_dev->spec->pool_id); in rbd_pool_id_show()
5149 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_pool_ns_show() local
5151 return sprintf(buf, "%s\n", rbd_dev->spec->pool_ns ?: ""); in rbd_pool_ns_show()
5157 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_name_show() local
5159 if (rbd_dev->spec->image_name) in rbd_name_show()
5160 return sprintf(buf, "%s\n", rbd_dev->spec->image_name); in rbd_name_show()
5168 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_image_id_show() local
5170 return sprintf(buf, "%s\n", rbd_dev->spec->image_id); in rbd_image_id_show()
5181 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_snap_show() local
5183 return sprintf(buf, "%s\n", rbd_dev->spec->snap_name); in rbd_snap_show()
5189 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_snap_id_show() local
5191 return sprintf(buf, "%llu\n", rbd_dev->spec->snap_id); in rbd_snap_id_show()
5203 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_parent_show() local
5206 if (!rbd_dev->parent) in rbd_parent_show()
5209 for ( ; rbd_dev->parent; rbd_dev = rbd_dev->parent) { in rbd_parent_show()
5210 struct rbd_spec *spec = rbd_dev->parent_spec; in rbd_parent_show()
5223 rbd_dev->parent_overlap); in rbd_parent_show()
5234 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_image_refresh() local
5240 ret = rbd_dev_refresh(rbd_dev); in rbd_image_refresh()
5344 static void rbd_dev_free(struct rbd_device *rbd_dev) in rbd_dev_free() argument
5346 WARN_ON(rbd_dev->watch_state != RBD_WATCH_STATE_UNREGISTERED); in rbd_dev_free()
5347 WARN_ON(rbd_dev->lock_state != RBD_LOCK_STATE_UNLOCKED); in rbd_dev_free()
5349 ceph_oid_destroy(&rbd_dev->header_oid); in rbd_dev_free()
5350 ceph_oloc_destroy(&rbd_dev->header_oloc); in rbd_dev_free()
5351 kfree(rbd_dev->config_info); in rbd_dev_free()
5353 rbd_put_client(rbd_dev->rbd_client); in rbd_dev_free()
5354 rbd_spec_put(rbd_dev->spec); in rbd_dev_free()
5355 kfree(rbd_dev->opts); in rbd_dev_free()
5356 kfree(rbd_dev); in rbd_dev_free()
5361 struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); in rbd_dev_release() local
5362 bool need_put = !!rbd_dev->opts; in rbd_dev_release()
5365 destroy_workqueue(rbd_dev->task_wq); in rbd_dev_release()
5366 ida_simple_remove(&rbd_dev_id_ida, rbd_dev->dev_id); in rbd_dev_release()
5369 rbd_dev_free(rbd_dev); in rbd_dev_release()
5383 struct rbd_device *rbd_dev; in __rbd_dev_create() local
5385 rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL); in __rbd_dev_create()
5386 if (!rbd_dev) in __rbd_dev_create()
5389 spin_lock_init(&rbd_dev->lock); in __rbd_dev_create()
5390 INIT_LIST_HEAD(&rbd_dev->node); in __rbd_dev_create()
5391 init_rwsem(&rbd_dev->header_rwsem); in __rbd_dev_create()
5393 rbd_dev->header.data_pool_id = CEPH_NOPOOL; in __rbd_dev_create()
5394 ceph_oid_init(&rbd_dev->header_oid); in __rbd_dev_create()
5395 rbd_dev->header_oloc.pool = spec->pool_id; in __rbd_dev_create()
5398 rbd_dev->header_oloc.pool_ns = in __rbd_dev_create()
5403 mutex_init(&rbd_dev->watch_mutex); in __rbd_dev_create()
5404 rbd_dev->watch_state = RBD_WATCH_STATE_UNREGISTERED; in __rbd_dev_create()
5405 INIT_DELAYED_WORK(&rbd_dev->watch_dwork, rbd_reregister_watch); in __rbd_dev_create()
5407 init_rwsem(&rbd_dev->lock_rwsem); in __rbd_dev_create()
5408 rbd_dev->lock_state = RBD_LOCK_STATE_UNLOCKED; in __rbd_dev_create()
5409 INIT_WORK(&rbd_dev->acquired_lock_work, rbd_notify_acquired_lock); in __rbd_dev_create()
5410 INIT_WORK(&rbd_dev->released_lock_work, rbd_notify_released_lock); in __rbd_dev_create()
5411 INIT_DELAYED_WORK(&rbd_dev->lock_dwork, rbd_acquire_lock); in __rbd_dev_create()
5412 INIT_WORK(&rbd_dev->unlock_work, rbd_release_lock_work); in __rbd_dev_create()
5413 spin_lock_init(&rbd_dev->lock_lists_lock); in __rbd_dev_create()
5414 INIT_LIST_HEAD(&rbd_dev->acquiring_list); in __rbd_dev_create()
5415 INIT_LIST_HEAD(&rbd_dev->running_list); in __rbd_dev_create()
5416 init_completion(&rbd_dev->acquire_wait); in __rbd_dev_create()
5417 init_completion(&rbd_dev->releasing_wait); in __rbd_dev_create()
5419 spin_lock_init(&rbd_dev->object_map_lock); in __rbd_dev_create()
5421 rbd_dev->dev.bus = &rbd_bus_type; in __rbd_dev_create()
5422 rbd_dev->dev.type = &rbd_device_type; in __rbd_dev_create()
5423 rbd_dev->dev.parent = &rbd_root_dev; in __rbd_dev_create()
5424 device_initialize(&rbd_dev->dev); in __rbd_dev_create()
5426 rbd_dev->rbd_client = rbdc; in __rbd_dev_create()
5427 rbd_dev->spec = spec; in __rbd_dev_create()
5429 return rbd_dev; in __rbd_dev_create()
5439 struct rbd_device *rbd_dev; in rbd_dev_create() local
5441 rbd_dev = __rbd_dev_create(rbdc, spec); in rbd_dev_create()
5442 if (!rbd_dev) in rbd_dev_create()
5445 rbd_dev->opts = opts; in rbd_dev_create()
5448 rbd_dev->dev_id = ida_simple_get(&rbd_dev_id_ida, 0, in rbd_dev_create()
5451 if (rbd_dev->dev_id < 0) in rbd_dev_create()
5454 sprintf(rbd_dev->name, RBD_DRV_NAME "%d", rbd_dev->dev_id); in rbd_dev_create()
5455 rbd_dev->task_wq = alloc_ordered_workqueue("%s-tasks", WQ_MEM_RECLAIM, in rbd_dev_create()
5456 rbd_dev->name); in rbd_dev_create()
5457 if (!rbd_dev->task_wq) in rbd_dev_create()
5463 dout("%s rbd_dev %p dev_id %d\n", __func__, rbd_dev, rbd_dev->dev_id); in rbd_dev_create()
5464 return rbd_dev; in rbd_dev_create()
5467 ida_simple_remove(&rbd_dev_id_ida, rbd_dev->dev_id); in rbd_dev_create()
5469 rbd_dev_free(rbd_dev); in rbd_dev_create()
5473 static void rbd_dev_destroy(struct rbd_device *rbd_dev) in rbd_dev_destroy() argument
5475 if (rbd_dev) in rbd_dev_destroy()
5476 put_device(&rbd_dev->dev); in rbd_dev_destroy()
5484 static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, in _rbd_dev_v2_snap_size() argument
5494 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in _rbd_dev_v2_snap_size()
5495 &rbd_dev->header_oloc, "get_size", in _rbd_dev_v2_snap_size()
5517 static int rbd_dev_v2_image_size(struct rbd_device *rbd_dev) in rbd_dev_v2_image_size() argument
5519 return _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, in rbd_dev_v2_image_size()
5520 &rbd_dev->header.obj_order, in rbd_dev_v2_image_size()
5521 &rbd_dev->header.image_size); in rbd_dev_v2_image_size()
5524 static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) in rbd_dev_v2_object_prefix() argument
5537 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_object_prefix()
5538 &rbd_dev->header_oloc, "get_object_prefix", in rbd_dev_v2_object_prefix()
5545 rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p, in rbd_dev_v2_object_prefix()
5549 if (IS_ERR(rbd_dev->header.object_prefix)) { in rbd_dev_v2_object_prefix()
5550 ret = PTR_ERR(rbd_dev->header.object_prefix); in rbd_dev_v2_object_prefix()
5551 rbd_dev->header.object_prefix = NULL; in rbd_dev_v2_object_prefix()
5553 dout(" object_prefix = %s\n", rbd_dev->header.object_prefix); in rbd_dev_v2_object_prefix()
5561 static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, in _rbd_dev_v2_snap_features() argument
5578 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in _rbd_dev_v2_snap_features()
5579 &rbd_dev->header_oloc, "get_features", in _rbd_dev_v2_snap_features()
5590 rbd_warn(rbd_dev, "image uses unsupported features: 0x%llx", in _rbd_dev_v2_snap_features()
5605 static int rbd_dev_v2_features(struct rbd_device *rbd_dev) in rbd_dev_v2_features() argument
5607 return _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP, in rbd_dev_v2_features()
5608 rbd_is_ro(rbd_dev), in rbd_dev_v2_features()
5609 &rbd_dev->header.features); in rbd_dev_v2_features()
5619 static int rbd_dev_v2_get_flags(struct rbd_device *rbd_dev) in rbd_dev_v2_get_flags() argument
5621 __le64 snapid = cpu_to_le64(rbd_dev->spec->snap_id); in rbd_dev_v2_get_flags()
5625 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_get_flags()
5626 &rbd_dev->header_oloc, "get_flags", in rbd_dev_v2_get_flags()
5634 rbd_dev->object_map_flags = le64_to_cpu(flags); in rbd_dev_v2_get_flags()
5683 static int __get_parent_info(struct rbd_device *rbd_dev, in __get_parent_info() argument
5688 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __get_parent_info()
5693 ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in __get_parent_info()
5705 ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in __get_parent_info()
5726 static int __get_parent_info_legacy(struct rbd_device *rbd_dev, in __get_parent_info_legacy() argument
5731 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in __get_parent_info_legacy()
5736 ret = ceph_osdc_call(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, in __get_parent_info_legacy()
5761 static int get_parent_info(struct rbd_device *rbd_dev, in get_parent_info() argument
5779 ceph_encode_64(&p, rbd_dev->spec->snap_id); in get_parent_info()
5780 ret = __get_parent_info(rbd_dev, req_page, reply_page, pii); in get_parent_info()
5782 ret = __get_parent_info_legacy(rbd_dev, req_page, reply_page, in get_parent_info()
5790 static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) in rbd_dev_v2_parent_info() argument
5800 ret = get_parent_info(rbd_dev, &pii); in rbd_dev_v2_parent_info()
5822 if (rbd_dev->parent_overlap) { in rbd_dev_v2_parent_info()
5823 rbd_dev->parent_overlap = 0; in rbd_dev_v2_parent_info()
5824 rbd_dev_parent_put(rbd_dev); in rbd_dev_v2_parent_info()
5826 rbd_dev->disk->disk_name); in rbd_dev_v2_parent_info()
5846 if (!rbd_dev->parent_spec) { in rbd_dev_v2_parent_info()
5856 rbd_dev->parent_spec = parent_spec; in rbd_dev_v2_parent_info()
5867 if (rbd_dev->parent_overlap) in rbd_dev_v2_parent_info()
5868 rbd_warn(rbd_dev, in rbd_dev_v2_parent_info()
5872 rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); in rbd_dev_v2_parent_info()
5875 rbd_dev->parent_overlap = pii.overlap; in rbd_dev_v2_parent_info()
5886 static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) in rbd_dev_v2_striping_info() argument
5896 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_striping_info()
5897 &rbd_dev->header_oloc, "get_stripe_unit_count", in rbd_dev_v2_striping_info()
5906 rbd_dev->header.stripe_unit = ceph_decode_64(&p); in rbd_dev_v2_striping_info()
5907 rbd_dev->header.stripe_count = ceph_decode_64(&p); in rbd_dev_v2_striping_info()
5911 static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev) in rbd_dev_v2_data_pool() argument
5916 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_data_pool()
5917 &rbd_dev->header_oloc, "get_data_pool", in rbd_dev_v2_data_pool()
5924 rbd_dev->header.data_pool_id = le64_to_cpu(data_pool_id); in rbd_dev_v2_data_pool()
5925 WARN_ON(rbd_dev->header.data_pool_id == CEPH_NOPOOL); in rbd_dev_v2_data_pool()
5929 static char *rbd_dev_image_name(struct rbd_device *rbd_dev) in rbd_dev_image_name() argument
5942 rbd_assert(!rbd_dev->spec->image_name); in rbd_dev_image_name()
5944 len = strlen(rbd_dev->spec->image_id); in rbd_dev_image_name()
5952 ceph_encode_string(&p, end, rbd_dev->spec->image_id, (u32)len); in rbd_dev_image_name()
5960 ret = rbd_obj_method_sync(rbd_dev, &oid, &rbd_dev->header_oloc, in rbd_dev_image_name()
5980 static u64 rbd_v1_snap_id_by_name(struct rbd_device *rbd_dev, const char *name) in rbd_v1_snap_id_by_name() argument
5982 struct ceph_snap_context *snapc = rbd_dev->header.snapc; in rbd_v1_snap_id_by_name()
5988 snap_name = rbd_dev->header.snap_names; in rbd_v1_snap_id_by_name()
5998 static u64 rbd_v2_snap_id_by_name(struct rbd_device *rbd_dev, const char *name) in rbd_v2_snap_id_by_name() argument
6000 struct ceph_snap_context *snapc = rbd_dev->header.snapc; in rbd_v2_snap_id_by_name()
6009 snap_name = rbd_dev_v2_snap_name(rbd_dev, snap_id); in rbd_v2_snap_id_by_name()
6027 static u64 rbd_snap_id_by_name(struct rbd_device *rbd_dev, const char *name) in rbd_snap_id_by_name() argument
6029 if (rbd_dev->image_format == 1) in rbd_snap_id_by_name()
6030 return rbd_v1_snap_id_by_name(rbd_dev, name); in rbd_snap_id_by_name()
6032 return rbd_v2_snap_id_by_name(rbd_dev, name); in rbd_snap_id_by_name()
6038 static int rbd_spec_fill_snap_id(struct rbd_device *rbd_dev) in rbd_spec_fill_snap_id() argument
6040 struct rbd_spec *spec = rbd_dev->spec; in rbd_spec_fill_snap_id()
6049 snap_id = rbd_snap_id_by_name(rbd_dev, spec->snap_name); in rbd_spec_fill_snap_id()
6067 static int rbd_spec_fill_names(struct rbd_device *rbd_dev) in rbd_spec_fill_names() argument
6069 struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; in rbd_spec_fill_names()
6070 struct rbd_spec *spec = rbd_dev->spec; in rbd_spec_fill_names()
6084 rbd_warn(rbd_dev, "no pool with id %llu", spec->pool_id); in rbd_spec_fill_names()
6093 image_name = rbd_dev_image_name(rbd_dev); in rbd_spec_fill_names()
6095 rbd_warn(rbd_dev, "unable to get image name"); in rbd_spec_fill_names()
6099 snap_name = rbd_snap_name(rbd_dev, spec->snap_id); in rbd_spec_fill_names()
6117 static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev) in rbd_dev_v2_snap_context() argument
6141 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_snap_context()
6142 &rbd_dev->header_oloc, "get_snapcontext", in rbd_dev_v2_snap_context()
6178 ceph_put_snap_context(rbd_dev->header.snapc); in rbd_dev_v2_snap_context()
6179 rbd_dev->header.snapc = snapc; in rbd_dev_v2_snap_context()
6189 static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, in rbd_dev_v2_snap_name() argument
6206 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, in rbd_dev_v2_snap_name()
6207 &rbd_dev->header_oloc, "get_snapshot_name", in rbd_dev_v2_snap_name()
6229 static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev) in rbd_dev_v2_header_info() argument
6231 bool first_time = rbd_dev->header.object_prefix == NULL; in rbd_dev_v2_header_info()
6234 ret = rbd_dev_v2_image_size(rbd_dev); in rbd_dev_v2_header_info()
6239 ret = rbd_dev_v2_header_onetime(rbd_dev); in rbd_dev_v2_header_info()
6244 ret = rbd_dev_v2_snap_context(rbd_dev); in rbd_dev_v2_header_info()
6246 kfree(rbd_dev->header.object_prefix); in rbd_dev_v2_header_info()
6247 rbd_dev->header.object_prefix = NULL; in rbd_dev_v2_header_info()
6253 static int rbd_dev_header_info(struct rbd_device *rbd_dev) in rbd_dev_header_info() argument
6255 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_dev_header_info()
6257 if (rbd_dev->image_format == 1) in rbd_dev_header_info()
6258 return rbd_dev_v1_header_info(rbd_dev); in rbd_dev_header_info()
6260 return rbd_dev_v2_header_info(rbd_dev); in rbd_dev_header_info()
6605 static void rbd_dev_image_unlock(struct rbd_device *rbd_dev) in rbd_dev_image_unlock() argument
6607 down_write(&rbd_dev->lock_rwsem); in rbd_dev_image_unlock()
6608 if (__rbd_is_lock_owner(rbd_dev)) in rbd_dev_image_unlock()
6609 __rbd_release_lock(rbd_dev); in rbd_dev_image_unlock()
6610 up_write(&rbd_dev->lock_rwsem); in rbd_dev_image_unlock()
6618 static int rbd_add_acquire_lock(struct rbd_device *rbd_dev) in rbd_add_acquire_lock() argument
6622 if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK)) { in rbd_add_acquire_lock()
6623 if (!rbd_dev->opts->exclusive && !rbd_dev->opts->lock_on_read) in rbd_add_acquire_lock()
6626 rbd_warn(rbd_dev, "exclusive-lock feature is not enabled"); in rbd_add_acquire_lock()
6630 if (rbd_is_ro(rbd_dev)) in rbd_add_acquire_lock()
6633 rbd_assert(!rbd_is_lock_owner(rbd_dev)); in rbd_add_acquire_lock()
6634 queue_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); in rbd_add_acquire_lock()
6635 ret = wait_for_completion_killable_timeout(&rbd_dev->acquire_wait, in rbd_add_acquire_lock()
6636 ceph_timeout_jiffies(rbd_dev->opts->lock_timeout)); in rbd_add_acquire_lock()
6638 ret = rbd_dev->acquire_err; in rbd_add_acquire_lock()
6640 cancel_delayed_work_sync(&rbd_dev->lock_dwork); in rbd_add_acquire_lock()
6646 rbd_warn(rbd_dev, "failed to acquire exclusive lock: %ld", ret); in rbd_add_acquire_lock()
6654 rbd_assert(!rbd_dev->opts->exclusive || rbd_is_lock_owner(rbd_dev)); in rbd_add_acquire_lock()
6672 static int rbd_dev_image_id(struct rbd_device *rbd_dev) in rbd_dev_image_id() argument
6686 if (rbd_dev->spec->image_id) { in rbd_dev_image_id()
6687 rbd_dev->image_format = *rbd_dev->spec->image_id ? 2 : 1; in rbd_dev_image_id()
6697 rbd_dev->spec->image_name); in rbd_dev_image_id()
6713 ret = rbd_obj_method_sync(rbd_dev, &oid, &rbd_dev->header_oloc, in rbd_dev_image_id()
6721 rbd_dev->image_format = 1; in rbd_dev_image_id()
6729 rbd_dev->image_format = 2; in rbd_dev_image_id()
6733 rbd_dev->spec->image_id = image_id; in rbd_dev_image_id()
6746 static void rbd_dev_unprobe(struct rbd_device *rbd_dev) in rbd_dev_unprobe() argument
6750 rbd_dev_parent_put(rbd_dev); in rbd_dev_unprobe()
6751 rbd_object_map_free(rbd_dev); in rbd_dev_unprobe()
6752 rbd_dev_mapping_clear(rbd_dev); in rbd_dev_unprobe()
6756 header = &rbd_dev->header; in rbd_dev_unprobe()
6764 static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev) in rbd_dev_v2_header_onetime() argument
6768 ret = rbd_dev_v2_object_prefix(rbd_dev); in rbd_dev_v2_header_onetime()
6776 ret = rbd_dev_v2_features(rbd_dev); in rbd_dev_v2_header_onetime()
6782 if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) { in rbd_dev_v2_header_onetime()
6783 ret = rbd_dev_v2_striping_info(rbd_dev); in rbd_dev_v2_header_onetime()
6788 if (rbd_dev->header.features & RBD_FEATURE_DATA_POOL) { in rbd_dev_v2_header_onetime()
6789 ret = rbd_dev_v2_data_pool(rbd_dev); in rbd_dev_v2_header_onetime()
6794 rbd_init_layout(rbd_dev); in rbd_dev_v2_header_onetime()
6798 rbd_dev->header.features = 0; in rbd_dev_v2_header_onetime()
6799 kfree(rbd_dev->header.object_prefix); in rbd_dev_v2_header_onetime()
6800 rbd_dev->header.object_prefix = NULL; in rbd_dev_v2_header_onetime()
6809 static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) in rbd_dev_probe_parent() argument
6814 if (!rbd_dev->parent_spec) in rbd_dev_probe_parent()
6823 parent = __rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec); in rbd_dev_probe_parent()
6833 __rbd_get_client(rbd_dev->rbd_client); in rbd_dev_probe_parent()
6834 rbd_spec_get(rbd_dev->parent_spec); in rbd_dev_probe_parent()
6842 rbd_dev->parent = parent; in rbd_dev_probe_parent()
6843 atomic_set(&rbd_dev->parent_ref, 1); in rbd_dev_probe_parent()
6847 rbd_dev_unparent(rbd_dev); in rbd_dev_probe_parent()
6852 static void rbd_dev_device_release(struct rbd_device *rbd_dev) in rbd_dev_device_release() argument
6854 clear_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); in rbd_dev_device_release()
6855 rbd_free_disk(rbd_dev); in rbd_dev_device_release()
6857 unregister_blkdev(rbd_dev->major, rbd_dev->name); in rbd_dev_device_release()
6864 static int rbd_dev_device_setup(struct rbd_device *rbd_dev) in rbd_dev_device_setup() argument
6871 ret = register_blkdev(0, rbd_dev->name); in rbd_dev_device_setup()
6875 rbd_dev->major = ret; in rbd_dev_device_setup()
6876 rbd_dev->minor = 0; in rbd_dev_device_setup()
6878 rbd_dev->major = rbd_major; in rbd_dev_device_setup()
6879 rbd_dev->minor = rbd_dev_id_to_minor(rbd_dev->dev_id); in rbd_dev_device_setup()
6884 ret = rbd_init_disk(rbd_dev); in rbd_dev_device_setup()
6888 set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE); in rbd_dev_device_setup()
6889 set_disk_ro(rbd_dev->disk, rbd_is_ro(rbd_dev)); in rbd_dev_device_setup()
6891 ret = dev_set_name(&rbd_dev->dev, "%d", rbd_dev->dev_id); in rbd_dev_device_setup()
6895 set_bit(RBD_DEV_FLAG_EXISTS, &rbd_dev->flags); in rbd_dev_device_setup()
6896 up_write(&rbd_dev->header_rwsem); in rbd_dev_device_setup()
6900 rbd_free_disk(rbd_dev); in rbd_dev_device_setup()
6903 unregister_blkdev(rbd_dev->major, rbd_dev->name); in rbd_dev_device_setup()
6905 up_write(&rbd_dev->header_rwsem); in rbd_dev_device_setup()
6909 static int rbd_dev_header_name(struct rbd_device *rbd_dev) in rbd_dev_header_name() argument
6911 struct rbd_spec *spec = rbd_dev->spec; in rbd_dev_header_name()
6916 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); in rbd_dev_header_name()
6917 if (rbd_dev->image_format == 1) in rbd_dev_header_name()
6918 ret = ceph_oid_aprintf(&rbd_dev->header_oid, GFP_KERNEL, "%s%s", in rbd_dev_header_name()
6921 ret = ceph_oid_aprintf(&rbd_dev->header_oid, GFP_KERNEL, "%s%s", in rbd_dev_header_name()
6927 static void rbd_print_dne(struct rbd_device *rbd_dev, bool is_snap) in rbd_print_dne() argument
6931 rbd_dev->spec->pool_name, in rbd_print_dne()
6932 rbd_dev->spec->pool_ns ?: "", in rbd_print_dne()
6933 rbd_dev->spec->pool_ns ? "/" : "", in rbd_print_dne()
6934 rbd_dev->spec->image_name); in rbd_print_dne()
6937 rbd_dev->spec->pool_name, in rbd_print_dne()
6938 rbd_dev->spec->pool_ns ?: "", in rbd_print_dne()
6939 rbd_dev->spec->pool_ns ? "/" : "", in rbd_print_dne()
6940 rbd_dev->spec->image_name, in rbd_print_dne()
6941 rbd_dev->spec->snap_name); in rbd_print_dne()
6945 static void rbd_dev_image_release(struct rbd_device *rbd_dev) in rbd_dev_image_release() argument
6947 if (!rbd_is_ro(rbd_dev)) in rbd_dev_image_release()
6948 rbd_unregister_watch(rbd_dev); in rbd_dev_image_release()
6950 rbd_dev_unprobe(rbd_dev); in rbd_dev_image_release()
6951 rbd_dev->image_format = 0; in rbd_dev_image_release()
6952 kfree(rbd_dev->spec->image_id); in rbd_dev_image_release()
6953 rbd_dev->spec->image_id = NULL; in rbd_dev_image_release()
6965 static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth) in rbd_dev_image_probe() argument
6967 bool need_watch = !rbd_is_ro(rbd_dev); in rbd_dev_image_probe()
6976 ret = rbd_dev_image_id(rbd_dev); in rbd_dev_image_probe()
6980 ret = rbd_dev_header_name(rbd_dev); in rbd_dev_image_probe()
6985 ret = rbd_register_watch(rbd_dev); in rbd_dev_image_probe()
6988 rbd_print_dne(rbd_dev, false); in rbd_dev_image_probe()
6994 down_write(&rbd_dev->header_rwsem); in rbd_dev_image_probe()
6996 ret = rbd_dev_header_info(rbd_dev); in rbd_dev_image_probe()
6999 rbd_print_dne(rbd_dev, false); in rbd_dev_image_probe()
7010 ret = rbd_spec_fill_snap_id(rbd_dev); in rbd_dev_image_probe()
7012 ret = rbd_spec_fill_names(rbd_dev); in rbd_dev_image_probe()
7015 rbd_print_dne(rbd_dev, true); in rbd_dev_image_probe()
7019 ret = rbd_dev_mapping_set(rbd_dev); in rbd_dev_image_probe()
7023 if (rbd_is_snap(rbd_dev) && in rbd_dev_image_probe()
7024 (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP)) { in rbd_dev_image_probe()
7025 ret = rbd_object_map_load(rbd_dev); in rbd_dev_image_probe()
7030 if (rbd_dev->header.features & RBD_FEATURE_LAYERING) { in rbd_dev_image_probe()
7031 ret = rbd_dev_v2_parent_info(rbd_dev); in rbd_dev_image_probe()
7036 ret = rbd_dev_probe_parent(rbd_dev, depth); in rbd_dev_image_probe()
7041 rbd_dev->image_format, rbd_dev->header_oid.name); in rbd_dev_image_probe()
7046 up_write(&rbd_dev->header_rwsem); in rbd_dev_image_probe()
7048 rbd_unregister_watch(rbd_dev); in rbd_dev_image_probe()
7049 rbd_dev_unprobe(rbd_dev); in rbd_dev_image_probe()
7051 rbd_dev->image_format = 0; in rbd_dev_image_probe()
7052 kfree(rbd_dev->spec->image_id); in rbd_dev_image_probe()
7053 rbd_dev->spec->image_id = NULL; in rbd_dev_image_probe()
7061 struct rbd_device *rbd_dev = NULL; in do_rbd_add() local
7094 rbd_dev = rbd_dev_create(rbdc, spec, rbd_opts); in do_rbd_add()
7095 if (!rbd_dev) { in do_rbd_add()
7104 if (rbd_dev->opts->read_only || in do_rbd_add()
7105 strcmp(rbd_dev->spec->snap_name, RBD_SNAP_HEAD_NAME)) in do_rbd_add()
7106 __set_bit(RBD_DEV_FLAG_READONLY, &rbd_dev->flags); in do_rbd_add()
7108 rbd_dev->config_info = kstrdup(buf, GFP_KERNEL); in do_rbd_add()
7109 if (!rbd_dev->config_info) { in do_rbd_add()
7114 rc = rbd_dev_image_probe(rbd_dev, 0); in do_rbd_add()
7118 if (rbd_dev->opts->alloc_size > rbd_dev->layout.object_size) { in do_rbd_add()
7119 rbd_warn(rbd_dev, "alloc_size adjusted to %u", in do_rbd_add()
7120 rbd_dev->layout.object_size); in do_rbd_add()
7121 rbd_dev->opts->alloc_size = rbd_dev->layout.object_size; in do_rbd_add()
7124 rc = rbd_dev_device_setup(rbd_dev); in do_rbd_add()
7128 rc = rbd_add_acquire_lock(rbd_dev); in do_rbd_add()
7134 rc = device_add(&rbd_dev->dev); in do_rbd_add()
7138 device_add_disk(&rbd_dev->dev, rbd_dev->disk, NULL); in do_rbd_add()
7140 blk_put_queue(rbd_dev->disk->queue); in do_rbd_add()
7143 list_add_tail(&rbd_dev->node, &rbd_dev_list); in do_rbd_add()
7146 pr_info("%s: capacity %llu features 0x%llx\n", rbd_dev->disk->disk_name, in do_rbd_add()
7147 (unsigned long long)get_capacity(rbd_dev->disk) << SECTOR_SHIFT, in do_rbd_add()
7148 rbd_dev->header.features); in do_rbd_add()
7155 rbd_dev_image_unlock(rbd_dev); in do_rbd_add()
7156 rbd_dev_device_release(rbd_dev); in do_rbd_add()
7158 rbd_dev_image_release(rbd_dev); in do_rbd_add()
7160 rbd_dev_destroy(rbd_dev); in do_rbd_add()
7183 static void rbd_dev_remove_parent(struct rbd_device *rbd_dev) in rbd_dev_remove_parent() argument
7185 while (rbd_dev->parent) { in rbd_dev_remove_parent()
7186 struct rbd_device *first = rbd_dev; in rbd_dev_remove_parent()
7214 struct rbd_device *rbd_dev = NULL; in do_rbd_remove() local
7243 rbd_dev = list_entry(tmp, struct rbd_device, node); in do_rbd_remove()
7244 if (rbd_dev->dev_id == dev_id) { in do_rbd_remove()
7250 spin_lock_irq(&rbd_dev->lock); in do_rbd_remove()
7251 if (rbd_dev->open_count && !force) in do_rbd_remove()
7254 &rbd_dev->flags)) in do_rbd_remove()
7256 spin_unlock_irq(&rbd_dev->lock); in do_rbd_remove()
7267 blk_mq_freeze_queue(rbd_dev->disk->queue); in do_rbd_remove()
7268 blk_set_queue_dying(rbd_dev->disk->queue); in do_rbd_remove()
7271 del_gendisk(rbd_dev->disk); in do_rbd_remove()
7273 list_del_init(&rbd_dev->node); in do_rbd_remove()
7275 device_del(&rbd_dev->dev); in do_rbd_remove()
7277 rbd_dev_image_unlock(rbd_dev); in do_rbd_remove()
7278 rbd_dev_device_release(rbd_dev); in do_rbd_remove()
7279 rbd_dev_image_release(rbd_dev); in do_rbd_remove()
7280 rbd_dev_destroy(rbd_dev); in do_rbd_remove()