readdir-ahead: do not zero-out iatt in fop cbk

...when ctime is zero. ia_type and ia_gfid always need to be non-zero
for things to work correctly.

Problem:
Commit c9bde3021202f1d5c5a2d19ac05a510fc1f788ac zeroed out the iatt
buffer in the cbks of modification fops before unwinding if the ctime in
the buffer was zero. This was causing the fops to fail: noticeable when
AFR's 'consistent-metadata' option was enabled. (AFR zeros out the ctime
when the option is set. See commit
4c4624c9bad2edf27128cb122c64f15d7d63bbc8).

Fixes:
-Do not zero out the ia_type and ia_gfid of the iatt buff under any
circumstance.
-Also, fixed _rda_inode_ctx_update_iatts() to always update these values from
the incoming buf when ctime is zero. Otherwise we end up with zero
ia_type and ia_gfid the first time the function is called *and* the
incoming buf has ctime set to zero.

fixes: bz#1670253
Reported-By:Michael Hanselmann <public@hansmi.ch>
Change-Id: Ib72228892d42c3513c19fc6dfb543f2aa3489eca
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
This commit is contained in:
Ravishankar N 2019-01-29 11:51:16 +05:30 committed by Raghavendra G
parent 4aee035cd2
commit 09db11b0c0
2 changed files with 27 additions and 20 deletions

View File

@ -0,0 +1,23 @@
#!/bin/bash
. $(dirname $0)/../../include.rc
. $(dirname $0)/../../volume.rc
cleanup;
TEST glusterd
TEST $CLI volume create $V0 replica 3 $H0:$B0/${V0}{0,1,2}
TEST $CLI volume set $V0 readdir-ahead on #on by default as of writing this .t.
TEST $CLI volume set $V0 consistent-metadata on
TEST $CLI volume start $V0
TEST glusterfs --volfile-server=$H0 --volfile-id=$V0 $M0
TEST touch $M0/FILE
echo "abc" >> $M0/FILE
EXPECT "^0$" echo $?
EXPECT "abc" cat $M0/FILE
echo "truncate" >$M0/FILE
EXPECT "^0$" echo $?
EXPECT "truncate" cat $M0/FILE
EXPECT_WITHIN $UMOUNT_TIMEOUT "Y" force_umount $M0
cleanup;

View File

@ -129,7 +129,10 @@ __rda_inode_ctx_update_iatts(inode_t *inode, xlator_t *this,
* An example of this case can be response of write request
* that is cached in write-behind.
*/
tmp_stat = ctx_p->statbuf;
if (stbuf_in)
tmp_stat = *stbuf_in;
else
tmp_stat = ctx_p->statbuf;
memset(&ctx_p->statbuf, 0, sizeof(ctx_p->statbuf));
gf_uuid_copy(ctx_p->statbuf.ia_gfid, tmp_stat.ia_gfid);
ctx_p->statbuf.ia_type = tmp_stat.ia_type;
@ -768,8 +771,6 @@ rda_writev_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
rda_inode_ctx_update_iatts(local->inode, this, postbuf, &postbuf_out,
local->generation);
if (postbuf_out.ia_ctime == 0)
memset(&postbuf_out, 0, sizeof(postbuf_out));
unwind:
RDA_STACK_UNWIND(writev, frame, op_ret, op_errno, prebuf, &postbuf_out,
xdata);
@ -804,9 +805,6 @@ rda_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
rda_inode_ctx_update_iatts(local->inode, this, postbuf, &postbuf_out,
local->generation);
if (postbuf_out.ia_ctime == 0)
memset(&postbuf_out, 0, sizeof(postbuf_out));
unwind:
RDA_STACK_UNWIND(fallocate, frame, op_ret, op_errno, prebuf, &postbuf_out,
xdata);
@ -840,9 +838,6 @@ rda_zerofill_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
rda_inode_ctx_update_iatts(local->inode, this, postbuf, &postbuf_out,
local->generation);
if (postbuf_out.ia_ctime == 0)
memset(&postbuf_out, 0, sizeof(postbuf_out));
unwind:
RDA_STACK_UNWIND(zerofill, frame, op_ret, op_errno, prebuf, &postbuf_out,
xdata);
@ -876,8 +871,6 @@ rda_discard_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
rda_inode_ctx_update_iatts(local->inode, this, postbuf, &postbuf_out,
local->generation);
if (postbuf_out.ia_ctime == 0)
memset(&postbuf_out, 0, sizeof(postbuf_out));
unwind:
RDA_STACK_UNWIND(discard, frame, op_ret, op_errno, prebuf, &postbuf_out,
xdata);
@ -911,9 +904,6 @@ rda_ftruncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
rda_inode_ctx_update_iatts(local->inode, this, postbuf, &postbuf_out,
local->generation);
if (postbuf_out.ia_ctime == 0)
memset(&postbuf_out, 0, sizeof(postbuf_out));
unwind:
RDA_STACK_UNWIND(ftruncate, frame, op_ret, op_errno, prebuf, &postbuf_out,
xdata);
@ -946,8 +936,6 @@ rda_truncate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
rda_mark_inode_dirty(this, local->inode);
rda_inode_ctx_update_iatts(local->inode, this, postbuf, &postbuf_out,
local->generation);
if (postbuf_out.ia_ctime == 0)
memset(&postbuf_out, 0, sizeof(postbuf_out));
unwind:
RDA_STACK_UNWIND(ftruncate, frame, op_ret, op_errno, prebuf, &postbuf_out,
@ -1035,8 +1023,6 @@ rda_setattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
rda_mark_inode_dirty(this, local->inode);
rda_inode_ctx_update_iatts(local->inode, this, statpost, &postbuf_out,
local->generation);
if (postbuf_out.ia_ctime == 0)
memset(&postbuf_out, 0, sizeof(postbuf_out));
unwind:
RDA_STACK_UNWIND(setattr, frame, op_ret, op_errno, statpre, &postbuf_out,
@ -1070,8 +1056,6 @@ rda_fsetattr_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
rda_mark_inode_dirty(this, local->inode);
rda_inode_ctx_update_iatts(local->inode, this, statpost, &postbuf_out,
local->generation);
if (postbuf_out.ia_ctime == 0)
memset(&postbuf_out, 0, sizeof(postbuf_out));
unwind:
RDA_STACK_UNWIND(fsetattr, frame, op_ret, op_errno, statpre, &postbuf_out,