2874c5fd28426 (Thomas Gleixner 2019-05-27 08:55:01 +0200 1) // SPDX-License-Identifier: GPL-2.0-or-later
ec26815ad847d (David Howells 2007-04-26 15:49:28 -0700 2) /* AFS Volume Location Service client
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 3) *
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 4) * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 5) * Written by David Howells (dhowells@redhat.com)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 6) */
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 7)
5a0e3ad6af866 (Tejun Heo 2010-03-24 17:04:11 +0900 8) #include <linux/gfp.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 9) #include <linux/init.h>
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 10) #include <linux/sched.h>
4d9df9868f31d (David Howells 2017-11-02 15:27:47 +0000 11) #include "afs_fs.h"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 12) #include "internal.h"
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 13)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 14) /*
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 15) * Deliver reply data to a VL.GetEntryByNameU call.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 16) */
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 17) static int afs_deliver_vl_get_entry_by_name_u(struct afs_call *call)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 18) {
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 19) struct afs_uvldbentry__xdr *uvldb;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 20) struct afs_vldb_entry *entry;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 21) bool new_only = false;
1fba5868eed82 (Marc Dionne 2018-05-16 11:04:23 -0300 22) u32 tmp, nr_servers, vlflags;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 23) int i, ret;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 24)
d001648ec7cf8 (David Howells 2016-08-30 20:42:14 +0100 25) _enter("");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 26)
d001648ec7cf8 (David Howells 2016-08-30 20:42:14 +0100 27) ret = afs_transfer_reply(call);
372ee16386bbf (David Howells 2016-08-03 14:11:40 +0100 28) if (ret < 0)
372ee16386bbf (David Howells 2016-08-03 14:11:40 +0100 29) return ret;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 30)
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 31) /* unmarshall the reply once we've received all of it */
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 32) uvldb = call->buffer;
ffba718e93540 (David Howells 2019-05-09 22:22:50 +0100 33) entry = call->ret_vldb;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 34)
45df8462730d2 (David Howells 2018-02-06 14:12:32 +0000 35) nr_servers = ntohl(uvldb->nServers);
45df8462730d2 (David Howells 2018-02-06 14:12:32 +0000 36) if (nr_servers > AFS_NMAXNSERVERS)
45df8462730d2 (David Howells 2018-02-06 14:12:32 +0000 37) nr_servers = AFS_NMAXNSERVERS;
45df8462730d2 (David Howells 2018-02-06 14:12:32 +0000 38)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 39) for (i = 0; i < ARRAY_SIZE(uvldb->name) - 1; i++)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 40) entry->name[i] = (u8)ntohl(uvldb->name[i]);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 41) entry->name[i] = 0;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 42) entry->name_len = strlen(entry->name);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 43)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 44) /* If there is a new replication site that we can use, ignore all the
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 45) * sites that aren't marked as new.
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 46) */
45df8462730d2 (David Howells 2018-02-06 14:12:32 +0000 47) for (i = 0; i < nr_servers; i++) {
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 48) tmp = ntohl(uvldb->serverFlags[i]);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 49) if (!(tmp & AFS_VLSF_DONTUSE) &&
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 50) (tmp & AFS_VLSF_NEWREPSITE))
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 51) new_only = true;
4d9df9868f31d (David Howells 2017-11-02 15:27:47 +0000 52) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 53)
1fba5868eed82 (Marc Dionne 2018-05-16 11:04:23 -0300 54) vlflags = ntohl(uvldb->flags);
45df8462730d2 (David Howells 2018-02-06 14:12:32 +0000 55) for (i = 0; i < nr_servers; i++) {
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 56) struct afs_uuid__xdr *xdr;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 57) struct afs_uuid *uuid;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 58) int j;
4a46fdba449a5 (Marc Dionne 2019-07-30 14:38:51 +0100 59) int n = entry->nr_servers;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 60)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 61) tmp = ntohl(uvldb->serverFlags[i]);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 62) if (tmp & AFS_VLSF_DONTUSE ||
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 63) (new_only && !(tmp & AFS_VLSF_NEWREPSITE)))
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 64) continue;
1fba5868eed82 (Marc Dionne 2018-05-16 11:04:23 -0300 65) if (tmp & AFS_VLSF_RWVOL) {
4a46fdba449a5 (Marc Dionne 2019-07-30 14:38:51 +0100 66) entry->fs_mask[n] |= AFS_VOL_VTM_RW;
1fba5868eed82 (Marc Dionne 2018-05-16 11:04:23 -0300 67) if (vlflags & AFS_VLF_BACKEXISTS)
4a46fdba449a5 (Marc Dionne 2019-07-30 14:38:51 +0100 68) entry->fs_mask[n] |= AFS_VOL_VTM_BAK;
1fba5868eed82 (Marc Dionne 2018-05-16 11:04:23 -0300 69) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 70) if (tmp & AFS_VLSF_ROVOL)
4a46fdba449a5 (Marc Dionne 2019-07-30 14:38:51 +0100 71) entry->fs_mask[n] |= AFS_VOL_VTM_RO;
4a46fdba449a5 (Marc Dionne 2019-07-30 14:38:51 +0100 72) if (!entry->fs_mask[n])
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 73) continue;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 74)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 75) xdr = &uvldb->serverNumber[i];
4a46fdba449a5 (Marc Dionne 2019-07-30 14:38:51 +0100 76) uuid = (struct afs_uuid *)&entry->fs_server[n];
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 77) uuid->time_low = xdr->time_low;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 78) uuid->time_mid = htons(ntohl(xdr->time_mid));
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 79) uuid->time_hi_and_version = htons(ntohl(xdr->time_hi_and_version));
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 80) uuid->clock_seq_hi_and_reserved = (u8)ntohl(xdr->clock_seq_hi_and_reserved);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 81) uuid->clock_seq_low = (u8)ntohl(xdr->clock_seq_low);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 82) for (j = 0; j < 6; j++)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 83) uuid->node[j] = (u8)ntohl(xdr->node[j]);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 84)
8100680592345 (David Howells 2020-04-16 17:05:28 +0100 85) entry->addr_version[n] = ntohl(uvldb->serverUnique[i]);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 86) entry->nr_servers++;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 87) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 88)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 89) for (i = 0; i < AFS_MAXTYPES; i++)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 90) entry->vid[i] = ntohl(uvldb->volumeId[i]);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 91)
1fba5868eed82 (Marc Dionne 2018-05-16 11:04:23 -0300 92) if (vlflags & AFS_VLF_RWEXISTS)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 93) __set_bit(AFS_VLDB_HAS_RW, &entry->flags);
1fba5868eed82 (Marc Dionne 2018-05-16 11:04:23 -0300 94) if (vlflags & AFS_VLF_ROEXISTS)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 95) __set_bit(AFS_VLDB_HAS_RO, &entry->flags);
1fba5868eed82 (Marc Dionne 2018-05-16 11:04:23 -0300 96) if (vlflags & AFS_VLF_BACKEXISTS)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 97) __set_bit(AFS_VLDB_HAS_BAK, &entry->flags);
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 98)
1fba5868eed82 (Marc Dionne 2018-05-16 11:04:23 -0300 99) if (!(vlflags & (AFS_VLF_RWEXISTS | AFS_VLF_ROEXISTS | AFS_VLF_BACKEXISTS))) {
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 100) entry->error = -ENOMEDIUM;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 101) __set_bit(AFS_VLDB_QUERY_ERROR, &entry->flags);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 102) }
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 103)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 104) __set_bit(AFS_VLDB_QUERY_VALID, &entry->flags);
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 105) _leave(" = 0 [done]");
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 106) return 0;
ec26815ad847d (David Howells 2007-04-26 15:49:28 -0700 107) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 108)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 109) static void afs_destroy_vl_get_entry_by_name_u(struct afs_call *call)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 110) {
ffba718e93540 (David Howells 2019-05-09 22:22:50 +0100 111) kfree(call->ret_vldb);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 112) afs_flat_call_destructor(call);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 113) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 114)
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 115) /*
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 116) * VL.GetEntryByNameU operation type.
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 117) */
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 118) static const struct afs_call_type afs_RXVLGetEntryByNameU = {
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 119) .name = "VL.GetEntryByNameU",
025db80c9e421 (David Howells 2017-11-02 15:27:51 +0000 120) .op = afs_VL_GetEntryByNameU,
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 121) .deliver = afs_deliver_vl_get_entry_by_name_u,
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 122) .destructor = afs_destroy_vl_get_entry_by_name_u,
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 123) };
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 124)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 125) /*
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 126) * Dispatch a get volume entry by name or ID operation (uuid variant). If the
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 127) * volname is a decimal number then it's a volume ID not a volume name.
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 128) */
0a5143f2f89cc (David Howells 2018-10-20 00:57:57 +0100 129) struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_vl_cursor *vc,
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 130) const char *volname,
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 131) int volnamesz)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 132) {
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 133) struct afs_vldb_entry *entry;
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 134) struct afs_call *call;
0a5143f2f89cc (David Howells 2018-10-20 00:57:57 +0100 135) struct afs_net *net = vc->cell->net;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 136) size_t reqsz, padsz;
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 137) __be32 *bp;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 138)
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 139) _enter("");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 140)
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 141) padsz = (4 - (volnamesz & 3)) & 3;
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 142) reqsz = 8 + volnamesz + padsz;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 143)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 144) entry = kzalloc(sizeof(struct afs_vldb_entry), GFP_KERNEL);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 145) if (!entry)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 146) return ERR_PTR(-ENOMEM);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 147)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 148) call = afs_alloc_flat_call(net, &afs_RXVLGetEntryByNameU, reqsz,
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 149) sizeof(struct afs_uvldbentry__xdr));
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 150) if (!call) {
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 151) kfree(entry);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 152) return ERR_PTR(-ENOMEM);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 153) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 154)
0a5143f2f89cc (David Howells 2018-10-20 00:57:57 +0100 155) call->key = vc->key;
ffba718e93540 (David Howells 2019-05-09 22:22:50 +0100 156) call->ret_vldb = entry;
94f699c9cdb11 (David Howells 2019-05-16 13:21:59 +0100 157) call->max_lifespan = AFS_VL_MAX_LIFESPAN;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 158)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 159) /* Marshall the parameters */
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 160) bp = call->request;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 161) *bp++ = htonl(VLGETENTRYBYNAMEU);
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 162) *bp++ = htonl(volnamesz);
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 163) memcpy(bp, volname, volnamesz);
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 164) if (padsz > 0)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 165) memset((void *)bp + volnamesz, 0, padsz);
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 166)
025db80c9e421 (David Howells 2017-11-02 15:27:51 +0000 167) trace_afs_make_vl_call(call);
0b9bf3812ad1f (David Howells 2019-04-25 14:26:50 +0100 168) afs_make_call(&vc->ac, call, GFP_KERNEL);
0b9bf3812ad1f (David Howells 2019-04-25 14:26:50 +0100 169) return (struct afs_vldb_entry *)afs_wait_for_call_to_complete(call, &vc->ac);
ec26815ad847d (David Howells 2007-04-26 15:49:28 -0700 170) }
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 171)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 172) /*
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 173) * Deliver reply data to a VL.GetAddrsU call.
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 174) *
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 175) * GetAddrsU(IN ListAddrByAttributes *inaddr,
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 176) * OUT afsUUID *uuidp1,
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 177) * OUT uint32_t *uniquifier,
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 178) * OUT uint32_t *nentries,
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 179) * OUT bulkaddrs *blkaddrs);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 180) */
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 181) static int afs_deliver_vl_get_addrs_u(struct afs_call *call)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 182) {
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 183) struct afs_addr_list *alist;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 184) __be32 *bp;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 185) u32 uniquifier, nentries, count;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 186) int i, ret;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 187)
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 188) _enter("{%u,%zu/%u}",
fc276122496df (David Howells 2019-11-21 09:12:17 +0000 189) call->unmarshall, iov_iter_count(call->iter), call->count);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 190)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 191) switch (call->unmarshall) {
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 192) case 0:
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 193) afs_extract_to_buf(call,
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 194) sizeof(struct afs_uuid__xdr) + 3 * sizeof(__be32));
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 195) call->unmarshall++;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 196)
e690c9e3f4fb2 (Gustavo A. R. Silva 2019-01-10 15:52:25 -0600 197) /* Extract the returned uuid, uniquifier, nentries and
e690c9e3f4fb2 (Gustavo A. R. Silva 2019-01-10 15:52:25 -0600 198) * blkaddrs size */
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 199) fallthrough;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 200) case 1:
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 201) ret = afs_extract_data(call, true);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 202) if (ret < 0)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 203) return ret;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 204)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 205) bp = call->buffer + sizeof(struct afs_uuid__xdr);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 206) uniquifier = ntohl(*bp++);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 207) nentries = ntohl(*bp++);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 208) count = ntohl(*bp);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 209)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 210) nentries = min(nentries, count);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 211) alist = afs_alloc_addrlist(nentries, FS_SERVICE, AFS_FS_PORT);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 212) if (!alist)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 213) return -ENOMEM;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 214) alist->version = uniquifier;
ffba718e93540 (David Howells 2019-05-09 22:22:50 +0100 215) call->ret_alist = alist;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 216) call->count = count;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 217) call->count2 = nentries;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 218) call->unmarshall++;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 219)
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 220) more_entries:
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 221) count = min(call->count, 4U);
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 222) afs_extract_to_buf(call, count * sizeof(__be32));
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 223)
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 224) fallthrough; /* and extract entries */
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 225) case 2:
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 226) ret = afs_extract_data(call, call->count > 4);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 227) if (ret < 0)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 228) return ret;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 229)
ffba718e93540 (David Howells 2019-05-09 22:22:50 +0100 230) alist = call->ret_alist;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 231) bp = call->buffer;
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 232) count = min(call->count, 4U);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 233) for (i = 0; i < count; i++)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 234) if (alist->nr_addrs < call->count2)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 235) afs_merge_fs_addr4(alist, *bp++, AFS_FS_PORT);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 236)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 237) call->count -= count;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 238) if (call->count > 0)
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 239) goto more_entries;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 240) call->unmarshall++;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 241) break;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 242) }
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 243)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 244) _leave(" = 0 [done]");
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 245) return 0;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 246) }
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 247)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 248) static void afs_vl_get_addrs_u_destructor(struct afs_call *call)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 249) {
ffba718e93540 (David Howells 2019-05-09 22:22:50 +0100 250) afs_put_addrlist(call->ret_alist);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 251) return afs_flat_call_destructor(call);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 252) }
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 253)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 254) /*
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 255) * VL.GetAddrsU operation type.
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 256) */
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 257) static const struct afs_call_type afs_RXVLGetAddrsU = {
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 258) .name = "VL.GetAddrsU",
025db80c9e421 (David Howells 2017-11-02 15:27:51 +0000 259) .op = afs_VL_GetAddrsU,
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 260) .deliver = afs_deliver_vl_get_addrs_u,
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 261) .destructor = afs_vl_get_addrs_u_destructor,
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 262) };
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 263)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 264) /*
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 265) * Dispatch an operation to get the addresses for a server, where the server is
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 266) * nominated by UUID.
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 267) */
0a5143f2f89cc (David Howells 2018-10-20 00:57:57 +0100 268) struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *vc,
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 269) const uuid_t *uuid)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 270) {
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 271) struct afs_ListAddrByAttributes__xdr *r;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 272) const struct afs_uuid *u = (const struct afs_uuid *)uuid;
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 273) struct afs_call *call;
0a5143f2f89cc (David Howells 2018-10-20 00:57:57 +0100 274) struct afs_net *net = vc->cell->net;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 275) __be32 *bp;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 276) int i;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 277)
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 278) _enter("");
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 279)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 280) call = afs_alloc_flat_call(net, &afs_RXVLGetAddrsU,
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 281) sizeof(__be32) + sizeof(struct afs_ListAddrByAttributes__xdr),
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 282) sizeof(struct afs_uuid__xdr) + 3 * sizeof(__be32));
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 283) if (!call)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 284) return ERR_PTR(-ENOMEM);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 285)
0a5143f2f89cc (David Howells 2018-10-20 00:57:57 +0100 286) call->key = vc->key;
ffba718e93540 (David Howells 2019-05-09 22:22:50 +0100 287) call->ret_alist = NULL;
94f699c9cdb11 (David Howells 2019-05-16 13:21:59 +0100 288) call->max_lifespan = AFS_VL_MAX_LIFESPAN;
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 289)
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 290) /* Marshall the parameters */
08e0e7c82eead (David Howells 2007-04-26 15:55:03 -0700 291) bp = call->request;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 292) *bp++ = htonl(VLGETADDRSU);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 293) r = (struct afs_ListAddrByAttributes__xdr *)bp;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 294) r->Mask = htonl(AFS_VLADDR_UUID);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 295) r->ipaddr = 0;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 296) r->index = 0;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 297) r->spare = 0;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 298) r->uuid.time_low = u->time_low;
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 299) r->uuid.time_mid = htonl(ntohs(u->time_mid));
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 300) r->uuid.time_hi_and_version = htonl(ntohs(u->time_hi_and_version));
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 301) r->uuid.clock_seq_hi_and_reserved = htonl(u->clock_seq_hi_and_reserved);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 302) r->uuid.clock_seq_low = htonl(u->clock_seq_low);
d2ddc776a4581 (David Howells 2017-11-02 15:27:50 +0000 303) for (i = 0; i < 6; i++)
fe342cf77bc3c (David Howells 2018-04-09 21:12:31 +0100 304) r->uuid.node[i] = htonl(u->node[i]);
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 305)
025db80c9e421 (David Howells 2017-11-02 15:27:51 +0000 306) trace_afs_make_vl_call(call);
0b9bf3812ad1f (David Howells 2019-04-25 14:26:50 +0100 307) afs_make_call(&vc->ac, call, GFP_KERNEL);
0b9bf3812ad1f (David Howells 2019-04-25 14:26:50 +0100 308) return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac);
ec26815ad847d (David Howells 2007-04-26 15:49:28 -0700 309) }
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 310)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 311) /*
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 312) * Deliver reply data to an VL.GetCapabilities operation.
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 313) */
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 314) static int afs_deliver_vl_get_capabilities(struct afs_call *call)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 315) {
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 316) u32 count;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 317) int ret;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 318)
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 319) _enter("{%u,%zu/%u}",
fc276122496df (David Howells 2019-11-21 09:12:17 +0000 320) call->unmarshall, iov_iter_count(call->iter), call->count);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 321)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 322) switch (call->unmarshall) {
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 323) case 0:
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 324) afs_extract_to_tmp(call);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 325) call->unmarshall++;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 326)
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 327) fallthrough; /* and extract the capabilities word count */
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 328) case 1:
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 329) ret = afs_extract_data(call, true);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 330) if (ret < 0)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 331) return ret;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 332)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 333) count = ntohl(call->tmp);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 334) call->count = count;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 335) call->count2 = count;
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 336)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 337) call->unmarshall++;
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 338) afs_extract_discard(call, count * sizeof(__be32));
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 339)
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 340) fallthrough; /* and extract capabilities words */
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 341) case 2:
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 342) ret = afs_extract_data(call, false);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 343) if (ret < 0)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 344) return ret;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 345)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 346) /* TODO: Examine capabilities */
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 347)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 348) call->unmarshall++;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 349) break;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 350) }
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 351)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 352) _leave(" = 0 [done]");
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 353) return 0;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 354) }
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 355)
3bf0fb6f33dd5 (David Howells 2018-10-20 00:57:59 +0100 356) static void afs_destroy_vl_get_capabilities(struct afs_call *call)
3bf0fb6f33dd5 (David Howells 2018-10-20 00:57:59 +0100 357) {
ffba718e93540 (David Howells 2019-05-09 22:22:50 +0100 358) afs_put_vlserver(call->net, call->vlserver);
3bf0fb6f33dd5 (David Howells 2018-10-20 00:57:59 +0100 359) afs_flat_call_destructor(call);
3bf0fb6f33dd5 (David Howells 2018-10-20 00:57:59 +0100 360) }
3bf0fb6f33dd5 (David Howells 2018-10-20 00:57:59 +0100 361)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 362) /*
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 363) * VL.GetCapabilities operation type
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 364) */
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 365) static const struct afs_call_type afs_RXVLGetCapabilities = {
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 366) .name = "VL.GetCapabilities",
025db80c9e421 (David Howells 2017-11-02 15:27:51 +0000 367) .op = afs_VL_GetCapabilities,
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 368) .deliver = afs_deliver_vl_get_capabilities,
3bf0fb6f33dd5 (David Howells 2018-10-20 00:57:59 +0100 369) .done = afs_vlserver_probe_result,
3bf0fb6f33dd5 (David Howells 2018-10-20 00:57:59 +0100 370) .destructor = afs_destroy_vl_get_capabilities,
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 371) };
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 372)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 373) /*
0a5143f2f89cc (David Howells 2018-10-20 00:57:57 +0100 374) * Probe a volume server for the capabilities that it supports. This can
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 375) * return up to 196 words.
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 376) *
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 377) * We use this to probe for service upgrade to determine what the server at the
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 378) * other end supports.
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 379) */
0b9bf3812ad1f (David Howells 2019-04-25 14:26:50 +0100 380) struct afs_call *afs_vl_get_capabilities(struct afs_net *net,
0b9bf3812ad1f (David Howells 2019-04-25 14:26:50 +0100 381) struct afs_addr_cursor *ac,
0b9bf3812ad1f (David Howells 2019-04-25 14:26:50 +0100 382) struct key *key,
0b9bf3812ad1f (David Howells 2019-04-25 14:26:50 +0100 383) struct afs_vlserver *server,
0b9bf3812ad1f (David Howells 2019-04-25 14:26:50 +0100 384) unsigned int server_index)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 385) {
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 386) struct afs_call *call;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 387) __be32 *bp;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 388)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 389) _enter("");
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 390)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 391) call = afs_alloc_flat_call(net, &afs_RXVLGetCapabilities, 1 * 4, 16 * 4);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 392) if (!call)
0b9bf3812ad1f (David Howells 2019-04-25 14:26:50 +0100 393) return ERR_PTR(-ENOMEM);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 394)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 395) call->key = key;
ffba718e93540 (David Howells 2019-05-09 22:22:50 +0100 396) call->vlserver = afs_get_vlserver(server);
ffba718e93540 (David Howells 2019-05-09 22:22:50 +0100 397) call->server_index = server_index;
3bf0fb6f33dd5 (David Howells 2018-10-20 00:57:59 +0100 398) call->upgrade = true;
0b9bf3812ad1f (David Howells 2019-04-25 14:26:50 +0100 399) call->async = true;
94f699c9cdb11 (David Howells 2019-05-16 13:21:59 +0100 400) call->max_lifespan = AFS_PROBE_MAX_LIFESPAN;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 401)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 402) /* marshall the parameters */
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 403) bp = call->request;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 404) *bp++ = htonl(VLGETCAPABILITIES);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 405)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 406) /* Can't take a ref on server */
025db80c9e421 (David Howells 2017-11-02 15:27:51 +0000 407) trace_afs_make_vl_call(call);
0b9bf3812ad1f (David Howells 2019-04-25 14:26:50 +0100 408) afs_make_call(ac, call, GFP_KERNEL);
0b9bf3812ad1f (David Howells 2019-04-25 14:26:50 +0100 409) return call;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 410) }
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 411)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 412) /*
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 413) * Deliver reply data to a YFSVL.GetEndpoints call.
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 414) *
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 415) * GetEndpoints(IN yfsServerAttributes *attr,
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 416) * OUT opr_uuid *uuid,
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 417) * OUT afs_int32 *uniquifier,
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 418) * OUT endpoints *fsEndpoints,
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 419) * OUT endpoints *volEndpoints)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 420) */
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 421) static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 422) {
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 423) struct afs_addr_list *alist;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 424) __be32 *bp;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 425) u32 uniquifier, size;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 426) int ret;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 427)
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 428) _enter("{%u,%zu,%u}",
fc276122496df (David Howells 2019-11-21 09:12:17 +0000 429) call->unmarshall, iov_iter_count(call->iter), call->count2);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 430)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 431) switch (call->unmarshall) {
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 432) case 0:
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 433) afs_extract_to_buf(call, sizeof(uuid_t) + 3 * sizeof(__be32));
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 434) call->unmarshall = 1;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 435)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 436) /* Extract the returned uuid, uniquifier, fsEndpoints count and
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 437) * either the first fsEndpoint type or the volEndpoints
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 438) * count if there are no fsEndpoints. */
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 439) fallthrough;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 440) case 1:
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 441) ret = afs_extract_data(call, true);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 442) if (ret < 0)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 443) return ret;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 444)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 445) bp = call->buffer + sizeof(uuid_t);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 446) uniquifier = ntohl(*bp++);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 447) call->count = ntohl(*bp++);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 448) call->count2 = ntohl(*bp); /* Type or next count */
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 449)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 450) if (call->count > YFS_MAXENDPOINTS)
7126ead910aa9 (David Howells 2020-04-08 16:49:08 +0100 451) return afs_protocol_error(call, afs_eproto_yvl_fsendpt_num);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 452)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 453) alist = afs_alloc_addrlist(call->count, FS_SERVICE, AFS_FS_PORT);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 454) if (!alist)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 455) return -ENOMEM;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 456) alist->version = uniquifier;
ffba718e93540 (David Howells 2019-05-09 22:22:50 +0100 457) call->ret_alist = alist;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 458)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 459) if (call->count == 0)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 460) goto extract_volendpoints;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 461)
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 462) next_fsendpoint:
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 463) switch (call->count2) {
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 464) case YFS_ENDPOINT_IPV4:
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 465) size = sizeof(__be32) * (1 + 1 + 1);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 466) break;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 467) case YFS_ENDPOINT_IPV6:
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 468) size = sizeof(__be32) * (1 + 4 + 1);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 469) break;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 470) default:
7126ead910aa9 (David Howells 2020-04-08 16:49:08 +0100 471) return afs_protocol_error(call, afs_eproto_yvl_fsendpt_type);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 472) }
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 473)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 474) size += sizeof(__be32);
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 475) afs_extract_to_buf(call, size);
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 476) call->unmarshall = 2;
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 477)
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 478) fallthrough; /* and extract fsEndpoints[] entries */
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 479) case 2:
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 480) ret = afs_extract_data(call, true);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 481) if (ret < 0)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 482) return ret;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 483)
ffba718e93540 (David Howells 2019-05-09 22:22:50 +0100 484) alist = call->ret_alist;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 485) bp = call->buffer;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 486) switch (call->count2) {
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 487) case YFS_ENDPOINT_IPV4:
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 488) if (ntohl(bp[0]) != sizeof(__be32) * 2)
7126ead910aa9 (David Howells 2020-04-08 16:49:08 +0100 489) return afs_protocol_error(
7126ead910aa9 (David Howells 2020-04-08 16:49:08 +0100 490) call, afs_eproto_yvl_fsendpt4_len);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 491) afs_merge_fs_addr4(alist, bp[1], ntohl(bp[2]));
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 492) bp += 3;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 493) break;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 494) case YFS_ENDPOINT_IPV6:
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 495) if (ntohl(bp[0]) != sizeof(__be32) * 5)
7126ead910aa9 (David Howells 2020-04-08 16:49:08 +0100 496) return afs_protocol_error(
7126ead910aa9 (David Howells 2020-04-08 16:49:08 +0100 497) call, afs_eproto_yvl_fsendpt6_len);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 498) afs_merge_fs_addr6(alist, bp + 1, ntohl(bp[5]));
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 499) bp += 6;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 500) break;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 501) default:
7126ead910aa9 (David Howells 2020-04-08 16:49:08 +0100 502) return afs_protocol_error(call, afs_eproto_yvl_fsendpt_type);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 503) }
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 504)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 505) /* Got either the type of the next entry or the count of
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 506) * volEndpoints if no more fsEndpoints.
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 507) */
fe342cf77bc3c (David Howells 2018-04-09 21:12:31 +0100 508) call->count2 = ntohl(*bp++);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 509)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 510) call->count--;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 511) if (call->count > 0)
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 512) goto next_fsendpoint;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 513)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 514) extract_volendpoints:
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 515) /* Extract the list of volEndpoints. */
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 516) call->count = call->count2;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 517) if (!call->count)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 518) goto end;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 519) if (call->count > YFS_MAXENDPOINTS)
7126ead910aa9 (David Howells 2020-04-08 16:49:08 +0100 520) return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 521)
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 522) afs_extract_to_buf(call, 1 * sizeof(__be32));
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 523) call->unmarshall = 3;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 524)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 525) /* Extract the type of volEndpoints[0]. Normally we would
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 526) * extract the type of the next endpoint when we extract the
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 527) * data of the current one, but this is the first...
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 528) */
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 529) fallthrough;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 530) case 3:
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 531) ret = afs_extract_data(call, true);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 532) if (ret < 0)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 533) return ret;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 534)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 535) bp = call->buffer;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 536)
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 537) next_volendpoint:
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 538) call->count2 = ntohl(*bp++);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 539) switch (call->count2) {
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 540) case YFS_ENDPOINT_IPV4:
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 541) size = sizeof(__be32) * (1 + 1 + 1);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 542) break;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 543) case YFS_ENDPOINT_IPV6:
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 544) size = sizeof(__be32) * (1 + 4 + 1);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 545) break;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 546) default:
7126ead910aa9 (David Howells 2020-04-08 16:49:08 +0100 547) return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 548) }
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 549)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 550) if (call->count > 1)
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 551) size += sizeof(__be32); /* Get next type too */
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 552) afs_extract_to_buf(call, size);
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 553) call->unmarshall = 4;
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 554)
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 555) fallthrough; /* and extract volEndpoints[] entries */
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 556) case 4:
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 557) ret = afs_extract_data(call, true);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 558) if (ret < 0)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 559) return ret;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 560)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 561) bp = call->buffer;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 562) switch (call->count2) {
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 563) case YFS_ENDPOINT_IPV4:
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 564) if (ntohl(bp[0]) != sizeof(__be32) * 2)
7126ead910aa9 (David Howells 2020-04-08 16:49:08 +0100 565) return afs_protocol_error(
7126ead910aa9 (David Howells 2020-04-08 16:49:08 +0100 566) call, afs_eproto_yvl_vlendpt4_len);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 567) bp += 3;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 568) break;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 569) case YFS_ENDPOINT_IPV6:
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 570) if (ntohl(bp[0]) != sizeof(__be32) * 5)
7126ead910aa9 (David Howells 2020-04-08 16:49:08 +0100 571) return afs_protocol_error(
7126ead910aa9 (David Howells 2020-04-08 16:49:08 +0100 572) call, afs_eproto_yvl_vlendpt6_len);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 573) bp += 6;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 574) break;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 575) default:
7126ead910aa9 (David Howells 2020-04-08 16:49:08 +0100 576) return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 577) }
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 578)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 579) /* Got either the type of the next entry or the count of
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 580) * volEndpoints if no more fsEndpoints.
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 581) */
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 582) call->count--;
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 583) if (call->count > 0)
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 584) goto next_volendpoint;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 585)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 586) end:
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 587) afs_extract_discard(call, 0);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 588) call->unmarshall = 5;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 589)
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 590) fallthrough; /* Done */
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 591) case 5:
12bdcf333fe13 (David Howells 2018-10-20 00:57:56 +0100 592) ret = afs_extract_data(call, false);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 593) if (ret < 0)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 594) return ret;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 595) call->unmarshall = 6;
b2db6c35ba986 (Gustavo A. R. Silva 2021-05-25 15:40:22 +0100 596) fallthrough;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 597)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 598) case 6:
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 599) break;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 600) }
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 601)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 602) _leave(" = 0 [done]");
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 603) return 0;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 604) }
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 605)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 606) /*
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 607) * YFSVL.GetEndpoints operation type.
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 608) */
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 609) static const struct afs_call_type afs_YFSVLGetEndpoints = {
025db80c9e421 (David Howells 2017-11-02 15:27:51 +0000 610) .name = "YFSVL.GetEndpoints",
025db80c9e421 (David Howells 2017-11-02 15:27:51 +0000 611) .op = afs_YFSVL_GetEndpoints,
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 612) .deliver = afs_deliver_yfsvl_get_endpoints,
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 613) .destructor = afs_vl_get_addrs_u_destructor,
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 614) };
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 615)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 616) /*
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 617) * Dispatch an operation to get the addresses for a server, where the server is
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 618) * nominated by UUID.
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 619) */
0a5143f2f89cc (David Howells 2018-10-20 00:57:57 +0100 620) struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *vc,
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 621) const uuid_t *uuid)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 622) {
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 623) struct afs_call *call;
0a5143f2f89cc (David Howells 2018-10-20 00:57:57 +0100 624) struct afs_net *net = vc->cell->net;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 625) __be32 *bp;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 626)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 627) _enter("");
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 628)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 629) call = afs_alloc_flat_call(net, &afs_YFSVLGetEndpoints,
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 630) sizeof(__be32) * 2 + sizeof(*uuid),
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 631) sizeof(struct in6_addr) + sizeof(__be32) * 3);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 632) if (!call)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 633) return ERR_PTR(-ENOMEM);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 634)
0a5143f2f89cc (David Howells 2018-10-20 00:57:57 +0100 635) call->key = vc->key;
ffba718e93540 (David Howells 2019-05-09 22:22:50 +0100 636) call->ret_alist = NULL;
94f699c9cdb11 (David Howells 2019-05-16 13:21:59 +0100 637) call->max_lifespan = AFS_VL_MAX_LIFESPAN;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 638)
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 639) /* Marshall the parameters */
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 640) bp = call->request;
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 641) *bp++ = htonl(YVLGETENDPOINTS);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 642) *bp++ = htonl(YFS_SERVER_UUID);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 643) memcpy(bp, uuid, sizeof(*uuid)); /* Type opr_uuid */
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 644)
025db80c9e421 (David Howells 2017-11-02 15:27:51 +0000 645) trace_afs_make_vl_call(call);
0b9bf3812ad1f (David Howells 2019-04-25 14:26:50 +0100 646) afs_make_call(&vc->ac, call, GFP_KERNEL);
0b9bf3812ad1f (David Howells 2019-04-25 14:26:50 +0100 647) return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac);
bf99a53ce22a2 (David Howells 2017-11-02 15:27:51 +0000 648) }
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 649)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 650) /*
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 651) * Deliver reply data to a YFSVL.GetCellName operation.
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 652) */
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 653) static int afs_deliver_yfsvl_get_cell_name(struct afs_call *call)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 654) {
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 655) char *cell_name;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 656) u32 namesz, paddedsz;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 657) int ret;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 658)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 659) _enter("{%u,%zu/%u}",
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 660) call->unmarshall, iov_iter_count(call->iter), call->count);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 661)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 662) switch (call->unmarshall) {
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 663) case 0:
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 664) afs_extract_to_tmp(call);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 665) call->unmarshall++;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 666)
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 667) fallthrough; /* and extract the cell name length */
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 668) case 1:
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 669) ret = afs_extract_data(call, true);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 670) if (ret < 0)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 671) return ret;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 672)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 673) namesz = ntohl(call->tmp);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 674) if (namesz > AFS_MAXCELLNAME)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 675) return afs_protocol_error(call, afs_eproto_cellname_len);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 676) paddedsz = (namesz + 3) & ~3;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 677) call->count = namesz;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 678) call->count2 = paddedsz - namesz;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 679)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 680) cell_name = kmalloc(namesz + 1, GFP_KERNEL);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 681) if (!cell_name)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 682) return -ENOMEM;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 683) cell_name[namesz] = 0;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 684) call->ret_str = cell_name;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 685)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 686) afs_extract_begin(call, cell_name, namesz);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 687) call->unmarshall++;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 688)
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 689) fallthrough; /* and extract cell name */
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 690) case 2:
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 691) ret = afs_extract_data(call, true);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 692) if (ret < 0)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 693) return ret;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 694)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 695) afs_extract_discard(call, call->count2);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 696) call->unmarshall++;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 697)
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 698) fallthrough; /* and extract padding */
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 699) case 3:
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 700) ret = afs_extract_data(call, false);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 701) if (ret < 0)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 702) return ret;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 703)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 704) call->unmarshall++;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 705) break;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 706) }
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 707)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 708) _leave(" = 0 [done]");
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 709) return 0;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 710) }
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 711)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 712) static void afs_destroy_yfsvl_get_cell_name(struct afs_call *call)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 713) {
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 714) kfree(call->ret_str);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 715) afs_flat_call_destructor(call);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 716) }
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 717)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 718) /*
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 719) * VL.GetCapabilities operation type
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 720) */
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 721) static const struct afs_call_type afs_YFSVLGetCellName = {
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 722) .name = "YFSVL.GetCellName",
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 723) .op = afs_YFSVL_GetCellName,
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 724) .deliver = afs_deliver_yfsvl_get_cell_name,
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 725) .destructor = afs_destroy_yfsvl_get_cell_name,
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 726) };
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 727)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 728) /*
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 729) * Probe a volume server for the capabilities that it supports. This can
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 730) * return up to 196 words.
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 731) *
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 732) * We use this to probe for service upgrade to determine what the server at the
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 733) * other end supports.
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 734) */
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 735) char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *vc)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 736) {
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 737) struct afs_call *call;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 738) struct afs_net *net = vc->cell->net;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 739) __be32 *bp;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 740)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 741) _enter("");
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 742)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 743) call = afs_alloc_flat_call(net, &afs_YFSVLGetCellName, 1 * 4, 0);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 744) if (!call)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 745) return ERR_PTR(-ENOMEM);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 746)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 747) call->key = vc->key;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 748) call->ret_str = NULL;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 749) call->max_lifespan = AFS_VL_MAX_LIFESPAN;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 750)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 751) /* marshall the parameters */
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 752) bp = call->request;
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 753) *bp++ = htonl(YVLGETCELLNAME);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 754)
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 755) /* Can't take a ref on server */
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 756) trace_afs_make_vl_call(call);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 757) afs_make_call(&vc->ac, call, GFP_KERNEL);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 758) return (char *)afs_wait_for_call_to_complete(call, &vc->ac);
c3e9f888263bb (David Howells 2020-04-29 17:26:41 +0100 759) }