@@ -53,6 +53,7 @@ struct nbd_sock {
53
53
int sent ;
54
54
bool dead ;
55
55
int fallback_index ;
56
+ int cookie ;
56
57
};
57
58
58
59
struct recv_thread_args {
@@ -61,6 +62,11 @@ struct recv_thread_args {
61
62
int index ;
62
63
};
63
64
65
+ struct link_dead_args {
66
+ struct work_struct work ;
67
+ int index ;
68
+ };
69
+
64
70
#define NBD_TIMEDOUT 0
65
71
#define NBD_DISCONNECT_REQUESTED 1
66
72
#define NBD_DISCONNECTED 2
@@ -100,6 +106,7 @@ struct nbd_device {
100
106
struct nbd_cmd {
101
107
struct nbd_device * nbd ;
102
108
int index ;
109
+ int cookie ;
103
110
struct completion send_complete ;
104
111
};
105
112
@@ -120,6 +127,7 @@ static int nbd_dev_dbg_init(struct nbd_device *nbd);
120
127
static void nbd_dev_dbg_close (struct nbd_device * nbd );
121
128
static void nbd_config_put (struct nbd_device * nbd );
122
129
static void nbd_connect_reply (struct genl_info * info , int index );
130
+ static void nbd_dead_link_work (struct work_struct * work );
123
131
124
132
static inline struct device * nbd_to_dev (struct nbd_device * nbd )
125
133
{
@@ -152,8 +160,24 @@ static struct device_attribute pid_attr = {
152
160
.show = pid_show ,
153
161
};
154
162
155
- static void nbd_mark_nsock_dead (struct nbd_sock * nsock )
163
+ static int nbd_disconnected (struct nbd_config * config )
164
+ {
165
+ return test_bit (NBD_DISCONNECTED , & config -> runtime_flags ) ||
166
+ test_bit (NBD_DISCONNECT_REQUESTED , & config -> runtime_flags );
167
+ }
168
+
169
+ static void nbd_mark_nsock_dead (struct nbd_device * nbd , struct nbd_sock * nsock ,
170
+ int notify )
156
171
{
172
+ if (!nsock -> dead && notify && !nbd_disconnected (nbd -> config )) {
173
+ struct link_dead_args * args ;
174
+ args = kmalloc (sizeof (struct link_dead_args ), GFP_NOIO );
175
+ if (args ) {
176
+ INIT_WORK (& args -> work , nbd_dead_link_work );
177
+ args -> index = nbd -> index ;
178
+ queue_work (system_wq , & args -> work );
179
+ }
180
+ }
157
181
if (!nsock -> dead )
158
182
kernel_sock_shutdown (nsock -> sock , SHUT_RDWR );
159
183
nsock -> dead = true;
@@ -215,8 +239,7 @@ static void sock_shutdown(struct nbd_device *nbd)
215
239
for (i = 0 ; i < config -> num_connections ; i ++ ) {
216
240
struct nbd_sock * nsock = config -> socks [i ];
217
241
mutex_lock (& nsock -> tx_lock );
218
- kernel_sock_shutdown (nsock -> sock , SHUT_RDWR );
219
- nbd_mark_nsock_dead (nsock );
242
+ nbd_mark_nsock_dead (nbd , nsock , 0 );
220
243
mutex_unlock (& nsock -> tx_lock );
221
244
}
222
245
dev_warn (disk_to_dev (nbd -> disk ), "shutting down sockets\n" );
@@ -248,7 +271,14 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req,
248
271
struct nbd_sock * nsock =
249
272
config -> socks [cmd -> index ];
250
273
mutex_lock (& nsock -> tx_lock );
251
- nbd_mark_nsock_dead (nsock );
274
+ /* We can have multiple outstanding requests, so
275
+ * we don't want to mark the nsock dead if we've
276
+ * already reconnected with a new socket, so
277
+ * only mark it dead if its the same socket we
278
+ * were sent out on.
279
+ */
280
+ if (cmd -> cookie == nsock -> cookie )
281
+ nbd_mark_nsock_dead (nbd , nsock , 1 );
252
282
mutex_unlock (& nsock -> tx_lock );
253
283
}
254
284
blk_mq_requeue_request (req , true);
@@ -370,6 +400,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
370
400
iov_iter_advance (& from , sent );
371
401
}
372
402
cmd -> index = index ;
403
+ cmd -> cookie = nsock -> cookie ;
373
404
request .type = htonl (type );
374
405
if (type != NBD_CMD_FLUSH ) {
375
406
request .from = cpu_to_be64 ((u64 )blk_rq_pos (req ) << 9 );
@@ -458,12 +489,6 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
458
489
return 0 ;
459
490
}
460
491
461
- static int nbd_disconnected (struct nbd_config * config )
462
- {
463
- return test_bit (NBD_DISCONNECTED , & config -> runtime_flags ) ||
464
- test_bit (NBD_DISCONNECT_REQUESTED , & config -> runtime_flags );
465
- }
466
-
467
492
/* NULL returned = something went wrong, inform userspace */
468
493
static struct nbd_cmd * nbd_read_stat (struct nbd_device * nbd , int index )
469
494
{
@@ -564,7 +589,7 @@ static void recv_work(struct work_struct *work)
564
589
struct nbd_sock * nsock = config -> socks [args -> index ];
565
590
566
591
mutex_lock (& nsock -> tx_lock );
567
- nbd_mark_nsock_dead (nsock );
592
+ nbd_mark_nsock_dead (nbd , nsock , 1 );
568
593
mutex_unlock (& nsock -> tx_lock );
569
594
ret = PTR_ERR (cmd );
570
595
break ;
@@ -691,7 +716,7 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index)
691
716
if (ret == - EAGAIN ) {
692
717
dev_err_ratelimited (disk_to_dev (nbd -> disk ),
693
718
"Request send failed trying another connection\n" );
694
- nbd_mark_nsock_dead (nsock );
719
+ nbd_mark_nsock_dead (nbd , nsock , 1 );
695
720
mutex_unlock (& nsock -> tx_lock );
696
721
goto again ;
697
722
}
@@ -780,6 +805,7 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
780
805
nsock -> sock = sock ;
781
806
nsock -> pending = NULL ;
782
807
nsock -> sent = 0 ;
808
+ nsock -> cookie = 0 ;
783
809
socks [config -> num_connections ++ ] = nsock ;
784
810
785
811
return 0 ;
@@ -824,6 +850,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg)
824
850
INIT_WORK (& args -> work , recv_work );
825
851
args -> index = i ;
826
852
args -> nbd = nbd ;
853
+ nsock -> cookie ++ ;
827
854
mutex_unlock (& nsock -> tx_lock );
828
855
sockfd_put (old );
829
856
@@ -1682,6 +1709,10 @@ static const struct genl_ops nbd_connect_genl_ops[] = {
1682
1709
},
1683
1710
};
1684
1711
1712
+ static const struct genl_multicast_group nbd_mcast_grps [] = {
1713
+ { .name = NBD_GENL_MCAST_GROUP_NAME , },
1714
+ };
1715
+
1685
1716
static struct genl_family nbd_genl_family __ro_after_init = {
1686
1717
.hdrsize = 0 ,
1687
1718
.name = NBD_GENL_FAMILY_NAME ,
@@ -1690,6 +1721,8 @@ static struct genl_family nbd_genl_family __ro_after_init = {
1690
1721
.ops = nbd_connect_genl_ops ,
1691
1722
.n_ops = ARRAY_SIZE (nbd_connect_genl_ops ),
1692
1723
.maxattr = NBD_ATTR_MAX ,
1724
+ .mcgrps = nbd_mcast_grps ,
1725
+ .n_mcgrps = ARRAY_SIZE (nbd_mcast_grps ),
1693
1726
};
1694
1727
1695
1728
static void nbd_connect_reply (struct genl_info * info , int index )
@@ -1716,6 +1749,38 @@ static void nbd_connect_reply(struct genl_info *info, int index)
1716
1749
genlmsg_reply (skb , info );
1717
1750
}
1718
1751
1752
+ static void nbd_mcast_index (int index )
1753
+ {
1754
+ struct sk_buff * skb ;
1755
+ void * msg_head ;
1756
+ int ret ;
1757
+
1758
+ skb = genlmsg_new (nla_total_size (sizeof (u32 )), GFP_KERNEL );
1759
+ if (!skb )
1760
+ return ;
1761
+ msg_head = genlmsg_put (skb , 0 , 0 , & nbd_genl_family , 0 ,
1762
+ NBD_CMD_LINK_DEAD );
1763
+ if (!msg_head ) {
1764
+ nlmsg_free (skb );
1765
+ return ;
1766
+ }
1767
+ ret = nla_put_u32 (skb , NBD_ATTR_INDEX , index );
1768
+ if (ret ) {
1769
+ nlmsg_free (skb );
1770
+ return ;
1771
+ }
1772
+ genlmsg_end (skb , msg_head );
1773
+ genlmsg_multicast (& nbd_genl_family , skb , 0 , 0 , GFP_KERNEL );
1774
+ }
1775
+
1776
+ static void nbd_dead_link_work (struct work_struct * work )
1777
+ {
1778
+ struct link_dead_args * args = container_of (work , struct link_dead_args ,
1779
+ work );
1780
+ nbd_mcast_index (args -> index );
1781
+ kfree (args );
1782
+ }
1783
+
1719
1784
static int __init nbd_init (void )
1720
1785
{
1721
1786
int i ;
0 commit comments