Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'ceph-for-6.6-rc4' of https://github.com/ceph/ceph-client

Pull ceph fixes from Ilya Dryomov:
"A series that fixes an involved 'double watch error' deadlock in RBD
marked for stable and two cleanups"

* tag 'ceph-for-6.6-rc4' of https://github.com/ceph/ceph-client:
rbd: take header_rwsem in rbd_dev_refresh() only when updating
rbd: decouple parent info read-in from updating rbd_dev
rbd: decouple header read-in from updating rbd_dev->header
rbd: move rbd_dev_refresh() definition
Revert "ceph: make members in struct ceph_mds_request_args_ext a union"
ceph: remove unnecessary check for NULL in parse_longname()

+240 -206
+227 -189
drivers/block/rbd.c
··· 632 632 static void rbd_dev_remove_parent(struct rbd_device *rbd_dev); 633 633 634 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); 635 + static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev, 636 + struct rbd_image_header *header); 638 637 static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, 639 638 u64 snap_id); 640 639 static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, ··· 994 995 RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL); 995 996 } 996 997 998 + static void rbd_image_header_cleanup(struct rbd_image_header *header) 999 + { 1000 + kfree(header->object_prefix); 1001 + ceph_put_snap_context(header->snapc); 1002 + kfree(header->snap_sizes); 1003 + kfree(header->snap_names); 1004 + 1005 + memset(header, 0, sizeof(*header)); 1006 + } 1007 + 997 1008 /* 998 1009 * Fill an rbd image header with information from the given format 1 999 1010 * on-disk header. 1000 1011 */ 1001 - static int rbd_header_from_disk(struct rbd_device *rbd_dev, 1002 - struct rbd_image_header_ondisk *ondisk) 1012 + static int rbd_header_from_disk(struct rbd_image_header *header, 1013 + struct rbd_image_header_ondisk *ondisk, 1014 + bool first_time) 1003 1015 { 1004 - struct rbd_image_header *header = &rbd_dev->header; 1005 - bool first_time = header->object_prefix == NULL; 1006 1016 struct ceph_snap_context *snapc; 1007 1017 char *object_prefix = NULL; 1008 1018 char *snap_names = NULL; ··· 1078 1070 if (first_time) { 1079 1071 header->object_prefix = object_prefix; 1080 1072 header->obj_order = ondisk->options.order; 1081 - rbd_init_layout(rbd_dev); 1082 - } else { 1083 - ceph_put_snap_context(header->snapc); 1084 - kfree(header->snap_names); 1085 - kfree(header->snap_sizes); 1086 1073 } 1087 1074 1088 1075 /* The remaining fields always get updated (when we refresh) */ ··· 4862 4859 * return, the rbd_dev->header field will contain up-to-date 4863 4860 * information about the image. 4864 4861 */ 4865 - static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) 4862 + static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev, 4863 + struct rbd_image_header *header, 4864 + bool first_time) 4866 4865 { 4867 4866 struct rbd_image_header_ondisk *ondisk = NULL; 4868 4867 u32 snap_count = 0; ··· 4912 4907 snap_count = le32_to_cpu(ondisk->snap_count); 4913 4908 } while (snap_count != want_count); 4914 4909 4915 - ret = rbd_header_from_disk(rbd_dev, ondisk); 4910 + ret = rbd_header_from_disk(header, ondisk, first_time); 4916 4911 out: 4917 4912 kfree(ondisk); 4918 4913 ··· 4934 4929 dout("setting size to %llu sectors", (unsigned long long)size); 4935 4930 set_capacity_and_notify(rbd_dev->disk, size); 4936 4931 } 4937 - } 4938 - 4939 - static int rbd_dev_refresh(struct rbd_device *rbd_dev) 4940 - { 4941 - u64 mapping_size; 4942 - int ret; 4943 - 4944 - down_write(&rbd_dev->header_rwsem); 4945 - mapping_size = rbd_dev->mapping.size; 4946 - 4947 - ret = rbd_dev_header_info(rbd_dev); 4948 - if (ret) 4949 - goto out; 4950 - 4951 - /* 4952 - * If there is a parent, see if it has disappeared due to the 4953 - * mapped image getting flattened. 4954 - */ 4955 - if (rbd_dev->parent) { 4956 - ret = rbd_dev_v2_parent_info(rbd_dev); 4957 - if (ret) 4958 - goto out; 4959 - } 4960 - 4961 - rbd_assert(!rbd_is_snap(rbd_dev)); 4962 - rbd_dev->mapping.size = rbd_dev->header.image_size; 4963 - 4964 - out: 4965 - up_write(&rbd_dev->header_rwsem); 4966 - if (!ret && mapping_size != rbd_dev->mapping.size) 4967 - rbd_dev_update_size(rbd_dev); 4968 - 4969 - return ret; 4970 4932 } 4971 4933 4972 4934 static const struct blk_mq_ops rbd_mq_ops = { ··· 5475 5503 return 0; 5476 5504 } 5477 5505 5478 - static int rbd_dev_v2_image_size(struct rbd_device *rbd_dev) 5479 - { 5480 - return _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, 5481 - &rbd_dev->header.obj_order, 5482 - &rbd_dev->header.image_size); 5483 - } 5484 - 5485 - static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) 5506 + static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev, 5507 + char **pobject_prefix) 5486 5508 { 5487 5509 size_t size; 5488 5510 void *reply_buf; 5511 + char *object_prefix; 5489 5512 int ret; 5490 5513 void *p; 5491 5514 ··· 5498 5531 goto out; 5499 5532 5500 5533 p = reply_buf; 5501 - rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p, 5502 - p + ret, NULL, GFP_NOIO); 5534 + object_prefix = ceph_extract_encoded_string(&p, p + ret, NULL, 5535 + GFP_NOIO); 5536 + if (IS_ERR(object_prefix)) { 5537 + ret = PTR_ERR(object_prefix); 5538 + goto out; 5539 + } 5503 5540 ret = 0; 5504 5541 5505 - if (IS_ERR(rbd_dev->header.object_prefix)) { 5506 - ret = PTR_ERR(rbd_dev->header.object_prefix); 5507 - rbd_dev->header.object_prefix = NULL; 5508 - } else { 5509 - dout(" object_prefix = %s\n", rbd_dev->header.object_prefix); 5510 - } 5542 + *pobject_prefix = object_prefix; 5543 + dout(" object_prefix = %s\n", object_prefix); 5511 5544 out: 5512 5545 kfree(reply_buf); 5513 5546 ··· 5558 5591 return 0; 5559 5592 } 5560 5593 5561 - static int rbd_dev_v2_features(struct rbd_device *rbd_dev) 5562 - { 5563 - return _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP, 5564 - rbd_is_ro(rbd_dev), 5565 - &rbd_dev->header.features); 5566 - } 5567 - 5568 5594 /* 5569 5595 * These are generic image flags, but since they are used only for 5570 5596 * object map, store them in rbd_dev->object_map_flags. ··· 5593 5633 bool has_overlap; 5594 5634 u64 overlap; 5595 5635 }; 5636 + 5637 + static void rbd_parent_info_cleanup(struct parent_image_info *pii) 5638 + { 5639 + kfree(pii->pool_ns); 5640 + kfree(pii->image_id); 5641 + 5642 + memset(pii, 0, sizeof(*pii)); 5643 + } 5596 5644 5597 5645 /* 5598 5646 * The caller is responsible for @pii. ··· 5671 5703 if (pii->has_overlap) 5672 5704 ceph_decode_64_safe(&p, end, pii->overlap, e_inval); 5673 5705 5706 + dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", 5707 + __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id, 5708 + pii->has_overlap, pii->overlap); 5674 5709 return 0; 5675 5710 5676 5711 e_inval: ··· 5712 5741 pii->has_overlap = true; 5713 5742 ceph_decode_64_safe(&p, end, pii->overlap, e_inval); 5714 5743 5744 + dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", 5745 + __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id, 5746 + pii->has_overlap, pii->overlap); 5715 5747 return 0; 5716 5748 5717 5749 e_inval: 5718 5750 return -EINVAL; 5719 5751 } 5720 5752 5721 - static int get_parent_info(struct rbd_device *rbd_dev, 5722 - struct parent_image_info *pii) 5753 + static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev, 5754 + struct parent_image_info *pii) 5723 5755 { 5724 5756 struct page *req_page, *reply_page; 5725 5757 void *p; ··· 5750 5776 return ret; 5751 5777 } 5752 5778 5753 - static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) 5779 + static int rbd_dev_setup_parent(struct rbd_device *rbd_dev) 5754 5780 { 5755 5781 struct rbd_spec *parent_spec; 5756 5782 struct parent_image_info pii = { 0 }; ··· 5760 5786 if (!parent_spec) 5761 5787 return -ENOMEM; 5762 5788 5763 - ret = get_parent_info(rbd_dev, &pii); 5789 + ret = rbd_dev_v2_parent_info(rbd_dev, &pii); 5764 5790 if (ret) 5765 5791 goto out_err; 5766 5792 5767 - dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", 5768 - __func__, pii.pool_id, pii.pool_ns, pii.image_id, pii.snap_id, 5769 - pii.has_overlap, pii.overlap); 5770 - 5771 - if (pii.pool_id == CEPH_NOPOOL || !pii.has_overlap) { 5772 - /* 5773 - * Either the parent never existed, or we have 5774 - * record of it but the image got flattened so it no 5775 - * longer has a parent. When the parent of a 5776 - * layered image disappears we immediately set the 5777 - * overlap to 0. The effect of this is that all new 5778 - * requests will be treated as if the image had no 5779 - * parent. 5780 - * 5781 - * If !pii.has_overlap, the parent image spec is not 5782 - * applicable. It's there to avoid duplication in each 5783 - * snapshot record. 5784 - */ 5785 - if (rbd_dev->parent_overlap) { 5786 - rbd_dev->parent_overlap = 0; 5787 - rbd_dev_parent_put(rbd_dev); 5788 - pr_info("%s: clone image has been flattened\n", 5789 - rbd_dev->disk->disk_name); 5790 - } 5791 - 5793 + if (pii.pool_id == CEPH_NOPOOL || !pii.has_overlap) 5792 5794 goto out; /* No parent? No problem. */ 5793 - } 5794 5795 5795 5796 /* The ceph file layout needs to fit pool id in 32 bits */ 5796 5797 ··· 5777 5828 } 5778 5829 5779 5830 /* 5780 - * The parent won't change (except when the clone is 5781 - * flattened, already handled that). So we only need to 5782 - * record the parent spec we have not already done so. 5831 + * The parent won't change except when the clone is flattened, 5832 + * so we only need to record the parent image spec once. 5783 5833 */ 5784 - if (!rbd_dev->parent_spec) { 5785 - parent_spec->pool_id = pii.pool_id; 5786 - if (pii.pool_ns && *pii.pool_ns) { 5787 - parent_spec->pool_ns = pii.pool_ns; 5788 - pii.pool_ns = NULL; 5789 - } 5790 - parent_spec->image_id = pii.image_id; 5791 - pii.image_id = NULL; 5792 - parent_spec->snap_id = pii.snap_id; 5793 - 5794 - rbd_dev->parent_spec = parent_spec; 5795 - parent_spec = NULL; /* rbd_dev now owns this */ 5834 + parent_spec->pool_id = pii.pool_id; 5835 + if (pii.pool_ns && *pii.pool_ns) { 5836 + parent_spec->pool_ns = pii.pool_ns; 5837 + pii.pool_ns = NULL; 5796 5838 } 5839 + parent_spec->image_id = pii.image_id; 5840 + pii.image_id = NULL; 5841 + parent_spec->snap_id = pii.snap_id; 5842 + 5843 + rbd_assert(!rbd_dev->parent_spec); 5844 + rbd_dev->parent_spec = parent_spec; 5845 + parent_spec = NULL; /* rbd_dev now owns this */ 5797 5846 5798 5847 /* 5799 - * We always update the parent overlap. If it's zero we issue 5800 - * a warning, as we will proceed as if there was no parent. 5848 + * Record the parent overlap. If it's zero, issue a warning as 5849 + * we will proceed as if there is no parent. 5801 5850 */ 5802 - if (!pii.overlap) { 5803 - if (parent_spec) { 5804 - /* refresh, careful to warn just once */ 5805 - if (rbd_dev->parent_overlap) 5806 - rbd_warn(rbd_dev, 5807 - "clone now standalone (overlap became 0)"); 5808 - } else { 5809 - /* initial probe */ 5810 - rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); 5811 - } 5812 - } 5851 + if (!pii.overlap) 5852 + rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); 5813 5853 rbd_dev->parent_overlap = pii.overlap; 5814 5854 5815 5855 out: 5816 5856 ret = 0; 5817 5857 out_err: 5818 - kfree(pii.pool_ns); 5819 - kfree(pii.image_id); 5858 + rbd_parent_info_cleanup(&pii); 5820 5859 rbd_spec_put(parent_spec); 5821 5860 return ret; 5822 5861 } 5823 5862 5824 - static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) 5863 + static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev, 5864 + u64 *stripe_unit, u64 *stripe_count) 5825 5865 { 5826 5866 struct { 5827 5867 __le64 stripe_unit; 5828 5868 __le64 stripe_count; 5829 5869 } __attribute__ ((packed)) striping_info_buf = { 0 }; 5830 5870 size_t size = sizeof (striping_info_buf); 5831 - void *p; 5832 5871 int ret; 5833 5872 5834 5873 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, ··· 5828 5891 if (ret < size) 5829 5892 return -ERANGE; 5830 5893 5831 - p = &striping_info_buf; 5832 - rbd_dev->header.stripe_unit = ceph_decode_64(&p); 5833 - rbd_dev->header.stripe_count = ceph_decode_64(&p); 5894 + *stripe_unit = le64_to_cpu(striping_info_buf.stripe_unit); 5895 + *stripe_count = le64_to_cpu(striping_info_buf.stripe_count); 5896 + dout(" stripe_unit = %llu stripe_count = %llu\n", *stripe_unit, 5897 + *stripe_count); 5898 + 5834 5899 return 0; 5835 5900 } 5836 5901 5837 - static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev) 5902 + static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev, s64 *data_pool_id) 5838 5903 { 5839 - __le64 data_pool_id; 5904 + __le64 data_pool_buf; 5840 5905 int ret; 5841 5906 5842 5907 ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, 5843 5908 &rbd_dev->header_oloc, "get_data_pool", 5844 - NULL, 0, &data_pool_id, sizeof(data_pool_id)); 5909 + NULL, 0, &data_pool_buf, 5910 + sizeof(data_pool_buf)); 5911 + dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); 5845 5912 if (ret < 0) 5846 5913 return ret; 5847 - if (ret < sizeof(data_pool_id)) 5914 + if (ret < sizeof(data_pool_buf)) 5848 5915 return -EBADMSG; 5849 5916 5850 - rbd_dev->header.data_pool_id = le64_to_cpu(data_pool_id); 5851 - WARN_ON(rbd_dev->header.data_pool_id == CEPH_NOPOOL); 5917 + *data_pool_id = le64_to_cpu(data_pool_buf); 5918 + dout(" data_pool_id = %lld\n", *data_pool_id); 5919 + WARN_ON(*data_pool_id == CEPH_NOPOOL); 5920 + 5852 5921 return 0; 5853 5922 } 5854 5923 ··· 6046 6103 return ret; 6047 6104 } 6048 6105 6049 - static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev) 6106 + static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, 6107 + struct ceph_snap_context **psnapc) 6050 6108 { 6051 6109 size_t size; 6052 6110 int ret; ··· 6108 6164 for (i = 0; i < snap_count; i++) 6109 6165 snapc->snaps[i] = ceph_decode_64(&p); 6110 6166 6111 - ceph_put_snap_context(rbd_dev->header.snapc); 6112 - rbd_dev->header.snapc = snapc; 6113 - 6167 + *psnapc = snapc; 6114 6168 dout(" snap context seq = %llu, snap_count = %u\n", 6115 6169 (unsigned long long)seq, (unsigned int)snap_count); 6116 6170 out: ··· 6157 6215 return snap_name; 6158 6216 } 6159 6217 6160 - static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev) 6218 + static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev, 6219 + struct rbd_image_header *header, 6220 + bool first_time) 6161 6221 { 6162 - bool first_time = rbd_dev->header.object_prefix == NULL; 6163 6222 int ret; 6164 6223 6165 - ret = rbd_dev_v2_image_size(rbd_dev); 6224 + ret = _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, 6225 + first_time ? &header->obj_order : NULL, 6226 + &header->image_size); 6166 6227 if (ret) 6167 6228 return ret; 6168 6229 6169 6230 if (first_time) { 6170 - ret = rbd_dev_v2_header_onetime(rbd_dev); 6231 + ret = rbd_dev_v2_header_onetime(rbd_dev, header); 6171 6232 if (ret) 6172 6233 return ret; 6173 6234 } 6174 6235 6175 - ret = rbd_dev_v2_snap_context(rbd_dev); 6176 - if (ret && first_time) { 6177 - kfree(rbd_dev->header.object_prefix); 6178 - rbd_dev->header.object_prefix = NULL; 6179 - } 6236 + ret = rbd_dev_v2_snap_context(rbd_dev, &header->snapc); 6237 + if (ret) 6238 + return ret; 6180 6239 6181 - return ret; 6240 + return 0; 6182 6241 } 6183 6242 6184 - static int rbd_dev_header_info(struct rbd_device *rbd_dev) 6243 + static int rbd_dev_header_info(struct rbd_device *rbd_dev, 6244 + struct rbd_image_header *header, 6245 + bool first_time) 6185 6246 { 6186 6247 rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); 6248 + rbd_assert(!header->object_prefix && !header->snapc); 6187 6249 6188 6250 if (rbd_dev->image_format == 1) 6189 - return rbd_dev_v1_header_info(rbd_dev); 6251 + return rbd_dev_v1_header_info(rbd_dev, header, first_time); 6190 6252 6191 - return rbd_dev_v2_header_info(rbd_dev); 6253 + return rbd_dev_v2_header_info(rbd_dev, header, first_time); 6192 6254 } 6193 6255 6194 6256 /* ··· 6680 6734 */ 6681 6735 static void rbd_dev_unprobe(struct rbd_device *rbd_dev) 6682 6736 { 6683 - struct rbd_image_header *header; 6684 - 6685 6737 rbd_dev_parent_put(rbd_dev); 6686 6738 rbd_object_map_free(rbd_dev); 6687 6739 rbd_dev_mapping_clear(rbd_dev); 6688 6740 6689 6741 /* Free dynamic fields from the header, then zero it out */ 6690 6742 6691 - header = &rbd_dev->header; 6692 - ceph_put_snap_context(header->snapc); 6693 - kfree(header->snap_sizes); 6694 - kfree(header->snap_names); 6695 - kfree(header->object_prefix); 6696 - memset(header, 0, sizeof (*header)); 6743 + rbd_image_header_cleanup(&rbd_dev->header); 6697 6744 } 6698 6745 6699 - static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev) 6746 + static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev, 6747 + struct rbd_image_header *header) 6700 6748 { 6701 6749 int ret; 6702 6750 6703 - ret = rbd_dev_v2_object_prefix(rbd_dev); 6751 + ret = rbd_dev_v2_object_prefix(rbd_dev, &header->object_prefix); 6704 6752 if (ret) 6705 - goto out_err; 6753 + return ret; 6706 6754 6707 6755 /* 6708 6756 * Get the and check features for the image. Currently the 6709 6757 * features are assumed to never change. 6710 6758 */ 6711 - ret = rbd_dev_v2_features(rbd_dev); 6759 + ret = _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP, 6760 + rbd_is_ro(rbd_dev), &header->features); 6712 6761 if (ret) 6713 - goto out_err; 6762 + return ret; 6714 6763 6715 6764 /* If the image supports fancy striping, get its parameters */ 6716 6765 6717 - if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) { 6718 - ret = rbd_dev_v2_striping_info(rbd_dev); 6719 - if (ret < 0) 6720 - goto out_err; 6721 - } 6722 - 6723 - if (rbd_dev->header.features & RBD_FEATURE_DATA_POOL) { 6724 - ret = rbd_dev_v2_data_pool(rbd_dev); 6766 + if (header->features & RBD_FEATURE_STRIPINGV2) { 6767 + ret = rbd_dev_v2_striping_info(rbd_dev, &header->stripe_unit, 6768 + &header->stripe_count); 6725 6769 if (ret) 6726 - goto out_err; 6770 + return ret; 6727 6771 } 6728 6772 6729 - rbd_init_layout(rbd_dev); 6730 - return 0; 6773 + if (header->features & RBD_FEATURE_DATA_POOL) { 6774 + ret = rbd_dev_v2_data_pool(rbd_dev, &header->data_pool_id); 6775 + if (ret) 6776 + return ret; 6777 + } 6731 6778 6732 - out_err: 6733 - rbd_dev->header.features = 0; 6734 - kfree(rbd_dev->header.object_prefix); 6735 - rbd_dev->header.object_prefix = NULL; 6736 - return ret; 6779 + return 0; 6737 6780 } 6738 6781 6739 6782 /* ··· 6917 6982 if (!depth) 6918 6983 down_write(&rbd_dev->header_rwsem); 6919 6984 6920 - ret = rbd_dev_header_info(rbd_dev); 6985 + ret = rbd_dev_header_info(rbd_dev, &rbd_dev->header, true); 6921 6986 if (ret) { 6922 6987 if (ret == -ENOENT && !need_watch) 6923 6988 rbd_print_dne(rbd_dev, false); 6924 6989 goto err_out_probe; 6925 6990 } 6991 + 6992 + rbd_init_layout(rbd_dev); 6926 6993 6927 6994 /* 6928 6995 * If this image is the one being mapped, we have pool name and ··· 6954 7017 } 6955 7018 6956 7019 if (rbd_dev->header.features & RBD_FEATURE_LAYERING) { 6957 - ret = rbd_dev_v2_parent_info(rbd_dev); 7020 + ret = rbd_dev_setup_parent(rbd_dev); 6958 7021 if (ret) 6959 7022 goto err_out_probe; 6960 7023 } ··· 6977 7040 rbd_dev->image_format = 0; 6978 7041 kfree(rbd_dev->spec->image_id); 6979 7042 rbd_dev->spec->image_id = NULL; 7043 + return ret; 7044 + } 7045 + 7046 + static void rbd_dev_update_header(struct rbd_device *rbd_dev, 7047 + struct rbd_image_header *header) 7048 + { 7049 + rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); 7050 + rbd_assert(rbd_dev->header.object_prefix); /* !first_time */ 7051 + 7052 + if (rbd_dev->header.image_size != header->image_size) { 7053 + rbd_dev->header.image_size = header->image_size; 7054 + 7055 + if (!rbd_is_snap(rbd_dev)) { 7056 + rbd_dev->mapping.size = header->image_size; 7057 + rbd_dev_update_size(rbd_dev); 7058 + } 7059 + } 7060 + 7061 + ceph_put_snap_context(rbd_dev->header.snapc); 7062 + rbd_dev->header.snapc = header->snapc; 7063 + header->snapc = NULL; 7064 + 7065 + if (rbd_dev->image_format == 1) { 7066 + kfree(rbd_dev->header.snap_names); 7067 + rbd_dev->header.snap_names = header->snap_names; 7068 + header->snap_names = NULL; 7069 + 7070 + kfree(rbd_dev->header.snap_sizes); 7071 + rbd_dev->header.snap_sizes = header->snap_sizes; 7072 + header->snap_sizes = NULL; 7073 + } 7074 + } 7075 + 7076 + static void rbd_dev_update_parent(struct rbd_device *rbd_dev, 7077 + struct parent_image_info *pii) 7078 + { 7079 + if (pii->pool_id == CEPH_NOPOOL || !pii->has_overlap) { 7080 + /* 7081 + * Either the parent never existed, or we have 7082 + * record of it but the image got flattened so it no 7083 + * longer has a parent. When the parent of a 7084 + * layered image disappears we immediately set the 7085 + * overlap to 0. The effect of this is that all new 7086 + * requests will be treated as if the image had no 7087 + * parent. 7088 + * 7089 + * If !pii.has_overlap, the parent image spec is not 7090 + * applicable. It's there to avoid duplication in each 7091 + * snapshot record. 7092 + */ 7093 + if (rbd_dev->parent_overlap) { 7094 + rbd_dev->parent_overlap = 0; 7095 + rbd_dev_parent_put(rbd_dev); 7096 + pr_info("%s: clone has been flattened\n", 7097 + rbd_dev->disk->disk_name); 7098 + } 7099 + } else { 7100 + rbd_assert(rbd_dev->parent_spec); 7101 + 7102 + /* 7103 + * Update the parent overlap. If it became zero, issue 7104 + * a warning as we will proceed as if there is no parent. 7105 + */ 7106 + if (!pii->overlap && rbd_dev->parent_overlap) 7107 + rbd_warn(rbd_dev, 7108 + "clone has become standalone (overlap 0)"); 7109 + rbd_dev->parent_overlap = pii->overlap; 7110 + } 7111 + } 7112 + 7113 + static int rbd_dev_refresh(struct rbd_device *rbd_dev) 7114 + { 7115 + struct rbd_image_header header = { 0 }; 7116 + struct parent_image_info pii = { 0 }; 7117 + int ret; 7118 + 7119 + dout("%s rbd_dev %p\n", __func__, rbd_dev); 7120 + 7121 + ret = rbd_dev_header_info(rbd_dev, &header, false); 7122 + if (ret) 7123 + goto out; 7124 + 7125 + /* 7126 + * If there is a parent, see if it has disappeared due to the 7127 + * mapped image getting flattened. 7128 + */ 7129 + if (rbd_dev->parent) { 7130 + ret = rbd_dev_v2_parent_info(rbd_dev, &pii); 7131 + if (ret) 7132 + goto out; 7133 + } 7134 + 7135 + down_write(&rbd_dev->header_rwsem); 7136 + rbd_dev_update_header(rbd_dev, &header); 7137 + if (rbd_dev->parent) 7138 + rbd_dev_update_parent(rbd_dev, &pii); 7139 + up_write(&rbd_dev->header_rwsem); 7140 + 7141 + out: 7142 + rbd_parent_info_cleanup(&pii); 7143 + rbd_image_header_cleanup(&header); 6980 7144 return ret; 6981 7145 } 6982 7146
+2 -4
fs/ceph/crypto.c
··· 249 249 if (!dir) { 250 250 /* This can happen if we're not mounting cephfs on the root */ 251 251 dir = ceph_get_inode(parent->i_sb, vino, NULL); 252 - if (!dir) 253 - dir = ERR_PTR(-ENOENT); 252 + if (IS_ERR(dir)) 253 + dout("Can't find inode %s (%s)\n", inode_number, name); 254 254 } 255 - if (IS_ERR(dir)) 256 - dout("Can't find inode %s (%s)\n", inode_number, name); 257 255 258 256 out: 259 257 kfree(inode_number);
+11 -13
include/linux/ceph/ceph_fs.h
··· 467 467 } __attribute__ ((packed)); 468 468 469 469 union ceph_mds_request_args_ext { 470 - union { 471 - union ceph_mds_request_args old; 472 - struct { 473 - __le32 mode; 474 - __le32 uid; 475 - __le32 gid; 476 - struct ceph_timespec mtime; 477 - struct ceph_timespec atime; 478 - __le64 size, old_size; /* old_size needed by truncate */ 479 - __le32 mask; /* CEPH_SETATTR_* */ 480 - struct ceph_timespec btime; 481 - } __attribute__ ((packed)) setattr_ext; 482 - }; 470 + union ceph_mds_request_args old; 471 + struct { 472 + __le32 mode; 473 + __le32 uid; 474 + __le32 gid; 475 + struct ceph_timespec mtime; 476 + struct ceph_timespec atime; 477 + __le64 size, old_size; /* old_size needed by truncate */ 478 + __le32 mask; /* CEPH_SETATTR_* */ 479 + struct ceph_timespec btime; 480 + } __attribute__ ((packed)) setattr_ext; 483 481 }; 484 482 485 483 #define CEPH_MDS_FLAG_REPLAY 1 /* this is a replayed op */