diff options
| author | Brian Foster <bfoster@redhat.com> | 2013-05-08 08:54:11 -0400 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2013-06-13 14:37:21 -0700 | 
| commit | d1ccc4e400728d90f2ef7904661f53deb7199123 (patch) | |
| tree | 1c491d1932795d85941861fa683431ee22608668 /xlators/cluster/dht/src/dht-inode-write.c | |
| parent | 328ea4b16a276b0e65ca719f60b82ce851dda848 (diff) | |
gluster: add fallocate fop support
Implement support for the fallocate file operation. fallocate
allocates blocks for a particular inode such that future writes
to the associated region of the file are guaranteed not to fail
with ENOSPC.
This patch adds fallocate support to the following areas:
	- libglusterfs
	- mount/fuse
	- io-stats
	- performance/md-cache,open-behind
	- quota
	- cluster/afr,dht,stripe
	- rpc/xdr
	- protocol/client,server
	- io-threads
	- marker
	- storage/posix
	- libgfapi
BUG: 949242
Change-Id: Ice8e61351f9d6115c5df68768bc844abbf0ce8bd
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-on: http://review.gluster.org/4969
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'xlators/cluster/dht/src/dht-inode-write.c')
| -rw-r--r-- | xlators/cluster/dht/src/dht-inode-write.c | 140 | 
1 files changed, 140 insertions, 0 deletions
diff --git a/xlators/cluster/dht/src/dht-inode-write.c b/xlators/cluster/dht/src/dht-inode-write.c index b87d2f73284..56ed36ef0a9 100644 --- a/xlators/cluster/dht/src/dht-inode-write.c +++ b/xlators/cluster/dht/src/dht-inode-write.c @@ -19,6 +19,7 @@  int dht_writev2 (xlator_t *this, call_frame_t *frame, int ret);  int dht_truncate2 (xlator_t *this, call_frame_t *frame, int ret);  int dht_setattr2 (xlator_t *this, call_frame_t *frame, int ret); +int dht_fallocate2(xlator_t *this, call_frame_t *frame, int op_ret);  int  dht_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, @@ -348,6 +349,145 @@ err:          return 0;  } + +int +dht_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                  int op_ret, int op_errno, struct iatt *prebuf, +                  struct iatt *postbuf, dict_t *xdata) +{ +        dht_local_t  *local = NULL; +        call_frame_t *prev = NULL; +        int           ret = -1; + +        GF_VALIDATE_OR_GOTO ("dht", frame, err); +        GF_VALIDATE_OR_GOTO ("dht", this, out); +        GF_VALIDATE_OR_GOTO ("dht", frame->local, out); +        GF_VALIDATE_OR_GOTO ("dht", cookie, out); + +        local = frame->local; +        prev = cookie; + +        if ((op_ret == -1) && (op_errno != ENOENT)) { +                local->op_errno = op_errno; +                local->op_ret = -1; +                gf_log (this->name, GF_LOG_DEBUG, +                        "subvolume %s returned -1 (%s)", +                        prev->this->name, strerror (op_errno)); + +                goto out; +        } + +        if (local->call_cnt != 1) { +                if (local->stbuf.ia_blocks) { +                        dht_iatt_merge (this, postbuf, &local->stbuf, NULL); +                        dht_iatt_merge (this, prebuf, &local->prebuf, NULL); +                } +                goto out; +        } +        local->rebalance.target_op_fn = dht_fallocate2; + +        /* Phase 2 of migration */ +        if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2 (postbuf)) { +                ret = dht_rebalance_complete_check (this, frame); +                if (!ret) +                        return 0; +        } + +        /* Check if the rebalance phase1 is true */ +        if (IS_DHT_MIGRATION_PHASE1 (postbuf)) { +                dht_iatt_merge (this, &local->stbuf, postbuf, NULL); +                dht_iatt_merge (this, &local->prebuf, prebuf, NULL); +                ret = fd_ctx_get (local->fd, this, NULL); +                if (!ret) { +                        dht_fallocate2 (this, frame, 0); +                        return 0; +                } +                ret = dht_rebalance_in_progress_check (this, frame); +                if (!ret) +                        return 0; +        } + +out: +        DHT_STRIP_PHASE1_FLAGS (postbuf); +        DHT_STRIP_PHASE1_FLAGS (prebuf); +        DHT_STACK_UNWIND (fallocate, frame, op_ret, op_errno, +                          prebuf, postbuf, xdata); +err: +        return 0; +} + +int +dht_fallocate2(xlator_t *this, call_frame_t *frame, int op_ret) +{ +        dht_local_t  *local  = NULL; +        xlator_t     *subvol = NULL; +        uint64_t      tmp_subvol = 0; +        int           ret = -1; + +        local = frame->local; + +        if (local->fd) +                ret = fd_ctx_get (local->fd, this, &tmp_subvol); +        if (!ret) +                subvol = (xlator_t *)(long)tmp_subvol; + +        if (!subvol) +                subvol = local->cached_subvol; + +        local->call_cnt = 2; /* This is the second attempt */ + +	STACK_WIND(frame, dht_fallocate_cbk, subvol, subvol->fops->fallocate, +		   local->fd, local->rebalance.flags, local->rebalance.offset, +		   local->rebalance.size, NULL); + +        return 0; +} + +int +dht_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t mode, +	      off_t offset, size_t len, dict_t *xdata) +{ +        xlator_t     *subvol = NULL; +        int           op_errno = -1; +        dht_local_t  *local = NULL; + +        VALIDATE_OR_GOTO (frame, err); +        VALIDATE_OR_GOTO (this, err); +        VALIDATE_OR_GOTO (fd, err); + +        local = dht_local_init (frame, NULL, fd, GF_FOP_FALLOCATE); +        if (!local) { +                op_errno = ENOMEM; +                goto err; +        } + +	local->rebalance.flags = mode; +        local->rebalance.offset = offset; +	local->rebalance.size = len; + +        local->call_cnt = 1; +        subvol = local->cached_subvol; +        if (!subvol) { +                gf_log (this->name, GF_LOG_DEBUG, +                        "no cached subvolume for fd=%p", fd); +                op_errno = EINVAL; +                goto err; +        } + +        STACK_WIND (frame, dht_fallocate_cbk, +                    subvol, subvol->fops->fallocate, +                    fd, mode, offset, len, xdata); + +        return 0; + +err: +        op_errno = (op_errno == -1) ? errno : op_errno; +        DHT_STACK_UNWIND (fallocate, frame, -1, op_errno, NULL, NULL, NULL); + +        return 0; +} + +  /* handle cases of migration here for 'setattr()' calls */  int  dht_file_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,  | 
