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/init.h>
13 #include <linux/sched.h>
17 * map volume locator abort codes to error codes
19 static int afs_vl_abort_to_error(u32 abort_code
)
21 _enter("%u", 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
;
53 return afs_abort_to_error(abort_code
);
58 * deliver reply data to a VL.GetEntryByXXX call
60 static int afs_deliver_vl_get_entry_by_xxx(struct afs_call
*call
,
61 struct sk_buff
*skb
, bool last
)
63 struct afs_cache_vlocation
*entry
;
70 afs_transfer_reply(call
, skb
);
74 if (call
->reply_size
!= call
->reply_max
)
77 /* unmarshall the reply once we've received all of it */
81 for (loop
= 0; loop
< 64; loop
++)
82 entry
->name
[loop
] = ntohl(*bp
++);
83 entry
->name
[loop
] = 0;
87 entry
->nservers
= ntohl(*bp
++);
89 for (loop
= 0; loop
< 8; loop
++)
90 entry
->servers
[loop
].s_addr
= *bp
++;
92 bp
+= 8; /* partition IDs */
94 for (loop
= 0; loop
< 8; loop
++) {
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
;
105 entry
->vid
[0] = ntohl(*bp
++);
106 entry
->vid
[1] = ntohl(*bp
++);
107 entry
->vid
[2] = ntohl(*bp
++);
111 tmp
= ntohl(*bp
++); /* flags */
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
;
122 _leave(" = 0 [done]");
127 * VL.GetEntryByName operation type
129 static 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
,
137 * VL.GetEntryById operation type
139 static 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
,
147 * dispatch a get volume entry by name operation
149 int afs_vl_get_entry_by_name(struct in_addr
*addr
,
152 struct afs_cache_vlocation
*entry
,
153 const struct afs_wait_mode
*wait_mode
)
155 struct afs_call
*call
;
156 size_t volnamesz
, reqsz
, padsz
;
161 volnamesz
= strlen(volname
);
162 padsz
= (4 - (volnamesz
& 3)) & 3;
163 reqsz
= 8 + volnamesz
+ padsz
;
165 call
= afs_alloc_flat_call(&afs_RXVLGetEntryByName
, reqsz
, 384);
171 call
->service_id
= VL_SERVICE
;
172 call
->port
= htons(AFS_VL_PORT
);
174 /* marshall the parameters */
176 *bp
++ = htonl(VLGETENTRYBYNAME
);
177 *bp
++ = htonl(volnamesz
);
178 memcpy(bp
, volname
, volnamesz
);
180 memset((void *) bp
+ volnamesz
, 0, padsz
);
182 /* initiate the call */
183 return afs_make_call(addr
, call
, GFP_KERNEL
, wait_mode
);
187 * dispatch a get volume entry by ID operation
189 int afs_vl_get_entry_by_id(struct in_addr
*addr
,
192 afs_voltype_t voltype
,
193 struct afs_cache_vlocation
*entry
,
194 const struct afs_wait_mode
*wait_mode
)
196 struct afs_call
*call
;
201 call
= afs_alloc_flat_call(&afs_RXVLGetEntryById
, 12, 384);
207 call
->service_id
= VL_SERVICE
;
208 call
->port
= htons(AFS_VL_PORT
);
210 /* marshall the parameters */
212 *bp
++ = htonl(VLGETENTRYBYID
);
213 *bp
++ = htonl(volid
);
214 *bp
= htonl(voltype
);
216 /* initiate the call */
217 return afs_make_call(addr
, call
, GFP_KERNEL
, wait_mode
);