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

📄 vlclient.c

📁 linux 内核源代码
💻 C
字号:
/* AFS Volume Location Service client * * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */#include <linux/init.h>#include <linux/sched.h>#include "internal.h"/* * map volume locator abort codes to error codes */static int afs_vl_abort_to_error(u32 abort_code){	_enter("%u", abort_code);	switch (abort_code) {	case AFSVL_IDEXIST:		return -EEXIST;	case AFSVL_IO:			return -EREMOTEIO;	case AFSVL_NAMEEXIST:		return -EEXIST;	case AFSVL_CREATEFAIL:		return -EREMOTEIO;	case AFSVL_NOENT:		return -ENOMEDIUM;	case AFSVL_EMPTY:		return -ENOMEDIUM;	case AFSVL_ENTDELETED:		return -ENOMEDIUM;	case AFSVL_BADNAME:		return -EINVAL;	case AFSVL_BADINDEX:		return -EINVAL;	case AFSVL_BADVOLTYPE:		return -EINVAL;	case AFSVL_BADSERVER:		return -EINVAL;	case AFSVL_BADPARTITION:	return -EINVAL;	case AFSVL_REPSFULL:		return -EFBIG;	case AFSVL_NOREPSERVER:		return -ENOENT;	case AFSVL_DUPREPSERVER:	return -EEXIST;	case AFSVL_RWNOTFOUND:		return -ENOENT;	case AFSVL_BADREFCOUNT:		return -EINVAL;	case AFSVL_SIZEEXCEEDED:	return -EINVAL;	case AFSVL_BADENTRY:		return -EINVAL;	case AFSVL_BADVOLIDBUMP:	return -EINVAL;	case AFSVL_IDALREADYHASHED:	return -EINVAL;	case AFSVL_ENTRYLOCKED:		return -EBUSY;	case AFSVL_BADVOLOPER:		return -EBADRQC;	case AFSVL_BADRELLOCKTYPE:	return -EINVAL;	case AFSVL_RERELEASE:		return -EREMOTEIO;	case AFSVL_BADSERVERFLAG:	return -EINVAL;	case AFSVL_PERM:		return -EACCES;	case AFSVL_NOMEM:		return -EREMOTEIO;	default:		return afs_abort_to_error(abort_code);	}}/* * deliver reply data to a VL.GetEntryByXXX call */static int afs_deliver_vl_get_entry_by_xxx(struct afs_call *call,					   struct sk_buff *skb, bool last){	struct afs_cache_vlocation *entry;	__be32 *bp;	u32 tmp;	int loop;	_enter(",,%u", last);	afs_transfer_reply(call, skb);	if (!last)		return 0;	if (call->reply_size != call->reply_max)		return -EBADMSG;	/* unmarshall the reply once we've received all of it */	entry = call->reply;	bp = call->buffer;	for (loop = 0; loop < 64; loop++)		entry->name[loop] = ntohl(*bp++);	entry->name[loop] = 0;	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++);		entry->srvtmask[loop] = 0;		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 */	entry->vidmask = 0;	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;	if (!entry->vidmask)		return -EBADMSG;	_leave(" = 0 [done]");	return 0;}/* * VL.GetEntryByName operation type */static const struct afs_call_type afs_RXVLGetEntryByName = {	.name		= "VL.GetEntryByName",	.deliver	= afs_deliver_vl_get_entry_by_xxx,	.abort_to_error	= afs_vl_abort_to_error,	.destructor	= afs_flat_call_destructor,};/* * VL.GetEntryById operation type */static const struct afs_call_type afs_RXVLGetEntryById = {	.name		= "VL.GetEntryById",	.deliver	= afs_deliver_vl_get_entry_by_xxx,	.abort_to_error	= afs_vl_abort_to_error,	.destructor	= afs_flat_call_destructor,};/* * dispatch a get volume entry by name operation */int afs_vl_get_entry_by_name(struct in_addr *addr,			     struct key *key,			     const char *volname,			     struct afs_cache_vlocation *entry,			     const struct afs_wait_mode *wait_mode){	struct afs_call *call;	size_t volnamesz, reqsz, padsz;	__be32 *bp;	_enter("");	volnamesz = strlen(volname);	padsz = (4 - (volnamesz & 3)) & 3;	reqsz = 8 + volnamesz + padsz;	call = afs_alloc_flat_call(&afs_RXVLGetEntryByName, reqsz, 384);	if (!call)		return -ENOMEM;	call->key = key;	call->reply = entry;	call->service_id = VL_SERVICE;	call->port = htons(AFS_VL_PORT);	/* marshall the parameters */	bp = call->request;	*bp++ = htonl(VLGETENTRYBYNAME);	*bp++ = htonl(volnamesz);	memcpy(bp, volname, volnamesz);	if (padsz > 0)		memset((void *) bp + volnamesz, 0, padsz);	/* initiate the call */	return afs_make_call(addr, call, GFP_KERNEL, wait_mode);}/* * dispatch a get volume entry by ID operation */int afs_vl_get_entry_by_id(struct in_addr *addr,			   struct key *key,			   afs_volid_t volid,			   afs_voltype_t voltype,			   struct afs_cache_vlocation *entry,			   const struct afs_wait_mode *wait_mode){	struct afs_call *call;	__be32 *bp;	_enter("");	call = afs_alloc_flat_call(&afs_RXVLGetEntryById, 12, 384);	if (!call)		return -ENOMEM;	call->key = key;	call->reply = entry;	call->service_id = VL_SERVICE;	call->port = htons(AFS_VL_PORT);	/* marshall the parameters */	bp = call->request;	*bp++ = htonl(VLGETENTRYBYID);	*bp++ = htonl(volid);	*bp   = htonl(voltype);	/* initiate the call */	return afs_make_call(addr, call, GFP_KERNEL, wait_mode);}

⌨️ 快捷键说明

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