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
)
63 struct afs_cache_vlocation
*entry
;
70 ret
= afs_transfer_reply(call
);
74 /* unmarshall the reply once we've received all of it */
78 for (loop
= 0; loop
< 64; loop
++)
79 entry
->name
[loop
] = ntohl(*bp
++);
80 entry
->name
[loop
] = 0;
84 entry
->nservers
= ntohl(*bp
++);
86 for (loop
= 0; loop
< 8; loop
++)
87 entry
->servers
[loop
].s_addr
= *bp
++;
89 bp
+= 8; /* partition IDs */
91 for (loop
= 0; loop
< 8; loop
++) {
93 entry
->srvtmask
[loop
] = 0;
94 if (tmp
& AFS_VLSF_RWVOL
)
95 entry
->srvtmask
[loop
] |= AFS_VOL_VTM_RW
;
96 if (tmp
& AFS_VLSF_ROVOL
)
97 entry
->srvtmask
[loop
] |= AFS_VOL_VTM_RO
;
98 if (tmp
& AFS_VLSF_BACKVOL
)
99 entry
->srvtmask
[loop
] |= AFS_VOL_VTM_BAK
;
102 entry
->vid
[0] = ntohl(*bp
++);
103 entry
->vid
[1] = ntohl(*bp
++);
104 entry
->vid
[2] = ntohl(*bp
++);
108 tmp
= ntohl(*bp
++); /* flags */
110 if (tmp
& AFS_VLF_RWEXISTS
)
111 entry
->vidmask
|= AFS_VOL_VTM_RW
;
112 if (tmp
& AFS_VLF_ROEXISTS
)
113 entry
->vidmask
|= AFS_VOL_VTM_RO
;
114 if (tmp
& AFS_VLF_BACKEXISTS
)
115 entry
->vidmask
|= AFS_VOL_VTM_BAK
;
119 _leave(" = 0 [done]");
124 * VL.GetEntryByName operation type
126 static const struct afs_call_type afs_RXVLGetEntryByName
= {
127 .name
= "VL.GetEntryByName",
128 .deliver
= afs_deliver_vl_get_entry_by_xxx
,
129 .abort_to_error
= afs_vl_abort_to_error
,
130 .destructor
= afs_flat_call_destructor
,
134 * VL.GetEntryById operation type
136 static const struct afs_call_type afs_RXVLGetEntryById
= {
137 .name
= "VL.GetEntryById",
138 .deliver
= afs_deliver_vl_get_entry_by_xxx
,
139 .abort_to_error
= afs_vl_abort_to_error
,
140 .destructor
= afs_flat_call_destructor
,
144 * dispatch a get volume entry by name operation
146 int afs_vl_get_entry_by_name(struct in_addr
*addr
,
149 struct afs_cache_vlocation
*entry
,
150 const struct afs_wait_mode
*wait_mode
)
152 struct afs_call
*call
;
153 size_t volnamesz
, reqsz
, padsz
;
158 volnamesz
= strlen(volname
);
159 padsz
= (4 - (volnamesz
& 3)) & 3;
160 reqsz
= 8 + volnamesz
+ padsz
;
162 call
= afs_alloc_flat_call(&afs_RXVLGetEntryByName
, reqsz
, 384);
168 call
->service_id
= VL_SERVICE
;
169 call
->port
= htons(AFS_VL_PORT
);
171 /* marshall the parameters */
173 *bp
++ = htonl(VLGETENTRYBYNAME
);
174 *bp
++ = htonl(volnamesz
);
175 memcpy(bp
, volname
, volnamesz
);
177 memset((void *) bp
+ volnamesz
, 0, padsz
);
179 /* initiate the call */
180 return afs_make_call(addr
, call
, GFP_KERNEL
, wait_mode
);
184 * dispatch a get volume entry by ID operation
186 int afs_vl_get_entry_by_id(struct in_addr
*addr
,
189 afs_voltype_t voltype
,
190 struct afs_cache_vlocation
*entry
,
191 const struct afs_wait_mode
*wait_mode
)
193 struct afs_call
*call
;
198 call
= afs_alloc_flat_call(&afs_RXVLGetEntryById
, 12, 384);
204 call
->service_id
= VL_SERVICE
;
205 call
->port
= htons(AFS_VL_PORT
);
207 /* marshall the parameters */
209 *bp
++ = htonl(VLGETENTRYBYID
);
210 *bp
++ = htonl(volid
);
211 *bp
= htonl(voltype
);
213 /* initiate the call */
214 return afs_make_call(addr
, call
, GFP_KERNEL
, wait_mode
);