Commit acf913b7 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linus-2019-10-26' of git://git.kernel.dk/linux-block

Pull block and io_uring fixes from Jens Axboe:
 "A bit bigger than usual at this point in time, mostly due to some good
  bug hunting work by Pavel that resulted in three io_uring fixes from
  him and two from me. Anyway, this pull request contains:

   - Revert of the submit-and-wait optimization for io_uring, it can't
     always be done safely. It depends on commands always making
     progress on their own, which isn't necessarily the case outside of
     strict file IO. (me)

   - Series of two patches from me and three from Pavel, fixing issues
     with shared data and sequencing for io_uring.

   - Lastly, two timeout sequence fixes for io_uring (zhangyi)

   - Two nbd patches fixing races (Josef)

   - libahci regulator_get_optional() fix (Mark)"

* tag 'for-linus-2019-10-26' of git://git.kernel.dk/linux-block:
  nbd: verify socket is supported during setup
  ata: libahci_platform: Fix regulator_get_optional() misuse
  nbd: handle racing with error'ed out commands
  nbd: protect cmd->status with cmd->lock
  io_uring: fix bad inflight accounting for SETUP_IOPOLL|SETUP_SQTHREAD
  io_uring: used cached copies of sq->dropped and cq->overflow
  io_uring: Fix race for sqes with userspace
  io_uring: Fix broken links with offloading
  io_uring: Fix corrupted user_data
  io_uring: correct timeout req sequence when inserting a new entry
  io_uring : correct timeout req sequence when waiting timeout
  io_uring: revert "io_uring: optimize submit_and_wait API"
parents f877bee5 cf1b2326
...@@ -153,17 +153,13 @@ int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv) ...@@ -153,17 +153,13 @@ int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv)
{ {
int rc, i; int rc, i;
if (hpriv->ahci_regulator) {
rc = regulator_enable(hpriv->ahci_regulator); rc = regulator_enable(hpriv->ahci_regulator);
if (rc) if (rc)
return rc; return rc;
}
if (hpriv->phy_regulator) {
rc = regulator_enable(hpriv->phy_regulator); rc = regulator_enable(hpriv->phy_regulator);
if (rc) if (rc)
goto disable_ahci_pwrs; goto disable_ahci_pwrs;
}
for (i = 0; i < hpriv->nports; i++) { for (i = 0; i < hpriv->nports; i++) {
if (!hpriv->target_pwrs[i]) if (!hpriv->target_pwrs[i])
...@@ -181,10 +177,8 @@ int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv) ...@@ -181,10 +177,8 @@ int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv)
if (hpriv->target_pwrs[i]) if (hpriv->target_pwrs[i])
regulator_disable(hpriv->target_pwrs[i]); regulator_disable(hpriv->target_pwrs[i]);
if (hpriv->phy_regulator)
regulator_disable(hpriv->phy_regulator); regulator_disable(hpriv->phy_regulator);
disable_ahci_pwrs: disable_ahci_pwrs:
if (hpriv->ahci_regulator)
regulator_disable(hpriv->ahci_regulator); regulator_disable(hpriv->ahci_regulator);
return rc; return rc;
} }
...@@ -207,9 +201,7 @@ void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv) ...@@ -207,9 +201,7 @@ void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv)
regulator_disable(hpriv->target_pwrs[i]); regulator_disable(hpriv->target_pwrs[i]);
} }
if (hpriv->ahci_regulator)
regulator_disable(hpriv->ahci_regulator); regulator_disable(hpriv->ahci_regulator);
if (hpriv->phy_regulator)
regulator_disable(hpriv->phy_regulator); regulator_disable(hpriv->phy_regulator);
} }
EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators); EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators);
...@@ -359,7 +351,7 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port, ...@@ -359,7 +351,7 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port,
struct regulator *target_pwr; struct regulator *target_pwr;
int rc = 0; int rc = 0;
target_pwr = regulator_get_optional(dev, "target"); target_pwr = regulator_get(dev, "target");
if (!IS_ERR(target_pwr)) if (!IS_ERR(target_pwr))
hpriv->target_pwrs[port] = target_pwr; hpriv->target_pwrs[port] = target_pwr;
...@@ -436,16 +428,14 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev, ...@@ -436,16 +428,14 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,
hpriv->clks[i] = clk; hpriv->clks[i] = clk;
} }
hpriv->ahci_regulator = devm_regulator_get_optional(dev, "ahci"); hpriv->ahci_regulator = devm_regulator_get(dev, "ahci");
if (IS_ERR(hpriv->ahci_regulator)) { if (IS_ERR(hpriv->ahci_regulator)) {
rc = PTR_ERR(hpriv->ahci_regulator); rc = PTR_ERR(hpriv->ahci_regulator);
if (rc == -EPROBE_DEFER) if (rc != 0)
goto err_out; goto err_out;
rc = 0;
hpriv->ahci_regulator = NULL;
} }
hpriv->phy_regulator = devm_regulator_get_optional(dev, "phy"); hpriv->phy_regulator = devm_regulator_get(dev, "phy");
if (IS_ERR(hpriv->phy_regulator)) { if (IS_ERR(hpriv->phy_regulator)) {
rc = PTR_ERR(hpriv->phy_regulator); rc = PTR_ERR(hpriv->phy_regulator);
if (rc == -EPROBE_DEFER) if (rc == -EPROBE_DEFER)
......
...@@ -385,17 +385,16 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req, ...@@ -385,17 +385,16 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req,
struct nbd_device *nbd = cmd->nbd; struct nbd_device *nbd = cmd->nbd;
struct nbd_config *config; struct nbd_config *config;
if (!mutex_trylock(&cmd->lock))
return BLK_EH_RESET_TIMER;
if (!refcount_inc_not_zero(&nbd->config_refs)) { if (!refcount_inc_not_zero(&nbd->config_refs)) {
cmd->status = BLK_STS_TIMEOUT; cmd->status = BLK_STS_TIMEOUT;
mutex_unlock(&cmd->lock);
goto done; goto done;
} }
config = nbd->config; config = nbd->config;
if (!mutex_trylock(&cmd->lock)) {
nbd_config_put(nbd);
return BLK_EH_RESET_TIMER;
}
if (config->num_connections > 1) { if (config->num_connections > 1) {
dev_err_ratelimited(nbd_to_dev(nbd), dev_err_ratelimited(nbd_to_dev(nbd),
"Connection timed out, retrying (%d/%d alive)\n", "Connection timed out, retrying (%d/%d alive)\n",
...@@ -711,6 +710,12 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index) ...@@ -711,6 +710,12 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index)
ret = -ENOENT; ret = -ENOENT;
goto out; goto out;
} }
if (cmd->status != BLK_STS_OK) {
dev_err(disk_to_dev(nbd->disk), "Command already handled %p\n",
req);
ret = -ENOENT;
goto out;
}
if (test_bit(NBD_CMD_REQUEUED, &cmd->flags)) { if (test_bit(NBD_CMD_REQUEUED, &cmd->flags)) {
dev_err(disk_to_dev(nbd->disk), "Raced with timeout on req %p\n", dev_err(disk_to_dev(nbd->disk), "Raced with timeout on req %p\n",
req); req);
...@@ -792,7 +797,10 @@ static bool nbd_clear_req(struct request *req, void *data, bool reserved) ...@@ -792,7 +797,10 @@ static bool nbd_clear_req(struct request *req, void *data, bool reserved)
{ {
struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req); struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req);
mutex_lock(&cmd->lock);
cmd->status = BLK_STS_IOERR; cmd->status = BLK_STS_IOERR;
mutex_unlock(&cmd->lock);
blk_mq_complete_request(req); blk_mq_complete_request(req);
return true; return true;
} }
...@@ -972,6 +980,25 @@ static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx, ...@@ -972,6 +980,25 @@ static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx,
return ret; return ret;
} }
static struct socket *nbd_get_socket(struct nbd_device *nbd, unsigned long fd,
int *err)
{
struct socket *sock;
*err = 0;
sock = sockfd_lookup(fd, err);
if (!sock)
return NULL;
if (sock->ops->shutdown == sock_no_shutdown) {
dev_err(disk_to_dev(nbd->disk), "Unsupported socket: shutdown callout must be supported.\n");
*err = -EINVAL;
return NULL;
}
return sock;
}
static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
bool netlink) bool netlink)
{ {
...@@ -981,7 +1008,7 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, ...@@ -981,7 +1008,7 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg,
struct nbd_sock *nsock; struct nbd_sock *nsock;
int err; int err;
sock = sockfd_lookup(arg, &err); sock = nbd_get_socket(nbd, arg, &err);
if (!sock) if (!sock)
return err; return err;
...@@ -1033,7 +1060,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg) ...@@ -1033,7 +1060,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg)
int i; int i;
int err; int err;
sock = sockfd_lookup(arg, &err); sock = nbd_get_socket(nbd, arg, &err);
if (!sock) if (!sock)
return err; return err;
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment