FAILED: patch "[PATCH] rbd: call rbd_dev_unprobe() after unwatching and flushing" 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]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 952c48b0ed18919bff7528501e9a3fff8a24f8cd Mon Sep 17 00:00:00 2001
From: Ilya Dryomov <[email protected]>
Date: Mon, 16 Mar 2020 15:52:54 +0100
Subject: [PATCH] rbd: call rbd_dev_unprobe() after unwatching and flushing
notifies
rbd_dev_unprobe() is supposed to undo most of rbd_dev_image_probe(), including rbd_dev_header_info(), which means that rbd_dev_header_info() isn't supposed to be called after rbd_dev_unprobe().
However, rbd_dev_image_release() calls rbd_dev_unprobe() before rbd_unregister_watch(). This is racy because a header update notify can sneak in:
"rbd unmap" thread ceph-watch-notify worker
rbd_dev_image_release()
rbd_dev_unprobe()
free and zero out header
rbd_watch_cb()
rbd_dev_refresh()
rbd_dev_header_info()
read in header
The same goes for "rbd map" because rbd_dev_image_probe() calls rbd_dev_unprobe() on errors. In both cases this results in a memory leak.
drivers/block/rbd.c +4 -4
@@ -6898,9 +6898,10 @@ static void rbd_print_dne(struct rbd_device *rbd_dev, bool is_snap)static void rbd_dev_image_release (struct rbd_device *rbd_dev) { -rbd_dev_unprobe (rbd_dev);if (rbd_dev->opts)rbd_unregister_watch (rbd_dev); + +rbd_dev_unprobe (rbd_dev); rbd_dev->image_format =0 ;kfree (rbd_dev->spec->image_id); rbd_dev->spec->image_id =NULL ;
@@ -6950,7 +6951,7 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)if (ret) {if (ret == -ENOENT && !need_watch)rbd_print_dne (rbd_dev, false); - goto err_out_watch; + goto err_out_probe; }/*
@@ -6995,12 +6996,11 @@ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth)return 0 ; err_out_probe: -rbd_dev_unprobe (rbd_dev); -err_out_watch:if (!depth)up_write (&rbd_dev->header_rwsem);if (need_watch)rbd_unregister_watch (rbd_dev); +rbd_dev_unprobe (rbd_dev); err_out_format: rbd_dev->image_format =0 ;kfree (rbd_dev->spec->image_id);
Sasha Levin
maintainerQuoted 36 lines · On Tue, Apr 21, 2020 at 07:07:22PM +0200, [email protected] wrote:
The 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]>.thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From
952c48b0ed18919bff7528501e9a3fff8a24f8cdMon Sep 17 00:00:00 2001
From: Ilya Dryomov <[email protected]>
Date: Mon, 16 Mar 2020 15:52:54 +0100
Subject: [PATCH] rbd: callrbd_dev_unprobe()after unwatching and flushing notifies
rbd_dev_unprobe()is supposed to undo most ofrbd_dev_image_probe(), includingrbd_dev_header_info(), which means thatrbd_dev_header_info()isn't supposed to be called afterrbd_dev_unprobe().However,
rbd_dev_image_release()callsrbd_dev_unprobe()beforerbd_unregister_watch(). This is racy because a header update notify can sneak in:"rbd unmap" thread ceph-watch-notify worker
rbd_dev_image_release()
rbd_dev_unprobe()
free and zero out header
rbd_watch_cb()
rbd_dev_refresh()
rbd_dev_header_info()
read in header
Quoted 7 lines
The same goes for "rbd map" because
rbd_dev_image_probe()callsrbd_dev_unprobe()on errors. In both cases this results in a memory leak.Fixes fd22aef8b47c ("rbd: move rbd_unregister_watch() call into rbd_dev_image_release()")Signed-off-by Ilya Dryomov <[email protected]>Reviewed-by Jason Dillaman <[email protected]>
Another conflict because we miss b9ef2b8858a0 ("rbd: don't establish watch for read-only mappings") on 5.4 and older. Fixed and queued up for 5.4-4.14.
Signature · 2 lines
Thanks, Sasha