summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac8
-rw-r--r--xlators/storage/posix/src/posix-messages.h18
-rw-r--r--xlators/storage/posix/src/posix.c65
3 files changed, 90 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index a02c72e0b71..e9f75a6a1b0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -901,6 +901,14 @@ if test "x${have_posix_fallocate}" = "xyes"; then
AC_DEFINE(HAVE_POSIX_FALLOCATE, 1, [define if posix_fallocate exists])
fi
+OLD_CFLAGS=${CFLAGS}
+CFLAGS="-D_GNU_SOURCE"
+AC_CHECK_DECL([SEEK_HOLE], , , [#include <unistd.h>])
+if test "x${ac_cv_have_decl_SEEK_HOLE}" = "xyes"; then
+ AC_DEFINE(HAVE_SEEK_HOLE, 1, [define if SEEK_HOLE is available])
+fi
+CFLAGS=${OLD_CFLAGS}
+
# Check the distribution where you are compiling glusterfs on
GF_DISTRIBUTION=
diff --git a/xlators/storage/posix/src/posix-messages.h b/xlators/storage/posix/src/posix-messages.h
index 961a706cc36..ad16c1dc00c 100644
--- a/xlators/storage/posix/src/posix-messages.h
+++ b/xlators/storage/posix/src/posix-messages.h
@@ -45,7 +45,7 @@
*/
#define POSIX_COMP_BASE GLFS_MSGID_COMP_POSIX
-#define GLFS_NUM_MESSAGES 105
+#define GLFS_NUM_MESSAGES 107
#define GLFS_MSGID_END (POSIX_COMP_BASE + GLFS_NUM_MESSAGES + 1)
/* Messaged with message IDs */
#define glfs_msg_start_x POSIX_COMP_BASE, "Invalid: Start of messages"
@@ -901,6 +901,22 @@
*
*/
+#define P_MSG_SEEK_UNKOWN (POSIX_COMP_BASE + 106)
+/*!
+ * @messageid
+ * @diagnosis
+ * @recommendedaction
+ *
+ */
+
+#define P_MSG_SEEK_FAILED (POSIX_COMP_BASE + 107)
+/*!
+ * @messageid
+ * @diagnosis
+ * @recommendedaction
+ *
+ */
+
/*------------*/
#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
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 = {