1 // SPDX-License-Identifier: GPL-2.0-or-later 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* AFS Cache Manager Service 2 /* AFS Cache Manager Service 3 * 3 * 4 * Copyright (C) 2002 Red Hat, Inc. All Rights 4 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.c 5 * Written by David Howells (dhowells@redhat.com) 6 */ 6 */ 7 7 8 #include <linux/module.h> 8 #include <linux/module.h> 9 #include <linux/init.h> 9 #include <linux/init.h> 10 #include <linux/slab.h> 10 #include <linux/slab.h> 11 #include <linux/sched.h> 11 #include <linux/sched.h> 12 #include <linux/ip.h> 12 #include <linux/ip.h> 13 #include "internal.h" 13 #include "internal.h" 14 #include "afs_cm.h" 14 #include "afs_cm.h" 15 #include "protocol_yfs.h" 15 #include "protocol_yfs.h" 16 #define RXRPC_TRACE_ONLY_DEFINE_ENUMS << 17 #include <trace/events/rxrpc.h> << 18 16 19 static int afs_deliver_cb_init_call_back_state 17 static int afs_deliver_cb_init_call_back_state(struct afs_call *); 20 static int afs_deliver_cb_init_call_back_state 18 static int afs_deliver_cb_init_call_back_state3(struct afs_call *); 21 static int afs_deliver_cb_probe(struct afs_cal 19 static int afs_deliver_cb_probe(struct afs_call *); 22 static int afs_deliver_cb_callback(struct afs_ 20 static int afs_deliver_cb_callback(struct afs_call *); 23 static int afs_deliver_cb_probe_uuid(struct af 21 static int afs_deliver_cb_probe_uuid(struct afs_call *); 24 static int afs_deliver_cb_tell_me_about_yourse 22 static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *); 25 static void afs_cm_destructor(struct afs_call 23 static void afs_cm_destructor(struct afs_call *); 26 static void SRXAFSCB_CallBack(struct work_stru 24 static void SRXAFSCB_CallBack(struct work_struct *); 27 static void SRXAFSCB_InitCallBackState(struct 25 static void SRXAFSCB_InitCallBackState(struct work_struct *); 28 static void SRXAFSCB_Probe(struct work_struct 26 static void SRXAFSCB_Probe(struct work_struct *); 29 static void SRXAFSCB_ProbeUuid(struct work_str 27 static void SRXAFSCB_ProbeUuid(struct work_struct *); 30 static void SRXAFSCB_TellMeAboutYourself(struc 28 static void SRXAFSCB_TellMeAboutYourself(struct work_struct *); 31 29 32 static int afs_deliver_yfs_cb_callback(struct 30 static int afs_deliver_yfs_cb_callback(struct afs_call *); 33 31 34 /* 32 /* 35 * CB.CallBack operation type 33 * CB.CallBack operation type 36 */ 34 */ 37 static const struct afs_call_type afs_SRXCBCal 35 static const struct afs_call_type afs_SRXCBCallBack = { 38 .name = "CB.CallBack", 36 .name = "CB.CallBack", 39 .deliver = afs_deliver_cb_callb 37 .deliver = afs_deliver_cb_callback, 40 .destructor = afs_cm_destructor, 38 .destructor = afs_cm_destructor, 41 .work = SRXAFSCB_CallBack, 39 .work = SRXAFSCB_CallBack, 42 }; 40 }; 43 41 44 /* 42 /* 45 * CB.InitCallBackState operation type 43 * CB.InitCallBackState operation type 46 */ 44 */ 47 static const struct afs_call_type afs_SRXCBIni 45 static const struct afs_call_type afs_SRXCBInitCallBackState = { 48 .name = "CB.InitCallBackStat 46 .name = "CB.InitCallBackState", 49 .deliver = afs_deliver_cb_init_ 47 .deliver = afs_deliver_cb_init_call_back_state, 50 .destructor = afs_cm_destructor, 48 .destructor = afs_cm_destructor, 51 .work = SRXAFSCB_InitCallBac 49 .work = SRXAFSCB_InitCallBackState, 52 }; 50 }; 53 51 54 /* 52 /* 55 * CB.InitCallBackState3 operation type 53 * CB.InitCallBackState3 operation type 56 */ 54 */ 57 static const struct afs_call_type afs_SRXCBIni 55 static const struct afs_call_type afs_SRXCBInitCallBackState3 = { 58 .name = "CB.InitCallBackStat 56 .name = "CB.InitCallBackState3", 59 .deliver = afs_deliver_cb_init_ 57 .deliver = afs_deliver_cb_init_call_back_state3, 60 .destructor = afs_cm_destructor, 58 .destructor = afs_cm_destructor, 61 .work = SRXAFSCB_InitCallBac 59 .work = SRXAFSCB_InitCallBackState, 62 }; 60 }; 63 61 64 /* 62 /* 65 * CB.Probe operation type 63 * CB.Probe operation type 66 */ 64 */ 67 static const struct afs_call_type afs_SRXCBPro 65 static const struct afs_call_type afs_SRXCBProbe = { 68 .name = "CB.Probe", 66 .name = "CB.Probe", 69 .deliver = afs_deliver_cb_probe 67 .deliver = afs_deliver_cb_probe, 70 .destructor = afs_cm_destructor, 68 .destructor = afs_cm_destructor, 71 .work = SRXAFSCB_Probe, 69 .work = SRXAFSCB_Probe, 72 }; 70 }; 73 71 74 /* 72 /* 75 * CB.ProbeUuid operation type 73 * CB.ProbeUuid operation type 76 */ 74 */ 77 static const struct afs_call_type afs_SRXCBPro 75 static const struct afs_call_type afs_SRXCBProbeUuid = { 78 .name = "CB.ProbeUuid", 76 .name = "CB.ProbeUuid", 79 .deliver = afs_deliver_cb_probe 77 .deliver = afs_deliver_cb_probe_uuid, 80 .destructor = afs_cm_destructor, 78 .destructor = afs_cm_destructor, 81 .work = SRXAFSCB_ProbeUuid, 79 .work = SRXAFSCB_ProbeUuid, 82 }; 80 }; 83 81 84 /* 82 /* 85 * CB.TellMeAboutYourself operation type 83 * CB.TellMeAboutYourself operation type 86 */ 84 */ 87 static const struct afs_call_type afs_SRXCBTel 85 static const struct afs_call_type afs_SRXCBTellMeAboutYourself = { 88 .name = "CB.TellMeAboutYours 86 .name = "CB.TellMeAboutYourself", 89 .deliver = afs_deliver_cb_tell_ 87 .deliver = afs_deliver_cb_tell_me_about_yourself, 90 .destructor = afs_cm_destructor, 88 .destructor = afs_cm_destructor, 91 .work = SRXAFSCB_TellMeAbout 89 .work = SRXAFSCB_TellMeAboutYourself, 92 }; 90 }; 93 91 94 /* 92 /* 95 * YFS CB.CallBack operation type 93 * YFS CB.CallBack operation type 96 */ 94 */ 97 static const struct afs_call_type afs_SRXYFSCB 95 static const struct afs_call_type afs_SRXYFSCB_CallBack = { 98 .name = "YFSCB.CallBack", 96 .name = "YFSCB.CallBack", 99 .deliver = afs_deliver_yfs_cb_c 97 .deliver = afs_deliver_yfs_cb_callback, 100 .destructor = afs_cm_destructor, 98 .destructor = afs_cm_destructor, 101 .work = SRXAFSCB_CallBack, 99 .work = SRXAFSCB_CallBack, 102 }; 100 }; 103 101 104 /* 102 /* 105 * route an incoming cache manager call 103 * route an incoming cache manager call 106 * - return T if supported, F if not 104 * - return T if supported, F if not 107 */ 105 */ 108 bool afs_cm_incoming_call(struct afs_call *cal 106 bool afs_cm_incoming_call(struct afs_call *call) 109 { 107 { 110 _enter("{%u, CB.OP %u}", call->service 108 _enter("{%u, CB.OP %u}", call->service_id, call->operation_ID); 111 109 112 switch (call->operation_ID) { 110 switch (call->operation_ID) { 113 case CBCallBack: 111 case CBCallBack: 114 call->type = &afs_SRXCBCallBac 112 call->type = &afs_SRXCBCallBack; 115 return true; 113 return true; 116 case CBInitCallBackState: 114 case CBInitCallBackState: 117 call->type = &afs_SRXCBInitCal 115 call->type = &afs_SRXCBInitCallBackState; 118 return true; 116 return true; 119 case CBInitCallBackState3: 117 case CBInitCallBackState3: 120 call->type = &afs_SRXCBInitCal 118 call->type = &afs_SRXCBInitCallBackState3; 121 return true; 119 return true; 122 case CBProbe: 120 case CBProbe: 123 call->type = &afs_SRXCBProbe; 121 call->type = &afs_SRXCBProbe; 124 return true; 122 return true; 125 case CBProbeUuid: 123 case CBProbeUuid: 126 call->type = &afs_SRXCBProbeUu 124 call->type = &afs_SRXCBProbeUuid; 127 return true; 125 return true; 128 case CBTellMeAboutYourself: 126 case CBTellMeAboutYourself: 129 call->type = &afs_SRXCBTellMeA 127 call->type = &afs_SRXCBTellMeAboutYourself; 130 return true; 128 return true; 131 case YFSCBCallBack: 129 case YFSCBCallBack: 132 if (call->service_id != YFS_CM 130 if (call->service_id != YFS_CM_SERVICE) 133 return false; 131 return false; 134 call->type = &afs_SRXYFSCB_Cal 132 call->type = &afs_SRXYFSCB_CallBack; 135 return true; 133 return true; 136 default: 134 default: 137 return false; 135 return false; 138 } 136 } 139 } 137 } 140 138 141 /* 139 /* 142 * Find the server record by peer address and 140 * Find the server record by peer address and record a probe to the cache 143 * manager from a server. 141 * manager from a server. 144 */ 142 */ 145 static int afs_find_cm_server_by_peer(struct a 143 static int afs_find_cm_server_by_peer(struct afs_call *call) 146 { 144 { 147 struct sockaddr_rxrpc srx; 145 struct sockaddr_rxrpc srx; 148 struct afs_server *server; 146 struct afs_server *server; 149 struct rxrpc_peer *peer; << 150 147 151 peer = rxrpc_kernel_get_call_peer(call !! 148 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx); 152 149 153 server = afs_find_server(call->net, pe !! 150 server = afs_find_server(call->net, &srx); 154 if (!server) { 151 if (!server) { 155 trace_afs_cm_no_server(call, & 152 trace_afs_cm_no_server(call, &srx); 156 return 0; 153 return 0; 157 } 154 } 158 155 159 call->server = server; 156 call->server = server; 160 return 0; 157 return 0; 161 } 158 } 162 159 163 /* 160 /* 164 * Find the server record by server UUID and r 161 * Find the server record by server UUID and record a probe to the cache 165 * manager from a server. 162 * manager from a server. 166 */ 163 */ 167 static int afs_find_cm_server_by_uuid(struct a 164 static int afs_find_cm_server_by_uuid(struct afs_call *call, 168 struct a 165 struct afs_uuid *uuid) 169 { 166 { 170 struct afs_server *server; 167 struct afs_server *server; 171 168 172 rcu_read_lock(); 169 rcu_read_lock(); 173 server = afs_find_server_by_uuid(call- 170 server = afs_find_server_by_uuid(call->net, call->request); 174 rcu_read_unlock(); 171 rcu_read_unlock(); 175 if (!server) { 172 if (!server) { 176 trace_afs_cm_no_server_u(call, 173 trace_afs_cm_no_server_u(call, call->request); 177 return 0; 174 return 0; 178 } 175 } 179 176 180 call->server = server; 177 call->server = server; 181 return 0; 178 return 0; 182 } 179 } 183 180 184 /* 181 /* 185 * Clean up a cache manager call. 182 * Clean up a cache manager call. 186 */ 183 */ 187 static void afs_cm_destructor(struct afs_call 184 static void afs_cm_destructor(struct afs_call *call) 188 { 185 { 189 kfree(call->buffer); 186 kfree(call->buffer); 190 call->buffer = NULL; 187 call->buffer = NULL; 191 } 188 } 192 189 193 /* 190 /* 194 * Abort a service call from within an action 191 * Abort a service call from within an action function. 195 */ 192 */ 196 static void afs_abort_service_call(struct afs_ 193 static void afs_abort_service_call(struct afs_call *call, u32 abort_code, int error, 197 enum rxrpc_ !! 194 const char *why) 198 { 195 { 199 rxrpc_kernel_abort_call(call->net->soc 196 rxrpc_kernel_abort_call(call->net->socket, call->rxcall, 200 abort_code, er 197 abort_code, error, why); 201 afs_set_call_complete(call, error, 0); 198 afs_set_call_complete(call, error, 0); 202 } 199 } 203 200 204 /* 201 /* 205 * The server supplied a list of callbacks tha 202 * The server supplied a list of callbacks that it wanted to break. 206 */ 203 */ 207 static void SRXAFSCB_CallBack(struct work_stru 204 static void SRXAFSCB_CallBack(struct work_struct *work) 208 { 205 { 209 struct afs_call *call = container_of(w 206 struct afs_call *call = container_of(work, struct afs_call, work); 210 207 211 _enter(""); 208 _enter(""); 212 209 213 /* We need to break the callbacks befo 210 /* We need to break the callbacks before sending the reply as the 214 * server holds up change visibility t 211 * server holds up change visibility till it receives our reply so as 215 * to maintain cache coherency. 212 * to maintain cache coherency. 216 */ 213 */ 217 if (call->server) { 214 if (call->server) { 218 trace_afs_server(call->server- 215 trace_afs_server(call->server->debug_id, 219 refcount_read 216 refcount_read(&call->server->ref), 220 atomic_read(& 217 atomic_read(&call->server->active), 221 afs_server_tr 218 afs_server_trace_callback); 222 afs_break_callbacks(call->serv 219 afs_break_callbacks(call->server, call->count, call->request); 223 } 220 } 224 221 225 afs_send_empty_reply(call); 222 afs_send_empty_reply(call); 226 afs_put_call(call); 223 afs_put_call(call); 227 _leave(""); 224 _leave(""); 228 } 225 } 229 226 230 /* 227 /* 231 * deliver request data to a CB.CallBack call 228 * deliver request data to a CB.CallBack call 232 */ 229 */ 233 static int afs_deliver_cb_callback(struct afs_ 230 static int afs_deliver_cb_callback(struct afs_call *call) 234 { 231 { 235 struct afs_callback_break *cb; 232 struct afs_callback_break *cb; 236 __be32 *bp; 233 __be32 *bp; 237 int ret, loop; 234 int ret, loop; 238 235 239 _enter("{%u}", call->unmarshall); 236 _enter("{%u}", call->unmarshall); 240 237 241 switch (call->unmarshall) { 238 switch (call->unmarshall) { 242 case 0: 239 case 0: 243 afs_extract_to_tmp(call); 240 afs_extract_to_tmp(call); 244 call->unmarshall++; 241 call->unmarshall++; 245 242 246 /* extract the FID array and i 243 /* extract the FID array and its count in two steps */ 247 fallthrough; 244 fallthrough; 248 case 1: 245 case 1: 249 _debug("extract FID count"); 246 _debug("extract FID count"); 250 ret = afs_extract_data(call, t 247 ret = afs_extract_data(call, true); 251 if (ret < 0) 248 if (ret < 0) 252 return ret; 249 return ret; 253 250 254 call->count = ntohl(call->tmp) 251 call->count = ntohl(call->tmp); 255 _debug("FID count: %u", call-> 252 _debug("FID count: %u", call->count); 256 if (call->count > AFSCBMAX) 253 if (call->count > AFSCBMAX) 257 return afs_protocol_er 254 return afs_protocol_error(call, afs_eproto_cb_fid_count); 258 255 259 call->buffer = kmalloc(array3_ 256 call->buffer = kmalloc(array3_size(call->count, 3, 4), 260 GFP_KER 257 GFP_KERNEL); 261 if (!call->buffer) 258 if (!call->buffer) 262 return -ENOMEM; 259 return -ENOMEM; 263 afs_extract_to_buf(call, call- 260 afs_extract_to_buf(call, call->count * 3 * 4); 264 call->unmarshall++; 261 call->unmarshall++; 265 262 266 fallthrough; 263 fallthrough; 267 case 2: 264 case 2: 268 _debug("extract FID array"); 265 _debug("extract FID array"); 269 ret = afs_extract_data(call, t 266 ret = afs_extract_data(call, true); 270 if (ret < 0) 267 if (ret < 0) 271 return ret; 268 return ret; 272 269 273 _debug("unmarshall FID array") 270 _debug("unmarshall FID array"); 274 call->request = kcalloc(call-> 271 call->request = kcalloc(call->count, 275 sizeof 272 sizeof(struct afs_callback_break), 276 GFP_KE 273 GFP_KERNEL); 277 if (!call->request) 274 if (!call->request) 278 return -ENOMEM; 275 return -ENOMEM; 279 276 280 cb = call->request; 277 cb = call->request; 281 bp = call->buffer; 278 bp = call->buffer; 282 for (loop = call->count; loop 279 for (loop = call->count; loop > 0; loop--, cb++) { 283 cb->fid.vid = ntoh 280 cb->fid.vid = ntohl(*bp++); 284 cb->fid.vnode = ntoh 281 cb->fid.vnode = ntohl(*bp++); 285 cb->fid.unique = ntoh 282 cb->fid.unique = ntohl(*bp++); 286 } 283 } 287 284 288 afs_extract_to_tmp(call); 285 afs_extract_to_tmp(call); 289 call->unmarshall++; 286 call->unmarshall++; 290 287 291 /* extract the callback array 288 /* extract the callback array and its count in two steps */ 292 fallthrough; 289 fallthrough; 293 case 3: 290 case 3: 294 _debug("extract CB count"); 291 _debug("extract CB count"); 295 ret = afs_extract_data(call, t 292 ret = afs_extract_data(call, true); 296 if (ret < 0) 293 if (ret < 0) 297 return ret; 294 return ret; 298 295 299 call->count2 = ntohl(call->tmp 296 call->count2 = ntohl(call->tmp); 300 _debug("CB count: %u", call->c 297 _debug("CB count: %u", call->count2); 301 if (call->count2 != call->coun 298 if (call->count2 != call->count && call->count2 != 0) 302 return afs_protocol_er 299 return afs_protocol_error(call, afs_eproto_cb_count); 303 call->iter = &call->def_iter; 300 call->iter = &call->def_iter; 304 iov_iter_discard(&call->def_it 301 iov_iter_discard(&call->def_iter, ITER_DEST, call->count2 * 3 * 4); 305 call->unmarshall++; 302 call->unmarshall++; 306 303 307 fallthrough; 304 fallthrough; 308 case 4: 305 case 4: 309 _debug("extract discard %zu/%u 306 _debug("extract discard %zu/%u", 310 iov_iter_count(call->it 307 iov_iter_count(call->iter), call->count2 * 3 * 4); 311 308 312 ret = afs_extract_data(call, f 309 ret = afs_extract_data(call, false); 313 if (ret < 0) 310 if (ret < 0) 314 return ret; 311 return ret; 315 312 316 call->unmarshall++; 313 call->unmarshall++; 317 fallthrough; 314 fallthrough; 318 315 319 case 5: 316 case 5: 320 break; 317 break; 321 } 318 } 322 319 323 if (!afs_check_call_state(call, AFS_CA 320 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING)) 324 return afs_io_error(call, afs_ 321 return afs_io_error(call, afs_io_error_cm_reply); 325 322 326 /* we'll need the file server record a 323 /* we'll need the file server record as that tells us which set of 327 * vnodes to operate upon */ 324 * vnodes to operate upon */ 328 return afs_find_cm_server_by_peer(call 325 return afs_find_cm_server_by_peer(call); 329 } 326 } 330 327 331 /* 328 /* 332 * allow the fileserver to request callback st 329 * allow the fileserver to request callback state (re-)initialisation 333 */ 330 */ 334 static void SRXAFSCB_InitCallBackState(struct 331 static void SRXAFSCB_InitCallBackState(struct work_struct *work) 335 { 332 { 336 struct afs_call *call = container_of(w 333 struct afs_call *call = container_of(work, struct afs_call, work); 337 334 338 _enter("{%p}", call->server); 335 _enter("{%p}", call->server); 339 336 340 if (call->server) 337 if (call->server) 341 afs_init_callback_state(call-> 338 afs_init_callback_state(call->server); 342 afs_send_empty_reply(call); 339 afs_send_empty_reply(call); 343 afs_put_call(call); 340 afs_put_call(call); 344 _leave(""); 341 _leave(""); 345 } 342 } 346 343 347 /* 344 /* 348 * deliver request data to a CB.InitCallBackSt 345 * deliver request data to a CB.InitCallBackState call 349 */ 346 */ 350 static int afs_deliver_cb_init_call_back_state 347 static int afs_deliver_cb_init_call_back_state(struct afs_call *call) 351 { 348 { 352 int ret; 349 int ret; 353 350 354 _enter(""); 351 _enter(""); 355 352 356 afs_extract_discard(call, 0); 353 afs_extract_discard(call, 0); 357 ret = afs_extract_data(call, false); 354 ret = afs_extract_data(call, false); 358 if (ret < 0) 355 if (ret < 0) 359 return ret; 356 return ret; 360 357 361 /* we'll need the file server record a 358 /* we'll need the file server record as that tells us which set of 362 * vnodes to operate upon */ 359 * vnodes to operate upon */ 363 return afs_find_cm_server_by_peer(call 360 return afs_find_cm_server_by_peer(call); 364 } 361 } 365 362 366 /* 363 /* 367 * deliver request data to a CB.InitCallBackSt 364 * deliver request data to a CB.InitCallBackState3 call 368 */ 365 */ 369 static int afs_deliver_cb_init_call_back_state 366 static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) 370 { 367 { 371 struct afs_uuid *r; 368 struct afs_uuid *r; 372 unsigned loop; 369 unsigned loop; 373 __be32 *b; 370 __be32 *b; 374 int ret; 371 int ret; 375 372 376 _enter(""); 373 _enter(""); 377 374 378 _enter("{%u}", call->unmarshall); 375 _enter("{%u}", call->unmarshall); 379 376 380 switch (call->unmarshall) { 377 switch (call->unmarshall) { 381 case 0: 378 case 0: 382 call->buffer = kmalloc_array(1 379 call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL); 383 if (!call->buffer) 380 if (!call->buffer) 384 return -ENOMEM; 381 return -ENOMEM; 385 afs_extract_to_buf(call, 11 * 382 afs_extract_to_buf(call, 11 * sizeof(__be32)); 386 call->unmarshall++; 383 call->unmarshall++; 387 384 388 fallthrough; 385 fallthrough; 389 case 1: 386 case 1: 390 _debug("extract UUID"); 387 _debug("extract UUID"); 391 ret = afs_extract_data(call, f 388 ret = afs_extract_data(call, false); 392 switch (ret) { 389 switch (ret) { 393 case 0: break; 390 case 0: break; 394 case -EAGAIN: return 0; 391 case -EAGAIN: return 0; 395 default: return ret; 392 default: return ret; 396 } 393 } 397 394 398 _debug("unmarshall UUID"); 395 _debug("unmarshall UUID"); 399 call->request = kmalloc(sizeof 396 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL); 400 if (!call->request) 397 if (!call->request) 401 return -ENOMEM; 398 return -ENOMEM; 402 399 403 b = call->buffer; 400 b = call->buffer; 404 r = call->request; 401 r = call->request; 405 r->time_low 402 r->time_low = b[0]; 406 r->time_mid 403 r->time_mid = htons(ntohl(b[1])); 407 r->time_hi_and_version 404 r->time_hi_and_version = htons(ntohl(b[2])); 408 r->clock_seq_hi_and_reserved 405 r->clock_seq_hi_and_reserved = ntohl(b[3]); 409 r->clock_seq_low 406 r->clock_seq_low = ntohl(b[4]); 410 407 411 for (loop = 0; loop < 6; loop+ 408 for (loop = 0; loop < 6; loop++) 412 r->node[loop] = ntohl( 409 r->node[loop] = ntohl(b[loop + 5]); 413 410 414 call->unmarshall++; 411 call->unmarshall++; 415 fallthrough; 412 fallthrough; 416 413 417 case 2: 414 case 2: 418 break; 415 break; 419 } 416 } 420 417 421 if (!afs_check_call_state(call, AFS_CA 418 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING)) 422 return afs_io_error(call, afs_ 419 return afs_io_error(call, afs_io_error_cm_reply); 423 420 424 /* we'll need the file server record a 421 /* we'll need the file server record as that tells us which set of 425 * vnodes to operate upon */ 422 * vnodes to operate upon */ 426 return afs_find_cm_server_by_uuid(call 423 return afs_find_cm_server_by_uuid(call, call->request); 427 } 424 } 428 425 429 /* 426 /* 430 * allow the fileserver to see if the cache ma 427 * allow the fileserver to see if the cache manager is still alive 431 */ 428 */ 432 static void SRXAFSCB_Probe(struct work_struct 429 static void SRXAFSCB_Probe(struct work_struct *work) 433 { 430 { 434 struct afs_call *call = container_of(w 431 struct afs_call *call = container_of(work, struct afs_call, work); 435 432 436 _enter(""); 433 _enter(""); 437 afs_send_empty_reply(call); 434 afs_send_empty_reply(call); 438 afs_put_call(call); 435 afs_put_call(call); 439 _leave(""); 436 _leave(""); 440 } 437 } 441 438 442 /* 439 /* 443 * deliver request data to a CB.Probe call 440 * deliver request data to a CB.Probe call 444 */ 441 */ 445 static int afs_deliver_cb_probe(struct afs_cal 442 static int afs_deliver_cb_probe(struct afs_call *call) 446 { 443 { 447 int ret; 444 int ret; 448 445 449 _enter(""); 446 _enter(""); 450 447 451 afs_extract_discard(call, 0); 448 afs_extract_discard(call, 0); 452 ret = afs_extract_data(call, false); 449 ret = afs_extract_data(call, false); 453 if (ret < 0) 450 if (ret < 0) 454 return ret; 451 return ret; 455 452 456 if (!afs_check_call_state(call, AFS_CA 453 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING)) 457 return afs_io_error(call, afs_ 454 return afs_io_error(call, afs_io_error_cm_reply); 458 return afs_find_cm_server_by_peer(call 455 return afs_find_cm_server_by_peer(call); 459 } 456 } 460 457 461 /* 458 /* 462 * Allow the fileserver to quickly find out if 459 * Allow the fileserver to quickly find out if the cache manager has been 463 * rebooted. 460 * rebooted. 464 */ 461 */ 465 static void SRXAFSCB_ProbeUuid(struct work_str 462 static void SRXAFSCB_ProbeUuid(struct work_struct *work) 466 { 463 { 467 struct afs_call *call = container_of(w 464 struct afs_call *call = container_of(work, struct afs_call, work); 468 struct afs_uuid *r = call->request; 465 struct afs_uuid *r = call->request; 469 466 470 _enter(""); 467 _enter(""); 471 468 472 if (memcmp(r, &call->net->uuid, sizeof 469 if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0) 473 afs_send_empty_reply(call); 470 afs_send_empty_reply(call); 474 else 471 else 475 afs_abort_service_call(call, 1 !! 472 afs_abort_service_call(call, 1, 1, "K-1"); 476 473 477 afs_put_call(call); 474 afs_put_call(call); 478 _leave(""); 475 _leave(""); 479 } 476 } 480 477 481 /* 478 /* 482 * deliver request data to a CB.ProbeUuid call 479 * deliver request data to a CB.ProbeUuid call 483 */ 480 */ 484 static int afs_deliver_cb_probe_uuid(struct af 481 static int afs_deliver_cb_probe_uuid(struct afs_call *call) 485 { 482 { 486 struct afs_uuid *r; 483 struct afs_uuid *r; 487 unsigned loop; 484 unsigned loop; 488 __be32 *b; 485 __be32 *b; 489 int ret; 486 int ret; 490 487 491 _enter("{%u}", call->unmarshall); 488 _enter("{%u}", call->unmarshall); 492 489 493 switch (call->unmarshall) { 490 switch (call->unmarshall) { 494 case 0: 491 case 0: 495 call->buffer = kmalloc_array(1 492 call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL); 496 if (!call->buffer) 493 if (!call->buffer) 497 return -ENOMEM; 494 return -ENOMEM; 498 afs_extract_to_buf(call, 11 * 495 afs_extract_to_buf(call, 11 * sizeof(__be32)); 499 call->unmarshall++; 496 call->unmarshall++; 500 497 501 fallthrough; 498 fallthrough; 502 case 1: 499 case 1: 503 _debug("extract UUID"); 500 _debug("extract UUID"); 504 ret = afs_extract_data(call, f 501 ret = afs_extract_data(call, false); 505 switch (ret) { 502 switch (ret) { 506 case 0: break; 503 case 0: break; 507 case -EAGAIN: return 0; 504 case -EAGAIN: return 0; 508 default: return ret; 505 default: return ret; 509 } 506 } 510 507 511 _debug("unmarshall UUID"); 508 _debug("unmarshall UUID"); 512 call->request = kmalloc(sizeof 509 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL); 513 if (!call->request) 510 if (!call->request) 514 return -ENOMEM; 511 return -ENOMEM; 515 512 516 b = call->buffer; 513 b = call->buffer; 517 r = call->request; 514 r = call->request; 518 r->time_low 515 r->time_low = b[0]; 519 r->time_mid 516 r->time_mid = htons(ntohl(b[1])); 520 r->time_hi_and_version 517 r->time_hi_and_version = htons(ntohl(b[2])); 521 r->clock_seq_hi_and_reserved 518 r->clock_seq_hi_and_reserved = ntohl(b[3]); 522 r->clock_seq_low 519 r->clock_seq_low = ntohl(b[4]); 523 520 524 for (loop = 0; loop < 6; loop+ 521 for (loop = 0; loop < 6; loop++) 525 r->node[loop] = ntohl( 522 r->node[loop] = ntohl(b[loop + 5]); 526 523 527 call->unmarshall++; 524 call->unmarshall++; 528 fallthrough; 525 fallthrough; 529 526 530 case 2: 527 case 2: 531 break; 528 break; 532 } 529 } 533 530 534 if (!afs_check_call_state(call, AFS_CA 531 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING)) 535 return afs_io_error(call, afs_ 532 return afs_io_error(call, afs_io_error_cm_reply); 536 return afs_find_cm_server_by_peer(call 533 return afs_find_cm_server_by_peer(call); 537 } 534 } 538 535 539 /* 536 /* 540 * allow the fileserver to ask about the cache 537 * allow the fileserver to ask about the cache manager's capabilities 541 */ 538 */ 542 static void SRXAFSCB_TellMeAboutYourself(struc 539 static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work) 543 { 540 { 544 struct afs_call *call = container_of(w 541 struct afs_call *call = container_of(work, struct afs_call, work); 545 int loop; 542 int loop; 546 543 547 struct { 544 struct { 548 struct /* InterfaceAddr */ { 545 struct /* InterfaceAddr */ { 549 __be32 nifs; 546 __be32 nifs; 550 __be32 uuid[11]; 547 __be32 uuid[11]; 551 __be32 ifaddr[32]; 548 __be32 ifaddr[32]; 552 __be32 netmask[32]; 549 __be32 netmask[32]; 553 __be32 mtu[32]; 550 __be32 mtu[32]; 554 } ia; 551 } ia; 555 struct /* Capabilities */ { 552 struct /* Capabilities */ { 556 __be32 capcount; 553 __be32 capcount; 557 __be32 caps[1]; 554 __be32 caps[1]; 558 } cap; 555 } cap; 559 } reply; 556 } reply; 560 557 561 _enter(""); 558 _enter(""); 562 559 563 memset(&reply, 0, sizeof(reply)); 560 memset(&reply, 0, sizeof(reply)); 564 561 565 reply.ia.uuid[0] = call->net->uuid.tim 562 reply.ia.uuid[0] = call->net->uuid.time_low; 566 reply.ia.uuid[1] = htonl(ntohs(call->n 563 reply.ia.uuid[1] = htonl(ntohs(call->net->uuid.time_mid)); 567 reply.ia.uuid[2] = htonl(ntohs(call->n 564 reply.ia.uuid[2] = htonl(ntohs(call->net->uuid.time_hi_and_version)); 568 reply.ia.uuid[3] = htonl((s8) call->ne 565 reply.ia.uuid[3] = htonl((s8) call->net->uuid.clock_seq_hi_and_reserved); 569 reply.ia.uuid[4] = htonl((s8) call->ne 566 reply.ia.uuid[4] = htonl((s8) call->net->uuid.clock_seq_low); 570 for (loop = 0; loop < 6; loop++) 567 for (loop = 0; loop < 6; loop++) 571 reply.ia.uuid[loop + 5] = hton 568 reply.ia.uuid[loop + 5] = htonl((s8) call->net->uuid.node[loop]); 572 569 573 reply.cap.capcount = htonl(1); 570 reply.cap.capcount = htonl(1); 574 reply.cap.caps[0] = htonl(AFS_CAP_ERRO 571 reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION); 575 afs_send_simple_reply(call, &reply, si 572 afs_send_simple_reply(call, &reply, sizeof(reply)); 576 afs_put_call(call); 573 afs_put_call(call); 577 _leave(""); 574 _leave(""); 578 } 575 } 579 576 580 /* 577 /* 581 * deliver request data to a CB.TellMeAboutYou 578 * deliver request data to a CB.TellMeAboutYourself call 582 */ 579 */ 583 static int afs_deliver_cb_tell_me_about_yourse 580 static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call) 584 { 581 { 585 int ret; 582 int ret; 586 583 587 _enter(""); 584 _enter(""); 588 585 589 afs_extract_discard(call, 0); 586 afs_extract_discard(call, 0); 590 ret = afs_extract_data(call, false); 587 ret = afs_extract_data(call, false); 591 if (ret < 0) 588 if (ret < 0) 592 return ret; 589 return ret; 593 590 594 if (!afs_check_call_state(call, AFS_CA 591 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING)) 595 return afs_io_error(call, afs_ 592 return afs_io_error(call, afs_io_error_cm_reply); 596 return afs_find_cm_server_by_peer(call 593 return afs_find_cm_server_by_peer(call); 597 } 594 } 598 595 599 /* 596 /* 600 * deliver request data to a YFS CB.CallBack c 597 * deliver request data to a YFS CB.CallBack call 601 */ 598 */ 602 static int afs_deliver_yfs_cb_callback(struct 599 static int afs_deliver_yfs_cb_callback(struct afs_call *call) 603 { 600 { 604 struct afs_callback_break *cb; 601 struct afs_callback_break *cb; 605 struct yfs_xdr_YFSFid *bp; 602 struct yfs_xdr_YFSFid *bp; 606 size_t size; 603 size_t size; 607 int ret, loop; 604 int ret, loop; 608 605 609 _enter("{%u}", call->unmarshall); 606 _enter("{%u}", call->unmarshall); 610 607 611 switch (call->unmarshall) { 608 switch (call->unmarshall) { 612 case 0: 609 case 0: 613 afs_extract_to_tmp(call); 610 afs_extract_to_tmp(call); 614 call->unmarshall++; 611 call->unmarshall++; 615 612 616 /* extract the FID array and i 613 /* extract the FID array and its count in two steps */ 617 fallthrough; 614 fallthrough; 618 case 1: 615 case 1: 619 _debug("extract FID count"); 616 _debug("extract FID count"); 620 ret = afs_extract_data(call, t 617 ret = afs_extract_data(call, true); 621 if (ret < 0) 618 if (ret < 0) 622 return ret; 619 return ret; 623 620 624 call->count = ntohl(call->tmp) 621 call->count = ntohl(call->tmp); 625 _debug("FID count: %u", call-> 622 _debug("FID count: %u", call->count); 626 if (call->count > YFSCBMAX) 623 if (call->count > YFSCBMAX) 627 return afs_protocol_er 624 return afs_protocol_error(call, afs_eproto_cb_fid_count); 628 625 629 size = array_size(call->count, 626 size = array_size(call->count, sizeof(struct yfs_xdr_YFSFid)); 630 call->buffer = kmalloc(size, G 627 call->buffer = kmalloc(size, GFP_KERNEL); 631 if (!call->buffer) 628 if (!call->buffer) 632 return -ENOMEM; 629 return -ENOMEM; 633 afs_extract_to_buf(call, size) 630 afs_extract_to_buf(call, size); 634 call->unmarshall++; 631 call->unmarshall++; 635 632 636 fallthrough; 633 fallthrough; 637 case 2: 634 case 2: 638 _debug("extract FID array"); 635 _debug("extract FID array"); 639 ret = afs_extract_data(call, f 636 ret = afs_extract_data(call, false); 640 if (ret < 0) 637 if (ret < 0) 641 return ret; 638 return ret; 642 639 643 _debug("unmarshall FID array") 640 _debug("unmarshall FID array"); 644 call->request = kcalloc(call-> 641 call->request = kcalloc(call->count, 645 sizeof 642 sizeof(struct afs_callback_break), 646 GFP_KE 643 GFP_KERNEL); 647 if (!call->request) 644 if (!call->request) 648 return -ENOMEM; 645 return -ENOMEM; 649 646 650 cb = call->request; 647 cb = call->request; 651 bp = call->buffer; 648 bp = call->buffer; 652 for (loop = call->count; loop 649 for (loop = call->count; loop > 0; loop--, cb++) { 653 cb->fid.vid = xdr_ 650 cb->fid.vid = xdr_to_u64(bp->volume); 654 cb->fid.vnode = xdr_ 651 cb->fid.vnode = xdr_to_u64(bp->vnode.lo); 655 cb->fid.vnode_hi = nto 652 cb->fid.vnode_hi = ntohl(bp->vnode.hi); 656 cb->fid.unique = ntoh 653 cb->fid.unique = ntohl(bp->vnode.unique); 657 bp++; 654 bp++; 658 } 655 } 659 656 660 afs_extract_to_tmp(call); 657 afs_extract_to_tmp(call); 661 call->unmarshall++; 658 call->unmarshall++; 662 fallthrough; 659 fallthrough; 663 660 664 case 3: 661 case 3: 665 break; 662 break; 666 } 663 } 667 664 668 if (!afs_check_call_state(call, AFS_CA 665 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING)) 669 return afs_io_error(call, afs_ 666 return afs_io_error(call, afs_io_error_cm_reply); 670 667 671 /* We'll need the file server record a 668 /* We'll need the file server record as that tells us which set of 672 * vnodes to operate upon. 669 * vnodes to operate upon. 673 */ 670 */ 674 return afs_find_cm_server_by_peer(call 671 return afs_find_cm_server_by_peer(call); 675 } 672 } 676 673
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.