Skip to content

Commit bb229bb

Browse files
committed
libceph: wait for latest osdmap in ceph_monc_blacklist_add()
Because map updates are distributed lazily, an OSD may not know about the new blacklist for quite some time after "osd blacklist add" command is completed. This makes it possible for a blacklisted but still alive client to overwrite a post-blacklist update, resulting in data corruption. Waiting for latest osdmap in ceph_monc_blacklist_add() and thus using the post-blacklist epoch for all post-blacklist requests ensures that all such requests "wait" for the blacklist to come into force on their respective OSDs. Cc: stable@vger.kernel.org Fixes: 6305a3b ("libceph: support for blacklisting clients") Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Jason Dillaman <dillaman@redhat.com>
1 parent 16d80c5 commit bb229bb

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

include/linux/ceph/libceph.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,8 @@ extern void ceph_destroy_client(struct ceph_client *client);
294294
extern int __ceph_open_session(struct ceph_client *client,
295295
unsigned long started);
296296
extern int ceph_open_session(struct ceph_client *client);
297+
int ceph_wait_for_latest_osdmap(struct ceph_client *client,
298+
unsigned long timeout);
297299

298300
/* pagevec.c */
299301
extern void ceph_release_page_vector(struct page **pages, int num_pages);

net/ceph/ceph_common.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,6 @@ int __ceph_open_session(struct ceph_client *client, unsigned long started)
738738
}
739739
EXPORT_SYMBOL(__ceph_open_session);
740740

741-
742741
int ceph_open_session(struct ceph_client *client)
743742
{
744743
int ret;
@@ -754,6 +753,23 @@ int ceph_open_session(struct ceph_client *client)
754753
}
755754
EXPORT_SYMBOL(ceph_open_session);
756755

756+
int ceph_wait_for_latest_osdmap(struct ceph_client *client,
757+
unsigned long timeout)
758+
{
759+
u64 newest_epoch;
760+
int ret;
761+
762+
ret = ceph_monc_get_version(&client->monc, "osdmap", &newest_epoch);
763+
if (ret)
764+
return ret;
765+
766+
if (client->osdc.osdmap->epoch >= newest_epoch)
767+
return 0;
768+
769+
ceph_osdc_maybe_request_map(&client->osdc);
770+
return ceph_monc_wait_osdmap(&client->monc, newest_epoch, timeout);
771+
}
772+
EXPORT_SYMBOL(ceph_wait_for_latest_osdmap);
757773

758774
static int __init init_ceph_lib(void)
759775
{

net/ceph/mon_client.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,15 @@ int ceph_monc_blacklist_add(struct ceph_mon_client *monc,
922922
mutex_unlock(&monc->mutex);
923923

924924
ret = wait_generic_request(req);
925+
if (!ret)
926+
/*
927+
* Make sure we have the osdmap that includes the blacklist
928+
* entry. This is needed to ensure that the OSDs pick up the
929+
* new blacklist before processing any future requests from
930+
* this client.
931+
*/
932+
ret = ceph_wait_for_latest_osdmap(monc->client, 0);
933+
925934
out:
926935
put_generic_request(req);
927936
return ret;

0 commit comments

Comments
 (0)