diff options
| author | Brian Foster <bfoster@redhat.com> | 2013-05-08 08:54:11 -0400 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2013-06-13 14:37:21 -0700 | 
| commit | d1ccc4e400728d90f2ef7904661f53deb7199123 (patch) | |
| tree | 1c491d1932795d85941861fa683431ee22608668 /libglusterfs/src | |
| parent | 328ea4b16a276b0e65ca719f60b82ce851dda848 (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.c | 65 | ||||
| -rw-r--r-- | libglusterfs/src/call-stub.h | 16 | ||||
| -rw-r--r-- | libglusterfs/src/compat.h | 6 | ||||
| -rw-r--r-- | libglusterfs/src/defaults.c | 29 | ||||
| -rw-r--r-- | libglusterfs/src/defaults.h | 18 | ||||
| -rw-r--r-- | libglusterfs/src/globals.c | 1 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs.h | 1 | ||||
| -rw-r--r-- | libglusterfs/src/syncop.c | 31 | ||||
| -rw-r--r-- | libglusterfs/src/syncop.h | 2 | ||||
| -rw-r--r-- | libglusterfs/src/syscall.c | 23 | ||||
| -rw-r--r-- | libglusterfs/src/syscall.h | 2 | ||||
| -rw-r--r-- | libglusterfs/src/xlator.c | 1 | ||||
| -rw-r--r-- | libglusterfs/src/xlator.h | 17 | 
13 files changed, 212 insertions, 0 deletions
diff --git a/libglusterfs/src/call-stub.c b/libglusterfs/src/call-stub.c index bd81c4ed2fa..2bb993411b8 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 335111835b6..d940fe6f173 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 3d0cee1a986..2bd9825417b 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 5bac845c100..32454a1e916 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 8a9de7899d3..bc2f6429b09 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 05ff52c2c52..ba5075b2eea 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 8ee55c70654..013cdfffa25 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 8e5db41fda7..f57e8da5a72 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 98e88ff37d5..59e62ad14a2 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 bb834dbfd9f..e8954cc237c 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 d5c6ce5f67b..f1c9f58c3fc 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 f9e5db67183..1926240e858 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 43fd063884a..ace73f2ed03 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,  | 
