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

📄 vote.c

📁 ocfs1.2.7 源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);	if (ocfs2_inode_is_new(inode))		return 0;	status = -EAGAIN;	while (status == -EAGAIN) {		if (!(osb->s_mount_opt & OCFS2_MOUNT_NOINTR) &&		    signal_pending(current))			return -ERESTARTSYS;		status = ocfs2_super_lock(osb, 0);		if (status < 0) {			mlog_errno(status);			break;		}		status = 0;		if (!ocfs2_node_map_is_only(osb, &osb->mounted_map,					   osb->node_num))			status = ocfs2_do_request_vote(osb, request, callback);		ocfs2_super_unlock(osb, 0);	}	return status;}static void ocfs2_delete_response_cb(void *priv,				     struct ocfs2_response_msg *resp){	int orphaned_slot, node;	struct inode *inode = priv;	orphaned_slot = be32_to_cpu(resp->r_orphaned_slot);	node = be32_to_cpu(resp->r_hdr.h_node_num);	mlog(0, "node %d tells us that inode %"MLFu64" is orphaned in slot "	     "%d\n", node, OCFS2_I(inode)->ip_blkno, orphaned_slot);	/* The other node may not actually know which slot the inode	 * is orphaned in. */	if (orphaned_slot == OCFS2_INVALID_SLOT)		return;	/* Ok, the responding node knows which slot this inode is	 * orphaned in. We verify that the information is correct and	 * then record this in the inode. ocfs2_delete_inode will use	 * this information to determine which lock to take. */	spin_lock(&OCFS2_I(inode)->ip_lock);	mlog_bug_on_msg(OCFS2_I(inode)->ip_orphaned_slot != orphaned_slot &&			OCFS2_I(inode)->ip_orphaned_slot			!= OCFS2_INVALID_SLOT, "Inode %"MLFu64": Node %d "			"says it's orphaned in slot %d, we think it's in %d\n",			OCFS2_I(inode)->ip_blkno,			be32_to_cpu(resp->r_hdr.h_node_num),			orphaned_slot, OCFS2_I(inode)->ip_orphaned_slot);	OCFS2_I(inode)->ip_orphaned_slot = orphaned_slot;	spin_unlock(&OCFS2_I(inode)->ip_lock);}int ocfs2_request_delete_vote(struct inode *inode){	int orphaned_slot, status;	struct ocfs2_net_response_cb delete_cb;	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);	struct ocfs2_vote_msg *request;	spin_lock(&OCFS2_I(inode)->ip_lock);	orphaned_slot = OCFS2_I(inode)->ip_orphaned_slot;	spin_unlock(&OCFS2_I(inode)->ip_lock);	delete_cb.rc_cb = ocfs2_delete_response_cb;	delete_cb.rc_priv = inode;	mlog(0, "Inode %"MLFu64", we start thinking orphaned slot is %d\n",	     OCFS2_I(inode)->ip_blkno, orphaned_slot);	status = -ENOMEM;	request = ocfs2_new_vote_request(osb, OCFS2_I(inode)->ip_blkno,					 inode->i_generation,					 OCFS2_VOTE_REQ_DELETE, orphaned_slot);	if (request) {		status = ocfs2_request_vote(inode, request, &delete_cb);		kfree(request);	}	return status;}static void ocfs2_setup_unlink_vote(struct ocfs2_vote_msg *request,				    struct dentry *dentry){	struct inode *parent = dentry->d_parent->d_inode;	/* We need some values which will uniquely identify a dentry	 * on the other nodes so that they can find it and run	 * d_delete against it. Parent directory block and full name	 * should suffice. */	mlog(0, "unlink/rename request: parent: %"MLFu64" name: %.*s\n",	     OCFS2_I(parent)->ip_blkno, dentry->d_name.len,	     dentry->d_name.name);	request->v_unlink_parent = cpu_to_be64(OCFS2_I(parent)->ip_blkno);	request->v_unlink_namelen = cpu_to_be32(dentry->d_name.len);	memcpy(request->v_unlink_dirent, dentry->d_name.name,	       dentry->d_name.len);}int ocfs2_request_unlink_vote(struct inode *inode,			      struct dentry *dentry,			      unsigned int nlink){	int status;	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);	struct ocfs2_vote_msg *request;	if (dentry->d_name.len > OCFS2_VOTE_FILENAME_LEN)		return -ENAMETOOLONG;	status = -ENOMEM;	request = ocfs2_new_vote_request(osb, OCFS2_I(inode)->ip_blkno,					 inode->i_generation,					 OCFS2_VOTE_REQ_UNLINK, nlink);	if (request) {		ocfs2_setup_unlink_vote(request, dentry);		status = ocfs2_request_vote(inode, request, NULL);		kfree(request);	}	return status;}int ocfs2_request_rename_vote(struct inode *inode,			      struct dentry *dentry){	int status;	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);	struct ocfs2_vote_msg *request;	if (dentry->d_name.len > OCFS2_VOTE_FILENAME_LEN)		return -ENAMETOOLONG;	status = -ENOMEM;	request = ocfs2_new_vote_request(osb, OCFS2_I(inode)->ip_blkno,					 inode->i_generation,					 OCFS2_VOTE_REQ_RENAME, 0);	if (request) {		ocfs2_setup_unlink_vote(request, dentry);		status = ocfs2_request_vote(inode, request, NULL);		kfree(request);	}	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, 0);	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:	if (request)		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, 0);	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:	if (request)		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 = %"MLFu64"\n", 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 = %"MLFu64"\n",	     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));	mlog(0, "v_generic1 = %u\n", be32_to_cpu(work->w_msg.md1.v_generic1));	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 + -