@@ -27,6 +27,7 @@ typedef struct rpc_xprt *(*xprt_switch_find_xprt_t)(struct rpc_xprt_switch *xps,
27
27
static const struct rpc_xprt_iter_ops rpc_xprt_iter_singular ;
28
28
static const struct rpc_xprt_iter_ops rpc_xprt_iter_roundrobin ;
29
29
static const struct rpc_xprt_iter_ops rpc_xprt_iter_listall ;
30
+ static const struct rpc_xprt_iter_ops rpc_xprt_iter_listoffline ;
30
31
31
32
static void xprt_switch_add_xprt_locked (struct rpc_xprt_switch * xps ,
32
33
struct rpc_xprt * xprt )
@@ -248,6 +249,18 @@ struct rpc_xprt *xprt_switch_find_first_entry(struct list_head *head)
248
249
return NULL ;
249
250
}
250
251
252
+ static
253
+ struct rpc_xprt * xprt_switch_find_first_entry_offline (struct list_head * head )
254
+ {
255
+ struct rpc_xprt * pos ;
256
+
257
+ list_for_each_entry_rcu (pos , head , xprt_switch ) {
258
+ if (!xprt_is_active (pos ))
259
+ return pos ;
260
+ }
261
+ return NULL ;
262
+ }
263
+
251
264
static
252
265
struct rpc_xprt * xprt_iter_first_entry (struct rpc_xprt_iter * xpi )
253
266
{
@@ -259,23 +272,35 @@ struct rpc_xprt *xprt_iter_first_entry(struct rpc_xprt_iter *xpi)
259
272
}
260
273
261
274
static
262
- struct rpc_xprt * xprt_switch_find_current_entry (struct list_head * head ,
263
- const struct rpc_xprt * cur )
275
+ struct rpc_xprt * _xprt_switch_find_current_entry (struct list_head * head ,
276
+ const struct rpc_xprt * cur ,
277
+ bool find_active )
264
278
{
265
279
struct rpc_xprt * pos ;
266
280
bool found = false;
267
281
268
282
list_for_each_entry_rcu (pos , head , xprt_switch ) {
269
283
if (cur == pos )
270
284
found = true;
271
- if (found && xprt_is_active (pos ))
285
+ if (found && ((find_active && xprt_is_active (pos )) ||
286
+ (!find_active && xprt_is_active (pos ))))
272
287
return pos ;
273
288
}
274
289
return NULL ;
275
290
}
276
291
277
292
static
278
- struct rpc_xprt * xprt_iter_current_entry (struct rpc_xprt_iter * xpi )
293
+ struct rpc_xprt * xprt_switch_find_current_entry (struct list_head * head ,
294
+ const struct rpc_xprt * cur )
295
+ {
296
+ return _xprt_switch_find_current_entry (head , cur , true);
297
+ }
298
+
299
+ static
300
+ struct rpc_xprt * _xprt_iter_current_entry (struct rpc_xprt_iter * xpi ,
301
+ struct rpc_xprt * first_entry (struct list_head * head ),
302
+ struct rpc_xprt * current_entry (struct list_head * head ,
303
+ const struct rpc_xprt * cur ))
279
304
{
280
305
struct rpc_xprt_switch * xps = rcu_dereference (xpi -> xpi_xpswitch );
281
306
struct list_head * head ;
@@ -284,8 +309,30 @@ struct rpc_xprt *xprt_iter_current_entry(struct rpc_xprt_iter *xpi)
284
309
return NULL ;
285
310
head = & xps -> xps_xprt_list ;
286
311
if (xpi -> xpi_cursor == NULL || xps -> xps_nxprts < 2 )
287
- return xprt_switch_find_first_entry (head );
288
- return xprt_switch_find_current_entry (head , xpi -> xpi_cursor );
312
+ return first_entry (head );
313
+ return current_entry (head , xpi -> xpi_cursor );
314
+ }
315
+
316
+ static
317
+ struct rpc_xprt * xprt_iter_current_entry (struct rpc_xprt_iter * xpi )
318
+ {
319
+ return _xprt_iter_current_entry (xpi , xprt_switch_find_first_entry ,
320
+ xprt_switch_find_current_entry );
321
+ }
322
+
323
+ static
324
+ struct rpc_xprt * xprt_switch_find_current_entry_offline (struct list_head * head ,
325
+ const struct rpc_xprt * cur )
326
+ {
327
+ return _xprt_switch_find_current_entry (head , cur , false);
328
+ }
329
+
330
+ static
331
+ struct rpc_xprt * xprt_iter_current_entry_offline (struct rpc_xprt_iter * xpi )
332
+ {
333
+ return _xprt_iter_current_entry (xpi ,
334
+ xprt_switch_find_first_entry_offline ,
335
+ xprt_switch_find_current_entry_offline );
289
336
}
290
337
291
338
bool rpc_xprt_switch_has_addr (struct rpc_xprt_switch * xps ,
@@ -310,15 +357,20 @@ bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps,
310
357
311
358
static
312
359
struct rpc_xprt * xprt_switch_find_next_entry (struct list_head * head ,
313
- const struct rpc_xprt * cur )
360
+ const struct rpc_xprt * cur , bool check_active )
314
361
{
315
362
struct rpc_xprt * pos , * prev = NULL ;
316
363
bool found = false;
317
364
318
365
list_for_each_entry_rcu (pos , head , xprt_switch ) {
319
366
if (cur == prev )
320
367
found = true;
321
- if (found && xprt_is_active (pos ))
368
+ /* for request to return active transports return only
369
+ * active, for request to return offline transports
370
+ * return only offline
371
+ */
372
+ if (found && ((check_active && xprt_is_active (pos )) ||
373
+ (!check_active && !xprt_is_active (pos ))))
322
374
return pos ;
323
375
prev = pos ;
324
376
}
@@ -355,7 +407,7 @@ struct rpc_xprt *__xprt_switch_find_next_entry_roundrobin(struct list_head *head
355
407
{
356
408
struct rpc_xprt * ret ;
357
409
358
- ret = xprt_switch_find_next_entry (head , cur );
410
+ ret = xprt_switch_find_next_entry (head , cur , true );
359
411
if (ret != NULL )
360
412
return ret ;
361
413
return xprt_switch_find_first_entry (head );
@@ -397,7 +449,14 @@ static
397
449
struct rpc_xprt * xprt_switch_find_next_entry_all (struct rpc_xprt_switch * xps ,
398
450
const struct rpc_xprt * cur )
399
451
{
400
- return xprt_switch_find_next_entry (& xps -> xps_xprt_list , cur );
452
+ return xprt_switch_find_next_entry (& xps -> xps_xprt_list , cur , true);
453
+ }
454
+
455
+ static
456
+ struct rpc_xprt * xprt_switch_find_next_entry_offline (struct rpc_xprt_switch * xps ,
457
+ const struct rpc_xprt * cur )
458
+ {
459
+ return xprt_switch_find_next_entry (& xps -> xps_xprt_list , cur , false);
401
460
}
402
461
403
462
static
@@ -407,6 +466,13 @@ struct rpc_xprt *xprt_iter_next_entry_all(struct rpc_xprt_iter *xpi)
407
466
xprt_switch_find_next_entry_all );
408
467
}
409
468
469
+ static
470
+ struct rpc_xprt * xprt_iter_next_entry_offline (struct rpc_xprt_iter * xpi )
471
+ {
472
+ return xprt_iter_next_entry_multiple (xpi ,
473
+ xprt_switch_find_next_entry_offline );
474
+ }
475
+
410
476
/*
411
477
* xprt_iter_rewind - Resets the xprt iterator
412
478
* @xpi: pointer to rpc_xprt_iter
@@ -460,6 +526,12 @@ void xprt_iter_init_listall(struct rpc_xprt_iter *xpi,
460
526
__xprt_iter_init (xpi , xps , & rpc_xprt_iter_listall );
461
527
}
462
528
529
+ void xprt_iter_init_listoffline (struct rpc_xprt_iter * xpi ,
530
+ struct rpc_xprt_switch * xps )
531
+ {
532
+ __xprt_iter_init (xpi , xps , & rpc_xprt_iter_listoffline );
533
+ }
534
+
463
535
/**
464
536
* xprt_iter_xchg_switch - Atomically swap out the rpc_xprt_switch
465
537
* @xpi: pointer to rpc_xprt_iter
@@ -574,3 +646,10 @@ const struct rpc_xprt_iter_ops rpc_xprt_iter_listall = {
574
646
.xpi_xprt = xprt_iter_current_entry ,
575
647
.xpi_next = xprt_iter_next_entry_all ,
576
648
};
649
+
650
+ static
651
+ const struct rpc_xprt_iter_ops rpc_xprt_iter_listoffline = {
652
+ .xpi_rewind = xprt_iter_default_rewind ,
653
+ .xpi_xprt = xprt_iter_current_entry_offline ,
654
+ .xpi_next = xprt_iter_next_entry_offline ,
655
+ };
0 commit comments