@@ -247,11 +247,11 @@ target_emulate_report_target_port_groups(struct se_cmd *cmd)
247
247
* this CDB was received upon to determine this value individually
248
248
* for ALUA target port group.
249
249
*/
250
- spin_lock ( & cmd -> se_lun -> lun_tg_pt_gp_lock );
251
- tg_pt_gp = cmd -> se_lun -> lun_tg_pt_gp ;
250
+ rcu_read_lock ( );
251
+ tg_pt_gp = rcu_dereference ( cmd -> se_lun -> lun_tg_pt_gp ) ;
252
252
if (tg_pt_gp )
253
253
buf [5 ] = tg_pt_gp -> tg_pt_gp_implicit_trans_secs ;
254
- spin_unlock ( & cmd -> se_lun -> lun_tg_pt_gp_lock );
254
+ rcu_read_unlock ( );
255
255
}
256
256
transport_kunmap_data_sg (cmd );
257
257
@@ -292,24 +292,24 @@ target_emulate_set_target_port_groups(struct se_cmd *cmd)
292
292
* Determine if explicit ALUA via SET_TARGET_PORT_GROUPS is allowed
293
293
* for the local tg_pt_gp.
294
294
*/
295
- spin_lock ( & l_lun -> lun_tg_pt_gp_lock );
296
- l_tg_pt_gp = l_lun -> lun_tg_pt_gp ;
295
+ rcu_read_lock ( );
296
+ l_tg_pt_gp = rcu_dereference ( l_lun -> lun_tg_pt_gp ) ;
297
297
if (!l_tg_pt_gp ) {
298
- spin_unlock ( & l_lun -> lun_tg_pt_gp_lock );
298
+ rcu_read_unlock ( );
299
299
pr_err ("Unable to access l_lun->tg_pt_gp\n" );
300
300
rc = TCM_UNSUPPORTED_SCSI_OPCODE ;
301
301
goto out ;
302
302
}
303
303
304
304
if (!(l_tg_pt_gp -> tg_pt_gp_alua_access_type & TPGS_EXPLICIT_ALUA )) {
305
- spin_unlock ( & l_lun -> lun_tg_pt_gp_lock );
305
+ rcu_read_unlock ( );
306
306
pr_debug ("Unable to process SET_TARGET_PORT_GROUPS"
307
307
" while TPGS_EXPLICIT_ALUA is disabled\n" );
308
308
rc = TCM_UNSUPPORTED_SCSI_OPCODE ;
309
309
goto out ;
310
310
}
311
311
valid_states = l_tg_pt_gp -> tg_pt_gp_alua_supported_states ;
312
- spin_unlock ( & l_lun -> lun_tg_pt_gp_lock );
312
+ rcu_read_unlock ( );
313
313
314
314
ptr = & buf [4 ]; /* Skip over RESERVED area in header */
315
315
@@ -662,17 +662,17 @@ target_alua_state_check(struct se_cmd *cmd)
662
662
" target port\n" );
663
663
return TCM_ALUA_OFFLINE ;
664
664
}
665
-
666
- if (!lun -> lun_tg_pt_gp )
665
+ rcu_read_lock ();
666
+ tg_pt_gp = rcu_dereference (lun -> lun_tg_pt_gp );
667
+ if (!tg_pt_gp ) {
668
+ rcu_read_unlock ();
667
669
return 0 ;
670
+ }
668
671
669
- spin_lock (& lun -> lun_tg_pt_gp_lock );
670
- tg_pt_gp = lun -> lun_tg_pt_gp ;
671
672
out_alua_state = tg_pt_gp -> tg_pt_gp_alua_access_state ;
672
673
nonop_delay_msecs = tg_pt_gp -> tg_pt_gp_nonop_delay_msecs ;
673
674
tg_pt_gp_id = tg_pt_gp -> tg_pt_gp_id ;
674
-
675
- spin_unlock (& lun -> lun_tg_pt_gp_lock );
675
+ rcu_read_unlock ();
676
676
/*
677
677
* Process ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED in a separate conditional
678
678
* statement so the compiler knows explicitly to check this case first.
@@ -1219,10 +1219,10 @@ static int core_alua_set_tg_pt_secondary_state(
1219
1219
struct t10_alua_tg_pt_gp * tg_pt_gp ;
1220
1220
int trans_delay_msecs ;
1221
1221
1222
- spin_lock ( & lun -> lun_tg_pt_gp_lock );
1223
- tg_pt_gp = lun -> lun_tg_pt_gp ;
1222
+ rcu_read_lock ( );
1223
+ tg_pt_gp = rcu_dereference ( lun -> lun_tg_pt_gp ) ;
1224
1224
if (!tg_pt_gp ) {
1225
- spin_unlock ( & lun -> lun_tg_pt_gp_lock );
1225
+ rcu_read_unlock ( );
1226
1226
pr_err ("Unable to complete secondary state"
1227
1227
" transition\n" );
1228
1228
return - EINVAL ;
@@ -1246,7 +1246,7 @@ static int core_alua_set_tg_pt_secondary_state(
1246
1246
"implicit" , config_item_name (& tg_pt_gp -> tg_pt_gp_group .cg_item ),
1247
1247
tg_pt_gp -> tg_pt_gp_id , (offline ) ? "OFFLINE" : "ONLINE" );
1248
1248
1249
- spin_unlock ( & lun -> lun_tg_pt_gp_lock );
1249
+ rcu_read_unlock ( );
1250
1250
/*
1251
1251
* Do the optional transition delay after we set the secondary
1252
1252
* ALUA access state.
@@ -1754,13 +1754,14 @@ void core_alua_free_tg_pt_gp(
1754
1754
__target_attach_tg_pt_gp (lun ,
1755
1755
dev -> t10_alua .default_tg_pt_gp );
1756
1756
} else
1757
- lun -> lun_tg_pt_gp = NULL ;
1757
+ rcu_assign_pointer ( lun -> lun_tg_pt_gp , NULL ) ;
1758
1758
spin_unlock (& lun -> lun_tg_pt_gp_lock );
1759
1759
1760
1760
spin_lock (& tg_pt_gp -> tg_pt_gp_lock );
1761
1761
}
1762
1762
spin_unlock (& tg_pt_gp -> tg_pt_gp_lock );
1763
1763
1764
+ synchronize_rcu ();
1764
1765
kmem_cache_free (t10_alua_tg_pt_gp_cache , tg_pt_gp );
1765
1766
}
1766
1767
@@ -1805,7 +1806,7 @@ static void __target_attach_tg_pt_gp(struct se_lun *lun,
1805
1806
assert_spin_locked (& lun -> lun_tg_pt_gp_lock );
1806
1807
1807
1808
spin_lock (& tg_pt_gp -> tg_pt_gp_lock );
1808
- lun -> lun_tg_pt_gp = tg_pt_gp ;
1809
+ rcu_assign_pointer ( lun -> lun_tg_pt_gp , tg_pt_gp ) ;
1809
1810
list_add_tail (& lun -> lun_tg_pt_gp_link , & tg_pt_gp -> tg_pt_gp_lun_list );
1810
1811
tg_pt_gp -> tg_pt_gp_members ++ ;
1811
1812
spin_lock (& lun -> lun_deve_lock );
@@ -1822,6 +1823,7 @@ void target_attach_tg_pt_gp(struct se_lun *lun,
1822
1823
spin_lock (& lun -> lun_tg_pt_gp_lock );
1823
1824
__target_attach_tg_pt_gp (lun , tg_pt_gp );
1824
1825
spin_unlock (& lun -> lun_tg_pt_gp_lock );
1826
+ synchronize_rcu ();
1825
1827
}
1826
1828
1827
1829
static void __target_detach_tg_pt_gp (struct se_lun * lun ,
@@ -1834,18 +1836,20 @@ static void __target_detach_tg_pt_gp(struct se_lun *lun,
1834
1836
tg_pt_gp -> tg_pt_gp_members -- ;
1835
1837
spin_unlock (& tg_pt_gp -> tg_pt_gp_lock );
1836
1838
1837
- lun -> lun_tg_pt_gp = NULL ;
1839
+ rcu_assign_pointer ( lun -> lun_tg_pt_gp , NULL ) ;
1838
1840
}
1839
1841
1840
1842
void target_detach_tg_pt_gp (struct se_lun * lun )
1841
1843
{
1842
1844
struct t10_alua_tg_pt_gp * tg_pt_gp ;
1843
1845
1844
1846
spin_lock (& lun -> lun_tg_pt_gp_lock );
1845
- tg_pt_gp = lun -> lun_tg_pt_gp ;
1847
+ tg_pt_gp = rcu_dereference_check (lun -> lun_tg_pt_gp ,
1848
+ lockdep_is_held (& lun -> lun_tg_pt_gp_lock ));
1846
1849
if (tg_pt_gp )
1847
1850
__target_detach_tg_pt_gp (lun , tg_pt_gp );
1848
1851
spin_unlock (& lun -> lun_tg_pt_gp_lock );
1852
+ synchronize_rcu ();
1849
1853
}
1850
1854
1851
1855
ssize_t core_alua_show_tg_pt_gp_info (struct se_lun * lun , char * page )
@@ -1854,8 +1858,8 @@ ssize_t core_alua_show_tg_pt_gp_info(struct se_lun *lun, char *page)
1854
1858
struct t10_alua_tg_pt_gp * tg_pt_gp ;
1855
1859
ssize_t len = 0 ;
1856
1860
1857
- spin_lock ( & lun -> lun_tg_pt_gp_lock );
1858
- tg_pt_gp = lun -> lun_tg_pt_gp ;
1861
+ rcu_read_lock ( );
1862
+ tg_pt_gp = rcu_dereference ( lun -> lun_tg_pt_gp ) ;
1859
1863
if (tg_pt_gp ) {
1860
1864
tg_pt_ci = & tg_pt_gp -> tg_pt_gp_group .cg_item ;
1861
1865
len += sprintf (page , "TG Port Alias: %s\nTG Port Group ID:"
@@ -1871,7 +1875,7 @@ ssize_t core_alua_show_tg_pt_gp_info(struct se_lun *lun, char *page)
1871
1875
"Offline" : "None" ,
1872
1876
core_alua_dump_status (lun -> lun_tg_pt_secondary_stat ));
1873
1877
}
1874
- spin_unlock ( & lun -> lun_tg_pt_gp_lock );
1878
+ rcu_read_unlock ( );
1875
1879
1876
1880
return len ;
1877
1881
}
@@ -1918,7 +1922,8 @@ ssize_t core_alua_store_tg_pt_gp_info(
1918
1922
}
1919
1923
1920
1924
spin_lock (& lun -> lun_tg_pt_gp_lock );
1921
- tg_pt_gp = lun -> lun_tg_pt_gp ;
1925
+ tg_pt_gp = rcu_dereference_check (lun -> lun_tg_pt_gp ,
1926
+ lockdep_is_held (& lun -> lun_tg_pt_gp_lock ));
1922
1927
if (tg_pt_gp ) {
1923
1928
/*
1924
1929
* Clearing an existing tg_pt_gp association, and replacing
@@ -1941,7 +1946,7 @@ ssize_t core_alua_store_tg_pt_gp_info(
1941
1946
dev -> t10_alua .default_tg_pt_gp );
1942
1947
spin_unlock (& lun -> lun_tg_pt_gp_lock );
1943
1948
1944
- return count ;
1949
+ goto sync_rcu ;
1945
1950
}
1946
1951
__target_detach_tg_pt_gp (lun , tg_pt_gp );
1947
1952
move = 1 ;
@@ -1958,6 +1963,8 @@ ssize_t core_alua_store_tg_pt_gp_info(
1958
1963
tg_pt_gp_new -> tg_pt_gp_id );
1959
1964
1960
1965
core_alua_put_tg_pt_gp_from_name (tg_pt_gp_new );
1966
+ sync_rcu :
1967
+ synchronize_rcu ();
1961
1968
return count ;
1962
1969
}
1963
1970
0 commit comments