forked from Minki/linux
afs: Implement client support for the YFSVL.GetCellName RPC op
Implement client support for the YFSVL.GetCellName RPC operation by which YFS permits the canonical cell name to be queried from a VL server. Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
parent
194d28cf19
commit
c3e9f88826
@ -10,7 +10,7 @@
|
||||
|
||||
#include <linux/in.h>
|
||||
|
||||
#define AFS_MAXCELLNAME 64 /* Maximum length of a cell name */
|
||||
#define AFS_MAXCELLNAME 256 /* Maximum length of a cell name */
|
||||
#define AFS_MAXVOLNAME 64 /* Maximum length of a volume name */
|
||||
#define AFS_MAXNSERVERS 8 /* Maximum servers in a basic volume record */
|
||||
#define AFS_NMAXNSERVERS 13 /* Maximum servers in a N/U-class volume record */
|
||||
|
@ -22,6 +22,7 @@ enum AFSVL_Operations {
|
||||
VLGETENTRYBYNAMEU = 527, /* AFS Get VLDB entry by name (UUID-variant) */
|
||||
VLGETADDRSU = 533, /* AFS Get addrs for fileserver */
|
||||
YVLGETENDPOINTS = 64002, /* YFS Get endpoints for file/volume server */
|
||||
YVLGETCELLNAME = 64014, /* YFS Get actual cell name */
|
||||
VLGETCAPABILITIES = 65537, /* AFS Get server capabilities */
|
||||
};
|
||||
|
||||
|
@ -116,6 +116,7 @@ struct afs_call {
|
||||
long ret0; /* Value to reply with instead of 0 */
|
||||
struct afs_addr_list *ret_alist;
|
||||
struct afs_vldb_entry *ret_vldb;
|
||||
char *ret_str;
|
||||
};
|
||||
struct afs_operation *op;
|
||||
unsigned int server_index;
|
||||
@ -1373,6 +1374,7 @@ extern struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *, const uu
|
||||
extern struct afs_call *afs_vl_get_capabilities(struct afs_net *, struct afs_addr_cursor *,
|
||||
struct key *, struct afs_vlserver *, unsigned int);
|
||||
extern struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *, const uuid_t *);
|
||||
extern char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *);
|
||||
|
||||
/*
|
||||
* vl_probe.c
|
||||
|
@ -8,7 +8,7 @@
|
||||
#define YFS_FS_SERVICE 2500
|
||||
#define YFS_CM_SERVICE 2501
|
||||
|
||||
#define YFSCBMAX 1024
|
||||
#define YFSCBMAX 1024
|
||||
|
||||
enum YFS_CM_Operations {
|
||||
YFSCBProbe = 206, /* probe client */
|
||||
|
@ -645,3 +645,114 @@ struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *vc,
|
||||
afs_make_call(&vc->ac, call, GFP_KERNEL);
|
||||
return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac);
|
||||
}
|
||||
|
||||
/*
|
||||
* Deliver reply data to a YFSVL.GetCellName operation.
|
||||
*/
|
||||
static int afs_deliver_yfsvl_get_cell_name(struct afs_call *call)
|
||||
{
|
||||
char *cell_name;
|
||||
u32 namesz, paddedsz;
|
||||
int ret;
|
||||
|
||||
_enter("{%u,%zu/%u}",
|
||||
call->unmarshall, iov_iter_count(call->iter), call->count);
|
||||
|
||||
switch (call->unmarshall) {
|
||||
case 0:
|
||||
afs_extract_to_tmp(call);
|
||||
call->unmarshall++;
|
||||
|
||||
/* Fall through - and extract the cell name length */
|
||||
case 1:
|
||||
ret = afs_extract_data(call, true);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
namesz = ntohl(call->tmp);
|
||||
if (namesz > AFS_MAXCELLNAME)
|
||||
return afs_protocol_error(call, afs_eproto_cellname_len);
|
||||
paddedsz = (namesz + 3) & ~3;
|
||||
call->count = namesz;
|
||||
call->count2 = paddedsz - namesz;
|
||||
|
||||
cell_name = kmalloc(namesz + 1, GFP_KERNEL);
|
||||
if (!cell_name)
|
||||
return -ENOMEM;
|
||||
cell_name[namesz] = 0;
|
||||
call->ret_str = cell_name;
|
||||
|
||||
afs_extract_begin(call, cell_name, namesz);
|
||||
call->unmarshall++;
|
||||
|
||||
/* Fall through - and extract cell name */
|
||||
case 2:
|
||||
ret = afs_extract_data(call, true);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
afs_extract_discard(call, call->count2);
|
||||
call->unmarshall++;
|
||||
|
||||
/* Fall through - and extract padding */
|
||||
case 3:
|
||||
ret = afs_extract_data(call, false);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
call->unmarshall++;
|
||||
break;
|
||||
}
|
||||
|
||||
_leave(" = 0 [done]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void afs_destroy_yfsvl_get_cell_name(struct afs_call *call)
|
||||
{
|
||||
kfree(call->ret_str);
|
||||
afs_flat_call_destructor(call);
|
||||
}
|
||||
|
||||
/*
|
||||
* VL.GetCapabilities operation type
|
||||
*/
|
||||
static const struct afs_call_type afs_YFSVLGetCellName = {
|
||||
.name = "YFSVL.GetCellName",
|
||||
.op = afs_YFSVL_GetCellName,
|
||||
.deliver = afs_deliver_yfsvl_get_cell_name,
|
||||
.destructor = afs_destroy_yfsvl_get_cell_name,
|
||||
};
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
_enter("");
|
||||
|
||||
call = afs_alloc_flat_call(net, &afs_YFSVLGetCellName, 1 * 4, 0);
|
||||
if (!call)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
call->key = vc->key;
|
||||
call->ret_str = NULL;
|
||||
call->max_lifespan = AFS_VL_MAX_LIFESPAN;
|
||||
|
||||
/* marshall the parameters */
|
||||
bp = call->request;
|
||||
*bp++ = htonl(YVLGETCELLNAME);
|
||||
|
||||
/* Can't take a ref on server */
|
||||
trace_afs_make_vl_call(call);
|
||||
afs_make_call(&vc->ac, call, GFP_KERNEL);
|
||||
return (char *)afs_wait_for_call_to_complete(call, &vc->ac);
|
||||
}
|
||||
|
@ -111,6 +111,7 @@ enum afs_vl_operation {
|
||||
afs_VL_GetEntryByNameU = 527, /* AFS Get Vol Entry By Name operation ID */
|
||||
afs_VL_GetAddrsU = 533, /* AFS Get FS server addresses */
|
||||
afs_YFSVL_GetEndpoints = 64002, /* YFS Get FS & Vol server addresses */
|
||||
afs_YFSVL_GetCellName = 64014, /* YFS Get actual cell name */
|
||||
afs_VL_GetCapabilities = 65537, /* AFS Get VL server capabilities */
|
||||
};
|
||||
|
||||
@ -143,6 +144,7 @@ enum afs_eproto_cause {
|
||||
afs_eproto_bad_status,
|
||||
afs_eproto_cb_count,
|
||||
afs_eproto_cb_fid_count,
|
||||
afs_eproto_cellname_len,
|
||||
afs_eproto_file_type,
|
||||
afs_eproto_ibulkst_cb_count,
|
||||
afs_eproto_ibulkst_count,
|
||||
@ -316,6 +318,7 @@ enum afs_cb_break_reason {
|
||||
EM(afs_VL_GetEntryByNameU, "VL.GetEntryByNameU") \
|
||||
EM(afs_VL_GetAddrsU, "VL.GetAddrsU") \
|
||||
EM(afs_YFSVL_GetEndpoints, "YFSVL.GetEndpoints") \
|
||||
EM(afs_YFSVL_GetCellName, "YFSVL.GetCellName") \
|
||||
E_(afs_VL_GetCapabilities, "VL.GetCapabilities")
|
||||
|
||||
#define afs_edit_dir_ops \
|
||||
@ -345,6 +348,7 @@ enum afs_cb_break_reason {
|
||||
EM(afs_eproto_bad_status, "BadStatus") \
|
||||
EM(afs_eproto_cb_count, "CbCount") \
|
||||
EM(afs_eproto_cb_fid_count, "CbFidCount") \
|
||||
EM(afs_eproto_cellname_len, "CellNameLen") \
|
||||
EM(afs_eproto_file_type, "FileTYpe") \
|
||||
EM(afs_eproto_ibulkst_cb_count, "IBS.CbCount") \
|
||||
EM(afs_eproto_ibulkst_count, "IBS.FidCount") \
|
||||
|
Loading…
Reference in New Issue
Block a user