提交 5964c1b8 编写于 作者: A Al Viro 提交者: Mike Marshall

orangefs: set correct ->downcall.status on failing to copy reply from daemon

... and clean the end of control device ->write_iter() while we are at it
Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: NMike Marshall <hubcap@omnibond.com>
上级 ddb84da3
...@@ -333,8 +333,7 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, ...@@ -333,8 +333,7 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
n = copy_from_iter(&op->downcall, downcall_size, iter); n = copy_from_iter(&op->downcall, downcall_size, iter);
if (n != downcall_size) { if (n != downcall_size) {
gossip_err("%s: failed to copy downcall.\n", __func__); gossip_err("%s: failed to copy downcall.\n", __func__);
ret = -EFAULT; goto Efault;
goto Broken;
} }
if (op->downcall.status) if (op->downcall.status)
...@@ -354,8 +353,7 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, ...@@ -354,8 +353,7 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
downcall_size, downcall_size,
op->downcall.trailer_size, op->downcall.trailer_size,
total); total);
ret = -EFAULT; goto Efault;
goto Broken;
} }
/* Only READDIR operations should have trailers. */ /* Only READDIR operations should have trailers. */
...@@ -364,8 +362,7 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, ...@@ -364,8 +362,7 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
gossip_err("%s: %x operation with trailer.", gossip_err("%s: %x operation with trailer.",
__func__, __func__,
op->downcall.type); op->downcall.type);
ret = -EFAULT; goto Efault;
goto Broken;
} }
/* READDIR operations should always have trailers. */ /* READDIR operations should always have trailers. */
...@@ -374,8 +371,7 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, ...@@ -374,8 +371,7 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
gossip_err("%s: %x operation with no trailer.", gossip_err("%s: %x operation with no trailer.",
__func__, __func__,
op->downcall.type); op->downcall.type);
ret = -EFAULT; goto Efault;
goto Broken;
} }
if (op->downcall.type != ORANGEFS_VFS_OP_READDIR) if (op->downcall.type != ORANGEFS_VFS_OP_READDIR)
...@@ -386,8 +382,7 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, ...@@ -386,8 +382,7 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
if (op->downcall.trailer_buf == NULL) { if (op->downcall.trailer_buf == NULL) {
gossip_err("%s: failed trailer vmalloc.\n", gossip_err("%s: failed trailer vmalloc.\n",
__func__); __func__);
ret = -ENOMEM; goto Enomem;
goto Broken;
} }
memset(op->downcall.trailer_buf, 0, op->downcall.trailer_size); memset(op->downcall.trailer_buf, 0, op->downcall.trailer_size);
n = copy_from_iter(op->downcall.trailer_buf, n = copy_from_iter(op->downcall.trailer_buf,
...@@ -396,8 +391,7 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, ...@@ -396,8 +391,7 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
if (n != op->downcall.trailer_size) { if (n != op->downcall.trailer_size) {
gossip_err("%s: failed to copy trailer.\n", __func__); gossip_err("%s: failed to copy trailer.\n", __func__);
vfree(op->downcall.trailer_buf); vfree(op->downcall.trailer_buf);
ret = -EFAULT; goto Efault;
goto Broken;
} }
wakeup: wakeup:
...@@ -406,38 +400,27 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb, ...@@ -406,38 +400,27 @@ static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
* that this op is done * that this op is done
*/ */
spin_lock(&op->lock); spin_lock(&op->lock);
if (unlikely(op_state_given_up(op))) { if (unlikely(op_is_cancel(op))) {
spin_unlock(&op->lock); spin_unlock(&op->lock);
goto out; put_cancel(op);
} } else if (unlikely(op_state_given_up(op))) {
spin_unlock(&op->lock);
} else {
set_op_state_serviced(op); set_op_state_serviced(op);
spin_unlock(&op->lock); spin_unlock(&op->lock);
}
/*
* If this operation is an I/O operation we need to wait
* for all data to be copied before we can return to avoid
* buffer corruption and races that can pull the buffers
* out from under us.
*
* Essentially we're synchronizing with other parts of the
* vfs implicitly by not allowing the user space
* application reading/writing this device to return until
* the buffers are done being used.
*/
out:
if (unlikely(op_is_cancel(op)))
put_cancel(op);
op_release(op); op_release(op);
return ret; return ret;
Broken: Efault:
spin_lock(&op->lock); op->downcall.status = -(ORANGEFS_ERROR_BIT | 9);
if (!op_state_given_up(op)) { ret = -EFAULT;
op->downcall.status = ret; goto wakeup;
set_op_state_serviced(op);
} Enomem:
spin_unlock(&op->lock); op->downcall.status = -(ORANGEFS_ERROR_BIT | 8);
goto out; ret = -ENOMEM;
goto wakeup;
} }
/* Returns whether any FS are still pending remounted */ /* Returns whether any FS are still pending remounted */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册