libceph, rbd: ignore addr->type while comparing in some cases
authorIlya Dryomov <idryomov@gmail.com>
Wed, 25 Nov 2020 13:41:59 +0000 (14:41 +0100)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 14 Dec 2020 22:21:50 +0000 (23:21 +0100)
For libceph, this ensures that libceph instance sharing (share option)
continues to work.  For rbd, this avoids blocklisting alive lock owners
(locker addr is always LEGACY, while watcher addr is ANY in nautilus).

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
drivers/block/rbd.c
include/linux/ceph/msgr.h
net/ceph/mon_client.c

index f84128abade3196b3a05812280973e0292b0f35e..bec85c054522e586b8a5c1737b7d6d750d0ad3c7 100644 (file)
@@ -3957,8 +3957,12 @@ static int find_watcher(struct rbd_device *rbd_dev,
 
        sscanf(locker->id.cookie, RBD_LOCK_COOKIE_PREFIX " %llu", &cookie);
        for (i = 0; i < num_watchers; i++) {
-               if (!memcmp(&watchers[i].addr, &locker->info.addr,
-                           sizeof(locker->info.addr)) &&
+               /*
+                * Ignore addr->type while comparing.  This mimics
+                * entity_addr_t::get_legacy_str() + strcmp().
+                */
+               if (ceph_addr_equal_no_type(&watchers[i].addr,
+                                           &locker->info.addr) &&
                    watchers[i].cookie == cookie) {
                        struct rbd_client_id cid = {
                                .gid = le64_to_cpu(watchers[i].name.num),
index 46939485f2c380225988fa658a5cd923bc4183a3..9a897a60f20beea32cdc4e4631c991339c1cca7c 100644 (file)
@@ -52,11 +52,18 @@ extern const char *ceph_entity_type_name(int type);
  * entity_addr -- network address
  */
 struct ceph_entity_addr {
-       __le32 type;
+       __le32 type;  /* CEPH_ENTITY_ADDR_TYPE_* */
        __le32 nonce;  /* unique id for process (e.g. pid) */
        struct sockaddr_storage in_addr;
 } __attribute__ ((packed));
 
+static inline bool ceph_addr_equal_no_type(const struct ceph_entity_addr *lhs,
+                                          const struct ceph_entity_addr *rhs)
+{
+       return !memcmp(&lhs->in_addr, &rhs->in_addr, sizeof(lhs->in_addr)) &&
+              lhs->nonce == rhs->nonce;
+}
+
 struct ceph_entity_inst {
        struct ceph_entity_name name;
        struct ceph_entity_addr addr;
index a9754a7fa78c9e2c743073abb3c82c9aca2cc6c0..f5f090b4e4090bdc4eb30015cac64b6da686541a 100644 (file)
@@ -161,9 +161,11 @@ int ceph_monmap_contains(struct ceph_monmap *m, struct ceph_entity_addr *addr)
 {
        int i;
 
-       for (i = 0; i < m->num_mon; i++)
-               if (memcmp(addr, &m->mon_inst[i].addr, sizeof(*addr)) == 0)
+       for (i = 0; i < m->num_mon; i++) {
+               if (ceph_addr_equal_no_type(addr, &m->mon_inst[i].addr))
                        return 1;
+       }
+
        return 0;
 }