@@ -1365,22 +1365,26 @@ int batadv_mcast_mesh_info_put(struct sk_buff *msg,
1365
1365
* to a netlink socket
1366
1366
* @msg: buffer for the message
1367
1367
* @portid: netlink port
1368
- * @seq: Sequence number of netlink message
1368
+ * @cb: Control block containing additional options
1369
1369
* @orig_node: originator to dump the multicast flags of
1370
1370
*
1371
1371
* Return: 0 or error code.
1372
1372
*/
1373
1373
static int
1374
- batadv_mcast_flags_dump_entry (struct sk_buff * msg , u32 portid , u32 seq ,
1374
+ batadv_mcast_flags_dump_entry (struct sk_buff * msg , u32 portid ,
1375
+ struct netlink_callback * cb ,
1375
1376
struct batadv_orig_node * orig_node )
1376
1377
{
1377
1378
void * hdr ;
1378
1379
1379
- hdr = genlmsg_put (msg , portid , seq , & batadv_netlink_family ,
1380
- NLM_F_MULTI , BATADV_CMD_GET_MCAST_FLAGS );
1380
+ hdr = genlmsg_put (msg , portid , cb -> nlh -> nlmsg_seq ,
1381
+ & batadv_netlink_family , NLM_F_MULTI ,
1382
+ BATADV_CMD_GET_MCAST_FLAGS );
1381
1383
if (!hdr )
1382
1384
return - ENOBUFS ;
1383
1385
1386
+ genl_dump_check_consistent (cb , hdr );
1387
+
1384
1388
if (nla_put (msg , BATADV_ATTR_ORIG_ADDRESS , ETH_ALEN ,
1385
1389
orig_node -> orig )) {
1386
1390
genlmsg_cancel (msg , hdr );
@@ -1405,31 +1409,35 @@ batadv_mcast_flags_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
1405
1409
* table to a netlink socket
1406
1410
* @msg: buffer for the message
1407
1411
* @portid: netlink port
1408
- * @seq: Sequence number of netlink message
1409
- * @head: bucket to dump
1412
+ * @cb: Control block containing additional options
1413
+ * @hash: hash to dump
1414
+ * @bucket: bucket index to dump
1410
1415
* @idx_skip: How many entries to skip
1411
1416
*
1412
1417
* Return: 0 or error code.
1413
1418
*/
1414
1419
static int
1415
- batadv_mcast_flags_dump_bucket (struct sk_buff * msg , u32 portid , u32 seq ,
1416
- struct hlist_head * head , long * idx_skip )
1420
+ batadv_mcast_flags_dump_bucket (struct sk_buff * msg , u32 portid ,
1421
+ struct netlink_callback * cb ,
1422
+ struct batadv_hashtable * hash ,
1423
+ unsigned int bucket , long * idx_skip )
1417
1424
{
1418
1425
struct batadv_orig_node * orig_node ;
1419
1426
long idx = 0 ;
1420
1427
1421
- rcu_read_lock ();
1422
- hlist_for_each_entry_rcu (orig_node , head , hash_entry ) {
1428
+ spin_lock_bh (& hash -> list_locks [bucket ]);
1429
+ cb -> seq = atomic_read (& hash -> generation ) << 1 | 1 ;
1430
+
1431
+ hlist_for_each_entry (orig_node , & hash -> table [bucket ], hash_entry ) {
1423
1432
if (!test_bit (BATADV_ORIG_CAPA_HAS_MCAST ,
1424
1433
& orig_node -> capa_initialized ))
1425
1434
continue ;
1426
1435
1427
1436
if (idx < * idx_skip )
1428
1437
goto skip ;
1429
1438
1430
- if (batadv_mcast_flags_dump_entry (msg , portid , seq ,
1431
- orig_node )) {
1432
- rcu_read_unlock ();
1439
+ if (batadv_mcast_flags_dump_entry (msg , portid , cb , orig_node )) {
1440
+ spin_unlock_bh (& hash -> list_locks [bucket ]);
1433
1441
* idx_skip = idx ;
1434
1442
1435
1443
return - EMSGSIZE ;
@@ -1438,7 +1446,7 @@ batadv_mcast_flags_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
1438
1446
skip :
1439
1447
idx ++ ;
1440
1448
}
1441
- rcu_read_unlock ( );
1449
+ spin_unlock_bh ( & hash -> list_locks [ bucket ] );
1442
1450
1443
1451
return 0 ;
1444
1452
}
@@ -1447,27 +1455,25 @@ batadv_mcast_flags_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
1447
1455
* __batadv_mcast_flags_dump() - dump multicast flags table to a netlink socket
1448
1456
* @msg: buffer for the message
1449
1457
* @portid: netlink port
1450
- * @seq: Sequence number of netlink message
1458
+ * @cb: Control block containing additional options
1451
1459
* @bat_priv: the bat priv with all the soft interface information
1452
1460
* @bucket: current bucket to dump
1453
1461
* @idx: index in current bucket to the next entry to dump
1454
1462
*
1455
1463
* Return: 0 or error code.
1456
1464
*/
1457
1465
static int
1458
- __batadv_mcast_flags_dump (struct sk_buff * msg , u32 portid , u32 seq ,
1466
+ __batadv_mcast_flags_dump (struct sk_buff * msg , u32 portid ,
1467
+ struct netlink_callback * cb ,
1459
1468
struct batadv_priv * bat_priv , long * bucket , long * idx )
1460
1469
{
1461
1470
struct batadv_hashtable * hash = bat_priv -> orig_hash ;
1462
1471
long bucket_tmp = * bucket ;
1463
- struct hlist_head * head ;
1464
1472
long idx_tmp = * idx ;
1465
1473
1466
1474
while (bucket_tmp < hash -> size ) {
1467
- head = & hash -> table [bucket_tmp ];
1468
-
1469
- if (batadv_mcast_flags_dump_bucket (msg , portid , seq , head ,
1470
- & idx_tmp ))
1475
+ if (batadv_mcast_flags_dump_bucket (msg , portid , cb , hash ,
1476
+ * bucket , & idx_tmp ))
1471
1477
break ;
1472
1478
1473
1479
bucket_tmp ++ ;
@@ -1550,8 +1556,7 @@ int batadv_mcast_flags_dump(struct sk_buff *msg, struct netlink_callback *cb)
1550
1556
return ret ;
1551
1557
1552
1558
bat_priv = netdev_priv (primary_if -> soft_iface );
1553
- ret = __batadv_mcast_flags_dump (msg , portid , cb -> nlh -> nlmsg_seq ,
1554
- bat_priv , bucket , idx );
1559
+ ret = __batadv_mcast_flags_dump (msg , portid , cb , bat_priv , bucket , idx );
1555
1560
1556
1561
batadv_hardif_put (primary_if );
1557
1562
return ret ;
0 commit comments