summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2013-05-08 08:54:11 -0400
committerAnand Avati <avati@redhat.com>2013-06-13 14:37:21 -0700
commitd1ccc4e400728d90f2ef7904661f53deb7199123 (patch)
tree1c491d1932795d85941861fa683431ee22608668 /libglusterfs/src
parent328ea4b16a276b0e65ca719f60b82ce851dda848 (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 'libglusterfs/src')
-rw-r--r--libglusterfs/src/call-stub.c65
-rw-r--r--libglusterfs/src/call-stub.h16
-rw-r--r--libglusterfs/src/compat.h6
-rw-r--r--libglusterfs/src/defaults.c29
-rw-r--r--libglusterfs/src/defaults.h18
-rw-r--r--libglusterfs/src/globals.c1
-rw-r--r--libglusterfs/src/glusterfs.h1
-rw-r--r--libglusterfs/src/syncop.c31
-rw-r--r--libglusterfs/src/syncop.h2
-rw-r--r--libglusterfs/src/syscall.c23
-rw-r--r--libglusterfs/src/syscall.h2
-rw-r--r--libglusterfs/src/xlator.c1
-rw-r--r--libglusterfs/src/xlator.h17
13 files changed, 212 insertions, 0 deletions
diff --git a/libglusterfs/src/call-stub.c b/libglusterfs/src/call-stub.c
index bd81c4ed2..2bb993411 100644
--- a/libglusterfs/src/call-stub.c
+++ b/libglusterfs/src/call-stub.c
@@ -2130,6 +2130,61 @@ out:
return stub;
}
+call_stub_t *
+fop_fallocate_cbk_stub(call_frame_t *frame, fop_fallocate_cbk_t fn,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost,
+ dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+
+ stub = stub_new (frame, 0, GF_FOP_FALLOCATE);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+
+ stub->fn_cbk.fallocate = fn;
+
+ stub->args_cbk.op_ret = op_ret;
+ stub->args_cbk.op_errno = op_errno;
+
+ if (statpre)
+ stub->args_cbk.prestat = *statpre;
+ if (statpost)
+ stub->args_cbk.poststat = *statpost;
+ if (xdata)
+ stub->args_cbk.xdata = dict_ref (xdata);
+out:
+ return stub;
+}
+
+call_stub_t *
+fop_fallocate_stub(call_frame_t *frame, fop_fallocate_t fn, fd_t *fd,
+ int32_t mode, off_t offset, size_t len, dict_t *xdata)
+{
+ call_stub_t *stub = NULL;
+
+ GF_VALIDATE_OR_GOTO ("call-stub", frame, out);
+ GF_VALIDATE_OR_GOTO ("call-stub", fn, out);
+
+ stub = stub_new (frame, 1, GF_FOP_FALLOCATE);
+ GF_VALIDATE_OR_GOTO ("call-stub", stub, out);
+
+ stub->fn.fallocate = fn;
+
+ if (fd)
+ stub->args.fd = fd_ref (fd);
+
+ stub->args.flags = mode;
+ stub->args.offset = offset;
+ stub->args.size = len;
+
+ if (xdata)
+ stub->args.xdata = dict_ref (xdata);
+out:
+ return stub;
+
+}
static void
call_resume_wind (call_stub_t *stub)
@@ -2347,6 +2402,12 @@ call_resume_wind (call_stub_t *stub)
stub->args.fd, &stub->args.stat,
stub->args.valid, stub->args.xdata);
break;
+ case GF_FOP_FALLOCATE:
+ stub->fn.fallocate(stub->frame, stub->frame->this,
+ stub->args.fd, stub->args.flags,
+ stub->args.offset, stub->args.size,
+ stub->args.xdata);
+ break;
default:
gf_log_callingfn ("call-stub", GF_LOG_ERROR,
"Invalid value of FOP (%d)",
@@ -2541,6 +2602,10 @@ call_resume_unwind (call_stub_t *stub)
STUB_UNWIND (stub, fsetattr, &stub->args_cbk.prestat,
&stub->args_cbk.poststat, stub->args_cbk.xdata);
break;
+ case GF_FOP_FALLOCATE:
+ STUB_UNWIND(stub, fallocate, &stub->args_cbk.prestat,
+ &stub->args_cbk.poststat, stub->args_cbk.xdata);
+ break;
default:
gf_log_callingfn ("call-stub", GF_LOG_ERROR,
"Invalid value of FOP (%d)",
diff --git a/libglusterfs/src/call-stub.h b/libglusterfs/src/call-stub.h
index 335111835..d940fe6f1 100644
--- a/libglusterfs/src/call-stub.h
+++ b/libglusterfs/src/call-stub.h
@@ -69,6 +69,7 @@ typedef struct {
fop_fxattrop_t fxattrop;
fop_setattr_t setattr;
fop_fsetattr_t fsetattr;
+ fop_fallocate_t fallocate;
} fn;
union {
@@ -113,6 +114,7 @@ typedef struct {
fop_fxattrop_cbk_t fxattrop;
fop_setattr_cbk_t setattr;
fop_fsetattr_cbk_t fsetattr;
+ fop_fallocate_cbk_t fallocate;
} fn_cbk;
struct {
@@ -713,6 +715,20 @@ fop_fsetattr_cbk_stub (call_frame_t *frame,
struct iatt *statpre,
struct iatt *statpost, dict_t *xdata);
+call_stub_t *
+fop_fallocate_stub(call_frame_t *frame,
+ fop_fallocate_t fn,
+ fd_t *fd,
+ int32_t mode, off_t offset,
+ size_t len, dict_t *xdata);
+
+call_stub_t *
+fop_fallocate_cbk_stub(call_frame_t *frame,
+ fop_fallocate_cbk_t fn,
+ int32_t op_ret, int32_t op_errno,
+ struct iatt *statpre, struct iatt *statpost,
+ dict_t *xdata);
+
void call_resume (call_stub_t *stub);
void call_stub_destroy (call_stub_t *stub);
void call_unwind_error (call_stub_t *stub, int op_ret, int op_errno);
diff --git a/libglusterfs/src/compat.h b/libglusterfs/src/compat.h
index 3d0cee1a9..2bd982541 100644
--- a/libglusterfs/src/compat.h
+++ b/libglusterfs/src/compat.h
@@ -32,6 +32,12 @@
#include <linux/limits.h>
#include <sys/xattr.h>
#include <endian.h>
+#ifdef HAVE_FALLOC_H
+#include <linux/falloc.h>
+#else
+#define FALLOC_FL_KEEP_SIZE 0x01 /* default is extend size */
+#define FALLOC_FL_PUNCH_HOLE 0x02 /* de-allocates range */
+#endif
#ifndef HAVE_LLISTXATTR
diff --git a/libglusterfs/src/defaults.c b/libglusterfs/src/defaults.c
index 5bac845c1..32454a1e9 100644
--- a/libglusterfs/src/defaults.c
+++ b/libglusterfs/src/defaults.c
@@ -455,6 +455,15 @@ default_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
}
int32_t
+default_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata)
+{
+ STACK_UNWIND_STRICT(fallocate, frame, op_ret, op_errno, pre, post, xdata);
+ return 0;
+}
+
+int32_t
default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, char *spec_data)
{
@@ -862,6 +871,17 @@ default_fsetattr_resume (call_frame_t *frame, xlator_t *this, fd_t *fd,
return 0;
}
+int32_t
+default_fallocate_resume(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t keep_size, off_t offset, size_t len, dict_t *xdata)
+{
+ STACK_WIND(frame, default_fallocate_cbk, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fallocate, fd, keep_size, offset, len,
+ xdata);
+ return 0;
+}
+
+
/* FOPS */
int32_t
@@ -1266,6 +1286,15 @@ default_fsetattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
return 0;
}
+int32_t
+default_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd,
+ int32_t keep_size, off_t offset, size_t len, dict_t *xdata)
+{
+ STACK_WIND_TAIL(frame, FIRST_CHILD(this),
+ FIRST_CHILD(this)->fops->fallocate, fd, keep_size, offset,
+ len, xdata);
+ return 0;
+}
int32_t
default_forget (xlator_t *this, inode_t *inode)
diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h
index 8a9de7899..bc2f6429b 100644
--- a/libglusterfs/src/defaults.h
+++ b/libglusterfs/src/defaults.h
@@ -243,6 +243,12 @@ int32_t default_fsetattr (call_frame_t *frame,
struct iatt *stbuf,
int32_t valid, dict_t *xdata);
+int32_t default_fallocate(call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t keep_size, off_t offset,
+ size_t len, dict_t *xdata);
+
/* Resume */
int32_t default_getspec_resume (call_frame_t *frame,
xlator_t *this,
@@ -453,6 +459,13 @@ int32_t default_fsetattr_resume (call_frame_t *frame,
struct iatt *stbuf,
int32_t valid, dict_t *xdata);
+int32_t default_fallocate_resume(call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t keep_size, off_t offset,
+ size_t len, dict_t *xdata);
+
+
/* _cbk */
int32_t
@@ -663,6 +676,11 @@ default_fsetattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *statpre,
struct iatt *statpost, dict_t *xdata);
+int32_t default_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *pre,
+ struct iatt *post, dict_t *xdata);
+
+
int32_t
default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, char *spec_data);
diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c
index 05ff52c2c..ba5075b2e 100644
--- a/libglusterfs/src/globals.c
+++ b/libglusterfs/src/globals.c
@@ -67,6 +67,7 @@ const char *gf_fop_list[GF_FOP_MAXVALUE] = {
[GF_FOP_RELEASE] = "RELEASE",
[GF_FOP_RELEASEDIR] = "RELEASEDIR",
[GF_FOP_FREMOVEXATTR]= "FREMOVEXATTR",
+ [GF_FOP_FALLOCATE] = "FALLOCATE",
};
/* THIS */
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
index 8ee55c706..013cdfffa 100644
--- a/libglusterfs/src/glusterfs.h
+++ b/libglusterfs/src/glusterfs.h
@@ -197,6 +197,7 @@ typedef enum {
GF_FOP_RELEASEDIR,
GF_FOP_GETSPEC,
GF_FOP_FREMOVEXATTR,
+ GF_FOP_FALLOCATE,
GF_FOP_MAXVALUE,
} glusterfs_fop_t;
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c
index 8e5db41fd..f57e8da5a 100644
--- a/libglusterfs/src/syncop.c
+++ b/libglusterfs/src/syncop.c
@@ -1917,6 +1917,37 @@ syncop_access (xlator_t *subvol, loc_t *loc, int32_t mask)
int
+syncop_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)
+{
+ struct syncargs *args = NULL;
+
+ args = cookie;
+
+ args->op_ret = op_ret;
+ args->op_errno = op_errno;
+
+ __wake (args);
+
+ return 0;
+}
+
+int
+syncop_fallocate(xlator_t *subvol, fd_t *fd, int32_t keep_size, off_t offset,
+ size_t len)
+{
+ struct syncargs args = {0, };
+
+ SYNCOP (subvol, (&args), syncop_fallocate_cbk, subvol->fops->fallocate,
+ fd, keep_size, offset, len, NULL);
+
+ errno = args.op_errno;
+ return args.op_ret;
+}
+
+
+int
syncop_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, struct gf_flock *flock,
dict_t *xdata)
diff --git a/libglusterfs/src/syncop.h b/libglusterfs/src/syncop.h
index 98e88ff37..59e62ad14 100644
--- a/libglusterfs/src/syncop.h
+++ b/libglusterfs/src/syncop.h
@@ -333,6 +333,8 @@ int syncop_mkdir (xlator_t *subvol, loc_t *loc, mode_t mode, dict_t *dict,
int syncop_link (xlator_t *subvol, loc_t *oldloc, loc_t *newloc);
int syncop_fsyncdir (xlator_t *subvol, fd_t *fd, int datasync);
int syncop_access (xlator_t *subvol, loc_t *loc, int32_t mask);
+int syncop_fallocate(xlator_t *subvol, fd_t *fd, int32_t keep_size, off_t offset,
+ size_t len);
int syncop_rename (xlator_t *subvol, loc_t *oldloc, loc_t *newloc);
diff --git a/libglusterfs/src/syscall.c b/libglusterfs/src/syscall.c
index bb834dbfd..e8954cc23 100644
--- a/libglusterfs/src/syscall.c
+++ b/libglusterfs/src/syscall.c
@@ -458,3 +458,26 @@ sys_access (const char *pathname, int mode)
{
return access (pathname, mode);
}
+
+
+int
+sys_fallocate(int fd, int mode, off_t offset, off_t len)
+{
+#ifdef HAVE_FALLOCATE
+ return fallocate(fd, mode, offset, len);
+#endif
+
+#ifdef HAVE_POSIX_FALLOCATE
+ if (mode) {
+ /* keep size not supported */
+ errno = EOPNOTSUPP;
+ return -1;
+ }
+
+ return posix_fallocate(fd, offset, len);
+#endif
+
+ errno = ENOSYS;
+ return -1;
+}
+
diff --git a/libglusterfs/src/syscall.h b/libglusterfs/src/syscall.h
index d5c6ce5f6..f1c9f58c3 100644
--- a/libglusterfs/src/syscall.h
+++ b/libglusterfs/src/syscall.h
@@ -139,4 +139,6 @@ sys_access (const char *pathname, int mode);
int
sys_ftruncate (int fd, off_t length);
+int sys_fallocate(int fd, int mode, off_t offset, off_t len);
+
#endif /* __SYSCALL_H__ */
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c
index f9e5db671..1926240e8 100644
--- a/libglusterfs/src/xlator.c
+++ b/libglusterfs/src/xlator.c
@@ -79,6 +79,7 @@ fill_defaults (xlator_t *xl)
SET_DEFAULT_FOP (fxattrop);
SET_DEFAULT_FOP (setattr);
SET_DEFAULT_FOP (fsetattr);
+ SET_DEFAULT_FOP (fallocate);
SET_DEFAULT_FOP (getspec);
diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h
index 43fd06388..ace73f2ed 100644
--- a/libglusterfs/src/xlator.h
+++ b/libglusterfs/src/xlator.h
@@ -417,6 +417,14 @@ typedef int32_t (*fop_fsetattr_cbk_t) (call_frame_t *frame,
struct iatt *preop_stbuf,
struct iatt *postop_stbuf, dict_t *xdata);
+typedef int32_t (*fop_fallocate_cbk_t) (call_frame_t *frame,
+ void *cookie,
+ xlator_t *this,
+ int32_t op_ret,
+ int32_t op_errno,
+ struct iatt *preop_stbuf,
+ struct iatt *postop_stbuf, dict_t *xdata);
+
typedef int32_t (*fop_lookup_t) (call_frame_t *frame,
xlator_t *this,
loc_t *loc,
@@ -634,6 +642,13 @@ typedef int32_t (*fop_fsetattr_t) (call_frame_t *frame,
struct iatt *stbuf,
int32_t valid, dict_t *xdata);
+typedef int32_t (*fop_fallocate_t) (call_frame_t *frame,
+ xlator_t *this,
+ fd_t *fd,
+ int32_t keep_size,
+ off_t offset,
+ size_t len,
+ dict_t *xdata);
struct xlator_fops {
fop_lookup_t lookup;
@@ -678,6 +693,7 @@ struct xlator_fops {
fop_setattr_t setattr;
fop_fsetattr_t fsetattr;
fop_getspec_t getspec;
+ fop_fallocate_t fallocate;
/* these entries are used for a typechecking hack in STACK_WIND _only_ */
fop_lookup_cbk_t lookup_cbk;
@@ -722,6 +738,7 @@ struct xlator_fops {
fop_setattr_cbk_t setattr_cbk;
fop_fsetattr_cbk_t fsetattr_cbk;
fop_getspec_cbk_t getspec_cbk;
+ fop_fallocate_cbk_t fallocate_cbk;
};
typedef int32_t (*cbk_forget_t) (xlator_t *this,