FAILED: patch "[PATCH] rbd: decouple header read-in from updating rbd_dev->header" failed to apply to 5.4-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.4.y
git checkout FETCH_HEAD
git cherry-pick -x 510a7330c82a
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2023100421-grip-velcro-c774@gregkh' --subject-prefix 'PATCH 5.4.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 510a7330c82a7754d5df0117a8589e8a539067c7 Mon Sep 17 00:00:00 2001
From: Ilya Dryomov <[email protected]>
Date: Tue, 19 Sep 2023 20:41:47 +0200
Subject: [PATCH] rbd: decouple header read-in from updating rbd_dev->header
Make rbd_dev_header_info() populate a passed struct rbd_image_header instead of rbd_dev->header and introduce rbd_dev_update_header() for updating mutable fields in rbd_dev->header upon refresh. The initial read-in of both mutable and immutable fields in rbd_dev_image_probe() passes in rbd_dev->header so no update step is required there.
rbd_init_layout() is now called directly from rbd_dev_image_probe() instead of individually in format 1 and format 2 implementations.
drivers/block/rbd.c +116 -94
@@ -632,7 +632,8 @@ void rbd_warn(struct rbd_device *rbd_dev, const char *fmt, ...)static void rbd_dev_remove_parent (struct rbd_device *rbd_dev);static int rbd_dev_refresh (struct rbd_device *rbd_dev); -static int rbd_dev_v2_header_onetime (struct rbd_device *rbd_dev); +static int rbd_dev_v2_header_onetime (struct rbd_device *rbd_dev, +struct rbd_image_header *header);static const char *rbd_dev_v2_snap_name (struct rbd_device *rbd_dev,u64 snap_id); static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
@@ -993,15 +994,24 @@ static void rbd_init_layout(struct rbd_device *rbd_dev)RCU_INIT_POINTER (rbd_dev->layout.pool_ns,NULL ); } +static void rbd_image_header_cleanup (struct rbd_image_header *header) +{ +kfree (header->object_prefix); +ceph_put_snap_context (header->snapc); +kfree (header->snap_sizes); +kfree (header->snap_names); + +memset (header,0 ,sizeof (*header)); +} +/* * Fill an rbd image header with information from the given format 1 * on-disk header. */ -static int rbd_header_from_disk (struct rbd_device *rbd_dev, -struct rbd_image_header_ondisk *ondisk) +static int rbd_header_from_disk (struct rbd_image_header *header, +struct rbd_image_header_ondisk *ondisk, +bool first_time) { -struct rbd_image_header *header = &rbd_dev->header; -bool first_time = header->object_prefix ==NULL ;struct ceph_snap_context *snapc;char *object_prefix =NULL ;char *snap_names =NULL ;
@@ -1068,11 +1078,6 @@ static int rbd_header_from_disk(struct rbd_device *rbd_dev,if (first_time) { header->object_prefix = object_prefix; header->obj_order = ondisk->options.order; -rbd_init_layout (rbd_dev); - }else { -ceph_put_snap_context (header->snapc); -kfree (header->snap_names); -kfree (header->snap_sizes); }/* The remaining fields always get updated (when we refresh) */
@@ -4857,7 +4862,9 @@ static int rbd_obj_read_sync(struct rbd_device *rbd_dev,* return, the rbd_dev->header field will contain up-to-date * information about the image. */ -static int rbd_dev_v1_header_info (struct rbd_device *rbd_dev) +static int rbd_dev_v1_header_info (struct rbd_device *rbd_dev, +struct rbd_image_header *header, +bool first_time) {struct rbd_image_header_ondisk *ondisk =NULL ;u32 snap_count =0 ;
@@ -4905,7 +4912,7 @@ static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) snap_count =le32_to_cpu (ondisk->snap_count); }while (snap_count != want_count); - ret =rbd_header_from_disk (rbd_dev, ondisk); + ret =rbd_header_from_disk (header, ondisk, first_time); out:kfree (ondisk);
@@ -5468,17 +5475,12 @@ static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id,return 0 ; } -static int rbd_dev_v2_image_size (struct rbd_device *rbd_dev) -{ -return _rbd_dev_v2_snap_size (rbd_dev,CEPH_NOSNAP , - &rbd_dev->header.obj_order, - &rbd_dev->header.image_size); -} - -static int rbd_dev_v2_object_prefix (struct rbd_device *rbd_dev) +static int rbd_dev_v2_object_prefix (struct rbd_device *rbd_dev, +char **pobject_prefix) {size_t size;void *reply_buf; +char *object_prefix;int ret;void *p;
@@ -5496,16 +5498,16 @@ static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) goto out; p = reply_buf; - rbd_dev->header.object_prefix =ceph_extract_encoded_string (&p, - p + ret,NULL ,GFP_NOIO ); + object_prefix =ceph_extract_encoded_string (&p, p + ret,NULL , +GFP_NOIO ); +if (IS_ERR (object_prefix)) { + ret =PTR_ERR (object_prefix); + goto out; + } ret =0 ; -if (IS_ERR (rbd_dev->header.object_prefix)) { - ret =PTR_ERR (rbd_dev->header.object_prefix); - rbd_dev->header.object_prefix =NULL ; - }else { -dout (" object_prefix = %s\n" , rbd_dev->header.object_prefix); - } + *pobject_prefix = object_prefix; +dout (" object_prefix = %s\n" , object_prefix); out:kfree (reply_buf);
@@ -5556,13 +5558,6 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id,return 0 ; } -static int rbd_dev_v2_features (struct rbd_device *rbd_dev) -{ -return _rbd_dev_v2_snap_features (rbd_dev,CEPH_NOSNAP , -rbd_is_ro (rbd_dev), - &rbd_dev->header.features); -} -/* * These are generic image flags, but since they are used only for * object map, store them in rbd_dev->object_map_flags.
@@ -5837,14 +5832,14 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev)return ret; } -static int rbd_dev_v2_striping_info (struct rbd_device *rbd_dev) +static int rbd_dev_v2_striping_info (struct rbd_device *rbd_dev, +u64 *stripe_unit,u64 *stripe_count) {struct {__le64 stripe_unit;__le64 stripe_count; } __attribute__ ((packed)) striping_info_buf = {0 };size_t size =sizeof (striping_info_buf); -void *p;int ret; ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid,
@@ -5856,27 +5851,33 @@ static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev)if (ret < size)return -ERANGE ; - p = &striping_info_buf; - rbd_dev->header.stripe_unit =ceph_decode_64 (&p); - rbd_dev->header.stripe_count =ceph_decode_64 (&p); + *stripe_unit =le64_to_cpu (striping_info_buf.stripe_unit); + *stripe_count =le64_to_cpu (striping_info_buf.stripe_count); +dout (" stripe_unit = %llu stripe_count = %llu\n" , *stripe_unit, + *stripe_count); +return 0 ; } -static int rbd_dev_v2_data_pool (struct rbd_device *rbd_dev) +static int rbd_dev_v2_data_pool (struct rbd_device *rbd_dev,s64 *data_pool_id) { -__le64 data_pool_id; +__le64 data_pool_buf;int ret; ret =rbd_obj_method_sync (rbd_dev, &rbd_dev->header_oid, &rbd_dev->header_oloc,"get_data_pool" , -NULL ,0 , &data_pool_id,sizeof (data_pool_id)); +NULL ,0 , &data_pool_buf, +sizeof (data_pool_buf)); +dout ("%s: rbd_obj_method_sync returned %d\n" , __func__, ret);if (ret <0 )return ret; -if (ret <sizeof (data_pool_id)) +if (ret <sizeof (data_pool_buf))return -EBADMSG ; - rbd_dev->header.data_pool_id =le64_to_cpu (data_pool_id); -WARN_ON (rbd_dev->header.data_pool_id ==CEPH_NOPOOL ); + *data_pool_id =le64_to_cpu (data_pool_buf); +dout (" data_pool_id = %lld\n" , *data_pool_id); +WARN_ON (*data_pool_id ==CEPH_NOPOOL ); +return 0 ; }
@@ -6068,7 +6069,8 @@ static int rbd_spec_fill_names(struct rbd_device *rbd_dev)return ret; } -static int rbd_dev_v2_snap_context (struct rbd_device *rbd_dev) +static int rbd_dev_v2_snap_context (struct rbd_device *rbd_dev, +struct ceph_snap_context **psnapc) {size_t size;int ret;
@@ -6129,9 +6131,7 @@ static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev)for (i =0 ; i < snap_count; i++) snapc->snaps[i] =ceph_decode_64 (&p); -ceph_put_snap_context (rbd_dev->header.snapc); - rbd_dev->header.snapc = snapc; - + *psnapc = snapc;dout (" snap context seq = %llu, snap_count = %u\n" , (unsigned long long )seq, (unsigned int )snap_count); out:
@@ -6180,38 +6180,42 @@ static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev,return snap_name; } -static int rbd_dev_v2_header_info (struct rbd_device *rbd_dev) +static int rbd_dev_v2_header_info (struct rbd_device *rbd_dev, +struct rbd_image_header *header, +bool first_time) { -bool first_time = rbd_dev->header.object_prefix ==NULL ;int ret; - ret =rbd_dev_v2_image_size (rbd_dev); + ret =_rbd_dev_v2_snap_size (rbd_dev,CEPH_NOSNAP , + first_time ? &header->obj_order :NULL , + &header->image_size);if (ret)return ret;if (first_time) { - ret =rbd_dev_v2_header_onetime (rbd_dev); + ret =rbd_dev_v2_header_onetime (rbd_dev, header);if (ret)return ret; } - ret =rbd_dev_v2_snap_context (rbd_dev); -if (ret && first_time) { -kfree (rbd_dev->header.object_prefix); - rbd_dev->header.object_prefix =NULL ; - } + ret =rbd_dev_v2_snap_context (rbd_dev, &header->snapc); +if (ret) +return ret; -return ret; +return 0 ; } -static int rbd_dev_header_info (struct rbd_device *rbd_dev) +static int rbd_dev_header_info (struct rbd_device *rbd_dev, +struct rbd_image_header *header, +bool first_time) {rbd_assert (rbd_image_format_valid (rbd_dev->image_format)); +rbd_assert (!header->object_prefix && !header->snapc);if (rbd_dev->image_format ==1 ) -return rbd_dev_v1_header_info (rbd_dev); +return rbd_dev_v1_header_info (rbd_dev, header, first_time); -return rbd_dev_v2_header_info (rbd_dev); +return rbd_dev_v2_header_info (rbd_dev, header, first_time); }/*
@@ -6699,60 +6703,49 @@ static int rbd_dev_image_id(struct rbd_device *rbd_dev)*/ static void rbd_dev_unprobe (struct rbd_device *rbd_dev) { -struct rbd_image_header *header; -rbd_dev_parent_put (rbd_dev);rbd_object_map_free (rbd_dev);rbd_dev_mapping_clear (rbd_dev);/* Free dynamic fields from the header, then zero it out */ - header = &rbd_dev->header; -ceph_put_snap_context (header->snapc); -kfree (header->snap_sizes); -kfree (header->snap_names); -kfree (header->object_prefix); -memset (header,0 ,sizeof (*header)); +rbd_image_header_cleanup (&rbd_dev->header); } -static int rbd_dev_v2_header_onetime (struct rbd_device *rbd_dev) +static int rbd_dev_v2_header_onetime (struct rbd_device *rbd_dev, +struct rbd_image_header *header) {int ret; - ret =rbd_dev_v2_object_prefix (rbd_dev); + ret =rbd_dev_v2_object_prefix (rbd_dev, &header->object_prefix);if (ret) - goto out_err; +return ret;/* * Get the and check features for the image. Currently the * features are assumed to never change. */ - ret =rbd_dev_v2_features (rbd_dev); + ret =_rbd_dev_v2_snap_features (rbd_dev,CEPH_NOSNAP , +rbd_is_ro (rbd_dev), &header->features);if (ret) - goto out_err; +return ret;/* If the image supports fancy striping, get its parameters */ -if (rbd_dev->header.features &RBD_FEATURE_STRIPINGV2 ) { - ret =rbd_dev_v2_striping_info (rbd_dev); -if (ret <0 ) - goto out_err; - } - -if (rbd_dev->header.features &RBD_FEATURE_DATA_POOL ) { - ret =rbd_dev_v2_data_pool (rbd_dev); +if (header->features &RBD_FEATURE_STRIPINGV2 ) { + ret =rbd_dev_v2_striping_info (rbd_dev, &header->stripe_unit, + &header->stripe_count);if (ret) - goto out_err; +return ret; } -rbd_init_layout (rbd_dev); -return 0 ; +if (header->features &RBD_FEATURE_DATA_POOL ) { + ret =rbd_dev_v2_data_pool (rbd_dev, &header->data_pool_id); +if (ret) +return ret; + } -out_err: - rbd_dev->header.features =0 ; -kfree (rbd_dev->header.object_prefix); - rbd_dev->header.object_prefix =NULL ; -return ret; +return 0 ; }/*
@@ -6947,13 +6940,15 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)if (!depth)down_write (&rbd_dev->header_rwsem); - ret =rbd_dev_header_info (rbd_dev); + ret =rbd_dev_header_info (rbd_dev, &rbd_dev->header, true);if (ret) {if (ret == -ENOENT && !need_watch)rbd_print_dne (rbd_dev, false); goto err_out_probe; } +rbd_init_layout (rbd_dev); +/* * If this image is the one being mapped, we have pool name and * id, image name and id, and snap name - need to fill snap id.
@@ -7008,15 +7003,39 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)return ret; } +static void rbd_dev_update_header (struct rbd_device *rbd_dev, +struct rbd_image_header *header) +{ +rbd_assert (rbd_image_format_valid (rbd_dev->image_format)); +rbd_assert (rbd_dev->header.object_prefix);/* !first_time */ + + rbd_dev->header.image_size = header->image_size; + +ceph_put_snap_context (rbd_dev->header.snapc); + rbd_dev->header.snapc = header->snapc; + header->snapc =NULL ; + +if (rbd_dev->image_format ==1 ) { +kfree (rbd_dev->header.snap_names); + rbd_dev->header.snap_names = header->snap_names; + header->snap_names =NULL ; + +kfree (rbd_dev->header.snap_sizes); + rbd_dev->header.snap_sizes = header->snap_sizes; + header->snap_sizes =NULL ; + } +} +static int rbd_dev_refresh (struct rbd_device *rbd_dev) { +struct rbd_image_header header = {0 };u64 mapping_size;int ret;down_write (&rbd_dev->header_rwsem); mapping_size = rbd_dev->mapping.size; - ret =rbd_dev_header_info (rbd_dev); + ret =rbd_dev_header_info (rbd_dev, &header, false);if (ret) goto out;
@@ -7030,6 +7049,8 @@ static int rbd_dev_refresh(struct rbd_device *rbd_dev) goto out; } +rbd_dev_update_header (rbd_dev, &header); +rbd_assert (!rbd_is_snap (rbd_dev)); rbd_dev->mapping.size = rbd_dev->header.image_size;
@@ -7038,6 +7059,7 @@ static int rbd_dev_refresh(struct rbd_device *rbd_dev)if (!ret && mapping_size != rbd_dev->mapping.size)rbd_dev_update_size (rbd_dev); +rbd_image_header_cleanup (&header);return ret; }