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 branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client

Pull Ceph fixes from Sage Weil:
"These paches from Ilya finally squash a race condition with layered
images that he's been chasing for a while"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
rbd: drop parent_ref in rbd_dev_unprobe() unconditionally
rbd: fix rbd_dev_parent_get() when parent_overlap == 0

+7 -18
+7 -18
drivers/block/rbd.c
··· 2098 2098 * If an image has a non-zero parent overlap, get a reference to its 2099 2099 * parent. 2100 2100 * 2101 - * We must get the reference before checking for the overlap to 2102 - * coordinate properly with zeroing the parent overlap in 2103 - * rbd_dev_v2_parent_info() when an image gets flattened. We 2104 - * drop it again if there is no overlap. 2105 - * 2106 2101 * Returns true if the rbd device has a parent with a non-zero 2107 2102 * overlap and a reference for it was successfully taken, or 2108 2103 * false otherwise. 2109 2104 */ 2110 2105 static bool rbd_dev_parent_get(struct rbd_device *rbd_dev) 2111 2106 { 2112 - int counter; 2107 + int counter = 0; 2113 2108 2114 2109 if (!rbd_dev->parent_spec) 2115 2110 return false; 2116 2111 2117 - counter = atomic_inc_return_safe(&rbd_dev->parent_ref); 2118 - if (counter > 0 && rbd_dev->parent_overlap) 2119 - return true; 2120 - 2121 - /* Image was flattened, but parent is not yet torn down */ 2112 + down_read(&rbd_dev->header_rwsem); 2113 + if (rbd_dev->parent_overlap) 2114 + counter = atomic_inc_return_safe(&rbd_dev->parent_ref); 2115 + up_read(&rbd_dev->header_rwsem); 2122 2116 2123 2117 if (counter < 0) 2124 2118 rbd_warn(rbd_dev, "parent reference overflow"); 2125 2119 2126 - return false; 2120 + return counter > 0; 2127 2121 } 2128 2122 2129 2123 /* ··· 4233 4239 */ 4234 4240 if (rbd_dev->parent_overlap) { 4235 4241 rbd_dev->parent_overlap = 0; 4236 - smp_mb(); 4237 4242 rbd_dev_parent_put(rbd_dev); 4238 4243 pr_info("%s: clone image has been flattened\n", 4239 4244 rbd_dev->disk->disk_name); ··· 4278 4285 * treat it specially. 4279 4286 */ 4280 4287 rbd_dev->parent_overlap = overlap; 4281 - smp_mb(); 4282 4288 if (!overlap) { 4283 4289 4284 4290 /* A null parent_spec indicates it's the initial probe */ ··· 5106 5114 { 5107 5115 struct rbd_image_header *header; 5108 5116 5109 - /* Drop parent reference unless it's already been done (or none) */ 5110 - 5111 - if (rbd_dev->parent_overlap) 5112 - rbd_dev_parent_put(rbd_dev); 5117 + rbd_dev_parent_put(rbd_dev); 5113 5118 5114 5119 /* Free dynamic fields from the header, then zero it out */ 5115 5120