diff options
author | Niels de Vos <ndevos@redhat.com> | 2015-06-21 16:59:15 +0200 |
---|---|---|
committer | Jeff Darcy <jdarcy@redhat.com> | 2016-02-10 04:38:25 -0800 |
commit | 4b725f2576b06a739e159981c6124118e26ccfbd (patch) | |
tree | 9d68096611c56d05a2a0187d815e18bf4de6df9b /xlators/storage/posix/src/posix.c | |
parent | 32935246bf884760800029cb20627ea94a865cee (diff) |
posix: implement seek() FOP
The only lseek() options we need are SEEK_HOLE and SEEK_DATA.
Change-Id: I5d15533c53fd710497f97c3cb4a8ea29fba47271
BUG: 1220173
Signed-off-by: Niels de Vos <ndevos@redhat.com>
Reviewed-on: http://review.gluster.org/11484
Smoke: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Diffstat (limited to 'xlators/storage/posix/src/posix.c')
-rw-r--r-- | xlators/storage/posix/src/posix.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index b0c23716a64..8f2296f0a17 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -9,6 +9,11 @@ */ #define __XOPEN_SOURCE 500 +/* for SEEK_HOLE and SEEK_DATA */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + #include <openssl/md5.h> #include <stdint.h> #include <sys/time.h> @@ -20,6 +25,7 @@ #include <sys/stat.h> #include <signal.h> #include <sys/uio.h> +#include <unistd.h> #ifndef GF_BSD_HOST_OS #include <alloca.h> @@ -973,6 +979,62 @@ posix_ipc (call_frame_t *frame, xlator_t *this, int32_t op, dict_t *xdata) } +#ifdef HAVE_SEEK_HOLE +static int32_t +posix_seek (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset, + gf_seek_what_t what, dict_t *xdata) +{ + struct posix_fd *pfd = NULL; + off_t ret = -1; + int err = 0; + int whence = 0; + + DECLARE_OLD_FS_ID_VAR; + + SET_FS_ID (frame->root->uid, frame->root->gid); + + VALIDATE_OR_GOTO (frame, out); + VALIDATE_OR_GOTO (this, out); + VALIDATE_OR_GOTO (fd, out); + + switch (what) { + case GF_SEEK_DATA: + whence = SEEK_DATA; + break; + case GF_SEEK_HOLE: + whence = SEEK_HOLE; + break; + default: + err = ENOTSUP; + gf_msg (this->name, GF_LOG_ERROR, ENOTSUP, + P_MSG_SEEK_UNKOWN, "don't know what to seek"); + goto out; + } + + ret = posix_fd_ctx_get (fd, this, &pfd); + if (ret < 0) { + gf_msg_debug (this->name, 0, "pfd is NULL from fd=%p", fd); + goto out; + } + + ret = lseek (pfd->fd, offset, whence); + if (ret == -1) { + err = errno; + gf_msg (this->name, GF_LOG_ERROR, err, P_MSG_SEEK_FAILED, + "seek failed on fd %d length %" PRId64 , pfd->fd, + offset); + goto out; + } + +out: + SET_TO_OLD_FS_ID (); + + STACK_UNWIND_STRICT (seek, frame, (ret == -1 ? -1 : 0), err, + (ret == -1 ? -1 : ret), xdata); + return 0; +} +#endif + int32_t posix_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd, dict_t *xdata) @@ -6998,6 +7060,9 @@ struct xlator_fops fops = { .discard = posix_discard, .zerofill = posix_zerofill, .ipc = posix_ipc, +#ifdef HAVE_SEEK_HOLE + .seek = posix_seek, +#endif }; struct xlator_cbks cbks = { |