vlclient.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 696 行 · 第 1/2 页

C
696
字号
	/* we want to get event notifications from the call */	add_wait_queue(&call->waitq, &myself);	/* marshall the parameters */	param[0] = htonl(VLGETENTRYBYID);	param[1] = htonl(volid);	param[2] = htonl(voltype);	piov[0].iov_len = sizeof(param);	piov[0].iov_base = param;	/* send the parameters to the server */	ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,				    0, &sent);	if (ret < 0)		goto abort;	/* wait for the reply to completely arrive */	bp = rxrpc_call_alloc_scratch(call, 384);	ret = rxrpc_call_read_data(call, bp, 384,				   RXRPC_CALL_READ_BLOCK |				   RXRPC_CALL_READ_ALL);	if (ret < 0) {		if (ret == -ECONNABORTED) {			ret = call->app_errno;			goto out_unwait;		}		goto abort;	}	/* unmarshall the reply */	for (loop = 0; loop < 64; loop++)		entry->name[loop] = ntohl(*bp++);	bp++; /* final NUL */	bp++; /* type */	entry->nservers = ntohl(*bp++);	for (loop = 0; loop < 8; loop++)		entry->servers[loop].s_addr = *bp++;	bp += 8; /* partition IDs */	for (loop = 0; loop < 8; loop++) {		tmp = ntohl(*bp++);		if (tmp & AFS_VLSF_RWVOL)			entry->srvtmask[loop] |= AFS_VOL_VTM_RW;		if (tmp & AFS_VLSF_ROVOL)			entry->srvtmask[loop] |= AFS_VOL_VTM_RO;		if (tmp & AFS_VLSF_BACKVOL)			entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;	}	entry->vid[0] = ntohl(*bp++);	entry->vid[1] = ntohl(*bp++);	entry->vid[2] = ntohl(*bp++);	bp++; /* clone ID */	tmp = ntohl(*bp++); /* flags */	if (tmp & AFS_VLF_RWEXISTS)		entry->vidmask |= AFS_VOL_VTM_RW;	if (tmp & AFS_VLF_ROEXISTS)		entry->vidmask |= AFS_VOL_VTM_RO;	if (tmp & AFS_VLF_BACKEXISTS)		entry->vidmask |= AFS_VOL_VTM_BAK;	ret = -ENOMEDIUM;	if (!entry->vidmask)		goto abort;#if 0 /* TODO: remove */	entry->nservers = 3;	entry->servers[0].s_addr = htonl(0xac101249);	entry->servers[1].s_addr = htonl(0xac101243);	entry->servers[2].s_addr = htonl(0xac10125b /*0xac10125b*/);	entry->srvtmask[0] = AFS_VOL_VTM_RO;	entry->srvtmask[1] = AFS_VOL_VTM_RO;	entry->srvtmask[2] = AFS_VOL_VTM_RO | AFS_VOL_VTM_RW;#endif	/* success */	entry->rtime = get_seconds();	ret = 0; out_unwait:	set_current_state(TASK_RUNNING);	remove_wait_queue(&call->waitq, &myself);	rxrpc_put_call(call); out_put_conn:	rxrpc_put_connection(conn); out:	_leave(" = %d", ret);	return ret; abort:	set_current_state(TASK_UNINTERRUPTIBLE);	rxrpc_call_abort(call, ret);	schedule();	goto out_unwait;} /* end afs_rxvl_get_entry_by_id() *//*****************************************************************************//* * look up a volume location database entry by ID asynchronously */int afs_rxvl_get_entry_by_id_async(struct afs_async_op *op,				   afs_volid_t volid,				   afs_voltype_t voltype){	struct rxrpc_connection *conn;	struct rxrpc_call *call;	struct kvec piov[1];	size_t sent;	int ret;	__be32 param[3];	_enter(",%x,%d,", volid, voltype);	/* get hold of the vlserver connection */	ret = afs_server_get_vlconn(op->server, &conn);	if (ret < 0) {		_leave(" = %d", ret);		return ret;	}	/* create a call through that connection */	ret = rxrpc_create_call(conn,				afs_rxvl_get_entry_by_id_attn,				afs_rxvl_get_entry_by_id_error,				afs_rxvl_aemap,				&op->call);	rxrpc_put_connection(conn);	if (ret < 0) {		printk("kAFS: Unable to create call: %d\n", ret);		_leave(" = %d", ret);		return ret;	}	op->call->app_opcode = VLGETENTRYBYID;	op->call->app_user = op;	call = op->call;	rxrpc_get_call(call);	/* send event notifications from the call to kafsasyncd */	afs_kafsasyncd_begin_op(op);	/* marshall the parameters */	param[0] = htonl(VLGETENTRYBYID);	param[1] = htonl(volid);	param[2] = htonl(voltype);	piov[0].iov_len = sizeof(param);	piov[0].iov_base = param;	/* allocate result read buffer in scratch space */	call->app_scr_ptr = rxrpc_call_alloc_scratch(op->call, 384);	/* send the parameters to the server */	ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,				    0, &sent);	if (ret < 0) {		rxrpc_call_abort(call, ret); /* handle from kafsasyncd */		ret = 0;		goto out;	}	/* wait for the reply to completely arrive */	ret = rxrpc_call_read_data(call, call->app_scr_ptr, 384, 0);	switch (ret) {	case 0:	case -EAGAIN:	case -ECONNABORTED:		ret = 0;		break;	/* all handled by kafsasyncd */	default:		rxrpc_call_abort(call, ret); /* make kafsasyncd handle it */		ret = 0;		break;	} out:	rxrpc_put_call(call);	_leave(" = %d", ret);	return ret;} /* end afs_rxvl_get_entry_by_id_async() *//*****************************************************************************//* * attend to the asynchronous get VLDB entry by ID */int afs_rxvl_get_entry_by_id_async2(struct afs_async_op *op,				    struct afs_cache_vlocation *entry){	__be32 *bp;	__u32 tmp;	int loop, ret;	_enter("{op=%p cst=%u}", op, op->call->app_call_state);	memset(entry, 0, sizeof(*entry));	if (op->call->app_call_state == RXRPC_CSTATE_COMPLETE) {		/* operation finished */		afs_kafsasyncd_terminate_op(op);		bp = op->call->app_scr_ptr;		/* unmarshall the reply */		for (loop = 0; loop < 64; loop++)			entry->name[loop] = ntohl(*bp++);		bp++; /* final NUL */		bp++; /* type */		entry->nservers = ntohl(*bp++);		for (loop = 0; loop < 8; loop++)			entry->servers[loop].s_addr = *bp++;		bp += 8; /* partition IDs */		for (loop = 0; loop < 8; loop++) {			tmp = ntohl(*bp++);			if (tmp & AFS_VLSF_RWVOL)				entry->srvtmask[loop] |= AFS_VOL_VTM_RW;			if (tmp & AFS_VLSF_ROVOL)				entry->srvtmask[loop] |= AFS_VOL_VTM_RO;			if (tmp & AFS_VLSF_BACKVOL)				entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;		}		entry->vid[0] = ntohl(*bp++);		entry->vid[1] = ntohl(*bp++);		entry->vid[2] = ntohl(*bp++);		bp++; /* clone ID */		tmp = ntohl(*bp++); /* flags */		if (tmp & AFS_VLF_RWEXISTS)			entry->vidmask |= AFS_VOL_VTM_RW;		if (tmp & AFS_VLF_ROEXISTS)			entry->vidmask |= AFS_VOL_VTM_RO;		if (tmp & AFS_VLF_BACKEXISTS)			entry->vidmask |= AFS_VOL_VTM_BAK;		ret = -ENOMEDIUM;		if (!entry->vidmask) {			rxrpc_call_abort(op->call, ret);			goto done;		}#if 0 /* TODO: remove */		entry->nservers = 3;		entry->servers[0].s_addr = htonl(0xac101249);		entry->servers[1].s_addr = htonl(0xac101243);		entry->servers[2].s_addr = htonl(0xac10125b /*0xac10125b*/);		entry->srvtmask[0] = AFS_VOL_VTM_RO;		entry->srvtmask[1] = AFS_VOL_VTM_RO;		entry->srvtmask[2] = AFS_VOL_VTM_RO | AFS_VOL_VTM_RW;#endif		/* success */		entry->rtime = get_seconds();		ret = 0;		goto done;	}	if (op->call->app_call_state == RXRPC_CSTATE_ERROR) {		/* operation error */		ret = op->call->app_errno;		goto done;	}	_leave(" = -EAGAIN");	return -EAGAIN; done:	rxrpc_put_call(op->call);	op->call = NULL;	_leave(" = %d", ret);	return ret;} /* end afs_rxvl_get_entry_by_id_async2() *//*****************************************************************************//* * handle attention events on an async get-entry-by-ID op * - called from krxiod */static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call){	struct afs_async_op *op = call->app_user;	_enter("{op=%p cst=%u}", op, call->app_call_state);	switch (call->app_call_state) {	case RXRPC_CSTATE_COMPLETE:		afs_kafsasyncd_attend_op(op);		break;	case RXRPC_CSTATE_CLNT_RCV_REPLY:		if (call->app_async_read)			break;	case RXRPC_CSTATE_CLNT_GOT_REPLY:		if (call->app_read_count == 0)			break;		printk("kAFS: Reply bigger than expected"		       " {cst=%u asyn=%d mark=%Zu rdy=%Zu pr=%u%s}",		       call->app_call_state,		       call->app_async_read,		       call->app_mark,		       call->app_ready_qty,		       call->pkt_rcv_count,		       call->app_last_rcv ? " last" : "");		rxrpc_call_abort(call, -EBADMSG);		break;	default:		BUG();	}	_leave("");} /* end afs_rxvl_get_entry_by_id_attn() *//*****************************************************************************//* * handle error events on an async get-entry-by-ID op * - called from krxiod */static void afs_rxvl_get_entry_by_id_error(struct rxrpc_call *call){	struct afs_async_op *op = call->app_user;	_enter("{op=%p cst=%u}", op, call->app_call_state);	afs_kafsasyncd_attend_op(op);	_leave("");} /* end afs_rxvl_get_entry_by_id_error() */

⌨️ 快捷键说明

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