linux/fs/afs/vlclient.c
<<
>>
Prefs
   1/* AFS Volume Location Service client
   2 *
   3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Howells (dhowells@redhat.com)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 */
  11
  12#include <linux/init.h>
  13#include <linux/sched.h>
  14#include "internal.h"
  15
  16/*
  17 * map volume locator abort codes to error codes
  18 */
  19static int afs_vl_abort_to_error(u32 abort_code)
  20{
  21        _enter("%u", abort_code);
  22
  23        switch (abort_code) {
  24        case AFSVL_IDEXIST:             return -EEXIST;
  25        case AFSVL_IO:                  return -EREMOTEIO;
  26        case AFSVL_NAMEEXIST:           return -EEXIST;
  27        case AFSVL_CREATEFAIL:          return -EREMOTEIO;
  28        case AFSVL_NOENT:               return -ENOMEDIUM;
  29        case AFSVL_EMPTY:               return -ENOMEDIUM;
  30        case AFSVL_ENTDELETED:          return -ENOMEDIUM;
  31        case AFSVL_BADNAME:             return -EINVAL;
  32        case AFSVL_BADINDEX:            return -EINVAL;
  33        case AFSVL_BADVOLTYPE:          return -EINVAL;
  34        case AFSVL_BADSERVER:           return -EINVAL;
  35        case AFSVL_BADPARTITION:        return -EINVAL;
  36        case AFSVL_REPSFULL:            return -EFBIG;
  37        case AFSVL_NOREPSERVER:         return -ENOENT;
  38        case AFSVL_DUPREPSERVER:        return -EEXIST;
  39        case AFSVL_RWNOTFOUND:          return -ENOENT;
  40        case AFSVL_BADREFCOUNT:         return -EINVAL;
  41        case AFSVL_SIZEEXCEEDED:        return -EINVAL;
  42        case AFSVL_BADENTRY:            return -EINVAL;
  43        case AFSVL_BADVOLIDBUMP:        return -EINVAL;
  44        case AFSVL_IDALREADYHASHED:     return -EINVAL;
  45        case AFSVL_ENTRYLOCKED:         return -EBUSY;
  46        case AFSVL_BADVOLOPER:          return -EBADRQC;
  47        case AFSVL_BADRELLOCKTYPE:      return -EINVAL;
  48        case AFSVL_RERELEASE:           return -EREMOTEIO;
  49        case AFSVL_BADSERVERFLAG:       return -EINVAL;
  50        case AFSVL_PERM:                return -EACCES;
  51        case AFSVL_NOMEM:               return -EREMOTEIO;
  52        default:
  53                return afs_abort_to_error(abort_code);
  54        }
  55}
  56
  57/*
  58 * deliver reply data to a VL.GetEntryByXXX call
  59 */
  60static int afs_deliver_vl_get_entry_by_xxx(struct afs_call *call,
  61                                           struct sk_buff *skb, bool last)
  62{
  63        struct afs_cache_vlocation *entry;
  64        __be32 *bp;
  65        u32 tmp;
  66        int loop;
  67
  68        _enter(",,%u", last);
  69
  70        afs_transfer_reply(call, skb);
  71        if (!last)
  72                return 0;
  73
  74        if (call->reply_size != call->reply_max)
  75                return -EBADMSG;
  76
  77        /* unmarshall the reply once we've received all of it */
  78        entry = call->reply;
  79        bp = call->buffer;
  80
  81        for (loop = 0; loop < 64; loop++)
  82                entry->name[loop] = ntohl(*bp++);
  83        entry->name[loop] = 0;
  84        bp++; /* final NUL */
  85
  86        bp++; /* type */
  87        entry->nservers = ntohl(*bp++);
  88
  89        for (loop = 0; loop < 8; loop++)
  90                entry->servers[loop].s_addr = *bp++;
  91
  92        bp += 8; /* partition IDs */
  93
  94        for (loop = 0; loop < 8; loop++) {
  95                tmp = ntohl(*bp++);
  96                entry->srvtmask[loop] = 0;
  97                if (tmp & AFS_VLSF_RWVOL)
  98                        entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
  99                if (tmp & AFS_VLSF_ROVOL)
 100                        entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
 101                if (tmp & AFS_VLSF_BACKVOL)
 102                        entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
 103        }
 104
 105        entry->vid[0] = ntohl(*bp++);
 106        entry->vid[1] = ntohl(*bp++);
 107        entry->vid[2] = ntohl(*bp++);
 108
 109        bp++; /* clone ID */
 110
 111        tmp = ntohl(*bp++); /* flags */
 112        entry->vidmask = 0;
 113        if (tmp & AFS_VLF_RWEXISTS)
 114                entry->vidmask |= AFS_VOL_VTM_RW;
 115        if (tmp & AFS_VLF_ROEXISTS)
 116                entry->vidmask |= AFS_VOL_VTM_RO;
 117        if (tmp & AFS_VLF_BACKEXISTS)
 118                entry->vidmask |= AFS_VOL_VTM_BAK;
 119        if (!entry->vidmask)
 120                return -EBADMSG;
 121
 122        _leave(" = 0 [done]");
 123        return 0;
 124}
 125
 126/*
 127 * VL.GetEntryByName operation type
 128 */
 129static const struct afs_call_type afs_RXVLGetEntryByName = {
 130        .name           = "VL.GetEntryByName",
 131        .deliver        = afs_deliver_vl_get_entry_by_xxx,
 132        .abort_to_error = afs_vl_abort_to_error,
 133        .destructor     = afs_flat_call_destructor,
 134};
 135
 136/*
 137 * VL.GetEntryById operation type
 138 */
 139static const struct afs_call_type afs_RXVLGetEntryById = {
 140        .name           = "VL.GetEntryById",
 141        .deliver        = afs_deliver_vl_get_entry_by_xxx,
 142        .abort_to_error = afs_vl_abort_to_error,
 143        .destructor     = afs_flat_call_destructor,
 144};
 145
 146/*
 147 * dispatch a get volume entry by name operation
 148 */
 149int afs_vl_get_entry_by_name(struct in_addr *addr,
 150                             struct key *key,
 151                             const char *volname,
 152                             struct afs_cache_vlocation *entry,
 153                             const struct afs_wait_mode *wait_mode)
 154{
 155        struct afs_call *call;
 156        size_t volnamesz, reqsz, padsz;
 157        __be32 *bp;
 158
 159        _enter("");
 160
 161        volnamesz = strlen(volname);
 162        padsz = (4 - (volnamesz & 3)) & 3;
 163        reqsz = 8 + volnamesz + padsz;
 164
 165        call = afs_alloc_flat_call(&afs_RXVLGetEntryByName, reqsz, 384);
 166        if (!call)
 167                return -ENOMEM;
 168
 169        call->key = key;
 170        call->reply = entry;
 171        call->service_id = VL_SERVICE;
 172        call->port = htons(AFS_VL_PORT);
 173
 174        /* marshall the parameters */
 175        bp = call->request;
 176        *bp++ = htonl(VLGETENTRYBYNAME);
 177        *bp++ = htonl(volnamesz);
 178        memcpy(bp, volname, volnamesz);
 179        if (padsz > 0)
 180                memset((void *) bp + volnamesz, 0, padsz);
 181
 182        /* initiate the call */
 183        return afs_make_call(addr, call, GFP_KERNEL, wait_mode);
 184}
 185
 186/*
 187 * dispatch a get volume entry by ID operation
 188 */
 189int afs_vl_get_entry_by_id(struct in_addr *addr,
 190                           struct key *key,
 191                           afs_volid_t volid,
 192                           afs_voltype_t voltype,
 193                           struct afs_cache_vlocation *entry,
 194                           const struct afs_wait_mode *wait_mode)
 195{
 196        struct afs_call *call;
 197        __be32 *bp;
 198
 199        _enter("");
 200
 201        call = afs_alloc_flat_call(&afs_RXVLGetEntryById, 12, 384);
 202        if (!call)
 203                return -ENOMEM;
 204
 205        call->key = key;
 206        call->reply = entry;
 207        call->service_id = VL_SERVICE;
 208        call->port = htons(AFS_VL_PORT);
 209
 210        /* marshall the parameters */
 211        bp = call->request;
 212        *bp++ = htonl(VLGETENTRYBYID);
 213        *bp++ = htonl(volid);
 214        *bp   = htonl(voltype);
 215
 216        /* initiate the call */
 217        return afs_make_call(addr, call, GFP_KERNEL, wait_mode);
 218}
 219
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.