diff options
| author | Yousef Alhouseen <alhouseenyousef@gmail.com> | 2026-06-24 20:59:25 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-07-17 15:50:01 +0200 |
| commit | fd62c1f591372f7dc4c5bc041569c2f0a4a86be1 (patch) | |
| tree | 0e7ec1016fb56997b9625e052a997c8f77caced8 /drivers/misc | |
| parent | 7bf6940d7cf41f1f0330a9bae4b7a886e18fd8e3 (diff) | |
| download | linux-next-fd62c1f591372f7dc4c5bc041569c2f0a4a86be1.tar.gz linux-next-fd62c1f591372f7dc4c5bc041569c2f0a4a86be1.zip | |
misc: ibmvmc: release send buffer on write errors
ibmvmc_get_valid_hmc_buffer() marks the selected send buffer busy before
ibmvmc_write() validates the backing storage or copies data from user
space. Error exits after that point leave the buffer permanently busy.
Keep the buffer pointer until ownership is handed to the hypervisor, and
mark it free again on local write failures. Also report an RDMA send
failure instead of returning a successful byte count.
Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>
Link: https://patch.msgid.link/20260624185925.2133-1-alhouseenyousef@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc')
| -rw-r--r-- | drivers/misc/ibmvmc.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/misc/ibmvmc.c b/drivers/misc/ibmvmc.c index beb18c34f20d..1f2968d9d01b 100644 --- a/drivers/misc/ibmvmc.c +++ b/drivers/misc/ibmvmc.c @@ -1040,7 +1040,7 @@ static ssize_t ibmvmc_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) { struct inode *inode; - struct ibmvmc_buffer *vmc_buffer; + struct ibmvmc_buffer *vmc_buffer = NULL; struct ibmvmc_file_session *session; struct crq_server_adapter *adapter; struct ibmvmc_hmc *hmc; @@ -1130,9 +1130,15 @@ static ssize_t ibmvmc_write(struct file *file, const char *buffer, dev_dbg(adapter->dev, "write: file = 0x%lx, count = 0x%lx\n", (unsigned long)file, (unsigned long)count); - ibmvmc_send_msg(adapter, vmc_buffer, hmc, count); + if (ibmvmc_send_msg(adapter, vmc_buffer, hmc, count)) { + ret = -EIO; + goto out; + } + vmc_buffer = NULL; ret = p - buffer; out: + if (vmc_buffer) + vmc_buffer->free = 1; spin_unlock_irqrestore(&hmc->lock, flags); return (ssize_t)(ret); } |
