/* * allow the fileserver to ask about the cache manager's capabilities */ static void SRXAFSCB_GetCapabilities(struct work_struct *work) { struct afs_interface *ifs; struct afs_call *call = container_of(work, struct afs_call, work); int loop, nifs; struct { struct /* InterfaceAddr */ { __be32 nifs; __be32 uuid[11]; __be32 ifaddr[32]; __be32 netmask[32]; __be32 mtu[32]; } ia; struct /* Capabilities */ { __be32 capcount; __be32 caps[1]; } cap; } reply; _enter(""); nifs = 0; ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL); if (ifs) { nifs = afs_get_ipv4_interfaces(ifs, 32, false); if (nifs < 0) { kfree(ifs); ifs = NULL; nifs = 0; } } memset(&reply, 0, sizeof(reply)); reply.ia.nifs = htonl(nifs); reply.ia.uuid[0] = htonl(afs_uuid.time_low); reply.ia.uuid[1] = htonl(afs_uuid.time_mid); reply.ia.uuid[2] = htonl(afs_uuid.time_hi_and_version); reply.ia.uuid[3] = htonl((s8) afs_uuid.clock_seq_hi_and_reserved); reply.ia.uuid[4] = htonl((s8) afs_uuid.clock_seq_low); for (loop = 0; loop < 6; loop++) reply.ia.uuid[loop + 5] = htonl((s8) afs_uuid.node[loop]); if (ifs) { for (loop = 0; loop < nifs; loop++) { reply.ia.ifaddr[loop] = ifs[loop].address.s_addr; reply.ia.netmask[loop] = ifs[loop].netmask.s_addr; reply.ia.mtu[loop] = htonl(ifs[loop].mtu); } kfree(ifs); } reply.cap.capcount = htonl(1); reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION); afs_send_simple_reply(call, &reply, sizeof(reply)); _leave(""); }
/* * 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 uuid_v1 *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)); afs_put_call(call); _leave(""); }