⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vote.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	spin_unlock(&osb->net_response_lock);}static int ocfs2_broadcast_vote(struct ocfs2_super *osb,				struct ocfs2_vote_msg *request,				unsigned int response_id,				int *response,				struct ocfs2_net_response_cb *callback){	int status, i, remote_err;	struct ocfs2_net_wait_ctxt *w = NULL;	int dequeued = 0;	mlog_entry_void();	w = ocfs2_new_net_wait_ctxt(response_id);	if (!w) {		status = -ENOMEM;		mlog_errno(status);		goto bail;	}	w->n_callback = callback;	/* we're pretty much ready to go at this point, and this fills	 * in n_response which we need anyway... */	ocfs2_queue_net_wait_ctxt(osb, w);	i = ocfs2_node_map_iterate(osb, &osb->mounted_map, 0);	while (i != O2NM_INVALID_NODE_NUM) {		if (i != osb->node_num) {			mlog(0, "trying to send request to node %i\n", i);			ocfs2_node_map_set_bit(osb, &w->n_node_map, i);			remote_err = 0;			status = o2net_send_message(OCFS2_MESSAGE_TYPE_VOTE,						    osb->net_key,						    request,						    sizeof(*request),						    i,						    &remote_err);			if (status == -ETIMEDOUT) {				mlog(0, "remote node %d timed out!\n", i);				status = -EAGAIN;				goto bail;			}			if (remote_err < 0) {				status = remote_err;				mlog(0, "remote error %d on node %d!\n",				     remote_err, i);				mlog_errno(status);				goto bail;			}			if (status < 0) {				mlog_errno(status);				goto bail;			}		}		i++;		i = ocfs2_node_map_iterate(osb, &osb->mounted_map, i);		mlog(0, "next is %d, i am %d\n", i, osb->node_num);	}	mlog(0, "done sending, now waiting on responses...\n");	wait_event(w->n_event, ocfs2_node_map_is_empty(osb, &w->n_node_map));	ocfs2_dequeue_net_wait_ctxt(osb, w);	dequeued = 1;	*response = w->n_response;	status = 0;bail:	if (w) {		if (!dequeued)			ocfs2_dequeue_net_wait_ctxt(osb, w);		kfree(w);	}	mlog_exit(status);	return status;}static struct ocfs2_vote_msg * ocfs2_new_vote_request(struct ocfs2_super *osb,						      u64 blkno,						      unsigned int generation,						      enum ocfs2_vote_request type){	struct ocfs2_vote_msg *request;	struct ocfs2_msg_hdr *hdr;	BUG_ON(!ocfs2_is_valid_vote_request(type));	request = kzalloc(sizeof(*request), GFP_NOFS);	if (!request) {		mlog_errno(-ENOMEM);	} else {		hdr = &request->v_hdr;		hdr->h_node_num = cpu_to_be32(osb->node_num);		hdr->h_request = cpu_to_be32(type);		hdr->h_blkno = cpu_to_be64(blkno);		hdr->h_generation = cpu_to_be32(generation);	}	return request;}/* Complete the buildup of a new vote request and process the * broadcast return value. */static int ocfs2_do_request_vote(struct ocfs2_super *osb,				 struct ocfs2_vote_msg *request,				 struct ocfs2_net_response_cb *callback){	int status, response = -EBUSY;	unsigned int response_id;	struct ocfs2_msg_hdr *hdr;	response_id = ocfs2_new_response_id(osb);	hdr = &request->v_hdr;	hdr->h_response_id = cpu_to_be32(response_id);	status = ocfs2_broadcast_vote(osb, request, response_id, &response,				      callback);	if (status < 0) {		mlog_errno(status);		goto bail;	}	status = response;bail:	return status;}int ocfs2_request_mount_vote(struct ocfs2_super *osb){	int status;	struct ocfs2_vote_msg *request = NULL;	request = ocfs2_new_vote_request(osb, 0ULL, 0, OCFS2_VOTE_REQ_MOUNT);	if (!request) {		status = -ENOMEM;		goto bail;	}	status = -EAGAIN;	while (status == -EAGAIN) {		if (!(osb->s_mount_opt & OCFS2_MOUNT_NOINTR) &&		    signal_pending(current)) {			status = -ERESTARTSYS;			goto bail;		}		if (ocfs2_node_map_is_only(osb, &osb->mounted_map,					   osb->node_num)) {			status = 0;			goto bail;		}		status = ocfs2_do_request_vote(osb, request, NULL);	}bail:	kfree(request);	return status;}int ocfs2_request_umount_vote(struct ocfs2_super *osb){	int status;	struct ocfs2_vote_msg *request = NULL;	request = ocfs2_new_vote_request(osb, 0ULL, 0, OCFS2_VOTE_REQ_UMOUNT);	if (!request) {		status = -ENOMEM;		goto bail;	}	status = -EAGAIN;	while (status == -EAGAIN) {		/* Do not check signals on this vote... We really want		 * this one to go all the way through. */		if (ocfs2_node_map_is_only(osb, &osb->mounted_map,					   osb->node_num)) {			status = 0;			goto bail;		}		status = ocfs2_do_request_vote(osb, request, NULL);	}bail:	kfree(request);	return status;}/* TODO: This should eventually be a hash table! */static struct ocfs2_net_wait_ctxt * __ocfs2_find_net_wait_ctxt(struct ocfs2_super *osb,							       u32 response_id){	struct list_head *p;	struct ocfs2_net_wait_ctxt *w = NULL;	list_for_each(p, &osb->net_response_list) {		w = list_entry(p, struct ocfs2_net_wait_ctxt, n_list);		if (response_id == w->n_response_id)			break;		w = NULL;	}	return w;}/* Translate response codes into local node errno values */static inline int ocfs2_translate_response(int response){	int ret;	switch (response) {	case OCFS2_RESPONSE_OK:		ret = 0;		break;	case OCFS2_RESPONSE_BUSY:		ret = -EBUSY;		break;	default:		ret = -EINVAL;	}	return ret;}static int ocfs2_handle_response_message(struct o2net_msg *msg,					 u32 len,					 void *data, void **ret_data){	unsigned int response_id, node_num;	int response_status;	struct ocfs2_super *osb = data;	struct ocfs2_response_msg *resp;	struct ocfs2_net_wait_ctxt * w;	struct ocfs2_net_response_cb *resp_cb;	resp = (struct ocfs2_response_msg *) msg->buf;	response_id = be32_to_cpu(resp->r_hdr.h_response_id);	node_num = be32_to_cpu(resp->r_hdr.h_node_num);	response_status = 		ocfs2_translate_response(be32_to_cpu(resp->r_response));	mlog(0, "received response message:\n");	mlog(0, "h_response_id = %u\n", response_id);	mlog(0, "h_request = %u\n", be32_to_cpu(resp->r_hdr.h_request));	mlog(0, "h_blkno = %llu\n",	     (unsigned long long)be64_to_cpu(resp->r_hdr.h_blkno));	mlog(0, "h_generation = %u\n", be32_to_cpu(resp->r_hdr.h_generation));	mlog(0, "h_node_num = %u\n", node_num);	mlog(0, "r_response = %d\n", response_status);	spin_lock(&osb->net_response_lock);	w = __ocfs2_find_net_wait_ctxt(osb, response_id);	if (!w) {		mlog(0, "request not found!\n");		goto bail;	}	resp_cb = w->n_callback;	if (response_status && (!w->n_response)) {		/* we only really need one negative response so don't		 * set it twice. */		w->n_response = response_status;	}	if (resp_cb) {		spin_unlock(&osb->net_response_lock);		resp_cb->rc_cb(resp_cb->rc_priv, resp);		spin_lock(&osb->net_response_lock);	}	__ocfs2_mark_node_responded(osb, w, node_num);bail:	spin_unlock(&osb->net_response_lock);	return 0;}static int ocfs2_handle_vote_message(struct o2net_msg *msg,				     u32 len,				     void *data, void **ret_data){	int status;	struct ocfs2_super *osb = data;	struct ocfs2_vote_work *work;	work = kmalloc(sizeof(struct ocfs2_vote_work), GFP_NOFS);	if (!work) {		status = -ENOMEM;		mlog_errno(status);		goto bail;	}	INIT_LIST_HEAD(&work->w_list);	memcpy(&work->w_msg, msg->buf, sizeof(struct ocfs2_vote_msg));	mlog(0, "scheduling vote request:\n");	mlog(0, "h_response_id = %u\n",	     be32_to_cpu(work->w_msg.v_hdr.h_response_id));	mlog(0, "h_request = %u\n", be32_to_cpu(work->w_msg.v_hdr.h_request));	mlog(0, "h_blkno = %llu\n",	     (unsigned long long)be64_to_cpu(work->w_msg.v_hdr.h_blkno));	mlog(0, "h_generation = %u\n",	     be32_to_cpu(work->w_msg.v_hdr.h_generation));	mlog(0, "h_node_num = %u\n",	     be32_to_cpu(work->w_msg.v_hdr.h_node_num));	spin_lock(&osb->vote_task_lock);	list_add_tail(&work->w_list, &osb->vote_list);	osb->vote_count++;	spin_unlock(&osb->vote_task_lock);	ocfs2_kick_vote_thread(osb);	status = 0;bail:	return status;}void ocfs2_unregister_net_handlers(struct ocfs2_super *osb){	if (!osb->net_key)		return;	o2net_unregister_handler_list(&osb->osb_net_handlers);	if (!list_empty(&osb->net_response_list))		mlog(ML_ERROR, "net response list not empty!\n");	osb->net_key = 0;}int ocfs2_register_net_handlers(struct ocfs2_super *osb){	int status = 0;	if (ocfs2_mount_local(osb))		return 0;	status = o2net_register_handler(OCFS2_MESSAGE_TYPE_RESPONSE,					osb->net_key,					sizeof(struct ocfs2_response_msg),					ocfs2_handle_response_message,					osb, NULL, &osb->osb_net_handlers);	if (status) {		mlog_errno(status);		goto bail;	}	status = o2net_register_handler(OCFS2_MESSAGE_TYPE_VOTE,					osb->net_key,					sizeof(struct ocfs2_vote_msg),					ocfs2_handle_vote_message,					osb, NULL, &osb->osb_net_handlers);	if (status) {		mlog_errno(status);		goto bail;	}bail:	if (status < 0)		ocfs2_unregister_net_handlers(osb);	return status;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -