cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

server_list.c (2983B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/* AFS fileserver list management.
      3 *
      4 * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
      5 * Written by David Howells (dhowells@redhat.com)
      6 */
      7
      8#include <linux/kernel.h>
      9#include <linux/slab.h>
     10#include "internal.h"
     11
     12void afs_put_serverlist(struct afs_net *net, struct afs_server_list *slist)
     13{
     14	int i;
     15
     16	if (slist && refcount_dec_and_test(&slist->usage)) {
     17		for (i = 0; i < slist->nr_servers; i++)
     18			afs_unuse_server(net, slist->servers[i].server,
     19					 afs_server_trace_put_slist);
     20		kfree(slist);
     21	}
     22}
     23
     24/*
     25 * Build a server list from a VLDB record.
     26 */
     27struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell,
     28					      struct key *key,
     29					      struct afs_vldb_entry *vldb,
     30					      u8 type_mask)
     31{
     32	struct afs_server_list *slist;
     33	struct afs_server *server;
     34	int ret = -ENOMEM, nr_servers = 0, i, j;
     35
     36	for (i = 0; i < vldb->nr_servers; i++)
     37		if (vldb->fs_mask[i] & type_mask)
     38			nr_servers++;
     39
     40	slist = kzalloc(struct_size(slist, servers, nr_servers), GFP_KERNEL);
     41	if (!slist)
     42		goto error;
     43
     44	refcount_set(&slist->usage, 1);
     45	rwlock_init(&slist->lock);
     46
     47	for (i = 0; i < AFS_MAXTYPES; i++)
     48		slist->vids[i] = vldb->vid[i];
     49
     50	/* Make sure a records exists for each server in the list. */
     51	for (i = 0; i < vldb->nr_servers; i++) {
     52		if (!(vldb->fs_mask[i] & type_mask))
     53			continue;
     54
     55		server = afs_lookup_server(cell, key, &vldb->fs_server[i],
     56					   vldb->addr_version[i]);
     57		if (IS_ERR(server)) {
     58			ret = PTR_ERR(server);
     59			if (ret == -ENOENT ||
     60			    ret == -ENOMEDIUM)
     61				continue;
     62			goto error_2;
     63		}
     64
     65		/* Insertion-sort by UUID */
     66		for (j = 0; j < slist->nr_servers; j++)
     67			if (memcmp(&slist->servers[j].server->uuid,
     68				   &server->uuid,
     69				   sizeof(server->uuid)) >= 0)
     70				break;
     71		if (j < slist->nr_servers) {
     72			if (slist->servers[j].server == server) {
     73				afs_put_server(cell->net, server,
     74					       afs_server_trace_put_slist_isort);
     75				continue;
     76			}
     77
     78			memmove(slist->servers + j + 1,
     79				slist->servers + j,
     80				(slist->nr_servers - j) * sizeof(struct afs_server_entry));
     81		}
     82
     83		slist->servers[j].server = server;
     84		slist->nr_servers++;
     85	}
     86
     87	if (slist->nr_servers == 0) {
     88		ret = -EDESTADDRREQ;
     89		goto error_2;
     90	}
     91
     92	return slist;
     93
     94error_2:
     95	afs_put_serverlist(cell->net, slist);
     96error:
     97	return ERR_PTR(ret);
     98}
     99
    100/*
    101 * Copy the annotations from an old server list to its potential replacement.
    102 */
    103bool afs_annotate_server_list(struct afs_server_list *new,
    104			      struct afs_server_list *old)
    105{
    106	struct afs_server *cur;
    107	int i, j;
    108
    109	if (old->nr_servers != new->nr_servers)
    110		goto changed;
    111
    112	for (i = 0; i < old->nr_servers; i++)
    113		if (old->servers[i].server != new->servers[i].server)
    114			goto changed;
    115
    116	return false;
    117
    118changed:
    119	/* Maintain the same preferred server as before if possible. */
    120	cur = old->servers[old->preferred].server;
    121	for (j = 0; j < new->nr_servers; j++) {
    122		if (new->servers[j].server == cur) {
    123			new->preferred = j;
    124			break;
    125		}
    126	}
    127
    128	return true;
    129}