diff options
| author | karthik-us <ksubrahm@redhat.com> | 2018-02-23 15:12:19 +0530 | 
|---|---|---|
| committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2018-03-02 05:28:00 +0000 | 
| commit | 11b3bbd649e15645c916c202d1e521d141f5130b (patch) | |
| tree | 6e306e44b86c25c14705b1f3880f0e22c55f107e | |
| parent | a42137eee3c9e340ac9c82ebacca14eeb4b9d912 (diff) | |
cluster/afr: Make afr_fsync a transaction
Change-Id: I713401feb96393f668efb074f2d5b870d19e6fda
BUG: 1548361
Signed-off-by: karthik-us <ksubrahm@redhat.com>
| -rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 163 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-inode-write.c | 108 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr-inode-write.h | 4 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr.c | 2 | ||||
| -rw-r--r-- | xlators/cluster/afr/src/afr.h | 4 | 
5 files changed, 117 insertions, 164 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index ea3df12b8bb..0052968e0e4 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -3503,169 +3503,6 @@ out:          return 0;  } -/* }}} */ - - -/* {{{ fsync */ - -int -afr_fsync_unwind_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -                      int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -                      struct iatt *postbuf, dict_t *xdata) -{ -        AFR_STACK_UNWIND (fsync, frame, op_ret, op_errno, prebuf, postbuf, -                          xdata); -        return 0; -} - -int -afr_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -               int32_t op_ret, int32_t op_errno, struct iatt *prebuf, -               struct iatt *postbuf, dict_t *xdata) -{ -        afr_local_t *local = NULL; -        afr_private_t *priv = NULL; -        int i = 0; -        int call_count = -1; -        int child_index = (long) cookie; -	int read_subvol = 0; -	call_stub_t *stub = NULL; - -        local = frame->local; -        priv = this->private; - -        LOCK (&frame->lock); -        { -                local->replies[child_index].valid = 1; -                local->replies[child_index].op_ret = op_ret; -                local->replies[child_index].op_errno = op_errno; -                if (op_ret == 0) { -                        if (prebuf) -                                local->replies[child_index].prestat = *prebuf; -                        if (postbuf) -                                local->replies[child_index].poststat = *postbuf; -                        if (xdata) -                                local->replies[child_index].xdata = -                                        dict_ref (xdata); -                } -        } -        UNLOCK (&frame->lock); - -        call_count = afr_frame_return (frame); - -        if (call_count == 0) { -                local->op_ret = -1; -                local->op_errno = afr_final_errno (local, priv); -	        read_subvol = afr_data_subvol_get (local->inode, this, NULL, -                                                   local->readable, NULL, NULL); -                /* Pick a reply that is valid and readable, with a preference -                 * given to read_subvol. */ -                for (i = 0; i < priv->child_count; i++) { -                        if (!local->replies[i].valid) -                                continue; -                        if (local->replies[i].op_ret != 0) -                                continue; -                        if (!local->readable[i]) -                                continue; -                        local->op_ret = local->replies[i].op_ret; -                        local->op_errno = local->replies[i].op_errno; -                        local->cont.inode_wfop.prebuf = -                                local->replies[i].prestat; -                        local->cont.inode_wfop.postbuf = -                                local->replies[i].poststat; -                        if (local->replies[i].xdata) { -                                if (local->xdata_rsp) -                                        dict_unref (local->xdata_rsp); -                                local->xdata_rsp = -                                        dict_ref (local->replies[i].xdata); -                        } -                        if (i == read_subvol) -                                break; -                } - -		/* Make a stub out of the frame, and register it -		   with the waking up post-op. When the call-stub resumes, -		   we are guaranteed that there was no post-op pending -		   (i.e changelogs were unset in the server). This is an -		   essential "guarantee", that fsync() returns only after -		   completely finishing EVERYTHING, including the delayed -		   post-op. This guarantee is expected by FUSE graph switching -		   for example. -		*/ -		stub = fop_fsync_cbk_stub (frame, afr_fsync_unwind_cbk, -                                           local->op_ret, local->op_errno, -                                           &local->cont.inode_wfop.prebuf, -                                           &local->cont.inode_wfop.postbuf, -                                           local->xdata_rsp); -		if (!stub) { -			AFR_STACK_UNWIND (fsync, frame, -1, ENOMEM, 0, 0, 0); -			return 0; -		} - -		/* If no new unstable writes happened between the -		   time we cleared the unstable write witness flag in afr_fsync -		   and now, calling afr_delayed_changelog_wake_up() should -		   wake up and skip over the fsync phase and go straight to -		   afr_changelog_post_op_now() -		*/ -		afr_delayed_changelog_wake_resume (this, local->fd, stub); -        } - -        return 0; -} - - -int -afr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, -	   dict_t *xdata) -{ -	afr_private_t *priv = NULL; -        afr_local_t *local = NULL; -        int i = 0; -        int32_t call_count = 0; -        int32_t op_errno = ENOMEM; - -	priv = this->private; - -	local = AFR_FRAME_INIT (frame, op_errno); -	if (!local) -		goto out; - -        local->op = GF_FOP_FSYNC; -	if (!afr_is_consistent_io_possible (local, priv, &op_errno)) -		goto out; - -        local->fd = fd_ref (fd); - -	if (afr_fd_has_witnessed_unstable_write (this, fd)) { -		/* don't care. we only wanted to CLEAR the bit */ -	} - -	local->inode = inode_ref (fd->inode); - -        call_count = local->call_count; -        for (i = 0; i < priv->child_count; i++) { -                if (local->child_up[i]) { -                        STACK_WIND_COOKIE (frame, afr_fsync_cbk, -                                           (void *) (long) i, -                                           priv->children[i], -                                           priv->children[i]->fops->fsync, -                                           fd, datasync, xdata); -                        if (!--call_count) -                                break; -                } -        } - -	return 0; -out: -	AFR_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL, NULL); - -        return 0; -} - -/* }}} */ - -/* {{{ fsync */  int  afr_fsyncdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c index 89ec6ee4d61..60c459d8463 100644 --- a/xlators/cluster/afr/src/afr-inode-write.c +++ b/xlators/cluster/afr/src/afr-inode-write.c @@ -2542,3 +2542,111 @@ out:  	AFR_STACK_UNWIND (fxattrop, frame, -1, op_errno, NULL, NULL);          return 0;  } + + +int +afr_fsync_unwind (call_frame_t *frame, xlator_t *this) +{ +        afr_local_t *local = NULL; +        call_frame_t   *main_frame = NULL; + +        local = frame->local; + +        main_frame = afr_transaction_detach_fop_frame (frame); +        if (!main_frame) +                return 0; + +        AFR_STACK_UNWIND (fsync, main_frame, local->op_ret, local->op_errno, +                          &local->cont.inode_wfop.prebuf, +                          &local->cont.inode_wfop.postbuf, local->xdata_rsp); + +        return 0; +} + + +int +afr_fsync_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                    int32_t op_ret, int32_t op_errno, struct iatt *prebuf, +                    struct iatt *postbuf, dict_t *xdata) +{ +        return __afr_inode_write_cbk (frame, cookie, this, op_ret, op_errno, +                                      prebuf, postbuf, NULL, xdata); +} + + +int +afr_fsync_wind (call_frame_t *frame, xlator_t *this, int subvol) +{ +        afr_local_t *local = NULL; +        afr_private_t *priv = NULL; + +        local = frame->local; +        priv = this->private; + +        STACK_WIND_COOKIE (frame, afr_fsync_wind_cbk, (void *)(long) subvol, +                           priv->children[subvol], +                           priv->children[subvol]->fops->fsync, +                           local->fd, local->cont.fsync.datasync, +                           local->xdata_req); +        return 0; +} + +int +afr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, +	   dict_t *xdata) +{ +        afr_local_t *local = NULL; +        call_frame_t *transaction_frame = NULL; +        int ret = -1; +        int32_t op_errno = ENOMEM; + +        transaction_frame = copy_frame (frame); +        if (!transaction_frame) +                goto out; + +	local = AFR_FRAME_INIT (transaction_frame, op_errno); +	if (!local) +		goto out; + +        if (xdata) +                local->xdata_req = dict_copy_with_ref (xdata, NULL); +        else +                local->xdata_req = dict_new (); + +        if (!local->xdata_req) +                goto out; + +        local->fd = fd_ref (fd); +        ret = afr_set_inode_local (this, local, fd->inode); +        if (ret) +                goto out; + +        local->op = GF_FOP_FSYNC; +        local->cont.fsync.datasync = datasync; + +	if (afr_fd_has_witnessed_unstable_write (this, fd)) { +		/* don't care. we only wanted to CLEAR the bit */ +	} + +        local->transaction.wind   = afr_fsync_wind; +        local->transaction.fop    = __afr_txn_write_fop; +        local->transaction.done   = __afr_txn_write_done; +        local->transaction.unwind = afr_fsync_unwind; + +        local->transaction.main_frame = frame; + +        ret = afr_transaction (transaction_frame, this, AFR_DATA_TRANSACTION); +        if (ret < 0) { +                op_errno = -ret; +                goto out; +        } + +	return 0; +out: +	if (transaction_frame) +		AFR_STACK_DESTROY (transaction_frame); + +	AFR_STACK_UNWIND (fsync, frame, -1, op_errno, NULL, NULL, NULL); + +        return 0; +} diff --git a/xlators/cluster/afr/src/afr-inode-write.h b/xlators/cluster/afr/src/afr-inode-write.h index e174cc2d610..1e8bb5c12b3 100644 --- a/xlators/cluster/afr/src/afr-inode-write.h +++ b/xlators/cluster/afr/src/afr-inode-write.h @@ -87,4 +87,8 @@ afr_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc,  int32_t  afr_fxattrop (call_frame_t *frame, xlator_t *this, fd_t *fd,                gf_xattrop_flags_t optype, dict_t *xattr, dict_t *xdata); + +int +afr_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync, +	   dict_t *xdata);  #endif /* __INODE_WRITE_H__ */ diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c index 10e81138aea..3467729c345 100644 --- a/xlators/cluster/afr/src/afr.c +++ b/xlators/cluster/afr/src/afr.c @@ -636,7 +636,6 @@ struct xlator_fops fops = {          .lk          = afr_lk,          .flush       = afr_flush,          .statfs      = afr_statfs, -        .fsync       = afr_fsync,          .fsyncdir    = afr_fsyncdir,          .inodelk     = afr_inodelk,          .finodelk    = afr_finodelk, @@ -668,6 +667,7 @@ struct xlator_fops fops = {          .zerofill    = afr_zerofill,          .xattrop     = afr_xattrop,          .fxattrop    = afr_fxattrop, +        .fsync       = afr_fsync,          /*inode open*/          .opendir     = afr_opendir, diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index fdda295718c..88d80f07a3c 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -725,6 +725,10 @@ typedef struct _afr_local {                          gf_seek_what_t what;                  } seek; +                struct { +                        int32_t datasync; +                } fsync; +          } cont;          struct {  | 
