// SPDX-License-Identifier: GPL-2.0-or-later /* AFS Volume Location Service client * * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com)
*/
/* * Deliver reply data to a VL.GetEntryByNameU call.
*/ staticint afs_deliver_vl_get_entry_by_name_u(struct afs_call *call)
{ struct afs_uvldbentry__xdr *uvldb; struct afs_vldb_entry *entry;
u32 nr_servers, vlflags; int i, ret;
_enter("");
ret = afs_transfer_reply(call); if (ret < 0) return ret;
/* unmarshall the reply once we've received all of it */
uvldb = call->buffer;
entry = call->ret_vldb;
nr_servers = ntohl(uvldb->nServers); if (nr_servers > AFS_NMAXNSERVERS)
nr_servers = AFS_NMAXNSERVERS;
for (i = 0; i < ARRAY_SIZE(uvldb->name) - 1; i++)
entry->name[i] = (u8)ntohl(uvldb->name[i]);
entry->name[i] = 0;
entry->name_len = strlen(entry->name);
vlflags = ntohl(uvldb->flags); for (i = 0; i < nr_servers; i++) { struct afs_uuid__xdr *xdr; struct afs_uuid *uuid;
u32 tmp = ntohl(uvldb->serverFlags[i]); int j; int n = entry->nr_servers;
if (tmp & AFS_VLSF_RWVOL) {
entry->fs_mask[n] |= AFS_VOL_VTM_RW; if (vlflags & AFS_VLF_BACKEXISTS)
entry->fs_mask[n] |= AFS_VOL_VTM_BAK;
} if (tmp & AFS_VLSF_ROVOL)
entry->fs_mask[n] |= AFS_VOL_VTM_RO; if (!entry->fs_mask[n]) continue;
/* * Dispatch a get volume entry by name or ID operation (uuid variant). If the * volname is a decimal number then it's a volume ID not a volume name.
*/ struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_vl_cursor *vc, constchar *volname, int volnamesz)
{ struct afs_vldb_entry *entry; struct afs_call *call; struct afs_net *net = vc->cell->net;
size_t reqsz, padsz;
__be32 *bp;
/* Extract the returned uuid, uniquifier, nentries and
* blkaddrs size */
fallthrough; case 1:
ret = afs_extract_data(call, true); if (ret < 0) return ret;
/* * Dispatch an operation to get the addresses for a server, where the server is * nominated by UUID.
*/ struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *vc, const uuid_t *uuid)
{ struct afs_ListAddrByAttributes__xdr *r; struct afs_addr_list *alist; conststruct afs_uuid *u = (conststruct afs_uuid *)uuid; struct afs_call *call; struct afs_net *net = vc->cell->net;
__be32 *bp; int i;
/* * Probe a volume server for the capabilities that it supports. This can * return up to 196 words. * * We use this to probe for service upgrade to determine what the server at the * other end supports.
*/ struct afs_call *afs_vl_get_capabilities(struct afs_net *net, struct afs_addr_list *alist, unsignedint addr_index, struct key *key, struct afs_vlserver *server, unsignedint server_index)
{ struct afs_call *call;
__be32 *bp;
/* Extract the returned uuid, uniquifier, fsEndpoints count and * either the first fsEndpoint type or the volEndpoints
* count if there are no fsEndpoints. */
fallthrough; case 1:
ret = afs_extract_data(call, true); if (ret < 0) return ret;
bp = call->buffer + sizeof(uuid_t);
uniquifier = ntohl(*bp++);
call->count = ntohl(*bp++);
call->count2 = ntohl(*bp); /* Type or next count */
if (call->count > YFS_MAXENDPOINTS) return afs_protocol_error(call, afs_eproto_yvl_fsendpt_num);
fallthrough; /* and extract fsEndpoints[] entries */ case 2:
ret = afs_extract_data(call, true); if (ret < 0) return ret;
alist = call->ret_alist;
bp = call->buffer; switch (call->count2) { case YFS_ENDPOINT_IPV4: if (ntohl(bp[0]) != sizeof(__be32) * 2) return afs_protocol_error(
call, afs_eproto_yvl_fsendpt4_len);
ret = afs_merge_fs_addr4(call->net, alist, bp[1], ntohl(bp[2])); if (ret < 0) return ret;
bp += 3; break; case YFS_ENDPOINT_IPV6: if (ntohl(bp[0]) != sizeof(__be32) * 5) return afs_protocol_error(
call, afs_eproto_yvl_fsendpt6_len);
ret = afs_merge_fs_addr6(call->net, alist, bp + 1, ntohl(bp[5])); if (ret < 0) return ret;
bp += 6; break; default: return afs_protocol_error(call, afs_eproto_yvl_fsendpt_type);
}
/* Got either the type of the next entry or the count of * volEndpoints if no more fsEndpoints.
*/
call->count2 = ntohl(*bp++);
call->count--; if (call->count > 0) goto next_fsendpoint;
extract_volendpoints: /* Extract the list of volEndpoints. */
call->count = call->count2; if (!call->count) goto end; if (call->count > YFS_MAXENDPOINTS) return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type);
/* Extract the type of volEndpoints[0]. Normally we would * extract the type of the next endpoint when we extract the * data of the current one, but this is the first...
*/
fallthrough; case 3:
ret = afs_extract_data(call, true); if (ret < 0) return ret;
if (call->count > 1)
size += sizeof(__be32); /* Get next type too */
afs_extract_to_buf(call, size);
call->unmarshall = 4;
fallthrough; /* and extract volEndpoints[] entries */ case 4:
ret = afs_extract_data(call, true); if (ret < 0) return ret;
bp = call->buffer; switch (call->count2) { case YFS_ENDPOINT_IPV4: if (ntohl(bp[0]) != sizeof(__be32) * 2) return afs_protocol_error(
call, afs_eproto_yvl_vlendpt4_len);
bp += 3; break; case YFS_ENDPOINT_IPV6: if (ntohl(bp[0]) != sizeof(__be32) * 5) return afs_protocol_error(
call, afs_eproto_yvl_vlendpt6_len);
bp += 6; break; default: return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type);
}
/* Got either the type of the next entry or the count of * volEndpoints if no more fsEndpoints.
*/
call->count--; if (call->count > 0) goto next_volendpoint;
/* * Dispatch an operation to get the addresses for a server, where the server is * nominated by UUID.
*/ struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *vc, const uuid_t *uuid)
{ struct afs_addr_list *alist; struct afs_call *call; struct afs_net *net = vc->cell->net;
__be32 *bp;
/* * Probe a volume server for the capabilities that it supports. This can * return up to 196 words. * * We use this to probe for service upgrade to determine what the server at the * other end supports.
*/ char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *vc)
{ struct afs_call *call; struct afs_net *net = vc->cell->net;
__be32 *bp; char *cellname;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.