From d1ccc4e400728d90f2ef7904661f53deb7199123 Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Wed, 8 May 2013 08:54:11 -0400 Subject: 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 Reviewed-on: http://review.gluster.org/4969 Tested-by: Gluster Build System Reviewed-by: Anand Avati --- xlators/mount/fuse/src/fuse-bridge.c | 47 +++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) (limited to 'xlators/mount/fuse') diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 43c98a23..59472b91 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -2653,6 +2653,51 @@ fuse_readdirp (xlator_t *this, fuse_in_header_t *finh, void *msg) fuse_resolve_and_resume (state, fuse_readdirp_resume); } +static int +fuse_fallocate_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 fuse_err_cbk(frame, cookie, this, op_ret, op_errno, xdata); +} + +static void +fuse_fallocate_resume(fuse_state_t *state) +{ + gf_log("glusterfs-fuse", GF_LOG_TRACE, + "%"PRIu64": FALLOCATE (%p, flags=%d, size=%zu, offset=%"PRId64")", + state->finh->unique, state->fd, state->flags, state->size, + state->off); + + /* we only support KEEP_SIZE */ + FUSE_FOP(state, fuse_fallocate_cbk, GF_FOP_FALLOCATE, fallocate, state->fd, + (state->flags & FALLOC_FL_KEEP_SIZE), state->off, state->size, + state->xdata); +} + +static void +fuse_fallocate(xlator_t *this, fuse_in_header_t *finh, void *msg) +{ + struct fuse_fallocate_in *ffi = msg; + fuse_state_t *state = NULL; + + GET_STATE(this, finh, state); + state->off = ffi->offset; + state->size = ffi->length; + state->flags = ffi->mode; + state->fd = FH_TO_FD(ffi->fh); + + /* discard TBD as separate FOP */ + if (state->flags & FALLOC_FL_PUNCH_HOLE) { + send_fuse_err(this, finh, EOPNOTSUPP); + free_fuse_state(state); + return; + } + + fuse_resolve_fd_init(state, &state->resolve, state->fd); + fuse_resolve_and_resume(state, fuse_fallocate_resume); +} + static void fuse_releasedir (xlator_t *this, fuse_in_header_t *finh, void *msg) @@ -4861,7 +4906,7 @@ static fuse_handler_t *fuse_std_ops[FUSE_OP_HIGH] = { /* [FUSE_POLL] */ /* [FUSE_NOTIFY_REPLY] */ /* [FUSE_BATCH_FORGET] */ - /* [FUSE_FALLOCATE] */ + [FUSE_FALLOCATE] = fuse_fallocate, [FUSE_READDIRPLUS] = fuse_readdirp, }; -- cgit