summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/ec/src/ec-inode-write.c
diff options
context:
space:
mode:
authorXavier Hernandez <xhernandez@datalab.es>2014-11-08 21:46:41 +0100
committerPranith Kumar Karampuri <pkarampu@redhat.com>2015-01-28 19:49:29 -0800
commitb17122ffc75c65bda2cf3b3d99832bbf2718e8d3 (patch)
tree258ad51bcf7d08bccc96cd94b7440a0dce227f33 /xlators/cluster/ec/src/ec-inode-write.c
parent88136b53f59e3b81aacc28df18bda575da35b02d (diff)
ec: Fix posix compliance failures
This patch solves some problems that caused dispersed volumes to not pass posix smoke tests: * Problems in open/create with O_WRONLY Opening files with -w- permissions using O_WRONLY returned an EACCES error because internally O_WRONLY was replaced with O_RDWR. * Problems with entrylk on renames. When source and destination were the same, ec tried to acquire the same entrylk twice, causing a deadlock. * Overwrite of a variable when reordering locks. On a rename, if the second lock needed to be placed at the beggining of the list, the 'lock' variable was overwritten and later its timer was cancelled, cancelling the incorrect one. * Handle O_TRUNC in open. When O_TRUNC was received in an open call, it was blindly propagated to child subvolumes. This caused a discrepancy between real file size and the size stored into trusted.ec.size xattr. This has been solved by removing O_TRUNC from open and later calling ftruncate. Change-Id: I20c3d6e1c11be314be86879be54b728e01013798 BUG: 1161886 Signed-off-by: Xavier Hernandez <xhernandez@datalab.es> Reviewed-on: http://review.gluster.org/9420 Reviewed-by: Dan Lambright <dlambrig@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com> Tested-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Diffstat (limited to 'xlators/cluster/ec/src/ec-inode-write.c')
-rw-r--r--xlators/cluster/ec/src/ec-inode-write.c62
1 files changed, 28 insertions, 34 deletions
diff --git a/xlators/cluster/ec/src/ec-inode-write.c b/xlators/cluster/ec/src/ec-inode-write.c
index a48ea09926a..140d59f5f20 100644
--- a/xlators/cluster/ec/src/ec-inode-write.c
+++ b/xlators/cluster/ec/src/ec-inode-write.c
@@ -1248,8 +1248,6 @@ int32_t ec_truncate_open_cbk(call_frame_t * frame, void * cookie,
int32_t ec_truncate_clean(ec_fop_data_t * fop)
{
- ec_fd_t * ctx;
-
if (fop->fd == NULL)
{
fop->fd = fd_create(fop->loc[0].inode, fop->frame->root->pid);
@@ -1257,13 +1255,6 @@ int32_t ec_truncate_clean(ec_fop_data_t * fop)
{
return 0;
}
- ctx = ec_fd_get(fop->fd, fop->xl);
- if ((ctx == NULL) || (loc_copy(&ctx->loc, &fop->loc[0]) != 0))
- {
- return 0;
- }
-
- ctx->flags = O_RDWR;
ec_open(fop->frame, fop->xl, fop->answer->mask, fop->minimum,
ec_truncate_open_cbk, fop, &fop->loc[0], O_RDWR, fop->fd,
@@ -1701,20 +1692,6 @@ out:
/* FOP: writev */
-int32_t ec_writev_init(ec_fop_data_t * fop)
-{
- ec_fd_t * ctx;
-
- ctx = ec_fd_get(fop->fd, fop->xl);
- if (ctx != NULL) {
- if ((ctx->flags & O_ACCMODE) == O_RDONLY) {
- return EBADF;
- }
- }
-
- return 0;
-}
-
int32_t ec_writev_merge_tail(call_frame_t * frame, void * cookie,
xlator_t * this, int32_t op_ret, int32_t op_errno,
struct iovec * vector, int32_t count,
@@ -1787,14 +1764,29 @@ int32_t ec_writev_merge_head(call_frame_t * frame, void * cookie,
return 0;
}
-void ec_writev_start(ec_fop_data_t * fop)
+void ec_writev_start(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;
+ fd_t *fd;
size_t tail;
+ uid_t uid;
+ gid_t gid;
+
+ fd = fd_anonymous(fop->fd->inode);
+ if (fd == NULL) {
+ ec_fop_set_error(fop, EIO);
+
+ return;
+ }
+
+ uid = fop->frame->root->uid;
+ fop->frame->root->uid = 0;
+ gid = fop->frame->root->gid;
+ fop->frame->root->gid = 0;
ctx = ec_fd_get(fop->fd, fop->xl);
if (ctx != NULL) {
@@ -1833,7 +1825,7 @@ void ec_writev_start(ec_fop_data_t * fop)
if (fop->head > 0)
{
ec_readv(fop->frame, fop->xl, -1, EC_MINIMUM_MIN, ec_writev_merge_head,
- NULL, fop->fd, ec->stripe_size, fop->offset, 0, NULL);
+ NULL, fd, ec->stripe_size, fop->offset, 0, NULL);
}
tail = fop->size - fop->user_size - fop->head;
if ((tail > 0) && ((fop->head == 0) || (fop->size > ec->stripe_size)))
@@ -1841,7 +1833,7 @@ void ec_writev_start(ec_fop_data_t * fop)
if (fop->pre_size > fop->offset + fop->head + fop->user_size)
{
ec_readv(fop->frame, fop->xl, -1, EC_MINIMUM_MIN,
- ec_writev_merge_tail, NULL, fop->fd, ec->stripe_size,
+ ec_writev_merge_tail, NULL, fd, ec->stripe_size,
fop->offset + fop->size - ec->stripe_size, 0, NULL);
}
else
@@ -1850,6 +1842,11 @@ void ec_writev_start(ec_fop_data_t * fop)
}
}
+ fop->frame->root->uid = uid;
+ fop->frame->root->gid = gid;
+
+ fd_unref(fd);
+
return;
out:
@@ -1860,6 +1857,11 @@ out:
iobref_unref(iobref);
}
+ fop->frame->root->uid = uid;
+ fop->frame->root->gid = gid;
+
+ fd_unref(fd);
+
ec_fop_set_error(fop, EIO);
}
@@ -2007,14 +2009,6 @@ int32_t ec_manager_writev(ec_fop_data_t * fop, int32_t state)
switch (state)
{
case EC_STATE_INIT:
- fop->error = ec_writev_init(fop);
- if (fop->error != 0)
- {
- return EC_STATE_REPORT;
- }
-
- /* Fall through */
-
case EC_STATE_LOCK:
ec_lock_prepare_fd(fop, fop->fd, 1);
ec_lock(fop);