diff options
author | Niels de Vos <ndevos@redhat.com> | 2015-06-21 18:32:40 +0200 |
---|---|---|
committer | Jeff Darcy <jdarcy@redhat.com> | 2016-02-04 09:21:28 -0800 |
commit | 5c39f43c13aa652b0db28ca7afea65982bd568cc (patch) | |
tree | be31d7b0903f3c29030d504c0b65f92397573f27 /api | |
parent | b609a55be4119c44b19252bd951780a78deb21c9 (diff) |
gfapi: add support for SEEK_HOLE and SEEK_DATA in glfs_lseek()
Change-Id: I142dde11923244809b03fcca8cd4c2f7d5ff3929
BUG: 1220173
Signed-off-by: Niels de Vos <ndevos@redhat.com>
Reviewed-on: http://review.gluster.org/11485
Smoke: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: jiffin tony Thottan <jthottan@redhat.com>
Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
Diffstat (limited to 'api')
-rw-r--r-- | api/src/glfs-fops.c | 71 |
1 files changed, 69 insertions, 2 deletions
diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c index c120c950a16..d4a69f89627 100644 --- a/api/src/glfs-fops.c +++ b/api/src/glfs-fops.c @@ -9,6 +9,12 @@ cases as published by the Free Software Foundation. */ +/* for SEEK_HOLE and SEEK_DATA */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include <unistd.h> #include "glfs-internal.h" #include "glfs-mem-types.h" @@ -519,12 +525,62 @@ invalid_fs: GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_creat, 3.4.0); +#ifdef HAVE_SEEK_HOLE +static int +glfs_seek (struct glfs_fd *glfd, off_t offset, int whence) +{ + int ret = -1; + xlator_t *subvol = NULL; + fd_t *fd = NULL; + gf_seek_what_t what = 0; + off_t off = -1; + + switch (whence) { + case SEEK_DATA: + what = GF_SEEK_DATA; + break; + case SEEK_HOLE: + what = GF_SEEK_HOLE; + break; + default: + /* other SEEK_* do not make sense, all operations get an offset + * and the position in the fd is not tracked */ + errno = EINVAL; + goto out; + } + + subvol = glfs_active_subvol (glfd->fs); + if (!subvol) { + errno = EIO; + goto out; + } + + fd = glfs_resolve_fd (glfd->fs, subvol, glfd); + if (!fd) { + errno = EBADFD; + goto done; + } + + ret = syncop_seek (subvol, fd, offset, what, NULL, &off); + DECODE_SYNCOP_ERR (ret); + + if (ret != -1) + glfd->offset = off; + +done: + glfs_subvol_done (glfd->fs, subvol); + +out: + return ret; +} +#endif off_t pub_glfs_lseek (struct glfs_fd *glfd, off_t offset, int whence) { - struct stat sb = {0, }; + struct stat sb = {0, }; int ret = -1; + off_t off = -1; DECLARE_OLD_THIS; __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs); @@ -544,11 +600,22 @@ pub_glfs_lseek (struct glfs_fd *glfd, off_t offset, int whence) } glfd->offset = sb.st_size + offset; break; +#ifdef HAVE_SEEK_HOLE + case SEEK_DATA: + case SEEK_HOLE: + ret = glfs_seek (glfd, offset, whence); + break; +#endif + default: + errno = EINVAL; } __GLFS_EXIT_FS; - return glfd->offset; + if (ret != -1) + off = glfd->offset; + + return off; invalid_fs: return -1; |