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

📄 fsclient.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	*bp++ = htonl(pos);	*bp++ = htonl(size);	*bp++ = htonl(i_size);	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);}/* * deliver reply data to an FS.StoreStatus */static int afs_deliver_fs_store_status(struct afs_call *call,				       struct sk_buff *skb, bool last){	afs_dataversion_t *store_version;	struct afs_vnode *vnode = call->reply;	const __be32 *bp;	_enter(",,%u", last);	afs_transfer_reply(call, skb);	if (!last) {		_leave(" = 0 [more]");		return 0;	}	if (call->reply_size != call->reply_max) {		_leave(" = -EBADMSG [%u != %u]",		       call->reply_size, call->reply_max);		return -EBADMSG;	}	/* unmarshall the reply once we've received all of it */	store_version = NULL;	if (call->operation_ID == FSSTOREDATA)		store_version = &call->store_version;	bp = call->buffer;	xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version);	/* xdr_decode_AFSVolSync(&bp, call->replyX); */	_leave(" = 0 [done]");	return 0;}/* * FS.StoreStatus operation type */static const struct afs_call_type afs_RXFSStoreStatus = {	.name		= "FS.StoreStatus",	.deliver	= afs_deliver_fs_store_status,	.abort_to_error	= afs_abort_to_error,	.destructor	= afs_flat_call_destructor,};static const struct afs_call_type afs_RXFSStoreData_as_Status = {	.name		= "FS.StoreData",	.deliver	= afs_deliver_fs_store_status,	.abort_to_error	= afs_abort_to_error,	.destructor	= afs_flat_call_destructor,};static const struct afs_call_type afs_RXFSStoreData64_as_Status = {	.name		= "FS.StoreData64",	.deliver	= afs_deliver_fs_store_status,	.abort_to_error	= afs_abort_to_error,	.destructor	= afs_flat_call_destructor,};/* * set the attributes on a very large file, using FS.StoreData rather than * FS.StoreStatus so as to alter the file size also */static int afs_fs_setattr_size64(struct afs_server *server, struct key *key,				 struct afs_vnode *vnode, struct iattr *attr,				 const struct afs_wait_mode *wait_mode){	struct afs_call *call;	__be32 *bp;	_enter(",%x,{%x:%u},,",	       key_serial(key), vnode->fid.vid, vnode->fid.vnode);	ASSERT(attr->ia_valid & ATTR_SIZE);	call = afs_alloc_flat_call(&afs_RXFSStoreData64_as_Status,				   (4 + 6 + 3 * 2) * 4,				   (21 + 6) * 4);	if (!call)		return -ENOMEM;	call->key = key;	call->reply = vnode;	call->service_id = FS_SERVICE;	call->port = htons(AFS_FS_PORT);	call->store_version = vnode->status.data_version + 1;	call->operation_ID = FSSTOREDATA;	/* marshall the parameters */	bp = call->request;	*bp++ = htonl(FSSTOREDATA64);	*bp++ = htonl(vnode->fid.vid);	*bp++ = htonl(vnode->fid.vnode);	*bp++ = htonl(vnode->fid.unique);	xdr_encode_AFS_StoreStatus(&bp, attr);	*bp++ = 0;				/* position of start of write */	*bp++ = 0;	*bp++ = 0;				/* size of write */	*bp++ = 0;	*bp++ = htonl(attr->ia_size >> 32);	/* new file length */	*bp++ = htonl((u32) attr->ia_size);	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);}/* * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus * so as to alter the file size also */static int afs_fs_setattr_size(struct afs_server *server, struct key *key,			       struct afs_vnode *vnode, struct iattr *attr,			       const struct afs_wait_mode *wait_mode){	struct afs_call *call;	__be32 *bp;	_enter(",%x,{%x:%u},,",	       key_serial(key), vnode->fid.vid, vnode->fid.vnode);	ASSERT(attr->ia_valid & ATTR_SIZE);	if (attr->ia_size >> 32)		return afs_fs_setattr_size64(server, key, vnode, attr,					     wait_mode);	call = afs_alloc_flat_call(&afs_RXFSStoreData_as_Status,				   (4 + 6 + 3) * 4,				   (21 + 6) * 4);	if (!call)		return -ENOMEM;	call->key = key;	call->reply = vnode;	call->service_id = FS_SERVICE;	call->port = htons(AFS_FS_PORT);	call->store_version = vnode->status.data_version + 1;	call->operation_ID = FSSTOREDATA;	/* marshall the parameters */	bp = call->request;	*bp++ = htonl(FSSTOREDATA);	*bp++ = htonl(vnode->fid.vid);	*bp++ = htonl(vnode->fid.vnode);	*bp++ = htonl(vnode->fid.unique);	xdr_encode_AFS_StoreStatus(&bp, attr);	*bp++ = 0;				/* position of start of write */	*bp++ = 0;				/* size of write */	*bp++ = htonl(attr->ia_size);		/* new file length */	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);}/* * set the attributes on a file, using FS.StoreData if there's a change in file * size, and FS.StoreStatus otherwise */int afs_fs_setattr(struct afs_server *server, struct key *key,		   struct afs_vnode *vnode, struct iattr *attr,		   const struct afs_wait_mode *wait_mode){	struct afs_call *call;	__be32 *bp;	if (attr->ia_valid & ATTR_SIZE)		return afs_fs_setattr_size(server, key, vnode, attr,					   wait_mode);	_enter(",%x,{%x:%u},,",	       key_serial(key), vnode->fid.vid, vnode->fid.vnode);	call = afs_alloc_flat_call(&afs_RXFSStoreStatus,				   (4 + 6) * 4,				   (21 + 6) * 4);	if (!call)		return -ENOMEM;	call->key = key;	call->reply = vnode;	call->service_id = FS_SERVICE;	call->port = htons(AFS_FS_PORT);	call->operation_ID = FSSTORESTATUS;	/* marshall the parameters */	bp = call->request;	*bp++ = htonl(FSSTORESTATUS);	*bp++ = htonl(vnode->fid.vid);	*bp++ = htonl(vnode->fid.vnode);	*bp++ = htonl(vnode->fid.unique);	xdr_encode_AFS_StoreStatus(&bp, attr);	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);}/* * deliver reply data to an FS.GetVolumeStatus */static int afs_deliver_fs_get_volume_status(struct afs_call *call,					    struct sk_buff *skb, bool last){	const __be32 *bp;	char *p;	int ret;	_enter("{%u},{%u},%d", call->unmarshall, skb->len, last);	switch (call->unmarshall) {	case 0:		call->offset = 0;		call->unmarshall++;		/* extract the returned status record */	case 1:		_debug("extract status");		ret = afs_extract_data(call, skb, last, call->buffer,				       12 * 4);		switch (ret) {		case 0:		break;		case -EAGAIN:	return 0;		default:	return ret;		}		bp = call->buffer;		xdr_decode_AFSFetchVolumeStatus(&bp, call->reply2);		call->offset = 0;		call->unmarshall++;		/* extract the volume name length */	case 2:		ret = afs_extract_data(call, skb, last, &call->tmp, 4);		switch (ret) {		case 0:		break;		case -EAGAIN:	return 0;		default:	return ret;		}		call->count = ntohl(call->tmp);		_debug("volname length: %u", call->count);		if (call->count >= AFSNAMEMAX)			return -EBADMSG;		call->offset = 0;		call->unmarshall++;		/* extract the volume name */	case 3:		_debug("extract volname");		if (call->count > 0) {			ret = afs_extract_data(call, skb, last, call->reply3,					       call->count);			switch (ret) {			case 0:		break;			case -EAGAIN:	return 0;			default:	return ret;			}		}		p = call->reply3;		p[call->count] = 0;		_debug("volname '%s'", p);		call->offset = 0;		call->unmarshall++;		/* extract the volume name padding */		if ((call->count & 3) == 0) {			call->unmarshall++;			goto no_volname_padding;		}		call->count = 4 - (call->count & 3);	case 4:		ret = afs_extract_data(call, skb, last, call->buffer,				       call->count);		switch (ret) {		case 0:		break;		case -EAGAIN:	return 0;		default:	return ret;		}		call->offset = 0;		call->unmarshall++;	no_volname_padding:		/* extract the offline message length */	case 5:		ret = afs_extract_data(call, skb, last, &call->tmp, 4);		switch (ret) {		case 0:		break;		case -EAGAIN:	return 0;		default:	return ret;		}		call->count = ntohl(call->tmp);		_debug("offline msg length: %u", call->count);		if (call->count >= AFSNAMEMAX)			return -EBADMSG;		call->offset = 0;		call->unmarshall++;		/* extract the offline message */	case 6:		_debug("extract offline");		if (call->count > 0) {			ret = afs_extract_data(call, skb, last, call->reply3,					       call->count);			switch (ret) {			case 0:		break;			case -EAGAIN:	return 0;			default:	return ret;			}		}		p = call->reply3;		p[call->count] = 0;		_debug("offline '%s'", p);		call->offset = 0;		call->unmarshall++;		/* extract the offline message padding */		if ((call->count & 3) == 0) {			call->unmarshall++;			goto no_offline_padding;		}		call->count = 4 - (call->count & 3);	case 7:		ret = afs_extract_data(call, skb, last, call->buffer,				       call->count);		switch (ret) {		case 0:		break;		case -EAGAIN:	return 0;		default:	return ret;		}		call->offset = 0;		call->unmarshall++;	no_offline_padding:		/* extract the message of the day length */	case 8:		ret = afs_extract_data(call, skb, last, &call->tmp, 4);		switch (ret) {		case 0:		break;		case -EAGAIN:	return 0;		default:	return ret;		}		call->count = ntohl(call->tmp);		_debug("motd length: %u", call->count);		if (call->count >= AFSNAMEMAX)			return -EBADMSG;		call->offset = 0;		call->unmarshall++;		/* extract the message of the day */	case 9:		_debug("extract motd");		if (call->count > 0) {			ret = afs_extract_data(call, skb, last, call->reply3,					       call->count);			switch (ret) {			case 0:		break;			case -EAGAIN:	return 0;			default:	return ret;			}		}		p = call->reply3;		p[call->count] = 0;		_debug("motd '%s'", p);		call->offset = 0;		call->unmarshall++;		/* extract the message of the day padding */		if ((call->count & 3) == 0) {			call->unmarshall++;			goto no_motd_padding;		}		call->count = 4 - (call->count & 3);	case 10:		ret = afs_extract_data(call, skb, last, call->buffer,				       call->count);		switch (ret) {		case 0:		break;		case -EAGAIN:	return 0;		default:	return ret;		}		call->offset = 0;		call->unmarshall++;	no_motd_padding:	case 11:		_debug("trailer %d", skb->len);		if (skb->len != 0)			return -EBADMSG;		break;	}	if (!last)		return 0;	_leave(" = 0 [done]");	return 0;}/* * destroy an FS.GetVolumeStatus call */static void afs_get_volume_status_call_destructor(struct afs_call *call){	kfree(call->reply3);	call->reply3 = NULL;	afs_flat_call_destructor(call);}/* * FS.GetVolumeStatus operation type */static const struct afs_call_type afs_RXFSGetVolumeStatus = {	.name		= "FS.GetVolumeStatus",	.deliver	= afs_deliver_fs_get_volume_status,	.abort_to_error	= afs_abort_to_error,	.destructor	= afs_get_volume_status_call_destructor,};/* * fetch the status of a volume */int afs_fs_get_volume_status(struct afs_server *server,			     struct key *key,			     struct afs_vnode *vnode,			     struct afs_volume_status *vs,			     const struct afs_wait_mode *wait_mode){	struct afs_call *call;	__be32 *bp;	void *tmpbuf;	_enter("");	tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);	if (!tmpbuf)		return -ENOMEM;	call = afs_alloc_flat_call(&afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);	if (!call) {		kfree(tmpbuf);		return -ENOMEM;	}	call->key = key;	call->reply = vnode;	call->reply2 = vs;	call->reply3 = tmpbuf;	call->service_id = FS_SERVICE;	call->port = htons(AFS_FS_PORT);	/* marshall the parameters */	bp = call->request;	bp[0] = htonl(FSGETVOLUMESTATUS);	bp[1] = htonl(vnode->fid.vid);	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);}/* * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock */static int afs_deliver_fs_xxxx_lock(struct afs_call *call,				    struct sk_buff *skb, bool last){	const __be32 *bp;	_enter("{%u},{%u},%d", call->unmarshall, skb->len, 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 */	bp = call->buffer;	/* xdr_decode_AFSVolSync(&bp, call->replyX); */	_leave(" = 0 [done]");	return 0;}/* * FS.SetLock operation type */static const struct afs_call_type afs_RXFSSetLock = {	.name		= "FS.SetLock",	.deliver	= afs_deliver_fs_xxxx_lock,	.abort_to_error	= afs_abort_to_error,	.destructor	= afs_flat_call_destructor,};/* * FS.ExtendLock operation type */static const struct afs_call_type afs_RXFSExtendLock = {	.name		= "FS.ExtendLock",	.deliver	= afs_deliver_fs_xxxx_lock,	.abort_to_error	= afs_abort_to_error,	.destructor	= afs_flat_call_destructor,};/* * FS.ReleaseLock operation type */static const struct afs_call_type afs_RXFSReleaseLock = {	.name		= "FS.ReleaseLock",	.deliver	= afs_deliver_fs_xxxx_lock,	.abort_to_error	= afs_abort_to_error,	.destructor	= afs_flat_call_destructor,};/* * get a lock on a file */int afs_fs_set_lock(struct afs_server *server,		    struct key *key,		    struct afs_vnode *vnode,		    afs_lock_type_t type,		    const struct afs_wait_mode *wait_mode){	struct afs_call *call;	__be32 *bp;	_enter("");	call = afs_alloc_flat_call(&afs_RXFSSetLock, 5 * 4, 6 * 4);	if (!call)		return -ENOMEM;	call->key = key;	call->reply = vnode;	call->service_id = FS_SERVICE;	call->port = htons(AFS_FS_PORT);	/* marshall the parameters */	bp = call->request;	*bp++ = htonl(FSSETLOCK);	*bp++ = htonl(vnode->fid.vid);	*bp++ = htonl(vnode->fid.vnode);	*bp++ = htonl(vnode->fid.unique);	*bp++ = htonl(type);	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);}/* * extend a lock on a file */int afs_fs_extend_lock(struct afs_server *server,		       struct key *key,		       struct afs_vnode *vnode,		       const struct afs_wait_mode *wait_mode){	struct afs_call *call;	__be32 *bp;	_enter("");	call = afs_alloc_flat_call(&afs_RXFSExtendLock, 4 * 4, 6 * 4);	if (!call)		return -ENOMEM;	call->key = key;	call->reply = vnode;	call->service_id = FS_SERVICE;	call->port = htons(AFS_FS_PORT);	/* marshall the parameters */	bp = call->request;	*bp++ = htonl(FSEXTENDLOCK);	*bp++ = htonl(vnode->fid.vid);	*bp++ = htonl(vnode->fid.vnode);	*bp++ = htonl(vnode->fid.unique);	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);}/* * release a lock on a file */int afs_fs_release_lock(struct afs_server *server,			struct key *key,			struct afs_vnode *vnode,			const struct afs_wait_mode *wait_mode){	struct afs_call *call;	__be32 *bp;	_enter("");	call = afs_alloc_flat_call(&afs_RXFSReleaseLock, 4 * 4, 6 * 4);	if (!call)		return -ENOMEM;	call->key = key;	call->reply = vnode;	call->service_id = FS_SERVICE;	call->port = htons(AFS_FS_PORT);	/* marshall the parameters */	bp = call->request;	*bp++ = htonl(FSRELEASELOCK);	*bp++ = htonl(vnode->fid.vid);	*bp++ = htonl(vnode->fid.vnode);	*bp++ = htonl(vnode->fid.unique);	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);}

⌨️ 快捷键说明

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