@@ -67,6 +67,7 @@ struct nbd_sock {
6767struct recv_thread_args {
6868 struct work_struct work ;
6969 struct nbd_device * nbd ;
70+ struct nbd_sock * nsock ;
7071 int index ;
7172};
7273
@@ -395,6 +396,22 @@ static u32 req_to_nbd_cmd_type(struct request *req)
395396 }
396397}
397398
399+ static struct nbd_config * nbd_get_config_unlocked (struct nbd_device * nbd )
400+ {
401+ if (refcount_inc_not_zero (& nbd -> config_refs )) {
402+ /*
403+ * Add smp_mb__after_atomic to ensure that reading nbd->config_refs
404+ * and reading nbd->config is ordered. The pair is the barrier in
405+ * nbd_alloc_and_init_config(), avoid nbd->config_refs is set
406+ * before nbd->config.
407+ */
408+ smp_mb__after_atomic ();
409+ return nbd -> config ;
410+ }
411+
412+ return NULL ;
413+ }
414+
398415static enum blk_eh_timer_return nbd_xmit_timeout (struct request * req )
399416{
400417 struct nbd_cmd * cmd = blk_mq_rq_to_pdu (req );
@@ -409,13 +426,13 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req)
409426 return BLK_EH_DONE ;
410427 }
411428
412- if (!refcount_inc_not_zero (& nbd -> config_refs )) {
429+ config = nbd_get_config_unlocked (nbd );
430+ if (!config ) {
413431 cmd -> status = BLK_STS_TIMEOUT ;
414432 __clear_bit (NBD_CMD_INFLIGHT , & cmd -> flags );
415433 mutex_unlock (& cmd -> lock );
416434 goto done ;
417435 }
418- config = nbd -> config ;
419436
420437 if (config -> num_connections > 1 ||
421438 (config -> num_connections == 1 && nbd -> tag_set .timeout )) {
@@ -489,15 +506,9 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req)
489506 return BLK_EH_DONE ;
490507}
491508
492- /*
493- * Send or receive packet. Return a positive value on success and
494- * negtive value on failue, and never return 0.
495- */
496- static int sock_xmit (struct nbd_device * nbd , int index , int send ,
497- struct iov_iter * iter , int msg_flags , int * sent )
509+ static int __sock_xmit (struct nbd_device * nbd , struct socket * sock , int send ,
510+ struct iov_iter * iter , int msg_flags , int * sent )
498511{
499- struct nbd_config * config = nbd -> config ;
500- struct socket * sock = config -> socks [index ]-> sock ;
501512 int result ;
502513 struct msghdr msg ;
503514 unsigned int noreclaim_flag ;
@@ -540,6 +551,19 @@ static int sock_xmit(struct nbd_device *nbd, int index, int send,
540551 return result ;
541552}
542553
554+ /*
555+ * Send or receive packet. Return a positive value on success and
556+ * negtive value on failure, and never return 0.
557+ */
558+ static int sock_xmit (struct nbd_device * nbd , int index , int send ,
559+ struct iov_iter * iter , int msg_flags , int * sent )
560+ {
561+ struct nbd_config * config = nbd -> config ;
562+ struct socket * sock = config -> socks [index ]-> sock ;
563+
564+ return __sock_xmit (nbd , sock , send , iter , msg_flags , sent );
565+ }
566+
543567/*
544568 * Different settings for sk->sk_sndtimeo can result in different return values
545569 * if there is a signal pending when we enter sendmsg, because reasons?
@@ -696,7 +720,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
696720 return 0 ;
697721}
698722
699- static int nbd_read_reply (struct nbd_device * nbd , int index ,
723+ static int nbd_read_reply (struct nbd_device * nbd , struct socket * sock ,
700724 struct nbd_reply * reply )
701725{
702726 struct kvec iov = {.iov_base = reply , .iov_len = sizeof (* reply )};
@@ -705,7 +729,7 @@ static int nbd_read_reply(struct nbd_device *nbd, int index,
705729
706730 reply -> magic = 0 ;
707731 iov_iter_kvec (& to , ITER_DEST , & iov , 1 , sizeof (* reply ));
708- result = sock_xmit (nbd , index , 0 , & to , MSG_WAITALL , NULL );
732+ result = __sock_xmit (nbd , sock , 0 , & to , MSG_WAITALL , NULL );
709733 if (result < 0 ) {
710734 if (!nbd_disconnected (nbd -> config ))
711735 dev_err (disk_to_dev (nbd -> disk ),
@@ -829,14 +853,14 @@ static void recv_work(struct work_struct *work)
829853 struct nbd_device * nbd = args -> nbd ;
830854 struct nbd_config * config = nbd -> config ;
831855 struct request_queue * q = nbd -> disk -> queue ;
832- struct nbd_sock * nsock ;
856+ struct nbd_sock * nsock = args -> nsock ;
833857 struct nbd_cmd * cmd ;
834858 struct request * rq ;
835859
836860 while (1 ) {
837861 struct nbd_reply reply ;
838862
839- if (nbd_read_reply (nbd , args -> index , & reply ))
863+ if (nbd_read_reply (nbd , nsock -> sock , & reply ))
840864 break ;
841865
842866 /*
@@ -871,7 +895,6 @@ static void recv_work(struct work_struct *work)
871895 percpu_ref_put (& q -> q_usage_counter );
872896 }
873897
874- nsock = config -> socks [args -> index ];
875898 mutex_lock (& nsock -> tx_lock );
876899 nbd_mark_nsock_dead (nbd , nsock , 1 );
877900 mutex_unlock (& nsock -> tx_lock );
@@ -977,12 +1000,12 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index)
9771000 struct nbd_sock * nsock ;
9781001 int ret ;
9791002
980- if (!refcount_inc_not_zero (& nbd -> config_refs )) {
1003+ config = nbd_get_config_unlocked (nbd );
1004+ if (!config ) {
9811005 dev_err_ratelimited (disk_to_dev (nbd -> disk ),
9821006 "Socks array is empty\n" );
9831007 return - EINVAL ;
9841008 }
985- config = nbd -> config ;
9861009
9871010 if (index >= config -> num_connections ) {
9881011 dev_err_ratelimited (disk_to_dev (nbd -> disk ),
@@ -1215,6 +1238,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg)
12151238 INIT_WORK (& args -> work , recv_work );
12161239 args -> index = i ;
12171240 args -> nbd = nbd ;
1241+ args -> nsock = nsock ;
12181242 nsock -> cookie ++ ;
12191243 mutex_unlock (& nsock -> tx_lock );
12201244 sockfd_put (old );
@@ -1397,6 +1421,7 @@ static int nbd_start_device(struct nbd_device *nbd)
13971421 refcount_inc (& nbd -> config_refs );
13981422 INIT_WORK (& args -> work , recv_work );
13991423 args -> nbd = nbd ;
1424+ args -> nsock = config -> socks [i ];
14001425 args -> index = i ;
14011426 queue_work (nbd -> recv_workq , & args -> work );
14021427 }
@@ -1530,30 +1555,45 @@ static int nbd_ioctl(struct block_device *bdev, blk_mode_t mode,
15301555 return error ;
15311556}
15321557
1533- static struct nbd_config * nbd_alloc_config ( void )
1558+ static int nbd_alloc_and_init_config ( struct nbd_device * nbd )
15341559{
15351560 struct nbd_config * config ;
15361561
1562+ if (WARN_ON (nbd -> config ))
1563+ return - EINVAL ;
1564+
15371565 if (!try_module_get (THIS_MODULE ))
1538- return ERR_PTR ( - ENODEV ) ;
1566+ return - ENODEV ;
15391567
15401568 config = kzalloc (sizeof (struct nbd_config ), GFP_NOFS );
15411569 if (!config ) {
15421570 module_put (THIS_MODULE );
1543- return ERR_PTR ( - ENOMEM ) ;
1571+ return - ENOMEM ;
15441572 }
15451573
15461574 atomic_set (& config -> recv_threads , 0 );
15471575 init_waitqueue_head (& config -> recv_wq );
15481576 init_waitqueue_head (& config -> conn_wait );
15491577 config -> blksize_bits = NBD_DEF_BLKSIZE_BITS ;
15501578 atomic_set (& config -> live_connections , 0 );
1551- return config ;
1579+
1580+ nbd -> config = config ;
1581+ /*
1582+ * Order refcount_set(&nbd->config_refs, 1) and nbd->config assignment,
1583+ * its pair is the barrier in nbd_get_config_unlocked().
1584+ * So nbd_get_config_unlocked() won't see nbd->config as null after
1585+ * refcount_inc_not_zero() succeed.
1586+ */
1587+ smp_mb__before_atomic ();
1588+ refcount_set (& nbd -> config_refs , 1 );
1589+
1590+ return 0 ;
15521591}
15531592
15541593static int nbd_open (struct gendisk * disk , blk_mode_t mode )
15551594{
15561595 struct nbd_device * nbd ;
1596+ struct nbd_config * config ;
15571597 int ret = 0 ;
15581598
15591599 mutex_lock (& nbd_index_mutex );
@@ -1566,27 +1606,25 @@ static int nbd_open(struct gendisk *disk, blk_mode_t mode)
15661606 ret = - ENXIO ;
15671607 goto out ;
15681608 }
1569- if (!refcount_inc_not_zero (& nbd -> config_refs )) {
1570- struct nbd_config * config ;
15711609
1610+ config = nbd_get_config_unlocked (nbd );
1611+ if (!config ) {
15721612 mutex_lock (& nbd -> config_lock );
15731613 if (refcount_inc_not_zero (& nbd -> config_refs )) {
15741614 mutex_unlock (& nbd -> config_lock );
15751615 goto out ;
15761616 }
1577- config = nbd_alloc_config ();
1578- if (IS_ERR (config )) {
1579- ret = PTR_ERR (config );
1617+ ret = nbd_alloc_and_init_config (nbd );
1618+ if (ret ) {
15801619 mutex_unlock (& nbd -> config_lock );
15811620 goto out ;
15821621 }
1583- nbd -> config = config ;
1584- refcount_set (& nbd -> config_refs , 1 );
1622+
15851623 refcount_inc (& nbd -> refs );
15861624 mutex_unlock (& nbd -> config_lock );
15871625 if (max_part )
15881626 set_bit (GD_NEED_PART_SCAN , & disk -> state );
1589- } else if (nbd_disconnected (nbd -> config )) {
1627+ } else if (nbd_disconnected (config )) {
15901628 if (max_part )
15911629 set_bit (GD_NEED_PART_SCAN , & disk -> state );
15921630 }
@@ -1990,22 +2028,17 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)
19902028 pr_err ("nbd%d already in use\n" , index );
19912029 return - EBUSY ;
19922030 }
1993- if (WARN_ON (nbd -> config )) {
1994- mutex_unlock (& nbd -> config_lock );
1995- nbd_put (nbd );
1996- return - EINVAL ;
1997- }
1998- config = nbd_alloc_config ();
1999- if (IS_ERR (config )) {
2031+
2032+ ret = nbd_alloc_and_init_config (nbd );
2033+ if (ret ) {
20002034 mutex_unlock (& nbd -> config_lock );
20012035 nbd_put (nbd );
20022036 pr_err ("couldn't allocate config\n" );
2003- return PTR_ERR ( config ) ;
2037+ return ret ;
20042038 }
2005- nbd -> config = config ;
2006- refcount_set (& nbd -> config_refs , 1 );
2007- set_bit (NBD_RT_BOUND , & config -> runtime_flags );
20082039
2040+ config = nbd -> config ;
2041+ set_bit (NBD_RT_BOUND , & config -> runtime_flags );
20092042 ret = nbd_genl_size_set (info , nbd );
20102043 if (ret )
20112044 goto out ;
@@ -2208,15 +2241,15 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
22082241 }
22092242 mutex_unlock (& nbd_index_mutex );
22102243
2211- if (!refcount_inc_not_zero (& nbd -> config_refs )) {
2244+ config = nbd_get_config_unlocked (nbd );
2245+ if (!config ) {
22122246 dev_err (nbd_to_dev (nbd ),
22132247 "not configured, cannot reconfigure\n" );
22142248 nbd_put (nbd );
22152249 return - EINVAL ;
22162250 }
22172251
22182252 mutex_lock (& nbd -> config_lock );
2219- config = nbd -> config ;
22202253 if (!test_bit (NBD_RT_BOUND , & config -> runtime_flags ) ||
22212254 !nbd -> pid ) {
22222255 dev_err (nbd_to_dev (nbd ),
0 commit comments