Blame view
fs/ceph/mdsmap.c
4.31 KB
3d14c5d2b ceph: factor out ... |
1 |
#include <linux/ceph/ceph_debug.h> |
2f2dc0534 ceph: MDS client |
2 3 4 5 6 7 |
#include <linux/bug.h> #include <linux/err.h> #include <linux/random.h> #include <linux/slab.h> #include <linux/types.h> |
3d14c5d2b ceph: factor out ... |
8 9 10 |
#include <linux/ceph/mdsmap.h> #include <linux/ceph/messenger.h> #include <linux/ceph/decode.h> |
2f2dc0534 ceph: MDS client |
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
#include "super.h" /* * choose a random mds that is "up" (i.e. has a state > 0), or -1. */ int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m) { int n = 0; int i; char r; /* count */ for (i = 0; i < m->m_max_mds; i++) if (m->m_info[i].state > 0) n++; if (n == 0) return -1; /* pick */ get_random_bytes(&r, 1); n = r % n; i = 0; for (i = 0; n > 0; i++, n--) while (m->m_info[i].state <= 0) i++; return i; } /* * Decode an MDS map * * Ignore any fields we don't care about (there are quite a few of * them). */ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end) { struct ceph_mdsmap *m; |
9ec7cab14 ceph: hex dump co... |
51 |
const void *start = *p; |
2f2dc0534 ceph: MDS client |
52 53 54 55 56 57 58 59 60 61 62 |
int i, j, n; int err = -EINVAL; u16 version; m = kzalloc(sizeof(*m), GFP_NOFS); if (m == NULL) return ERR_PTR(-ENOMEM); ceph_decode_16_safe(p, end, version, bad); ceph_decode_need(p, end, 8*sizeof(u32) + sizeof(u64), bad); |
c89136ea4 ceph: convert enc... |
63 64 65 66 67 68 69 70 |
m->m_epoch = ceph_decode_32(p); m->m_client_epoch = ceph_decode_32(p); m->m_last_failure = ceph_decode_32(p); m->m_root = ceph_decode_32(p); m->m_session_timeout = ceph_decode_32(p); m->m_session_autoclose = ceph_decode_32(p); m->m_max_file_size = ceph_decode_64(p); m->m_max_mds = ceph_decode_32(p); |
2f2dc0534 ceph: MDS client |
71 72 73 74 75 76 |
m->m_info = kcalloc(m->m_max_mds, sizeof(*m->m_info), GFP_NOFS); if (m->m_info == NULL) goto badmem; /* pick out active nodes from mds_info (state > 0) */ |
c89136ea4 ceph: convert enc... |
77 |
n = ceph_decode_32(p); |
2f2dc0534 ceph: MDS client |
78 |
for (i = 0; i < n; i++) { |
94045e115 ceph: decode upda... |
79 |
u64 global_id; |
2f2dc0534 ceph: MDS client |
80 81 82 83 84 85 86 |
u32 namelen; s32 mds, inc, state; u64 state_seq; u8 infoversion; struct ceph_entity_addr addr; u32 num_export_targets; void *pexport_targets = NULL; |
0deb01c99 ceph: track laggy... |
87 |
struct ceph_timespec laggy_since; |
2f2dc0534 ceph: MDS client |
88 |
|
94045e115 ceph: decode upda... |
89 90 |
ceph_decode_need(p, end, sizeof(u64)*2 + 1 + sizeof(u32), bad); global_id = ceph_decode_64(p); |
c89136ea4 ceph: convert enc... |
91 |
infoversion = ceph_decode_8(p); |
94045e115 ceph: decode upda... |
92 |
*p += sizeof(u64); |
c89136ea4 ceph: convert enc... |
93 |
namelen = ceph_decode_32(p); /* skip mds name */ |
2f2dc0534 ceph: MDS client |
94 95 96 |
*p += namelen; ceph_decode_need(p, end, |
e251e2880 ceph: fix mdsmap ... |
97 |
4*sizeof(u32) + sizeof(u64) + |
2f2dc0534 ceph: MDS client |
98 99 |
sizeof(addr) + sizeof(struct ceph_timespec), bad); |
c89136ea4 ceph: convert enc... |
100 101 102 103 |
mds = ceph_decode_32(p); inc = ceph_decode_32(p); state = ceph_decode_32(p); state_seq = ceph_decode_64(p); |
94045e115 ceph: decode upda... |
104 105 |
ceph_decode_copy(p, &addr, sizeof(addr)); ceph_decode_addr(&addr); |
0deb01c99 ceph: track laggy... |
106 |
ceph_decode_copy(p, &laggy_since, sizeof(laggy_since)); |
2f2dc0534 ceph: MDS client |
107 108 |
*p += sizeof(u32); ceph_decode_32_safe(p, end, namelen, bad); |
e251e2880 ceph: fix mdsmap ... |
109 |
*p += namelen; |
2f2dc0534 ceph: MDS client |
110 111 112 |
if (infoversion >= 2) { ceph_decode_32_safe(p, end, num_export_targets, bad); pexport_targets = *p; |
e251e2880 ceph: fix mdsmap ... |
113 |
*p += num_export_targets * sizeof(u32); |
2f2dc0534 ceph: MDS client |
114 115 116 |
} else { num_export_targets = 0; } |
94045e115 ceph: decode upda... |
117 118 |
dout("mdsmap_decode %d/%d %lld mds%d.%d %s %s ", |
3d14c5d2b ceph: factor out ... |
119 120 |
i+1, n, global_id, mds, inc, ceph_pr_addr(&addr.in_addr), |
2f2dc0534 ceph: MDS client |
121 122 |
ceph_mds_state_name(state)); if (mds >= 0 && mds < m->m_max_mds && state > 0) { |
94045e115 ceph: decode upda... |
123 |
m->m_info[mds].global_id = global_id; |
2f2dc0534 ceph: MDS client |
124 125 |
m->m_info[mds].state = state; m->m_info[mds].addr = addr; |
0deb01c99 ceph: track laggy... |
126 127 128 |
m->m_info[mds].laggy = (laggy_since.tv_sec != 0 || laggy_since.tv_nsec != 0); |
2f2dc0534 ceph: MDS client |
129 130 131 132 133 134 |
m->m_info[mds].num_export_targets = num_export_targets; if (num_export_targets) { m->m_info[mds].export_targets = kcalloc(num_export_targets, sizeof(u32), GFP_NOFS); for (j = 0; j < num_export_targets; j++) |
c89136ea4 ceph: convert enc... |
135 136 |
m->m_info[mds].export_targets[j] = ceph_decode_32(&pexport_targets); |
2f2dc0534 ceph: MDS client |
137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
} else { m->m_info[mds].export_targets = NULL; } } } /* pg_pools */ ceph_decode_32_safe(p, end, n, bad); m->m_num_data_pg_pools = n; m->m_data_pg_pools = kcalloc(n, sizeof(u32), GFP_NOFS); if (!m->m_data_pg_pools) goto badmem; ceph_decode_need(p, end, sizeof(u32)*(n+1), bad); for (i = 0; i < n; i++) |
c89136ea4 ceph: convert enc... |
151 152 |
m->m_data_pg_pools[i] = ceph_decode_32(p); m->m_cas_pg_pool = ceph_decode_32(p); |
2f2dc0534 ceph: MDS client |
153 154 155 156 157 158 159 160 161 162 163 |
/* ok, we don't care about the rest. */ dout("mdsmap_decode success epoch %u ", m->m_epoch); return m; badmem: err = -ENOMEM; bad: pr_err("corrupt mdsmap "); |
9ec7cab14 ceph: hex dump co... |
164 165 166 |
print_hex_dump(KERN_DEBUG, "mdsmap: ", DUMP_PREFIX_OFFSET, 16, 1, start, end - start, true); |
2f2dc0534 ceph: MDS client |
167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
ceph_mdsmap_destroy(m); return ERR_PTR(-EINVAL); } void ceph_mdsmap_destroy(struct ceph_mdsmap *m) { int i; for (i = 0; i < m->m_max_mds; i++) kfree(m->m_info[i].export_targets); kfree(m->m_info); kfree(m->m_data_pg_pools); kfree(m); } |