From eaf7164ff824ad4d69cf225e49c54fc473b300b8 Mon Sep 17 00:00:00 2001 From: Xavier Hernandez Date: Sat, 8 Nov 2014 21:07:09 +0100 Subject: ec: Remove O_APPEND from flags on create and open. Allowing O_APPEND flag to pass through to the brick files corrupts fragment contents because writes are not stored on the desired place. Write fop has been modified so that it uses current file size as its write offset. This guarantees that all writes, even those comming from different file descriptors and clients, will write to the end of the file. Change-Id: I9f721f12217a98231fe52e344166d1c94172c272 BUG: 1161621 Signed-off-by: Xavier Hernandez Reviewed-on: http://review.gluster.org/9079 Tested-by: Gluster Build System Reviewed-by: Dan Lambright Reviewed-by: Vijay Bellur --- xlators/cluster/ec/src/ec-inode-write.c | 104 ++++++++++++++++---------------- 1 file changed, 53 insertions(+), 51 deletions(-) (limited to 'xlators/cluster/ec/src/ec-inode-write.c') diff --git a/xlators/cluster/ec/src/ec-inode-write.c b/xlators/cluster/ec/src/ec-inode-write.c index 9c3f6fcd115..a48ea09926a 100644 --- a/xlators/cluster/ec/src/ec-inode-write.c +++ b/xlators/cluster/ec/src/ec-inode-write.c @@ -1703,64 +1703,16 @@ out: int32_t ec_writev_init(ec_fop_data_t * fop) { - ec_t * ec = fop->xl->private; - struct iobref * iobref = NULL; - struct iobuf * iobuf = NULL; - void * ptr = NULL; ec_fd_t * ctx; ctx = ec_fd_get(fop->fd, fop->xl); - if (ctx != NULL) - { - if ((ctx->flags & O_ACCMODE) == O_RDONLY) - { + if (ctx != NULL) { + if ((ctx->flags & O_ACCMODE) == O_RDONLY) { return EBADF; } } - fop->user_size = iov_length(fop->vector, fop->int32); - fop->head = ec_adjust_offset(ec, &fop->offset, 0); - fop->size = ec_adjust_size(ec, fop->user_size + fop->head, 0); - - iobref = iobref_new(); - if (iobref == NULL) - { - goto out; - } - iobuf = iobuf_get2(fop->xl->ctx->iobuf_pool, fop->size); - if (iobuf == NULL) - { - goto out; - } - if (iobref_add(iobref, iobuf) != 0) - { - goto out; - } - - ptr = iobuf->ptr + fop->head; - ec_iov_copy_to(ptr, fop->vector, fop->int32, 0, fop->user_size); - - fop->vector[0].iov_base = iobuf->ptr; - fop->vector[0].iov_len = fop->size; - - iobuf_unref(iobuf); - - iobref_unref(fop->buffers); - fop->buffers = iobref; - return 0; - -out: - if (iobuf != NULL) - { - iobuf_unref(iobuf); - } - if (iobref != NULL) - { - iobref_unref(iobref); - } - - return EIO; } int32_t ec_writev_merge_tail(call_frame_t * frame, void * cookie, @@ -1837,9 +1789,47 @@ int32_t ec_writev_merge_head(call_frame_t * frame, void * cookie, void ec_writev_start(ec_fop_data_t * fop) { - ec_t * ec = fop->xl->private; + ec_t *ec = fop->xl->private; + struct iobref *iobref = NULL; + struct iobuf *iobuf = NULL; + void *ptr = NULL; + ec_fd_t *ctx; size_t tail; + ctx = ec_fd_get(fop->fd, fop->xl); + if (ctx != NULL) { + if ((ctx->flags & O_APPEND) != 0) { + fop->offset = fop->pre_size; + } + } + + fop->user_size = iov_length(fop->vector, fop->int32); + fop->head = ec_adjust_offset(ec, &fop->offset, 0); + fop->size = ec_adjust_size(ec, fop->user_size + fop->head, 0); + + iobref = iobref_new(); + if (iobref == NULL) { + goto out; + } + iobuf = iobuf_get2(fop->xl->ctx->iobuf_pool, fop->size); + if (iobuf == NULL) { + goto out; + } + if (iobref_add(iobref, iobuf) != 0) { + goto out; + } + + ptr = iobuf->ptr + fop->head; + ec_iov_copy_to(ptr, fop->vector, fop->int32, 0, fop->user_size); + + fop->vector[0].iov_base = iobuf->ptr; + fop->vector[0].iov_len = fop->size; + + iobuf_unref(iobuf); + + iobref_unref(fop->buffers); + fop->buffers = iobref; + if (fop->head > 0) { ec_readv(fop->frame, fop->xl, -1, EC_MINIMUM_MIN, ec_writev_merge_head, @@ -1859,6 +1849,18 @@ void ec_writev_start(ec_fop_data_t * fop) memset(fop->vector[0].iov_base + fop->size - tail, 0, tail); } } + + return; + +out: + if (iobuf != NULL) { + iobuf_unref(iobuf); + } + if (iobref != NULL) { + iobref_unref(iobref); + } + + ec_fop_set_error(fop, EIO); } int32_t ec_combine_writev(ec_fop_data_t * fop, ec_cbk_data_t * dst, -- cgit