fs/ceph/mdsmap.c

Source file repositories/reference/linux-study-clean/fs/ceph/mdsmap.c

File Facts

System
Linux kernel
Corpus path
fs/ceph/mdsmap.c
Extension
.c
Size
11606 bytes
Lines
463
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

while (n-- > 0) {
			u32 len;
			ceph_decode_need(p, end, sizeof(u64) + sizeof(u32),
					 bad);
			*p += sizeof(u64);
			len = ceph_decode_32(p);
			ceph_decode_need(p, end, len, bad);
			*p += len;
		}
	}
	return 0;
bad:
	return -1;
}

/*
 * 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(struct ceph_mds_client *mdsc, void **p,
				       void *end, bool msgr2)
{
	struct ceph_client *cl = mdsc->fsc->client;
	struct ceph_mdsmap *m;
	const void *start = *p;
	int i, j, n;
	int err;
	u8 mdsmap_v;
	u16 mdsmap_ev;
	u32 target;

	m = kzalloc_obj(*m, GFP_NOFS);
	if (!m)
		return ERR_PTR(-ENOMEM);

	ceph_decode_need(p, end, 1 + 1, bad);
	mdsmap_v = ceph_decode_8(p);
	*p += sizeof(u8);			/* mdsmap_cv */
	if (mdsmap_v >= 4) {
	       u32 mdsmap_len;
	       ceph_decode_32_safe(p, end, mdsmap_len, bad);
	       if (end < *p + mdsmap_len)
		       goto bad;
	       end = *p + mdsmap_len;
	}

	ceph_decode_need(p, end, 8*sizeof(u32) + sizeof(u64), bad);
	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);

	/*
	 * pick out the active nodes as the m_num_active_mds, the
	 * m_num_active_mds maybe larger than m_max_mds when decreasing
	 * the max_mds in cluster side, in other case it should less
	 * than or equal to m_max_mds.
	 */
	m->m_num_active_mds = n = ceph_decode_32(p);

	/*
	 * the possible max rank, it maybe larger than the m_num_active_mds,
	 * for example if the mds_max == 2 in the cluster, when the MDS(0)
	 * was laggy and being replaced by a new MDS, we will temporarily
	 * receive a new mds map with n_num_mds == 1 and the active MDS(1),
	 * and the mds rank >= m_num_active_mds.
	 */
	m->possible_max_rank = max(m->m_num_active_mds, m->m_max_mds);

	m->m_info = kzalloc_objs(*m->m_info, m->possible_max_rank, GFP_NOFS);
	if (!m->m_info)
		goto nomem;

	/* pick out active nodes from mds_info (state > 0) */
	for (i = 0; i < n; i++) {
		u64 global_id;
		u32 namelen;
		s32 mds, inc, state;
		u8 info_v;
		void *info_end = NULL;
		struct ceph_entity_addr addr;
		u32 num_export_targets;
		void *pexport_targets = NULL;
		struct ceph_timespec laggy_since;

Annotation

Implementation Notes