@@ -600,7 +600,7 @@ static int get_rsb_struct(struct dlm_ls *ls, const void *name, int len,
600
600
{
601
601
struct dlm_rsb * r ;
602
602
603
- r = dlm_allocate_rsb (ls );
603
+ r = dlm_allocate_rsb ();
604
604
if (!r )
605
605
return - ENOMEM ;
606
606
@@ -733,11 +733,13 @@ static int find_rsb_dir(struct dlm_ls *ls, const void *name, int len,
733
733
}
734
734
735
735
retry :
736
+ error = dlm_search_rsb_tree (& ls -> ls_rsbtbl , name , len , & r );
737
+ if (error )
738
+ goto do_new ;
736
739
737
740
/* check if the rsb is active under read lock - likely path */
738
741
read_lock_bh (& ls -> ls_rsbtbl_lock );
739
- error = dlm_search_rsb_tree (& ls -> ls_rsbtbl , name , len , & r );
740
- if (error ) {
742
+ if (!rsb_flag (r , RSB_HASHED )) {
741
743
read_unlock_bh (& ls -> ls_rsbtbl_lock );
742
744
goto do_new ;
743
745
}
@@ -918,11 +920,13 @@ static int find_rsb_nodir(struct dlm_ls *ls, const void *name, int len,
918
920
int error ;
919
921
920
922
retry :
923
+ error = dlm_search_rsb_tree (& ls -> ls_rsbtbl , name , len , & r );
924
+ if (error )
925
+ goto do_new ;
921
926
922
927
/* check if the rsb is in active state under read lock - likely path */
923
928
read_lock_bh (& ls -> ls_rsbtbl_lock );
924
- error = dlm_search_rsb_tree (& ls -> ls_rsbtbl , name , len , & r );
925
- if (error ) {
929
+ if (!rsb_flag (r , RSB_HASHED )) {
926
930
read_unlock_bh (& ls -> ls_rsbtbl_lock );
927
931
goto do_new ;
928
932
}
@@ -1151,7 +1155,7 @@ static void __dlm_master_lookup(struct dlm_ls *ls, struct dlm_rsb *r, int our_no
1151
1155
r -> res_dir_nodeid = our_nodeid ;
1152
1156
}
1153
1157
1154
- if (fix_master && dlm_is_removed (ls , r -> res_master_nodeid )) {
1158
+ if (fix_master && r -> res_master_nodeid && dlm_is_removed (ls , r -> res_master_nodeid )) {
1155
1159
/* Recovery uses this function to set a new master when
1156
1160
* the previous master failed. Setting NEW_MASTER will
1157
1161
* force dlm_recover_masters to call recover_master on this
@@ -1276,43 +1280,45 @@ static int _dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, const char *na
1276
1280
}
1277
1281
1278
1282
retry :
1283
+ error = dlm_search_rsb_tree (& ls -> ls_rsbtbl , name , len , & r );
1284
+ if (error )
1285
+ goto not_found ;
1279
1286
1280
1287
/* check if the rsb is active under read lock - likely path */
1281
1288
read_lock_bh (& ls -> ls_rsbtbl_lock );
1282
- error = dlm_search_rsb_tree (& ls -> ls_rsbtbl , name , len , & r );
1283
- if (!error ) {
1284
- if (rsb_flag (r , RSB_INACTIVE )) {
1285
- read_unlock_bh (& ls -> ls_rsbtbl_lock );
1286
- goto do_inactive ;
1287
- }
1288
-
1289
- /* because the rsb is active, we need to lock_rsb before
1290
- * checking/changing re_master_nodeid
1291
- */
1289
+ if (!rsb_flag (r , RSB_HASHED )) {
1290
+ read_unlock_bh (& ls -> ls_rsbtbl_lock );
1291
+ goto not_found ;
1292
+ }
1292
1293
1293
- hold_rsb ( r );
1294
+ if ( rsb_flag ( r , RSB_INACTIVE )) {
1294
1295
read_unlock_bh (& ls -> ls_rsbtbl_lock );
1295
- lock_rsb (r );
1296
+ goto do_inactive ;
1297
+ }
1296
1298
1297
- __dlm_master_lookup (ls , r , our_nodeid , from_nodeid , false,
1298
- flags , r_nodeid , result );
1299
+ /* because the rsb is active, we need to lock_rsb before
1300
+ * checking/changing re_master_nodeid
1301
+ */
1299
1302
1300
- /* the rsb was active */
1301
- unlock_rsb ( r );
1302
- put_rsb (r );
1303
+ hold_rsb ( r );
1304
+ read_unlock_bh ( & ls -> ls_rsbtbl_lock );
1305
+ lock_rsb (r );
1303
1306
1304
- return 0 ;
1305
- } else {
1306
- read_unlock_bh (& ls -> ls_rsbtbl_lock );
1307
- goto not_found ;
1308
- }
1307
+ __dlm_master_lookup (ls , r , our_nodeid , from_nodeid , false,
1308
+ flags , r_nodeid , result );
1309
+
1310
+ /* the rsb was active */
1311
+ unlock_rsb (r );
1312
+ put_rsb (r );
1313
+
1314
+ return 0 ;
1309
1315
1310
1316
do_inactive :
1311
- /* unlikely path - relookup under write */
1317
+ /* unlikely path - check if still part of ls_rsbtbl */
1312
1318
write_lock_bh (& ls -> ls_rsbtbl_lock );
1313
1319
1314
- error = dlm_search_rsb_tree ( & ls -> ls_rsbtbl , name , len , & r );
1315
- if (! error ) {
1320
+ /* see comment in find_rsb_dir */
1321
+ if (rsb_flag ( r , RSB_HASHED ) ) {
1316
1322
if (!rsb_flag (r , RSB_INACTIVE )) {
1317
1323
write_unlock_bh (& ls -> ls_rsbtbl_lock );
1318
1324
/* something as changed, very unlikely but
@@ -1403,14 +1409,14 @@ void dlm_dump_rsb_name(struct dlm_ls *ls, const char *name, int len)
1403
1409
struct dlm_rsb * r = NULL ;
1404
1410
int error ;
1405
1411
1406
- read_lock_bh ( & ls -> ls_rsbtbl_lock );
1412
+ rcu_read_lock ( );
1407
1413
error = dlm_search_rsb_tree (& ls -> ls_rsbtbl , name , len , & r );
1408
1414
if (!error )
1409
1415
goto out ;
1410
1416
1411
1417
dlm_dump_rsb (r );
1412
1418
out :
1413
- read_unlock_bh ( & ls -> ls_rsbtbl_lock );
1419
+ rcu_read_unlock ( );
1414
1420
}
1415
1421
1416
1422
static void deactivate_rsb (struct kref * kref )
@@ -1442,18 +1448,6 @@ static void deactivate_rsb(struct kref *kref)
1442
1448
}
1443
1449
}
1444
1450
1445
- /* See comment for unhold_lkb */
1446
-
1447
- static void unhold_rsb (struct dlm_rsb * r )
1448
- {
1449
- int rv ;
1450
-
1451
- /* inactive rsbs are not ref counted */
1452
- WARN_ON (rsb_flag (r , RSB_INACTIVE ));
1453
- rv = kref_put (& r -> res_ref , deactivate_rsb );
1454
- DLM_ASSERT (!rv , dlm_dump_rsb (r ););
1455
- }
1456
-
1457
1451
void free_inactive_rsb (struct dlm_rsb * r )
1458
1452
{
1459
1453
WARN_ON_ONCE (!rsb_flag (r , RSB_INACTIVE ));
@@ -1497,7 +1491,7 @@ static int _create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret,
1497
1491
limit .max = end ;
1498
1492
limit .min = start ;
1499
1493
1500
- lkb = dlm_allocate_lkb (ls );
1494
+ lkb = dlm_allocate_lkb ();
1501
1495
if (!lkb )
1502
1496
return - ENOMEM ;
1503
1497
@@ -1533,11 +1527,21 @@ static int find_lkb(struct dlm_ls *ls, uint32_t lkid, struct dlm_lkb **lkb_ret)
1533
1527
{
1534
1528
struct dlm_lkb * lkb ;
1535
1529
1536
- read_lock_bh ( & ls -> ls_lkbxa_lock );
1530
+ rcu_read_lock ( );
1537
1531
lkb = xa_load (& ls -> ls_lkbxa , lkid );
1538
- if (lkb )
1539
- kref_get (& lkb -> lkb_ref );
1540
- read_unlock_bh (& ls -> ls_lkbxa_lock );
1532
+ if (lkb ) {
1533
+ /* check if lkb is still part of lkbxa under lkbxa_lock as
1534
+ * the lkb_ref is tight to the lkbxa data structure, see
1535
+ * __put_lkb().
1536
+ */
1537
+ read_lock_bh (& ls -> ls_lkbxa_lock );
1538
+ if (kref_read (& lkb -> lkb_ref ))
1539
+ kref_get (& lkb -> lkb_ref );
1540
+ else
1541
+ lkb = NULL ;
1542
+ read_unlock_bh (& ls -> ls_lkbxa_lock );
1543
+ }
1544
+ rcu_read_unlock ();
1541
1545
1542
1546
* lkb_ret = lkb ;
1543
1547
return lkb ? 0 : - ENOENT ;
@@ -1675,10 +1679,8 @@ static void del_lkb(struct dlm_rsb *r, struct dlm_lkb *lkb)
1675
1679
1676
1680
static void move_lkb (struct dlm_rsb * r , struct dlm_lkb * lkb , int sts )
1677
1681
{
1678
- hold_lkb (lkb );
1679
1682
del_lkb (r , lkb );
1680
1683
add_lkb (r , lkb , sts );
1681
- unhold_lkb (lkb );
1682
1684
}
1683
1685
1684
1686
static int msg_reply_type (int mstype )
@@ -4323,16 +4325,27 @@ static void receive_remove(struct dlm_ls *ls, const struct dlm_message *ms)
4323
4325
memset (name , 0 , sizeof (name ));
4324
4326
memcpy (name , ms -> m_extra , len );
4325
4327
4326
- write_lock_bh (& ls -> ls_rsbtbl_lock );
4327
-
4328
+ rcu_read_lock ();
4328
4329
rv = dlm_search_rsb_tree (& ls -> ls_rsbtbl , name , len , & r );
4329
4330
if (rv ) {
4331
+ rcu_read_unlock ();
4330
4332
/* should not happen */
4331
4333
log_error (ls , "%s from %d not found %s" , __func__ ,
4332
4334
from_nodeid , name );
4335
+ return ;
4336
+ }
4337
+
4338
+ write_lock_bh (& ls -> ls_rsbtbl_lock );
4339
+ if (!rsb_flag (r , RSB_HASHED )) {
4340
+ rcu_read_unlock ();
4333
4341
write_unlock_bh (& ls -> ls_rsbtbl_lock );
4342
+ /* should not happen */
4343
+ log_error (ls , "%s from %d got removed during removal %s" ,
4344
+ __func__ , from_nodeid , name );
4334
4345
return ;
4335
4346
}
4347
+ /* at this stage the rsb can only being freed here */
4348
+ rcu_read_unlock ();
4336
4349
4337
4350
if (!rsb_flag (r , RSB_INACTIVE )) {
4338
4351
if (r -> res_master_nodeid != from_nodeid ) {
@@ -5297,7 +5310,7 @@ int dlm_recover_waiters_post(struct dlm_ls *ls)
5297
5310
case DLM_MSG_LOOKUP :
5298
5311
case DLM_MSG_REQUEST :
5299
5312
_request_lock (r , lkb );
5300
- if (is_master (r ))
5313
+ if (r -> res_nodeid != -1 && is_master (r ))
5301
5314
confirm_master (r , 0 );
5302
5315
break ;
5303
5316
case DLM_MSG_CONVERT :
@@ -5409,9 +5422,8 @@ void dlm_recover_purge(struct dlm_ls *ls, const struct list_head *root_list)
5409
5422
return ;
5410
5423
5411
5424
list_for_each_entry (r , root_list , res_root_list ) {
5412
- hold_rsb (r );
5413
5425
lock_rsb (r );
5414
- if (is_master (r )) {
5426
+ if (r -> res_nodeid != -1 && is_master (r )) {
5415
5427
purge_dead_list (ls , r , & r -> res_grantqueue ,
5416
5428
nodeid_gone , & lkb_count );
5417
5429
purge_dead_list (ls , r , & r -> res_convertqueue ,
@@ -5420,7 +5432,7 @@ void dlm_recover_purge(struct dlm_ls *ls, const struct list_head *root_list)
5420
5432
nodeid_gone , & lkb_count );
5421
5433
}
5422
5434
unlock_rsb (r );
5423
- unhold_rsb ( r );
5435
+
5424
5436
cond_resched ();
5425
5437
}
5426
5438
0 commit comments