diff options
author | Xavier Hernandez <xhernandez@datalab.es> | 2014-11-08 21:07:09 +0100 |
---|---|---|
committer | Raghavendra Bhat <raghavendra@redhat.com> | 2014-12-18 06:36:43 -0800 |
commit | 2372a9ed54f6e30e3ac744e1daf8ec379dd236ae (patch) | |
tree | b93c44f0a169c32f0de0a7b6af33e01ffc7319fa /xlators/cluster/ec | |
parent | ad16db31df793d90a40fbfced82cae1c86d94658 (diff) |
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.
This is backport of http://review.gluster.org/9079/
Change-Id: I9f721f12217a98231fe52e344166d1c94172c272
BUG: 1161885
Signed-off-by: Xavier Hernandez <xhernandez@datalab.es>
Reviewed-on: http://review.gluster.org/9080
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Dan Lambright <dlambrig@redhat.com>
Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com>
Tested-by: Raghavendra Bhat <raghavendra@redhat.com>
Diffstat (limited to 'xlators/cluster/ec')
-rw-r--r-- | xlators/cluster/ec/src/ec-dir-write.c | 4 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec-heal.c | 2 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec-inode-read.c | 3 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec-inode-write.c | 104 |
4 files changed, 60 insertions, 53 deletions
diff --git a/xlators/cluster/ec/src/ec-dir-write.c b/xlators/cluster/ec/src/ec-dir-write.c index 6aa9badb76b..e1bbf7bae15 100644 --- a/xlators/cluster/ec/src/ec-dir-write.c +++ b/xlators/cluster/ec/src/ec-dir-write.c @@ -194,7 +194,9 @@ int32_t ec_manager_create(ec_fop_data_t * fop, int32_t state) return EC_STATE_REPORT; } - fop->int32 &= ~O_ACCMODE; + /* We need to write to specific offsets on the bricks, so we + * need to remove O_APPEND from flags (if present) */ + fop->int32 &= ~(O_ACCMODE | O_APPEND); fop->int32 |= O_RDWR; /* Fall through */ diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c index 73df4eab8f6..956d70a93fd 100644 --- a/xlators/cluster/ec/src/ec-heal.c +++ b/xlators/cluster/ec/src/ec-heal.c @@ -989,7 +989,7 @@ void ec_heal_reopen_fd(ec_heal_t * heal) } else { - flags = ctx_fd->flags & ~O_TRUNC; + flags = ctx_fd->flags & ~(O_TRUNC | O_APPEND); if ((flags & O_ACCMODE) == O_WRONLY) { flags &= ~O_ACCMODE; diff --git a/xlators/cluster/ec/src/ec-inode-read.c b/xlators/cluster/ec/src/ec-inode-read.c index 3f7920239ec..8f89224987d 100644 --- a/xlators/cluster/ec/src/ec-inode-read.c +++ b/xlators/cluster/ec/src/ec-inode-read.c @@ -674,6 +674,9 @@ int32_t ec_manager_open(ec_fop_data_t * fop, int32_t state) fop->int32 &= ~O_ACCMODE; fop->int32 |= O_RDWR; } + /* We need to write to specific offsets on the bricks, so we + * need to remove O_APPEND from flags (if present) */ + fop->int32 &= ~O_APPEND; /* Fall through */ diff --git a/xlators/cluster/ec/src/ec-inode-write.c b/xlators/cluster/ec/src/ec-inode-write.c index c120f067b6a..a0571d5a6f7 100644 --- a/xlators/cluster/ec/src/ec-inode-write.c +++ b/xlators/cluster/ec/src/ec-inode-write.c @@ -1710,64 +1710,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, @@ -1844,9 +1796,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, @@ -1866,6 +1856,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, |