summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2012-07-23 09:22:35 -0400
committerAnand Avati <avati@redhat.com>2012-07-25 16:28:02 -0700
commit22e4e55ecf65764812cfb76cd0b14a40b4161f25 (patch)
treefa796fa87f96f13ae4b233b60b3fb17e4806c31c /xlators
parentfd2f9c0be1a5e170ca71079b2da2c9f3d64341ae (diff)
performance/write-behind: detect short writes and pend an EIO error
Write-behind returns write requests immediately and queues the request in memory for merging, etc. If a write is incomplete, pend an EIO error for the next fop. This ensures that write failures are not silent and potentially ignored. BUG: 809975 Change-Id: I0e0e6c8e710efab58ccfaf746501d00e459eb7ef Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-on: http://review.gluster.com/3712 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Jeff Darcy <jdarcy@redhat.com> Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r--xlators/performance/write-behind/src/write-behind.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c
index 704bde416bf..ddd8a6ba244 100644
--- a/xlators/performance/write-behind/src/write-behind.c
+++ b/xlators/performance/write-behind/src/write-behind.c
@@ -423,6 +423,7 @@ wb_sync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
wb_request_t *request = NULL, *dummy = NULL;
wb_local_t *per_request_local = NULL;
int32_t ret = -1;
+ int32_t total_write_size = 0;
fd_t *fd = NULL;
GF_ASSERT (frame);
@@ -448,6 +449,7 @@ wb_sync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
if (request->flags.write_request.write_behind) {
file->window_current -= request->write_size;
+ total_write_size += request->write_size;
}
__wb_request_unref (request);
@@ -456,7 +458,19 @@ wb_sync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
if (op_ret == -1) {
file->op_ret = op_ret;
file->op_errno = op_errno;
- }
+ } else if (op_ret < total_write_size) {
+ /*
+ * We've encountered a short write, for whatever reason.
+ * Set an EIO error for the next fop. This should be
+ * valid for writev or flush (close).
+ *
+ * TODO: Retry the write so we can potentially capture
+ * a real error condition (i.e., ENOSPC).
+ */
+ file->op_ret = -1;
+ file->op_errno = EIO;
+ }
+
fd = file->fd;
}
UNLOCK (&file->lock);