13d14c5d2SYehuda Sadeh #include <linux/ceph/ceph_debug.h> 22f2dc053SSage Weil 32f2dc053SSage Weil #include <linux/bug.h> 42f2dc053SSage Weil #include <linux/err.h> 52f2dc053SSage Weil #include <linux/random.h> 62f2dc053SSage Weil #include <linux/slab.h> 72f2dc053SSage Weil #include <linux/types.h> 82f2dc053SSage Weil 93d14c5d2SYehuda Sadeh #include <linux/ceph/mdsmap.h> 103d14c5d2SYehuda Sadeh #include <linux/ceph/messenger.h> 113d14c5d2SYehuda Sadeh #include <linux/ceph/decode.h> 122f2dc053SSage Weil 132f2dc053SSage Weil #include "super.h" 142f2dc053SSage Weil 152f2dc053SSage Weil 162f2dc053SSage Weil /* 172f2dc053SSage Weil * choose a random mds that is "up" (i.e. has a state > 0), or -1. 182f2dc053SSage Weil */ 192f2dc053SSage Weil int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m) 202f2dc053SSage Weil { 212f2dc053SSage Weil int n = 0; 222f2dc053SSage Weil int i; 23a84cd293SSam Lang 24a84cd293SSam Lang /* special case for one mds */ 25*76201b63SYan, Zheng if (1 == m->m_num_mds && m->m_info[0].state > 0) 26a84cd293SSam Lang return 0; 272f2dc053SSage Weil 282f2dc053SSage Weil /* count */ 29*76201b63SYan, Zheng for (i = 0; i < m->m_num_mds; i++) 302f2dc053SSage Weil if (m->m_info[i].state > 0) 312f2dc053SSage Weil n++; 322f2dc053SSage Weil if (n == 0) 332f2dc053SSage Weil return -1; 342f2dc053SSage Weil 352f2dc053SSage Weil /* pick */ 36a84cd293SSam Lang n = prandom_u32() % n; 372f2dc053SSage Weil i = 0; 382f2dc053SSage Weil for (i = 0; n > 0; i++, n--) 392f2dc053SSage Weil while (m->m_info[i].state <= 0) 402f2dc053SSage Weil i++; 412f2dc053SSage Weil 422f2dc053SSage Weil return i; 432f2dc053SSage Weil } 442f2dc053SSage Weil 45e9e427f0SYan, Zheng #define __decode_and_drop_type(p, end, type, bad) \ 46e9e427f0SYan, Zheng do { \ 47e9e427f0SYan, Zheng if (*p + sizeof(type) > end) \ 48e9e427f0SYan, Zheng goto bad; \ 49e9e427f0SYan, Zheng *p += sizeof(type); \ 50e9e427f0SYan, Zheng } while (0) 51e9e427f0SYan, Zheng 52e9e427f0SYan, Zheng #define __decode_and_drop_set(p, end, type, bad) \ 53e9e427f0SYan, Zheng do { \ 54e9e427f0SYan, Zheng u32 n; \ 55e9e427f0SYan, Zheng size_t need; \ 56e9e427f0SYan, Zheng ceph_decode_32_safe(p, end, n, bad); \ 57e9e427f0SYan, Zheng need = sizeof(type) * n; \ 58e9e427f0SYan, Zheng ceph_decode_need(p, end, need, bad); \ 59e9e427f0SYan, Zheng *p += need; \ 60e9e427f0SYan, Zheng } while (0) 61e9e427f0SYan, Zheng 62e9e427f0SYan, Zheng #define __decode_and_drop_map(p, end, ktype, vtype, bad) \ 63e9e427f0SYan, Zheng do { \ 64e9e427f0SYan, Zheng u32 n; \ 65e9e427f0SYan, Zheng size_t need; \ 66e9e427f0SYan, Zheng ceph_decode_32_safe(p, end, n, bad); \ 67e9e427f0SYan, Zheng need = (sizeof(ktype) + sizeof(vtype)) * n; \ 68e9e427f0SYan, Zheng ceph_decode_need(p, end, need, bad); \ 69e9e427f0SYan, Zheng *p += need; \ 70e9e427f0SYan, Zheng } while (0) 71e9e427f0SYan, Zheng 72e9e427f0SYan, Zheng 73e9e427f0SYan, Zheng static int __decode_and_drop_compat_set(void **p, void* end) 74e9e427f0SYan, Zheng { 75e9e427f0SYan, Zheng int i; 76e9e427f0SYan, Zheng /* compat, ro_compat, incompat*/ 77e9e427f0SYan, Zheng for (i = 0; i < 3; i++) { 78e9e427f0SYan, Zheng u32 n; 79e9e427f0SYan, Zheng ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad); 80e9e427f0SYan, Zheng /* mask */ 81e9e427f0SYan, Zheng *p += sizeof(u64); 82e9e427f0SYan, Zheng /* names (map<u64, string>) */ 83e9e427f0SYan, Zheng n = ceph_decode_32(p); 84e9e427f0SYan, Zheng while (n-- > 0) { 85e9e427f0SYan, Zheng u32 len; 86e9e427f0SYan, Zheng ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), 87e9e427f0SYan, Zheng bad); 88e9e427f0SYan, Zheng *p += sizeof(u64); 89e9e427f0SYan, Zheng len = ceph_decode_32(p); 90e9e427f0SYan, Zheng ceph_decode_need(p, end, len, bad); 91e9e427f0SYan, Zheng *p += len; 92e9e427f0SYan, Zheng } 93e9e427f0SYan, Zheng } 94e9e427f0SYan, Zheng return 0; 95e9e427f0SYan, Zheng bad: 96e9e427f0SYan, Zheng return -1; 97e9e427f0SYan, Zheng } 98e9e427f0SYan, Zheng 992f2dc053SSage Weil /* 1002f2dc053SSage Weil * Decode an MDS map 1012f2dc053SSage Weil * 1022f2dc053SSage Weil * Ignore any fields we don't care about (there are quite a few of 1032f2dc053SSage Weil * them). 1042f2dc053SSage Weil */ 1052f2dc053SSage Weil struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) 1062f2dc053SSage Weil { 1072f2dc053SSage Weil struct ceph_mdsmap *m; 1089ec7cab1SSage Weil const void *start = *p; 1092f2dc053SSage Weil int i, j, n; 1102f2dc053SSage Weil int err = -EINVAL; 111d463a43dSYan, Zheng u8 mdsmap_v, mdsmap_cv; 112e9e427f0SYan, Zheng u16 mdsmap_ev; 1132f2dc053SSage Weil 1142f2dc053SSage Weil m = kzalloc(sizeof(*m), GFP_NOFS); 1152f2dc053SSage Weil if (m == NULL) 1162f2dc053SSage Weil return ERR_PTR(-ENOMEM); 1172f2dc053SSage Weil 118d463a43dSYan, Zheng ceph_decode_need(p, end, 1 + 1, bad); 119d463a43dSYan, Zheng mdsmap_v = ceph_decode_8(p); 120d463a43dSYan, Zheng mdsmap_cv = ceph_decode_8(p); 121d463a43dSYan, Zheng if (mdsmap_v >= 4) { 122d463a43dSYan, Zheng u32 mdsmap_len; 123d463a43dSYan, Zheng ceph_decode_32_safe(p, end, mdsmap_len, bad); 124d463a43dSYan, Zheng if (end < *p + mdsmap_len) 1254f6a7e5eSSage Weil goto bad; 126d463a43dSYan, Zheng end = *p + mdsmap_len; 1274f6a7e5eSSage Weil } 1282f2dc053SSage Weil 1292f2dc053SSage Weil ceph_decode_need(p, end, 8*sizeof(u32) + sizeof(u64), bad); 130c89136eaSSage Weil m->m_epoch = ceph_decode_32(p); 131c89136eaSSage Weil m->m_client_epoch = ceph_decode_32(p); 132c89136eaSSage Weil m->m_last_failure = ceph_decode_32(p); 133c89136eaSSage Weil m->m_root = ceph_decode_32(p); 134c89136eaSSage Weil m->m_session_timeout = ceph_decode_32(p); 135c89136eaSSage Weil m->m_session_autoclose = ceph_decode_32(p); 136c89136eaSSage Weil m->m_max_file_size = ceph_decode_64(p); 137c89136eaSSage Weil m->m_max_mds = ceph_decode_32(p); 138*76201b63SYan, Zheng m->m_num_mds = m->m_max_mds; 1392f2dc053SSage Weil 140*76201b63SYan, Zheng m->m_info = kcalloc(m->m_num_mds, sizeof(*m->m_info), GFP_NOFS); 1412f2dc053SSage Weil if (m->m_info == NULL) 142e9e427f0SYan, Zheng goto nomem; 1432f2dc053SSage Weil 1442f2dc053SSage Weil /* pick out active nodes from mds_info (state > 0) */ 145c89136eaSSage Weil n = ceph_decode_32(p); 1462f2dc053SSage Weil for (i = 0; i < n; i++) { 14794045e11SSage Weil u64 global_id; 1482f2dc053SSage Weil u32 namelen; 1492f2dc053SSage Weil s32 mds, inc, state; 1502f2dc053SSage Weil u64 state_seq; 151d463a43dSYan, Zheng u8 info_v; 152d463a43dSYan, Zheng void *info_end = NULL; 1532f2dc053SSage Weil struct ceph_entity_addr addr; 1542f2dc053SSage Weil u32 num_export_targets; 1552f2dc053SSage Weil void *pexport_targets = NULL; 1560deb01c9SSage Weil struct ceph_timespec laggy_since; 1576af86528SDan Carpenter struct ceph_mds_info *info; 1582f2dc053SSage Weil 159d463a43dSYan, Zheng ceph_decode_need(p, end, sizeof(u64) + 1, bad); 16094045e11SSage Weil global_id = ceph_decode_64(p); 161d463a43dSYan, Zheng info_v= ceph_decode_8(p); 162d463a43dSYan, Zheng if (info_v >= 4) { 163d463a43dSYan, Zheng u32 info_len; 164d463a43dSYan, Zheng u8 info_cv; 165d463a43dSYan, Zheng ceph_decode_need(p, end, 1 + sizeof(u32), bad); 166d463a43dSYan, Zheng info_cv = ceph_decode_8(p); 167d463a43dSYan, Zheng info_len = ceph_decode_32(p); 168d463a43dSYan, Zheng info_end = *p + info_len; 169d463a43dSYan, Zheng if (info_end > end) 170d463a43dSYan, Zheng goto bad; 171d463a43dSYan, Zheng } 172d463a43dSYan, Zheng 173d463a43dSYan, Zheng ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad); 17494045e11SSage Weil *p += sizeof(u64); 175c89136eaSSage Weil namelen = ceph_decode_32(p); /* skip mds name */ 1762f2dc053SSage Weil *p += namelen; 1772f2dc053SSage Weil 1782f2dc053SSage Weil ceph_decode_need(p, end, 179e251e288SSage Weil 4*sizeof(u32) + sizeof(u64) + 1802f2dc053SSage Weil sizeof(addr) + sizeof(struct ceph_timespec), 1812f2dc053SSage Weil bad); 182c89136eaSSage Weil mds = ceph_decode_32(p); 183c89136eaSSage Weil inc = ceph_decode_32(p); 184c89136eaSSage Weil state = ceph_decode_32(p); 185c89136eaSSage Weil state_seq = ceph_decode_64(p); 18694045e11SSage Weil ceph_decode_copy(p, &addr, sizeof(addr)); 18794045e11SSage Weil ceph_decode_addr(&addr); 1880deb01c9SSage Weil ceph_decode_copy(p, &laggy_since, sizeof(laggy_since)); 1892f2dc053SSage Weil *p += sizeof(u32); 1902f2dc053SSage Weil ceph_decode_32_safe(p, end, namelen, bad); 191e251e288SSage Weil *p += namelen; 192d463a43dSYan, Zheng if (info_v >= 2) { 1932f2dc053SSage Weil ceph_decode_32_safe(p, end, num_export_targets, bad); 1942f2dc053SSage Weil pexport_targets = *p; 195e251e288SSage Weil *p += num_export_targets * sizeof(u32); 1962f2dc053SSage Weil } else { 1972f2dc053SSage Weil num_export_targets = 0; 1982f2dc053SSage Weil } 1992f2dc053SSage Weil 200d463a43dSYan, Zheng if (info_end && *p != info_end) { 201d463a43dSYan, Zheng if (*p > info_end) 202d463a43dSYan, Zheng goto bad; 203d463a43dSYan, Zheng *p = info_end; 204d463a43dSYan, Zheng } 205d463a43dSYan, Zheng 20694045e11SSage Weil dout("mdsmap_decode %d/%d %lld mds%d.%d %s %s\n", 2073d14c5d2SYehuda Sadeh i+1, n, global_id, mds, inc, 2083d14c5d2SYehuda Sadeh ceph_pr_addr(&addr.in_addr), 2092f2dc053SSage Weil ceph_mds_state_name(state)); 2106af86528SDan Carpenter 211*76201b63SYan, Zheng if (mds < 0 || state <= 0) 2126af86528SDan Carpenter continue; 2136af86528SDan Carpenter 214*76201b63SYan, Zheng if (mds >= m->m_num_mds) { 215*76201b63SYan, Zheng int new_num = max(mds + 1, m->m_num_mds * 2); 216*76201b63SYan, Zheng void *new_m_info = krealloc(m->m_info, 217*76201b63SYan, Zheng new_num * sizeof(*m->m_info), 218*76201b63SYan, Zheng GFP_NOFS | __GFP_ZERO); 219*76201b63SYan, Zheng if (!new_m_info) 220*76201b63SYan, Zheng goto nomem; 221*76201b63SYan, Zheng m->m_info = new_m_info; 222*76201b63SYan, Zheng m->m_num_mds = new_num; 223*76201b63SYan, Zheng } 224*76201b63SYan, Zheng 2256af86528SDan Carpenter info = &m->m_info[mds]; 2266af86528SDan Carpenter info->global_id = global_id; 2276af86528SDan Carpenter info->state = state; 2286af86528SDan Carpenter info->addr = addr; 2296af86528SDan Carpenter info->laggy = (laggy_since.tv_sec != 0 || 2300deb01c9SSage Weil laggy_since.tv_nsec != 0); 2316af86528SDan Carpenter info->num_export_targets = num_export_targets; 2322f2dc053SSage Weil if (num_export_targets) { 2336af86528SDan Carpenter info->export_targets = kcalloc(num_export_targets, 2346af86528SDan Carpenter sizeof(u32), GFP_NOFS); 2356af86528SDan Carpenter if (info->export_targets == NULL) 236e9e427f0SYan, Zheng goto nomem; 2372f2dc053SSage Weil for (j = 0; j < num_export_targets; j++) 2386af86528SDan Carpenter info->export_targets[j] = 239c89136eaSSage Weil ceph_decode_32(&pexport_targets); 2402f2dc053SSage Weil } else { 2416af86528SDan Carpenter info->export_targets = NULL; 2422f2dc053SSage Weil } 2432f2dc053SSage Weil } 244*76201b63SYan, Zheng if (m->m_num_mds > m->m_max_mds) { 245*76201b63SYan, Zheng /* find max up mds */ 246*76201b63SYan, Zheng for (i = m->m_num_mds; i >= m->m_max_mds; i--) { 247*76201b63SYan, Zheng if (i == 0 || m->m_info[i-1].state > 0) 248*76201b63SYan, Zheng break; 249*76201b63SYan, Zheng } 250*76201b63SYan, Zheng m->m_num_mds = i; 251*76201b63SYan, Zheng } 2522f2dc053SSage Weil 2532f2dc053SSage Weil /* pg_pools */ 2542f2dc053SSage Weil ceph_decode_32_safe(p, end, n, bad); 2552f2dc053SSage Weil m->m_num_data_pg_pools = n; 2564f6a7e5eSSage Weil m->m_data_pg_pools = kcalloc(n, sizeof(u64), GFP_NOFS); 2572f2dc053SSage Weil if (!m->m_data_pg_pools) 258e9e427f0SYan, Zheng goto nomem; 2594f6a7e5eSSage Weil ceph_decode_need(p, end, sizeof(u64)*(n+1), bad); 2602f2dc053SSage Weil for (i = 0; i < n; i++) 2614f6a7e5eSSage Weil m->m_data_pg_pools[i] = ceph_decode_64(p); 2624f6a7e5eSSage Weil m->m_cas_pg_pool = ceph_decode_64(p); 263e9e427f0SYan, Zheng m->m_enabled = m->m_epoch > 1; 2642f2dc053SSage Weil 265e9e427f0SYan, Zheng mdsmap_ev = 1; 266e9e427f0SYan, Zheng if (mdsmap_v >= 2) { 267e9e427f0SYan, Zheng ceph_decode_16_safe(p, end, mdsmap_ev, bad_ext); 268e9e427f0SYan, Zheng } 269e9e427f0SYan, Zheng if (mdsmap_ev >= 3) { 270e9e427f0SYan, Zheng if (__decode_and_drop_compat_set(p, end) < 0) 271e9e427f0SYan, Zheng goto bad_ext; 272e9e427f0SYan, Zheng } 273e9e427f0SYan, Zheng /* metadata_pool */ 274e9e427f0SYan, Zheng if (mdsmap_ev < 5) { 275e9e427f0SYan, Zheng __decode_and_drop_type(p, end, u32, bad_ext); 276e9e427f0SYan, Zheng } else { 277e9e427f0SYan, Zheng __decode_and_drop_type(p, end, u64, bad_ext); 278e9e427f0SYan, Zheng } 279e9e427f0SYan, Zheng 280e9e427f0SYan, Zheng /* created + modified + tableserver */ 281e9e427f0SYan, Zheng __decode_and_drop_type(p, end, struct ceph_timespec, bad_ext); 282e9e427f0SYan, Zheng __decode_and_drop_type(p, end, struct ceph_timespec, bad_ext); 283e9e427f0SYan, Zheng __decode_and_drop_type(p, end, u32, bad_ext); 284e9e427f0SYan, Zheng 285e9e427f0SYan, Zheng /* in */ 286e9e427f0SYan, Zheng { 287e9e427f0SYan, Zheng int num_laggy = 0; 288e9e427f0SYan, Zheng ceph_decode_32_safe(p, end, n, bad_ext); 289e9e427f0SYan, Zheng ceph_decode_need(p, end, sizeof(u32) * n, bad_ext); 290e9e427f0SYan, Zheng 291e9e427f0SYan, Zheng for (i = 0; i < n; i++) { 292e9e427f0SYan, Zheng s32 mds = ceph_decode_32(p); 293*76201b63SYan, Zheng if (mds >= 0 && mds < m->m_num_mds) { 294e9e427f0SYan, Zheng if (m->m_info[mds].laggy) 295e9e427f0SYan, Zheng num_laggy++; 296e9e427f0SYan, Zheng } 297e9e427f0SYan, Zheng } 298e9e427f0SYan, Zheng m->m_num_laggy = num_laggy; 299*76201b63SYan, Zheng 300*76201b63SYan, Zheng if (n > m->m_num_mds) { 301*76201b63SYan, Zheng void *new_m_info = krealloc(m->m_info, 302*76201b63SYan, Zheng n * sizeof(*m->m_info), 303*76201b63SYan, Zheng GFP_NOFS | __GFP_ZERO); 304*76201b63SYan, Zheng if (!new_m_info) 305*76201b63SYan, Zheng goto nomem; 306*76201b63SYan, Zheng m->m_info = new_m_info; 307*76201b63SYan, Zheng } 308*76201b63SYan, Zheng m->m_num_mds = n; 309e9e427f0SYan, Zheng } 310e9e427f0SYan, Zheng 311e9e427f0SYan, Zheng /* inc */ 312e9e427f0SYan, Zheng __decode_and_drop_map(p, end, u32, u32, bad_ext); 313e9e427f0SYan, Zheng /* up */ 314e9e427f0SYan, Zheng __decode_and_drop_map(p, end, u32, u64, bad_ext); 315e9e427f0SYan, Zheng /* failed */ 316e9e427f0SYan, Zheng __decode_and_drop_set(p, end, u32, bad_ext); 317e9e427f0SYan, Zheng /* stopped */ 318e9e427f0SYan, Zheng __decode_and_drop_set(p, end, u32, bad_ext); 319e9e427f0SYan, Zheng 320e9e427f0SYan, Zheng if (mdsmap_ev >= 4) { 321e9e427f0SYan, Zheng /* last_failure_osd_epoch */ 322e9e427f0SYan, Zheng __decode_and_drop_type(p, end, u32, bad_ext); 323e9e427f0SYan, Zheng } 324e9e427f0SYan, Zheng if (mdsmap_ev >= 6) { 325e9e427f0SYan, Zheng /* ever_allowed_snaps */ 326e9e427f0SYan, Zheng __decode_and_drop_type(p, end, u8, bad_ext); 327e9e427f0SYan, Zheng /* explicitly_allowed_snaps */ 328e9e427f0SYan, Zheng __decode_and_drop_type(p, end, u8, bad_ext); 329e9e427f0SYan, Zheng } 330e9e427f0SYan, Zheng if (mdsmap_ev >= 7) { 331e9e427f0SYan, Zheng /* inline_data_enabled */ 332e9e427f0SYan, Zheng __decode_and_drop_type(p, end, u8, bad_ext); 333e9e427f0SYan, Zheng } 334e9e427f0SYan, Zheng if (mdsmap_ev >= 8) { 335e9e427f0SYan, Zheng u32 name_len; 336e9e427f0SYan, Zheng /* enabled */ 337e9e427f0SYan, Zheng ceph_decode_8_safe(p, end, m->m_enabled, bad_ext); 338e9e427f0SYan, Zheng ceph_decode_32_safe(p, end, name_len, bad_ext); 339e9e427f0SYan, Zheng ceph_decode_need(p, end, name_len, bad_ext); 340e9e427f0SYan, Zheng *p += name_len; 341e9e427f0SYan, Zheng } 342e9e427f0SYan, Zheng /* damaged */ 343e9e427f0SYan, Zheng if (mdsmap_ev >= 9) { 344e9e427f0SYan, Zheng size_t need; 345e9e427f0SYan, Zheng ceph_decode_32_safe(p, end, n, bad_ext); 346e9e427f0SYan, Zheng need = sizeof(u32) * n; 347e9e427f0SYan, Zheng ceph_decode_need(p, end, need, bad_ext); 348e9e427f0SYan, Zheng *p += need; 349e9e427f0SYan, Zheng m->m_damaged = n > 0; 350e9e427f0SYan, Zheng } else { 351e9e427f0SYan, Zheng m->m_damaged = false; 352e9e427f0SYan, Zheng } 353e9e427f0SYan, Zheng bad_ext: 354d463a43dSYan, Zheng *p = end; 3552f2dc053SSage Weil dout("mdsmap_decode success epoch %u\n", m->m_epoch); 3562f2dc053SSage Weil return m; 357e9e427f0SYan, Zheng nomem: 3582f2dc053SSage Weil err = -ENOMEM; 359e9e427f0SYan, Zheng goto out_err; 3602f2dc053SSage Weil bad: 3612f2dc053SSage Weil pr_err("corrupt mdsmap\n"); 3629ec7cab1SSage Weil print_hex_dump(KERN_DEBUG, "mdsmap: ", 3639ec7cab1SSage Weil DUMP_PREFIX_OFFSET, 16, 1, 3649ec7cab1SSage Weil start, end - start, true); 365e9e427f0SYan, Zheng out_err: 3662f2dc053SSage Weil ceph_mdsmap_destroy(m); 367c213b50bSEmil Goode return ERR_PTR(err); 3682f2dc053SSage Weil } 3692f2dc053SSage Weil 3702f2dc053SSage Weil void ceph_mdsmap_destroy(struct ceph_mdsmap *m) 3712f2dc053SSage Weil { 3722f2dc053SSage Weil int i; 3732f2dc053SSage Weil 374*76201b63SYan, Zheng for (i = 0; i < m->m_num_mds; i++) 3752f2dc053SSage Weil kfree(m->m_info[i].export_targets); 3762f2dc053SSage Weil kfree(m->m_info); 3772f2dc053SSage Weil kfree(m->m_data_pg_pools); 3782f2dc053SSage Weil kfree(m); 3792f2dc053SSage Weil } 380e9e427f0SYan, Zheng 381e9e427f0SYan, Zheng bool ceph_mdsmap_is_cluster_available(struct ceph_mdsmap *m) 382e9e427f0SYan, Zheng { 383e9e427f0SYan, Zheng int i, nr_active = 0; 384e9e427f0SYan, Zheng if (!m->m_enabled) 385e9e427f0SYan, Zheng return false; 386e9e427f0SYan, Zheng if (m->m_damaged) 387e9e427f0SYan, Zheng return false; 388e9e427f0SYan, Zheng if (m->m_num_laggy > 0) 389e9e427f0SYan, Zheng return false; 390*76201b63SYan, Zheng for (i = 0; i < m->m_num_mds; i++) { 391e9e427f0SYan, Zheng if (m->m_info[i].state == CEPH_MDS_STATE_ACTIVE) 392e9e427f0SYan, Zheng nr_active++; 393e9e427f0SYan, Zheng } 394e9e427f0SYan, Zheng return nr_active > 0; 395e9e427f0SYan, Zheng } 396