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