1 From bb229bbb3bf63d23128e851a1f3b85c083178fa1 Mon Sep 17 00:00:00 2001
2 From: Ilya Dryomov <idryomov@gmail.com>
3 Date: Wed, 20 Mar 2019 09:46:58 +0100
4 Subject: libceph: wait for latest osdmap in ceph_monc_blacklist_add()
6 From: Ilya Dryomov <idryomov@gmail.com>
8 commit bb229bbb3bf63d23128e851a1f3b85c083178fa1 upstream.
10 Because map updates are distributed lazily, an OSD may not know about
11 the new blacklist for quite some time after "osd blacklist add" command
12 is completed. This makes it possible for a blacklisted but still alive
13 client to overwrite a post-blacklist update, resulting in data
16 Waiting for latest osdmap in ceph_monc_blacklist_add() and thus using
17 the post-blacklist epoch for all post-blacklist requests ensures that
18 all such requests "wait" for the blacklist to come into force on their
21 Cc: stable@vger.kernel.org
22 Fixes: 6305a3b41515 ("libceph: support for blacklisting clients")
23 Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
24 Reviewed-by: Jason Dillaman <dillaman@redhat.com>
25 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28 include/linux/ceph/libceph.h | 2 ++
29 net/ceph/ceph_common.c | 18 +++++++++++++++++-
30 net/ceph/mon_client.c | 9 +++++++++
31 3 files changed, 28 insertions(+), 1 deletion(-)
33 --- a/include/linux/ceph/libceph.h
34 +++ b/include/linux/ceph/libceph.h
35 @@ -294,6 +294,8 @@ extern void ceph_destroy_client(struct c
36 extern int __ceph_open_session(struct ceph_client *client,
37 unsigned long started);
38 extern int ceph_open_session(struct ceph_client *client);
39 +int ceph_wait_for_latest_osdmap(struct ceph_client *client,
40 + unsigned long timeout);
43 extern void ceph_release_page_vector(struct page **pages, int num_pages);
44 --- a/net/ceph/ceph_common.c
45 +++ b/net/ceph/ceph_common.c
46 @@ -738,7 +738,6 @@ int __ceph_open_session(struct ceph_clie
48 EXPORT_SYMBOL(__ceph_open_session);
51 int ceph_open_session(struct ceph_client *client)
54 @@ -754,6 +753,23 @@ int ceph_open_session(struct ceph_client
56 EXPORT_SYMBOL(ceph_open_session);
58 +int ceph_wait_for_latest_osdmap(struct ceph_client *client,
59 + unsigned long timeout)
64 + ret = ceph_monc_get_version(&client->monc, "osdmap", &newest_epoch);
68 + if (client->osdc.osdmap->epoch >= newest_epoch)
71 + ceph_osdc_maybe_request_map(&client->osdc);
72 + return ceph_monc_wait_osdmap(&client->monc, newest_epoch, timeout);
74 +EXPORT_SYMBOL(ceph_wait_for_latest_osdmap);
76 static int __init init_ceph_lib(void)
78 --- a/net/ceph/mon_client.c
79 +++ b/net/ceph/mon_client.c
80 @@ -922,6 +922,15 @@ int ceph_monc_blacklist_add(struct ceph_
81 mutex_unlock(&monc->mutex);
83 ret = wait_generic_request(req);
86 + * Make sure we have the osdmap that includes the blacklist
87 + * entry. This is needed to ensure that the OSDs pick up the
88 + * new blacklist before processing any future requests from
91 + ret = ceph_wait_for_latest_osdmap(monc->client, 0);
94 put_generic_request(req);