Blame view

fs/afs/vlclient.c 5.44 KB
ec26815ad   David Howells   [AFS]: Clean up t...
1
  /* AFS Volume Location Service client
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
9
10
   *
   * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
   * Written by David Howells (dhowells@redhat.com)
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version
   * 2 of the License, or (at your option) any later version.
   */
5a0e3ad6a   Tejun Heo   include cleanup: ...
11
  #include <linux/gfp.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
  #include <linux/init.h>
  #include <linux/sched.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
  #include "internal.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
  /*
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
16
   * map volume locator abort codes to error codes
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
   */
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
18
  static int afs_vl_abort_to_error(u32 abort_code)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
  {
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  	_enter("%u", abort_code);
  
  	switch (abort_code) {
  	case AFSVL_IDEXIST:		return -EEXIST;
  	case AFSVL_IO:			return -EREMOTEIO;
  	case AFSVL_NAMEEXIST:		return -EEXIST;
  	case AFSVL_CREATEFAIL:		return -EREMOTEIO;
  	case AFSVL_NOENT:		return -ENOMEDIUM;
  	case AFSVL_EMPTY:		return -ENOMEDIUM;
  	case AFSVL_ENTDELETED:		return -ENOMEDIUM;
  	case AFSVL_BADNAME:		return -EINVAL;
  	case AFSVL_BADINDEX:		return -EINVAL;
  	case AFSVL_BADVOLTYPE:		return -EINVAL;
  	case AFSVL_BADSERVER:		return -EINVAL;
  	case AFSVL_BADPARTITION:	return -EINVAL;
  	case AFSVL_REPSFULL:		return -EFBIG;
  	case AFSVL_NOREPSERVER:		return -ENOENT;
  	case AFSVL_DUPREPSERVER:	return -EEXIST;
  	case AFSVL_RWNOTFOUND:		return -ENOENT;
  	case AFSVL_BADREFCOUNT:		return -EINVAL;
  	case AFSVL_SIZEEXCEEDED:	return -EINVAL;
  	case AFSVL_BADENTRY:		return -EINVAL;
  	case AFSVL_BADVOLIDBUMP:	return -EINVAL;
  	case AFSVL_IDALREADYHASHED:	return -EINVAL;
  	case AFSVL_ENTRYLOCKED:		return -EBUSY;
  	case AFSVL_BADVOLOPER:		return -EBADRQC;
  	case AFSVL_BADRELLOCKTYPE:	return -EINVAL;
  	case AFSVL_RERELEASE:		return -EREMOTEIO;
  	case AFSVL_BADSERVERFLAG:	return -EINVAL;
  	case AFSVL_PERM:		return -EACCES;
  	case AFSVL_NOMEM:		return -EREMOTEIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
  	default:
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
52
  		return afs_abort_to_error(abort_code);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
  	}
ec26815ad   David Howells   [AFS]: Clean up t...
54
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
  /*
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
57
   * deliver reply data to a VL.GetEntryByXXX call
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
   */
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
59
60
  static int afs_deliver_vl_get_entry_by_xxx(struct afs_call *call,
  					   struct sk_buff *skb, bool last)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  {
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
62
63
64
65
  	struct afs_cache_vlocation *entry;
  	__be32 *bp;
  	u32 tmp;
  	int loop;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66

08e0e7c82   David Howells   [AF_RXRPC]: Make ...
67
  	_enter(",,%u", last);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68

08e0e7c82   David Howells   [AF_RXRPC]: Make ...
69
70
71
  	afs_transfer_reply(call, skb);
  	if (!last)
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72

08e0e7c82   David Howells   [AF_RXRPC]: Make ...
73
74
  	if (call->reply_size != call->reply_max)
  		return -EBADMSG;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75

08e0e7c82   David Howells   [AF_RXRPC]: Make ...
76
77
78
  	/* unmarshall the reply once we've received all of it */
  	entry = call->reply;
  	bp = call->buffer;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
81
  	for (loop = 0; loop < 64; loop++)
  		entry->name[loop] = ntohl(*bp++);
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
82
  	entry->name[loop] = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
84
85
86
87
88
89
90
91
92
93
94
  	bp++; /* final NUL */
  
  	bp++; /* type */
  	entry->nservers = ntohl(*bp++);
  
  	for (loop = 0; loop < 8; loop++)
  		entry->servers[loop].s_addr = *bp++;
  
  	bp += 8; /* partition IDs */
  
  	for (loop = 0; loop < 8; loop++) {
  		tmp = ntohl(*bp++);
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
95
  		entry->srvtmask[loop] = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  		if (tmp & AFS_VLSF_RWVOL)
  			entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
  		if (tmp & AFS_VLSF_ROVOL)
  			entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
  		if (tmp & AFS_VLSF_BACKVOL)
  			entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
  	}
  
  	entry->vid[0] = ntohl(*bp++);
  	entry->vid[1] = ntohl(*bp++);
  	entry->vid[2] = ntohl(*bp++);
  
  	bp++; /* clone ID */
  
  	tmp = ntohl(*bp++); /* flags */
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
111
  	entry->vidmask = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
113
114
115
116
117
  	if (tmp & AFS_VLF_RWEXISTS)
  		entry->vidmask |= AFS_VOL_VTM_RW;
  	if (tmp & AFS_VLF_ROEXISTS)
  		entry->vidmask |= AFS_VOL_VTM_RO;
  	if (tmp & AFS_VLF_BACKEXISTS)
  		entry->vidmask |= AFS_VOL_VTM_BAK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
  	if (!entry->vidmask)
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
119
120
121
122
  		return -EBADMSG;
  
  	_leave(" = 0 [done]");
  	return 0;
ec26815ad   David Howells   [AFS]: Clean up t...
123
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
  /*
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
126
   * VL.GetEntryByName operation type
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
   */
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
128
  static const struct afs_call_type afs_RXVLGetEntryByName = {
00d3b7a45   David Howells   [AFS]: Add securi...
129
  	.name		= "VL.GetEntryByName",
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
130
131
132
133
  	.deliver	= afs_deliver_vl_get_entry_by_xxx,
  	.abort_to_error	= afs_vl_abort_to_error,
  	.destructor	= afs_flat_call_destructor,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134

08e0e7c82   David Howells   [AF_RXRPC]: Make ...
135
136
137
138
  /*
   * VL.GetEntryById operation type
   */
  static const struct afs_call_type afs_RXVLGetEntryById = {
00d3b7a45   David Howells   [AFS]: Add securi...
139
  	.name		= "VL.GetEntryById",
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
140
141
142
143
  	.deliver	= afs_deliver_vl_get_entry_by_xxx,
  	.abort_to_error	= afs_vl_abort_to_error,
  	.destructor	= afs_flat_call_destructor,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
  /*
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
146
   * dispatch a get volume entry by name operation
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
   */
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
148
  int afs_vl_get_entry_by_name(struct in_addr *addr,
00d3b7a45   David Howells   [AFS]: Add securi...
149
  			     struct key *key,
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
150
151
152
  			     const char *volname,
  			     struct afs_cache_vlocation *entry,
  			     const struct afs_wait_mode *wait_mode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153
  {
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
154
155
156
  	struct afs_call *call;
  	size_t volnamesz, reqsz, padsz;
  	__be32 *bp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157

08e0e7c82   David Howells   [AF_RXRPC]: Make ...
158
  	_enter("");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159

08e0e7c82   David Howells   [AF_RXRPC]: Make ...
160
161
162
  	volnamesz = strlen(volname);
  	padsz = (4 - (volnamesz & 3)) & 3;
  	reqsz = 8 + volnamesz + padsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163

08e0e7c82   David Howells   [AF_RXRPC]: Make ...
164
165
166
  	call = afs_alloc_flat_call(&afs_RXVLGetEntryByName, reqsz, 384);
  	if (!call)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167

00d3b7a45   David Howells   [AFS]: Add securi...
168
  	call->key = key;
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
169
170
171
  	call->reply = entry;
  	call->service_id = VL_SERVICE;
  	call->port = htons(AFS_VL_PORT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
  
  	/* marshall the parameters */
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
174
175
176
177
178
179
180
181
182
  	bp = call->request;
  	*bp++ = htonl(VLGETENTRYBYNAME);
  	*bp++ = htonl(volnamesz);
  	memcpy(bp, volname, volnamesz);
  	if (padsz > 0)
  		memset((void *) bp + volnamesz, 0, padsz);
  
  	/* initiate the call */
  	return afs_make_call(addr, call, GFP_KERNEL, wait_mode);
ec26815ad   David Howells   [AFS]: Clean up t...
183
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
185
  /*
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
186
   * dispatch a get volume entry by ID operation
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187
   */
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
188
  int afs_vl_get_entry_by_id(struct in_addr *addr,
00d3b7a45   David Howells   [AFS]: Add securi...
189
  			   struct key *key,
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
190
191
192
193
  			   afs_volid_t volid,
  			   afs_voltype_t voltype,
  			   struct afs_cache_vlocation *entry,
  			   const struct afs_wait_mode *wait_mode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194
  {
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
195
  	struct afs_call *call;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
196
  	__be32 *bp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197

08e0e7c82   David Howells   [AF_RXRPC]: Make ...
198
  	_enter("");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199

08e0e7c82   David Howells   [AF_RXRPC]: Make ...
200
201
202
  	call = afs_alloc_flat_call(&afs_RXVLGetEntryById, 12, 384);
  	if (!call)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203

00d3b7a45   David Howells   [AFS]: Add securi...
204
  	call->key = key;
08e0e7c82   David Howells   [AF_RXRPC]: Make ...
205
206
207
  	call->reply = entry;
  	call->service_id = VL_SERVICE;
  	call->port = htons(AFS_VL_PORT);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208

08e0e7c82   David Howells   [AF_RXRPC]: Make ...
209
210
211
212
213
  	/* marshall the parameters */
  	bp = call->request;
  	*bp++ = htonl(VLGETENTRYBYID);
  	*bp++ = htonl(volid);
  	*bp   = htonl(voltype);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214

08e0e7c82   David Howells   [AF_RXRPC]: Make ...
215
216
  	/* initiate the call */
  	return afs_make_call(addr, call, GFP_KERNEL, wait_mode);
ec26815ad   David Howells   [AFS]: Clean up t...
217
  }