Root/
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/gfp.h> |
13 | #include <linux/init.h> |
14 | #include <linux/sched.h> |
15 | #include "internal.h" |
16 | |
17 | /* |
18 | * map volume locator abort codes to error codes |
19 | */ |
20 | static int afs_vl_abort_to_error(u32 abort_code) |
21 | { |
22 | _enter("%u", abort_code); |
23 | |
24 | switch (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; |
53 | default: |
54 | return afs_abort_to_error(abort_code); |
55 | } |
56 | } |
57 | |
58 | /* |
59 | * deliver reply data to a VL.GetEntryByXXX call |
60 | */ |
61 | static int afs_deliver_vl_get_entry_by_xxx(struct afs_call *call, |
62 | struct sk_buff *skb, bool last) |
63 | { |
64 | struct afs_cache_vlocation *entry; |
65 | __be32 *bp; |
66 | u32 tmp; |
67 | int loop; |
68 | |
69 | _enter(",,%u", last); |
70 | |
71 | afs_transfer_reply(call, skb); |
72 | if (!last) |
73 | return 0; |
74 | |
75 | if (call->reply_size != call->reply_max) |
76 | return -EBADMSG; |
77 | |
78 | /* unmarshall the reply once we've received all of it */ |
79 | entry = call->reply; |
80 | bp = call->buffer; |
81 | |
82 | for (loop = 0; loop < 64; loop++) |
83 | entry->name[loop] = ntohl(*bp++); |
84 | entry->name[loop] = 0; |
85 | bp++; /* final NUL */ |
86 | |
87 | bp++; /* type */ |
88 | entry->nservers = ntohl(*bp++); |
89 | |
90 | for (loop = 0; loop < 8; loop++) |
91 | entry->servers[loop].s_addr = *bp++; |
92 | |
93 | bp += 8; /* partition IDs */ |
94 | |
95 | for (loop = 0; loop < 8; loop++) { |
96 | tmp = ntohl(*bp++); |
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; |
104 | } |
105 | |
106 | entry->vid[0] = ntohl(*bp++); |
107 | entry->vid[1] = ntohl(*bp++); |
108 | entry->vid[2] = ntohl(*bp++); |
109 | |
110 | bp++; /* clone ID */ |
111 | |
112 | tmp = ntohl(*bp++); /* flags */ |
113 | entry->vidmask = 0; |
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; |
120 | if (!entry->vidmask) |
121 | return -EBADMSG; |
122 | |
123 | _leave(" = 0 [done]"); |
124 | return 0; |
125 | } |
126 | |
127 | /* |
128 | * VL.GetEntryByName operation type |
129 | */ |
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, |
135 | }; |
136 | |
137 | /* |
138 | * VL.GetEntryById operation type |
139 | */ |
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, |
145 | }; |
146 | |
147 | /* |
148 | * dispatch a get volume entry by name operation |
149 | */ |
150 | int afs_vl_get_entry_by_name(struct in_addr *addr, |
151 | struct key *key, |
152 | const char *volname, |
153 | struct afs_cache_vlocation *entry, |
154 | const struct afs_wait_mode *wait_mode) |
155 | { |
156 | struct afs_call *call; |
157 | size_t volnamesz, reqsz, padsz; |
158 | __be32 *bp; |
159 | |
160 | _enter(""); |
161 | |
162 | volnamesz = strlen(volname); |
163 | padsz = (4 - (volnamesz & 3)) & 3; |
164 | reqsz = 8 + volnamesz + padsz; |
165 | |
166 | call = afs_alloc_flat_call(&afs_RXVLGetEntryByName, reqsz, 384); |
167 | if (!call) |
168 | return -ENOMEM; |
169 | |
170 | call->key = key; |
171 | call->reply = entry; |
172 | call->service_id = VL_SERVICE; |
173 | call->port = htons(AFS_VL_PORT); |
174 | |
175 | /* marshall the parameters */ |
176 | bp = call->request; |
177 | *bp++ = htonl(VLGETENTRYBYNAME); |
178 | *bp++ = htonl(volnamesz); |
179 | memcpy(bp, volname, volnamesz); |
180 | if (padsz > 0) |
181 | memset((void *) bp + volnamesz, 0, padsz); |
182 | |
183 | /* initiate the call */ |
184 | return afs_make_call(addr, call, GFP_KERNEL, wait_mode); |
185 | } |
186 | |
187 | /* |
188 | * dispatch a get volume entry by ID operation |
189 | */ |
190 | int afs_vl_get_entry_by_id(struct in_addr *addr, |
191 | struct key *key, |
192 | afs_volid_t volid, |
193 | afs_voltype_t voltype, |
194 | struct afs_cache_vlocation *entry, |
195 | const struct afs_wait_mode *wait_mode) |
196 | { |
197 | struct afs_call *call; |
198 | __be32 *bp; |
199 | |
200 | _enter(""); |
201 | |
202 | call = afs_alloc_flat_call(&afs_RXVLGetEntryById, 12, 384); |
203 | if (!call) |
204 | return -ENOMEM; |
205 | |
206 | call->key = key; |
207 | call->reply = entry; |
208 | call->service_id = VL_SERVICE; |
209 | call->port = htons(AFS_VL_PORT); |
210 | |
211 | /* marshall the parameters */ |
212 | bp = call->request; |
213 | *bp++ = htonl(VLGETENTRYBYID); |
214 | *bp++ = htonl(volid); |
215 | *bp = htonl(voltype); |
216 | |
217 | /* initiate the call */ |
218 | return afs_make_call(addr, call, GFP_KERNEL, wait_mode); |
219 | } |
220 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9