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 */
|
CBGetXStatsVersion = 209, /* get version of extended statistics */
|
||||||
CBGetXStats = 210, /* get contents of extended statistics data */
|
CBGetXStats = 210, /* get contents of extended statistics data */
|
||||||
CBInitCallBackState3 = 213, /* initialise callback state, version 3 */
|
CBInitCallBackState3 = 213, /* initialise callback state, version 3 */
|
||||||
|
CBProbeUuid = 214, /* check the client hasn't rebooted */
|
||||||
CBTellMeAboutYourself = 65538, /* get client capabilities */
|
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);
|
struct sk_buff *, bool);
|
||||||
static int afs_deliver_cb_probe(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_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 *,
|
static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *,
|
||||||
struct sk_buff *, bool);
|
struct sk_buff *, bool);
|
||||||
static void afs_cm_destructor(struct afs_call *);
|
static void afs_cm_destructor(struct afs_call *);
|
||||||
|
@ -70,6 +71,16 @@ static const struct afs_call_type afs_SRXCBProbe = {
|
||||||
.destructor = afs_cm_destructor,
|
.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
|
* CB.TellMeAboutYourself operation type
|
||||||
*/
|
*/
|
||||||
|
@ -392,6 +403,102 @@ static int afs_deliver_cb_probe(struct afs_call *call, struct sk_buff *skb,
|
||||||
return 0;
|
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
|
* allow the fileserver to ask about the cache manager's capabilities
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue