1 /* AFS Volume Location Service client
3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
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.
12 #include <linux/gfp.h>
13 #include <linux/init.h>
14 #include <linux/sched.h>
18 * map volume locator abort codes to error codes
20 static int afs_vl_abort_to_error(u32 abort_code
)
22 _enter("%u", abort_code
);
25 case AFSVL_IDEXIST
: return -EEXIST
;
26 case AFSVL_IO
: return -EREMOTEIO
;
27 case AFSVL_NAMEEXIST
: return -EEXIST
;
28 case AFSVL_CREATEFAIL
: return -EREMOTEIO
;
29 case AFSVL_NOENT
: return -ENOMEDIUM
;
30 case AFSVL_EMPTY
: return -ENOMEDIUM
;
31 case AFSVL_ENTDELETED
: return -ENOMEDIUM
;
32 case AFSVL_BADNAME
: return -EINVAL
;
33 case AFSVL_BADINDEX
: return -EINVAL
;
34 case AFSVL_BADVOLTYPE
: return -EINVAL
;
35 case AFSVL_BADSERVER
: return -EINVAL
;
36 case AFSVL_BADPARTITION
: return -EINVAL
;
37 case AFSVL_REPSFULL
: return -EFBIG
;
38 case AFSVL_NOREPSERVER
: return -ENOENT
;
39 case AFSVL_DUPREPSERVER
: return -EEXIST
;
40 case AFSVL_RWNOTFOUND
: return -ENOENT
;
41 case AFSVL_BADREFCOUNT
: return -EINVAL
;
42 case AFSVL_SIZEEXCEEDED
: return -EINVAL
;
43 case AFSVL_BADENTRY
: return -EINVAL
;
44 case AFSVL_BADVOLIDBUMP
: return -EINVAL
;
45 case AFSVL_IDALREADYHASHED
: return -EINVAL
;
46 case AFSVL_ENTRYLOCKED
: return -EBUSY
;
47 case AFSVL_BADVOLOPER
: return -EBADRQC
;
48 case AFSVL_BADRELLOCKTYPE
: return -EINVAL
;
49 case AFSVL_RERELEASE
: return -EREMOTEIO
;
50 case AFSVL_BADSERVERFLAG
: return -EINVAL
;
51 case AFSVL_PERM
: return -EACCES
;
52 case AFSVL_NOMEM
: return -EREMOTEIO
;
54 return afs_abort_to_error(abort_code
);
59 * deliver reply data to a VL.GetEntryByXXX call
61 static int afs_deliver_vl_get_entry_by_xxx(struct afs_call
*call
,
62 struct sk_buff
*skb
, bool last
)
64 struct afs_cache_vlocation
*entry
;
71 afs_transfer_reply(call
, skb
);
75 if (call
->reply_size
!= call
->reply_max
)
78 /* unmarshall the reply once we've received all of it */
82 for (loop
= 0; loop
< 64; loop
++)
83 entry
->name
[loop
] = ntohl(*bp
++);
84 entry
->name
[loop
] = 0;
88 entry
->nservers
= ntohl(*bp
++);
90 for (loop
= 0; loop
< 8; loop
++)
91 entry
->servers
[loop
].s_addr
= *bp
++;
93 bp
+= 8; /* partition IDs */
95 for (loop
= 0; loop
< 8; loop
++) {
97 entry
->srvtmask
[loop
] = 0;
98 if (tmp
& AFS_VLSF_RWVOL
)
99 entry
->srvtmask
[loop
] |= AFS_VOL_VTM_RW
;
100 if (tmp
& AFS_VLSF_ROVOL
)
101 entry
->srvtmask
[loop
] |= AFS_VOL_VTM_RO
;
102 if (tmp
& AFS_VLSF_BACKVOL
)
103 entry
->srvtmask
[loop
] |= AFS_VOL_VTM_BAK
;
106 entry
->vid
[0] = ntohl(*bp
++);
107 entry
->vid
[1] = ntohl(*bp
++);
108 entry
->vid
[2] = ntohl(*bp
++);
112 tmp
= ntohl(*bp
++); /* flags */
114 if (tmp
& AFS_VLF_RWEXISTS
)
115 entry
->vidmask
|= AFS_VOL_VTM_RW
;
116 if (tmp
& AFS_VLF_ROEXISTS
)
117 entry
->vidmask
|= AFS_VOL_VTM_RO
;
118 if (tmp
& AFS_VLF_BACKEXISTS
)
119 entry
->vidmask
|= AFS_VOL_VTM_BAK
;
123 _leave(" = 0 [done]");
128 * VL.GetEntryByName operation type
130 static const struct afs_call_type afs_RXVLGetEntryByName
= {
131 .name
= "VL.GetEntryByName",
132 .deliver
= afs_deliver_vl_get_entry_by_xxx
,
133 .abort_to_error
= afs_vl_abort_to_error
,
134 .destructor
= afs_flat_call_destructor
,
138 * VL.GetEntryById operation type
140 static const struct afs_call_type afs_RXVLGetEntryById
= {
141 .name
= "VL.GetEntryById",
142 .deliver
= afs_deliver_vl_get_entry_by_xxx
,
143 .abort_to_error
= afs_vl_abort_to_error
,
144 .destructor
= afs_flat_call_destructor
,
148 * dispatch a get volume entry by name operation
150 int afs_vl_get_entry_by_name(struct in_addr
*addr
,
153 struct afs_cache_vlocation
*entry
,
154 const struct afs_wait_mode
*wait_mode
)
156 struct afs_call
*call
;
157 size_t volnamesz
, reqsz
, padsz
;
162 volnamesz
= strlen(volname
);
163 padsz
= (4 - (volnamesz
& 3)) & 3;
164 reqsz
= 8 + volnamesz
+ padsz
;
166 call
= afs_alloc_flat_call(&afs_RXVLGetEntryByName
, reqsz
, 384);
172 call
->service_id
= VL_SERVICE
;
173 call
->port
= htons(AFS_VL_PORT
);
175 /* marshall the parameters */
177 *bp
++ = htonl(VLGETENTRYBYNAME
);
178 *bp
++ = htonl(volnamesz
);
179 memcpy(bp
, volname
, volnamesz
);
181 memset((void *) bp
+ volnamesz
, 0, padsz
);
183 /* initiate the call */
184 return afs_make_call(addr
, call
, GFP_KERNEL
, wait_mode
);
188 * dispatch a get volume entry by ID operation
190 int afs_vl_get_entry_by_id(struct in_addr
*addr
,
193 afs_voltype_t voltype
,
194 struct afs_cache_vlocation
*entry
,
195 const struct afs_wait_mode
*wait_mode
)
197 struct afs_call
*call
;
202 call
= afs_alloc_flat_call(&afs_RXVLGetEntryById
, 12, 384);
208 call
->service_id
= VL_SERVICE
;
209 call
->port
= htons(AFS_VL_PORT
);
211 /* marshall the parameters */
213 *bp
++ = htonl(VLGETENTRYBYID
);
214 *bp
++ = htonl(volid
);
215 *bp
= htonl(voltype
);
217 /* initiate the call */
218 return afs_make_call(addr
, call
, GFP_KERNEL
, wait_mode
);