afs: support the CB.ProbeUuid RPC op
Add support for the CB.ProbeUuid cache manager RPC op. This allows a modern OpenAFS server to quickly ask if the client has been rebooted. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
7c80bcce34
commit
9396d496d7
|
@ -24,6 +24,7 @@ enum AFS_CM_Operations {
|
|||
CBGetXStatsVersion = 209, /* get version of extended statistics */
|
||||
CBGetXStats = 210, /* get contents of extended statistics data */
|
||||
CBInitCallBackState3 = 213, /* initialise callback state, version 3 */
|
||||
CBProbeUuid = 214, /* check the client hasn't rebooted */
|
||||
CBTellMeAboutYourself = 65538, /* get client capabilities */
|
||||
};
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *,
|
|||
struct sk_buff *, bool);
|
||||
static int afs_deliver_cb_probe(struct afs_call *, struct sk_buff *, bool);
|
||||
static int afs_deliver_cb_callback(struct afs_call *, struct sk_buff *, bool);
|
||||
static int afs_deliver_cb_probe_uuid(struct afs_call *, struct sk_buff *, bool);
|
||||
static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *,
|
||||
struct sk_buff *, bool);
|
||||
static void afs_cm_destructor(struct afs_call *);
|
||||
|
@ -70,6 +71,16 @@ static const struct afs_call_type afs_SRXCBProbe = {
|
|||
.destructor = afs_cm_destructor,
|
||||
};
|
||||
|
||||
/*
|
||||
* CB.ProbeUuid operation type
|
||||
*/
|
||||
static const struct afs_call_type afs_SRXCBProbeUuid = {
|
||||
.name = "CB.ProbeUuid",
|
||||
.deliver = afs_deliver_cb_probe_uuid,
|
||||
.abort_to_error = afs_abort_to_error,
|
||||
.destructor = afs_cm_destructor,
|
||||
};
|
||||
|
||||
/*
|
||||
* CB.TellMeAboutYourself operation type
|
||||
*/
|
||||
|
@ -392,6 +403,102 @@ static int afs_deliver_cb_probe(struct afs_call *call, struct sk_buff *skb,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* allow the fileserver to quickly find out if the fileserver has been rebooted
|
||||
*/
|
||||
static void SRXAFSCB_ProbeUuid(struct work_struct *work)
|
||||
{
|
||||
struct afs_call *call = container_of(work, struct afs_call, work);
|
||||
struct afs_uuid *r = call->request;
|
||||
|
||||
struct {
|
||||
__be32 match;
|
||||
} reply;
|
||||
|
||||
_enter("");
|
||||
|
||||
|
||||
if (memcmp(r, &afs_uuid, sizeof(afs_uuid)) == 0)
|
||||
reply.match = htonl(0);
|
||||
else
|
||||
reply.match = htonl(1);
|
||||
|
||||
afs_send_simple_reply(call, &reply, sizeof(reply));
|
||||
_leave("");
|
||||
}
|
||||
|
||||
/*
|
||||
* deliver request data to a CB.ProbeUuid call
|
||||
*/
|
||||
static int afs_deliver_cb_probe_uuid(struct afs_call *call, struct sk_buff *skb,
|
||||
bool last)
|
||||
{
|
||||
struct afs_uuid *r;
|
||||
unsigned loop;
|
||||
__be32 *b;
|
||||
int ret;
|
||||
|
||||
_enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
|
||||
|
||||
if (skb->len > 0)
|
||||
return -EBADMSG;
|
||||
if (!last)
|
||||
return 0;
|
||||
|
||||
switch (call->unmarshall) {
|
||||
case 0:
|
||||
call->offset = 0;
|
||||
call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL);
|
||||
if (!call->buffer)
|
||||
return -ENOMEM;
|
||||
call->unmarshall++;
|
||||
|
||||
case 1:
|
||||
_debug("extract UUID");
|
||||
ret = afs_extract_data(call, skb, last, call->buffer,
|
||||
11 * sizeof(__be32));
|
||||
switch (ret) {
|
||||
case 0: break;
|
||||
case -EAGAIN: return 0;
|
||||
default: return ret;
|
||||
}
|
||||
|
||||
_debug("unmarshall UUID");
|
||||
call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
|
||||
if (!call->request)
|
||||
return -ENOMEM;
|
||||
|
||||
b = call->buffer;
|
||||
r = call->request;
|
||||
r->time_low = ntohl(b[0]);
|
||||
r->time_mid = ntohl(b[1]);
|
||||
r->time_hi_and_version = ntohl(b[2]);
|
||||
r->clock_seq_hi_and_reserved = ntohl(b[3]);
|
||||
r->clock_seq_low = ntohl(b[4]);
|
||||
|
||||
for (loop = 0; loop < 6; loop++)
|
||||
r->node[loop] = ntohl(b[loop + 5]);
|
||||
|
||||
call->offset = 0;
|
||||
call->unmarshall++;
|
||||
|
||||
case 2:
|
||||
_debug("trailer");
|
||||
if (skb->len != 0)
|
||||
return -EBADMSG;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!last)
|
||||
return 0;
|
||||
|
||||
call->state = AFS_CALL_REPLYING;
|
||||
|
||||
INIT_WORK(&call->work, SRXAFSCB_ProbeUuid);
|
||||
schedule_work(&call->work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* allow the fileserver to ask about the cache manager's capabilities
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue