From: Christoph Hellwig <hch@lst.de> Date: 2021-08-25 16:34:32
Hi Josef and Jens,
this series tries to deal with the fallout of the recent lock scope
reduction as pointed out by Tetsuo and szybot and inspired by /
reused from the catchall patch by Tetsuo. One big change is that
I finally decided to kill off the ->destroy_complete scheme entirely
because I'm pretty sure it is not needed with the various fixes and
we can just return an error for the tiny race condition where it
matters. Xiubo, can you double check this with your nbd-runner
setup? nbd-runner itself seems pretty generic and not directly
reproduce anything here.
Note that the syzbot reproduer still fails eventually, but in
devtmpfsd in a way that does not look related to the loop code
at all.
From: Christoph Hellwig <hch@lst.de> Date: 2021-08-25 16:37:29
When nbd_genl_connect restarts to wait for a disconnecting device, nbd
needs to be reset to NULL. Do that by facoring out a helper to find
an unused device.
Fixes: 6177b56c96ff ("nbd: refactor device search and allocation in nbd_genl_connect")
Reported-by: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Reported-by: Hillf Danton <redacted>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/block/nbd.c | 32 ++++++++++++++++++--------------
1 file changed, 18 insertions(+), 14 deletions(-)
From: Christoph Hellwig <hch@lst.de> Date: 2021-08-25 16:38:57
From: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Previously nbd_index_mutex was held during whole add/remove/lookup
operations in order to guarantee that partially initialized devices are
not reachable via idr_find() or idr_for_each(). But now that partially
initialized devices become reachable as soon as idr_alloc() succeeds,
we need to skip partially initialized devices. Since it seems that
all functions use refcount_inc_not_zero(&nbd->refs) in order to skip
destroying devices, update nbd->refs from zero to non-zero as the last
step of device initialization in order to also skip partially initialized
devices.
Fixes: 6e4df4c64881 ("nbd: reduce the nbd_index_mutex scope")
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
[hch: split from a larger patch, added comments]
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/block/nbd.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
From: Christoph Hellwig <hch@lst.de> Date: 2021-08-25 16:42:10
Device marked as NBD_DESTROY_ON_DISCONNECT can and should be skipped
given that they won't survive the disconnect. So skip them and try
to grab a reference directly and just continue if the the devices
is being torn down or created and thus has a zero refcount.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/block/nbd.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
@@ -1893,8 +1897,6 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)if(!refcount_inc_not_zero(&nbd->refs)){mutex_unlock(&nbd_index_mutex);-if(index==-1)-gotoagain;pr_err("nbd: device at index %d is going down\n",index);return-EINVAL;
From: Christoph Hellwig <hch@lst.de> Date: 2021-08-25 16:43:14
The nbd->destroy_complete pointer is not really needed. For creating
a device without a specific index we now simplify skip devices marked
NBD_DESTROY_ON_DISCONNECT as there is not much point to reuse them.
For device creation with a specific index there is no real need to
treat the case of a requested but not finished disconnect different
than any other device that is being shutdown, i.e. we can just return
an error, as a slightly different race window would anyway.
Fixes: 6e4df4c64881 ("nbd: reduce the nbd_index_mutex scope")
Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Reported-by: syzbot+2c98885bcd769f56b6d6@syzkaller.appspotmail.com
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/block/nbd.c | 52 ++++++++++++---------------------------------
1 file changed, 14 insertions(+), 38 deletions(-)
@@ -1880,31 +1863,24 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info)}again:mutex_lock(&nbd_index_mutex);-if(index==-1)+if(index==-1){nbd=nbd_find_get_unused();-else+}else{nbd=idr_find(&nbd_index_idr,index);-if(nbd&&index!=-1){-if(test_bit(NBD_DESTROY_ON_DISCONNECT,&nbd->flags)&&-test_bit(NBD_DISCONNECT_REQUESTED,&nbd->flags)){-nbd->destroy_complete=&destroy_complete;-mutex_unlock(&nbd_index_mutex);--/* wait until the nbd device is completely destroyed */-wait_for_completion(&destroy_complete);-gotoagain;-}--if(!refcount_inc_not_zero(&nbd->refs)){-mutex_unlock(&nbd_index_mutex);-pr_err("nbd: device at index %d is going down\n",-index);-return-EINVAL;+if(nbd){+if((test_bit(NBD_DESTROY_ON_DISCONNECT,&nbd->flags)&&+test_bit(NBD_DISCONNECT_REQUESTED,&nbd->flags))||+!refcount_inc_not_zero(&nbd->refs)){+mutex_unlock(&nbd_index_mutex);+pr_err("nbd: device at index %d is going down\n",+index);+return-EINVAL;+}}-mutex_unlock(&nbd_index_mutex);-}else{-mutex_unlock(&nbd_index_mutex);+}+mutex_unlock(&nbd_index_mutex);+if(!nbd){nbd=nbd_dev_add(index,2);if(IS_ERR(nbd)){pr_err("nbd: failed to add new device\n");
From: Josef Bacik <josef@toxicpanda.com> Date: 2021-08-25 20:15:02
On 8/25/21 12:31 PM, Christoph Hellwig wrote:
Hi Josef and Jens,
this series tries to deal with the fallout of the recent lock scope
reduction as pointed out by Tetsuo and szybot and inspired by /
reused from the catchall patch by Tetsuo. One big change is that
I finally decided to kill off the ->destroy_complete scheme entirely
because I'm pretty sure it is not needed with the various fixes and
we can just return an error for the tiny race condition where it
matters. Xiubo, can you double check this with your nbd-runner
setup? nbd-runner itself seems pretty generic and not directly
reproduce anything here.
Note that the syzbot reproduer still fails eventually, but in
devtmpfsd in a way that does not look related to the loop code
at all.
Looks good to me, you can add
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Thanks,
Josef
Hi Josef and Jens,
this series tries to deal with the fallout of the recent lock scope
reduction as pointed out by Tetsuo and szybot and inspired by /
reused from the catchall patch by Tetsuo. One big change is that
I finally decided to kill off the ->destroy_complete scheme entirely
because I'm pretty sure it is not needed with the various fixes and
we can just return an error for the tiny race condition where it
matters. Xiubo, can you double check this with your nbd-runner
setup? nbd-runner itself seems pretty generic and not directly
reproduce anything here.
Note that the syzbot reproduer still fails eventually, but in
devtmpfsd in a way that does not look related to the loop code
at all.
Hi Josef and Jens,
this series tries to deal with the fallout of the recent lock scope
reduction as pointed out by Tetsuo and szybot and inspired by /
reused from the catchall patch by Tetsuo. One big change is that
I finally decided to kill off the ->destroy_complete scheme entirely
because I'm pretty sure it is not needed with the various fixes and
we can just return an error for the tiny race condition where it
matters. Xiubo, can you double check this with your nbd-runner
setup? nbd-runner itself seems pretty generic and not directly
reproduce anything here.
Note that the syzbot reproduer still fails eventually, but in
devtmpfsd in a way that does not look related to the loop code
at all.
Sorry, I think I have missed this thread.
Test this and works well for me by using the nbd-runner.