diff options
author | Pranith Kumar K <pranithk@gluster.com> | 2012-06-15 15:13:31 +0530 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2012-06-19 23:50:30 -0700 |
commit | 79aa6092a277975cb618d89da645080e51958543 (patch) | |
tree | 1c24f103ab1c48d3884aeafe59cfc4410c8287f7 /xlators | |
parent | d51d9b4154d6a70efcde30514620cc0442252436 (diff) |
protocol/client: Re-open should not have O_CREAT|O_TRUNC|O_EXCL
RCA
The bug is observed in 3.2.x because posix xlator changes
the uid/gid of file as per frame->root-uid/gid if O_CREAT flag
is set in open fop. Posix does not do this in 3.3.x so that
bug does not appear anymore but this issue exposed the actual
bug in client xlator re-open. Re-open of a file on re-connection
should not perform re-open with the same flags at the time of
open/create/opendir. Imagine a case where a file is opened with
O_TRUNC|O_RDWR and some data is written to it, now if the brick
goes down and comes back the file will be truncated.
When I tested this case, the file is not truncated because locks
xlator resets O_TRUNC unconditionally.
Client xlator re-open bug and locks xlator bug cancel each other.
Fix
Reset O_CREAT|O_TRUNC|O_EXCL flags in re-open.
Locks xlator should not reset O_TRUNC.
Additional changes
Removed wbflags as it is not assigned at all.
Testcases
Automated go program is at:
://bugzilla.redhat.com/show_bug.cgi?id=807976#c2
Change-Id: I0080344fdda2e62e7c976c35a5bf5f1fa8838891
BUG: 807976
Signed-off-by: Pranith Kumar K <pranithk@gluster.com>
Reviewed-on: http://review.gluster.com/3582
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com>
Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/features/locks/src/posix.c | 3 | ||||
-rw-r--r-- | xlators/protocol/client/src/client-handshake.c | 1 | ||||
-rw-r--r-- | xlators/protocol/client/src/client.h | 2 | ||||
-rw-r--r-- | xlators/protocol/client/src/client3_1-fops.c | 11 |
4 files changed, 6 insertions, 11 deletions
diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c index 2c0f583e6f7..90caadb0cc8 100644 --- a/xlators/features/locks/src/posix.c +++ b/xlators/features/locks/src/posix.c @@ -614,10 +614,9 @@ int pl_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) { - /* why isn't O_TRUNC being handled ? */ STACK_WIND (frame, pl_open_cbk, FIRST_CHILD(this), FIRST_CHILD(this)->fops->open, - loc, flags & ~O_TRUNC, fd, xdata); + loc, flags, fd, xdata); return 0; } diff --git a/xlators/protocol/client/src/client-handshake.c b/xlators/protocol/client/src/client-handshake.c index d8ca8402109..3703f93b095 100644 --- a/xlators/protocol/client/src/client-handshake.c +++ b/xlators/protocol/client/src/client-handshake.c @@ -1188,6 +1188,7 @@ protocol_client_reopen (xlator_t *this, clnt_fd_ctx_t *fdctx) memcpy (req.gfid, fdctx->gfid, 16); req.flags = gf_flags_from_flags (fdctx->flags); + req.flags = req.flags & (~(O_TRUNC|O_CREAT|O_EXCL)); gf_log (frame->this->name, GF_LOG_DEBUG, "attempting reopen on %s", local->loc.path); diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h index ac999db5a16..9d8a818aa9f 100644 --- a/xlators/protocol/client/src/client.h +++ b/xlators/protocol/client/src/client.h @@ -119,7 +119,6 @@ typedef struct _client_fd_ctx { char is_dir; char released; int32_t flags; - int32_t wbflags; fd_lk_ctx_t *lk_ctx; pthread_mutex_t mutex; lk_heal_state_t lk_heal_state; @@ -145,7 +144,6 @@ typedef struct client_local { fd_t *fd; clnt_fd_ctx_t *fdctx; uint32_t flags; - uint32_t wbflags; struct iobref *iobref; client_posix_lock_t *client_lock; diff --git a/xlators/protocol/client/src/client3_1-fops.c b/xlators/protocol/client/src/client3_1-fops.c index 76668724b5e..2356d1f8bc7 100644 --- a/xlators/protocol/client/src/client3_1-fops.c +++ b/xlators/protocol/client/src/client3_1-fops.c @@ -372,7 +372,7 @@ out: int client_add_fd_to_saved_fds (xlator_t *this, fd_t *fd, loc_t *loc, int32_t flags, - int32_t wbflags, int64_t remote_fd, int is_dir) + int64_t remote_fd, int is_dir) { int ret = 0; uuid_t gfid = {0}; @@ -397,7 +397,6 @@ client_add_fd_to_saved_fds (xlator_t *this, fd_t *fd, loc_t *loc, int32_t flags, fdctx->is_dir = is_dir; fdctx->remote_fd = remote_fd; fdctx->flags = flags; - fdctx->wbflags = wbflags; fdctx->lk_ctx = fd_lk_ctx_ref (fd->lk_ctx); fdctx->lk_heal_state = GF_LK_HEAL_DONE; @@ -452,8 +451,7 @@ client3_1_open_cbk (struct rpc_req *req, struct iovec *iov, int count, if (-1 != rsp.op_ret) { ret = client_add_fd_to_saved_fds (frame->this, fd, &local->loc, - local->flags, local->wbflags, - rsp.fd, 0); + local->flags, rsp.fd, 0); if (ret) { rsp.op_ret = -1; rsp.op_errno = -ret; @@ -2067,8 +2065,7 @@ client3_1_create_cbk (struct rpc_req *req, struct iovec *iov, int count, gf_stat_to_iatt (&rsp.postparent, &postparent); uuid_copy (local->loc.gfid, stbuf.ia_gfid); ret = client_add_fd_to_saved_fds (frame->this, fd, &local->loc, - local->flags, 0, - rsp.fd, 0); + local->flags, rsp.fd, 0); if (ret) { rsp.op_ret = -1; rsp.op_errno = -ret; @@ -2546,7 +2543,7 @@ client3_1_opendir_cbk (struct rpc_req *req, struct iovec *iov, int count, if (-1 != rsp.op_ret) { ret = client_add_fd_to_saved_fds (frame->this, fd, &local->loc, - 0, 0, rsp.fd, 1); + 0, rsp.fd, 1); if (ret) { rsp.op_ret = -1; rsp.op_errno = -ret; |