diff options
Diffstat (limited to 'libglusterfs/src')
| -rw-r--r-- | libglusterfs/src/Makefile.am | 2 | ||||
| -rw-r--r-- | libglusterfs/src/call-stub.c | 58 | ||||
| -rw-r--r-- | libglusterfs/src/default-args.c | 42 | ||||
| -rw-r--r-- | libglusterfs/src/defaults-tmpl.c | 1 | ||||
| -rwxr-xr-x | libglusterfs/src/generator.py | 13 | ||||
| -rw-r--r-- | libglusterfs/src/globals.c | 1 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs/call-stub.h | 14 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs/compat.h | 19 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs/default-args.h | 11 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs/defaults.h | 42 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs/syncop.h | 24 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs/syscall.h | 29 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs/xlator.h | 13 | ||||
| -rw-r--r-- | libglusterfs/src/libglusterfs.sym | 10 | ||||
| -rw-r--r-- | libglusterfs/src/syncop.c | 63 | ||||
| -rw-r--r-- | libglusterfs/src/syscall.c | 32 | ||||
| -rw-r--r-- | libglusterfs/src/xlator.c | 1 | 
17 files changed, 369 insertions, 6 deletions
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am index 1d06f1586a9..970f4b74978 100644 --- a/libglusterfs/src/Makefile.am +++ b/libglusterfs/src/Makefile.am @@ -6,7 +6,7 @@ libglusterfs_la_CFLAGS = $(GF_CFLAGS) $(GF_DARWIN_LIBGLUSTERFS_CFLAGS) \  libglusterfs_la_CPPFLAGS = $(GF_CPPFLAGS) -D__USE_FILE_OFFSET64 \  	-DXLATORDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator\" \  	-DXLATORPARENTDIR=\"$(libdir)/glusterfs/$(PACKAGE_VERSION)\" \ -	-DXXH_NAMESPACE=GF_ \ +	-DXXH_NAMESPACE=GF_ -D__USE_LARGEFILE64 \  	-I$(top_srcdir)/rpc/xdr/src/ -I$(top_builddir)/rpc/xdr/src/ \  	-I$(top_srcdir)/rpc/rpc-lib/src/ -I$(CONTRIBDIR)/rbtree \  	-I$(CONTRIBDIR)/libexecinfo ${ARGP_STANDALONE_CPPFLAGS} \ diff --git a/libglusterfs/src/call-stub.c b/libglusterfs/src/call-stub.c index 96454dfaeb5..886dfa52ccc 100644 --- a/libglusterfs/src/call-stub.c +++ b/libglusterfs/src/call-stub.c @@ -1818,6 +1818,51 @@ out:  }  call_stub_t * +fop_copy_file_range_stub(call_frame_t *frame, fop_copy_file_range_t fn, +                         fd_t *fd_in, off64_t off_in, fd_t *fd_out, +                         off64_t off_out, size_t len, uint32_t flags, +                         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_COPY_FILE_RANGE); +    GF_VALIDATE_OR_GOTO("call-stub", stub, out); + +    stub->fn.copy_file_range = fn; + +    args_copy_file_range_store(&stub->args, fd_in, off_in, fd_out, off_out, len, +                               flags, xdata); + +out: +    return stub; +} + +call_stub_t * +fop_copy_file_range_cbk_stub(call_frame_t *frame, fop_copy_file_range_cbk_t fn, +                             int32_t op_ret, int32_t op_errno, +                             struct iatt *stbuf, struct iatt *prebuf_dst, +                             struct iatt *postbuf_dst, 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, 0, GF_FOP_COPY_FILE_RANGE); +    GF_VALIDATE_OR_GOTO("call-stub", stub, out); + +    stub->fn_cbk.copy_file_range = fn; +    args_copy_file_range_cbk_store(&stub->args_cbk, op_ret, op_errno, stbuf, +                                   prebuf_dst, postbuf_dst, xdata); + +out: +    return stub; +} + +call_stub_t *  fop_put_stub(call_frame_t *frame, fop_put_t fn, loc_t *loc, mode_t mode,               mode_t umask, uint32_t flags, struct iovec *vector, int32_t count,               off_t offset, struct iobref *iobref, dict_t *xattr, dict_t *xdata) @@ -2213,6 +2258,13 @@ call_resume_wind(call_stub_t *stub)                           stub->args.iobref, stub->args.xattr, stub->args.xdata);              break; +        case GF_FOP_COPY_FILE_RANGE: +            stub->fn.copy_file_range( +                stub->frame, stub->frame->this, stub->args.fd, +                stub->args.off_in, stub->args.fd_dst, stub->args.off_out, +                stub->args.size, stub->args.flags, stub->args.xdata); +            break; +          default:              gf_msg_callingfn("call-stub", GF_LOG_ERROR, EINVAL,                               LG_MSG_INVALID_ENTRY, @@ -2439,6 +2491,12 @@ call_resume_unwind(call_stub_t *stub)                          stub->args_cbk.xdata);              break; +        case GF_FOP_COPY_FILE_RANGE: +            STUB_UNWIND(stub, copy_file_range, &stub->args_cbk.stat, +                        &stub->args_cbk.prestat, &stub->args_cbk.poststat, +                        stub->args_cbk.xdata); +            break; +          default:              gf_msg_callingfn("call-stub", GF_LOG_ERROR, EINVAL,                               LG_MSG_INVALID_ENTRY, diff --git a/libglusterfs/src/default-args.c b/libglusterfs/src/default-args.c index 479974e1637..cfceabd1f46 100644 --- a/libglusterfs/src/default-args.c +++ b/libglusterfs/src/default-args.c @@ -1541,6 +1541,48 @@ args_namelink_store(default_args_t *args, loc_t *loc, dict_t *xdata)      return 0;  } +int +args_copy_file_range_store(default_args_t *args, fd_t *fd_in, off64_t off_in, +                           fd_t *fd_out, off64_t off_out, size_t len, +                           uint32_t flags, dict_t *xdata) +{ +    if (fd_in) +        args->fd = fd_ref(fd_in); +    if (fd_out) +        args->fd_dst = fd_ref(fd_out); +    args->size = len; +    args->off_in = off_in; +    args->off_out = off_out; +    args->flags = flags; + +    if (xdata) +        args->xdata = dict_ref(xdata); + +    return 0; +} + +int +args_copy_file_range_cbk_store(default_args_cbk_t *args, int32_t op_ret, +                               int32_t op_errno, struct iatt *stbuf, +                               struct iatt *prebuf_dst, +                               struct iatt *postbuf_dst, dict_t *xdata) +{ +    args->op_ret = op_ret; +    args->op_errno = op_errno; +    if (op_ret >= 0) { +        if (postbuf_dst) +            args->poststat = *postbuf_dst; +        if (prebuf_dst) +            args->prestat = *prebuf_dst; +        if (stbuf) +            args->stat = *stbuf; +    } +    if (xdata) +        args->xdata = dict_ref(xdata); + +    return 0; +} +  void  args_cbk_wipe(default_args_cbk_t *args_cbk)  { diff --git a/libglusterfs/src/defaults-tmpl.c b/libglusterfs/src/defaults-tmpl.c index 97de8193dcb..5bf64e8c6c6 100644 --- a/libglusterfs/src/defaults-tmpl.c +++ b/libglusterfs/src/defaults-tmpl.c @@ -84,6 +84,7 @@ struct xlator_fops _default_fops = {      .put = default_put,      .icreate = default_icreate,      .namelink = default_namelink, +    .copy_file_range = default_copy_file_range,  };  struct xlator_fops *default_fops = &_default_fops; diff --git a/libglusterfs/src/generator.py b/libglusterfs/src/generator.py index c17d450502d..5b7aa4764a0 100755 --- a/libglusterfs/src/generator.py +++ b/libglusterfs/src/generator.py @@ -599,6 +599,19 @@ ops['namelink'] = (  	('cbk-arg',     'xdata',                 'dict_t *'),  ) +ops['copy_file_range'] = ( +        ('fop-arg',     'fd_in',                 'fd_t *'), +        ('fop-arg',     'off_in',                'off64_t '), +        ('fop-arg',     'fd_out',                'fd_t *'), +        ('fop-arg',     'off_out',               'off64_t '), +        ('fop-arg',     'len',                   'size_t'), +        ('fop-arg',     'flags',                 'uint32_t'), +        ('fop-arg',     'xdata',                 'dict_t *'), +        ('cbk-arg',     'stbuf',                 'struct iatt *'), +        ('cbk-arg',     'prebuf_dst',            'struct iatt *'), +        ('cbk-arg',     'postbuf_dst',           'struct iatt *'), +        ('cbk-arg',     'xdata',                 'dict_t *'), +)  #####################################################################  xlator_cbks['forget'] = (  	('fn-arg',      'this',        'xlator_t *'), diff --git a/libglusterfs/src/globals.c b/libglusterfs/src/globals.c index 35482545ab3..4fec0638926 100644 --- a/libglusterfs/src/globals.c +++ b/libglusterfs/src/globals.c @@ -77,6 +77,7 @@ const char *gf_fop_list[GF_FOP_MAXVALUE] = {      [GF_FOP_PUT] = "PUT",      [GF_FOP_ICREATE] = "ICREATE",      [GF_FOP_NAMELINK] = "NAMELINK", +    [GF_FOP_COPY_FILE_RANGE] = "COPY_FILE_RANGE",  };  const char *gf_upcall_list[GF_UPCALL_FLAGS_MAXVALUE] = { diff --git a/libglusterfs/src/glusterfs/call-stub.h b/libglusterfs/src/glusterfs/call-stub.h index bfed0fbc14a..c01c935e73d 100644 --- a/libglusterfs/src/glusterfs/call-stub.h +++ b/libglusterfs/src/glusterfs/call-stub.h @@ -81,6 +81,7 @@ typedef struct _call_stub {          fop_put_t put;          fop_icreate_t icreate;          fop_namelink_t namelink; +        fop_copy_file_range_t copy_file_range;      } fn;      union { @@ -136,6 +137,7 @@ typedef struct _call_stub {          fop_put_cbk_t put;          fop_icreate_cbk_t icreate;          fop_namelink_cbk_t namelink; +        fop_copy_file_range_cbk_t copy_file_range;      } fn_cbk;      default_args_t args; @@ -589,6 +591,18 @@ fop_namelink_cbk_stub(call_frame_t *frame, fop_namelink_cbk_t fn,                        int32_t op_ret, int32_t op_errno, struct iatt *prebuf,                        struct iatt *postbuf, dict_t *xdata); +call_stub_t * +fop_copy_file_range_stub(call_frame_t *frame, fop_copy_file_range_t fn, +                         fd_t *fd_in, off64_t off_in, fd_t *fd_out, +                         off64_t off_out, size_t len, uint32_t flags, +                         dict_t *xdata); + +call_stub_t * +fop_copy_file_range_cbk_stub(call_frame_t *frame, fop_copy_file_range_cbk_t fn, +                             int32_t op_ret, int32_t op_errno, +                             struct iatt *stbuf, struct iatt *prebuf_dst, +                             struct iatt *postbuf_dst, dict_t *xdata); +  void  call_resume(call_stub_t *stub);  void diff --git a/libglusterfs/src/glusterfs/compat.h b/libglusterfs/src/glusterfs/compat.h index 38c07b5ae7c..9374b79f9af 100644 --- a/libglusterfs/src/glusterfs/compat.h +++ b/libglusterfs/src/glusterfs/compat.h @@ -116,6 +116,25 @@  #include <limits.h>  #include <libgen.h> +/* + * This is where things like off64_t are defined. + * So include it before declaring _OFF64_T_DECLARED. + * If the freebsd version has support for off64_t + * including stdio.h should be sufficient. + */ +#include <stdio.h> + +#ifndef _OFF64_T_DECLARED +/* + * Including <stdio.h> (done above) should actually define + * _OFF64_T_DECLARED with off64_t data type being available + * for consumption. But, off64_t data type is not recognizable + * for FreeBSD versions less than 11. Hence, int64_t is typedefed + * to off64_t. + */ +#define _OFF64_T_DECLARED +typedef int64_t off64_t; +#endif /* _OFF64_T_DECLARED */  #ifndef XATTR_CREATE  enum { diff --git a/libglusterfs/src/glusterfs/default-args.h b/libglusterfs/src/glusterfs/default-args.h index f15f558202b..ca7526fcab6 100644 --- a/libglusterfs/src/glusterfs/default-args.h +++ b/libglusterfs/src/glusterfs/default-args.h @@ -234,6 +234,12 @@ void  args_lease_cbk_store(default_args_cbk_t *args, int32_t op_ret, int32_t op_errno,                       struct gf_lease *lease, dict_t *xdata); +int +args_copy_file_range_cbk_store(default_args_cbk_t *args, int32_t op_ret, +                               int32_t op_errno, struct iatt *stbuf, +                               struct iatt *prebuf_dst, +                               struct iatt *postbuf_dst, dict_t *xdata); +  void  args_cbk_wipe(default_args_cbk_t *args_cbk); @@ -439,6 +445,11 @@ args_icreate_store(default_args_t *args, loc_t *loc, mode_t mode,  int  args_namelink_store(default_args_t *args, loc_t *loc, dict_t *xdata); +int +args_copy_file_range_store(default_args_t *args, fd_t *fd_in, off64_t off_in, +                           fd_t *fd_out, off_t off64_out, size_t len, +                           uint32_t flags, dict_t *xdata); +  void  args_cbk_init(default_args_cbk_t *args_cbk);  #endif /* _DEFAULT_ARGS_H */ diff --git a/libglusterfs/src/glusterfs/defaults.h b/libglusterfs/src/glusterfs/defaults.h index 5d6b8e28a51..5a818eeb91a 100644 --- a/libglusterfs/src/glusterfs/defaults.h +++ b/libglusterfs/src/glusterfs/defaults.h @@ -48,10 +48,20 @@ typedef struct {  } default_args_cbk_t;  typedef struct { -    loc_t loc;  /* @old in rename(), link() */ -    loc_t loc2; /* @new in rename(), link() */ -    fd_t *fd; +    loc_t loc;    /* @old in rename(), link() */ +    loc_t loc2;   /* @new in rename(), link() */ +    fd_t *fd;     /* for all the fd based ops */ +    fd_t *fd_dst; /* Only for copy_file_range destination */      off_t offset; +    /* +     * According to the man page of copy_file_range, +     * the offsets for source and destination file +     * are of type loff_t. But the type loff_t is +     * linux specific and is actual a typedef of +     * off64_t. +     */ +    off64_t off_in;  /* For copy_file_range source fd */ +    off64_t off_out; /* For copy_file_range destination fd only */      int mask;      size_t size;      mode_t mode; @@ -323,6 +333,11 @@ int32_t  default_namelink(call_frame_t *frame, xlator_t *this, loc_t *loc,                   dict_t *xdata); +int32_t +default_copy_file_range(call_frame_t *frame, xlator_t *this, fd_t *fd_in, +                        off64_t off_in, fd_t *fd_out, off64_t off_out, +                        size_t len, uint32_t flags, dict_t *xdata); +  /* Resume */  int32_t  default_getspec_resume(call_frame_t *frame, xlator_t *this, const char *key, @@ -542,6 +557,11 @@ default_put_resume(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,                     int32_t count, off_t off, struct iobref *iobref,                     dict_t *xattr, dict_t *xdata); +int32_t +default_copy_file_range_resume(call_frame_t *frame, xlator_t *this, fd_t *fd_in, +                               off_t off64_in, fd_t *fd_out, off64_t off_out, +                               size_t len, uint32_t flags, dict_t *xdata); +  /* _cbk_resume */  int32_t @@ -813,6 +833,13 @@ int32_t  default_namelink_resume(call_frame_t *frame, xlator_t *this, loc_t *loc,                          dict_t *xdata); +int32_t +default_copy_file_range_cbk_resume(call_frame_t *frame, void *cookie, +                                   xlator_t *this, int32_t op_ret, +                                   int32_t op_errno, struct iatt *stbuf, +                                   struct iatt *prebuf_dst, +                                   struct iatt *postbuf_dst, dict_t *xdata); +  /* _CBK */  int32_t  default_lookup_cbk(call_frame_t *frame, void *cookie, xlator_t *this, @@ -1072,6 +1099,12 @@ default_namelink_cbk(call_frame_t *frame, void *cookie, xlator_t *this,                       struct iatt *postbuf, dict_t *xdata);  int32_t +default_copy_file_range_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                            int32_t op_ret, int32_t op_errno, +                            struct iatt *stbuf, struct iatt *prebuf_dst, +                            struct iatt *postbuf_dst, dict_t *xdata); + +int32_t  default_lookup_failure_cbk(call_frame_t *frame, int32_t op_errno);  int32_t @@ -1231,6 +1264,9 @@ int32_t  default_namelink_failure_cbk(call_frame_t *frame, int32_t op_errno);  int32_t +default_copy_file_range_failure_cbk(call_frame_t *frame, int32_t op_errno); + +int32_t  default_mem_acct_init(xlator_t *this);  void diff --git a/libglusterfs/src/glusterfs/syncop.h b/libglusterfs/src/glusterfs/syncop.h index 203abe92b57..7a6167b0488 100644 --- a/libglusterfs/src/glusterfs/syncop.h +++ b/libglusterfs/src/glusterfs/syncop.h @@ -138,8 +138,19 @@ typedef struct syncbarrier syncbarrier_t;  struct syncargs {      int op_ret;      int op_errno; + +    /* +     * The below 3 iatt structures are used in the fops +     * whose callbacks get struct iatt as one of the +     * a return arguments. Currently, the maximum number +     * of iatt structures returned is 3 for some fops +     * such as mknod, copy_file_range, mkdir etc. So +     * all the following 3 iatt structures would be used +     * for those fops. +     */      struct iatt iatt1;      struct iatt iatt2; +    struct iatt iatt3;      dict_t *xattr;      struct statvfs statvfs_buf;      struct iovec *vector; @@ -634,4 +645,17 @@ syncop_entrylk(xlator_t *subvol, const char *volume, loc_t *loc,                 const char *basename, entrylk_cmd cmd, entrylk_type type,                 dict_t *xdata_in, dict_t **xdata_out); +int +syncop_copy_file_range(xlator_t *subvol, fd_t *fd_in, off64_t off_in, +                       fd_t *fd_out, off64_t off_out, size_t len, +                       uint32_t flags, struct iatt *stbuf, +                       struct iatt *preiatt_dst, struct iatt *postiatt_dst, +                       dict_t *xdata_in, dict_t **xdata_out); + +int +syncop_copy_file_range_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                           int op_ret, int op_errno, struct iatt *stbuf, +                           struct iatt *prebuf_dst, struct iatt *postbuf_dst, +                           dict_t *xdata); +  #endif /* _SYNCOP_H */ diff --git a/libglusterfs/src/glusterfs/syscall.h b/libglusterfs/src/glusterfs/syscall.h index faaf694b22c..6b33c141a5e 100644 --- a/libglusterfs/src/glusterfs/syscall.h +++ b/libglusterfs/src/glusterfs/syscall.h @@ -17,6 +17,7 @@  #include <sys/stat.h>  #include <sys/time.h>  #include <sys/socket.h> +#include <stdio.h>  /* GF follows the Linux XATTR definition, which differs in Darwin. */  #define GF_XATTR_CREATE 0x1  /* set value, fail if attr already exists */ @@ -228,4 +229,32 @@ sys_socket(int domain, int type, int protocol);  int  sys_accept(int sock, struct sockaddr *sockaddr, socklen_t *socklen, int flags); +#ifdef GF_BSD_HOST_OS +#ifndef _OFF64_T_DECLARED +/* + * Including <stdio.h> (done above) should actually define + * _OFF64_T_DECLARED with off64_t data type being available + * for consumption. But, off64_t data type is not recognizable + * for FreeBSD versions less than 11. Hence, int64_t is typedefed + * to off64_t. + */ +#define _OFF64_T_DECLARED +typedef int64_t off64_t; +#endif /* _OFF64_T_DECLARED */ +#endif /* GF_BSD_HOST_OS */ + +/* + * According to the man page of copy_file_range, both off_in and off_out are + * pointers to the data type loff_t (i.e. loff_t *). But, freebsd does not + * have (and recognize) loff_t. Since loff_t is 64 bits, use off64_t + * instead.  Since it's a pointer type it should be okay. It just needs + * to be a pointer-to-64-bit pointer for both 32- and 64-bit platforms. + * off64_t is recognized by freebsd. + * TODO: In future, when freebsd can recognize loff_t, probably revisit this + *       and change the off_in and off_out to (loff_t *). + */ +ssize_t +sys_copy_file_range(int fd_in, off64_t *off_in, int fd_out, off64_t *off_out, +                    size_t len, unsigned int flags); +  #endif /* __SYSCALL_H__ */ diff --git a/libglusterfs/src/glusterfs/xlator.h b/libglusterfs/src/glusterfs/xlator.h index 4137d12eb27..12d507bc021 100644 --- a/libglusterfs/src/glusterfs/xlator.h +++ b/libglusterfs/src/glusterfs/xlator.h @@ -23,6 +23,7 @@  #include "glusterfs/list.h"  #include "glusterfs/latency.h"  #include "glusterfs/compat-uuid.h" +#include "glusterfs/syscall.h"  #define FIRST_CHILD(xl) (xl->children->xlator)  #define SECOND_CHILD(xl) (xl->children->next->xlator) @@ -354,6 +355,11 @@ typedef int32_t (*fop_namelink_cbk_t)(call_frame_t *frame, void *cookie,                                        int32_t op_errno, struct iatt *prebuf,                                        struct iatt *postbuf, dict_t *xdata); +typedef int32_t (*fop_copy_file_range_cbk_t)( +    call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, +    int32_t op_errno, struct iatt *stbuf, struct iatt *prebuf_dst, +    struct iatt *postbuf_dst, dict_t *xdata); +  typedef int32_t (*fop_lookup_t)(call_frame_t *frame, xlator_t *this, loc_t *loc,                                  dict_t *xdata); @@ -544,6 +550,11 @@ typedef int32_t (*fop_icreate_t)(call_frame_t *frame, xlator_t *this,  typedef int32_t (*fop_namelink_t)(call_frame_t *frame, xlator_t *this,                                    loc_t *loc, dict_t *xdata); +typedef int32_t (*fop_copy_file_range_t)(call_frame_t *frame, xlator_t *this, +                                         fd_t *fd_in, off64_t off_in, +                                         fd_t *fd_out, off64_t off_out, +                                         size_t len, uint32_t flags, +                                         dict_t *xdata);  /* WARNING: make sure the list is in order with FOP definition in     `rpc/xdr/src/glusterfs-fops.x`. @@ -609,6 +620,7 @@ struct xlator_fops {      fop_put_t put;      fop_icreate_t icreate;      fop_namelink_t namelink; +    fop_copy_file_range_t copy_file_range;      /* these entries are used for a typechecking hack in STACK_WIND _only_ */      /* make sure to add _cbk variables only after defining regular fops as @@ -673,6 +685,7 @@ struct xlator_fops {      fop_put_cbk_t put_cbk;      fop_icreate_cbk_t icreate_cbk;      fop_namelink_cbk_t namelink_cbk; +    fop_copy_file_range_cbk_t copy_file_range_cbk;  };  typedef int32_t (*cbk_forget_t)(xlator_t *this, inode_t *inode); diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym index baf44de64ad..6ca6a639456 100644 --- a/libglusterfs/src/libglusterfs.sym +++ b/libglusterfs/src/libglusterfs.sym @@ -92,6 +92,8 @@ args_xattrop_cbk_store  args_xattrop_store  args_zerofill_cbk_store  args_zerofill_store +args_copy_file_range_cbk_store +args_copy_file_range_store  bin_to_data  call_resume  call_resume_keep_stub @@ -351,6 +353,10 @@ default_put  default_put_cbk  default_put_failure_cbk  default_put_resume +default_copy_file_range +default_copy_file_range_cbk +default_copy_file_range_failure_cbk +default_copy_file_range_resume  __dentry_grep  dht_is_linkfile  dict_add @@ -471,6 +477,8 @@ fd_unref  _fini  fop_access_stub  fop_create_stub +fop_copy_file_range_stub +fop_copy_file_range_cbk_stub  fop_discard_stub  fop_entrylk_stub  fop_enum_to_pri_string @@ -933,6 +941,7 @@ synclock_unlock  syncop_access  syncop_close  syncop_create +syncop_copy_file_range  syncopctx_getctx  syncopctx_setfsgid  syncopctx_setfsgroups @@ -1006,6 +1015,7 @@ sys_chmod  sys_chown  sys_close  sys_closedir +sys_copy_file_range  sys_creat  sys_fallocate  sys_fchmod diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c index b70953725ce..bf70daf95c3 100644 --- a/libglusterfs/src/syncop.c +++ b/libglusterfs/src/syncop.c @@ -3397,4 +3397,65 @@ syncop_namelink_cbk(call_frame_t *frame, void *cookie, xlator_t *this,      __wake(args);      return 0; -}
\ No newline at end of file +} + +int +syncop_copy_file_range(xlator_t *subvol, fd_t *fd_in, off64_t off_in, +                       fd_t *fd_out, off64_t off_out, size_t len, +                       uint32_t flags, struct iatt *stbuf, +                       struct iatt *preiatt_dst, struct iatt *postiatt_dst, +                       dict_t *xdata_in, dict_t **xdata_out) +{ +    struct syncargs args = { +        0, +    }; + +    SYNCOP(subvol, (&args), syncop_copy_file_range_cbk, +           subvol->fops->copy_file_range, fd_in, off_in, fd_out, off_out, len, +           flags, xdata_in); + +    if (stbuf) { +        *stbuf = args.iatt1; +    } +    if (preiatt_dst) { +        *preiatt_dst = args.iatt2; +    } +    if (postiatt_dst) { +        *postiatt_dst = args.iatt3; +    } + +    if (xdata_out) { +        *xdata_out = args.xdata; +    } else if (args.xdata) { +        dict_unref(args.xdata); +    } + +    errno = args.op_errno; +    return args.op_ret; +} + +int +syncop_copy_file_range_cbk(call_frame_t *frame, void *cookie, xlator_t *this, +                           int op_ret, int op_errno, struct iatt *stbuf, +                           struct iatt *prebuf_dst, struct iatt *postbuf_dst, +                           dict_t *xdata) +{ +    struct syncargs *args = NULL; + +    args = cookie; + +    args->op_ret = op_ret; +    args->op_errno = op_errno; +    if (xdata) +        args->xdata = dict_ref(xdata); + +    if (op_ret >= 0) { +        args->iatt1 = *stbuf; +        args->iatt2 = *prebuf_dst; +        args->iatt3 = *postbuf_dst; +    } + +    __wake(args); + +    return 0; +} diff --git a/libglusterfs/src/syscall.c b/libglusterfs/src/syscall.c index c72a8e16b34..1d88c8adac1 100644 --- a/libglusterfs/src/syscall.c +++ b/libglusterfs/src/syscall.c @@ -8,8 +8,8 @@    cases as published by the Free Software Foundation.  */ -#include "glusterfs/syscall.h"  #include "glusterfs/compat.h" +#include "glusterfs/syscall.h"  #include "glusterfs/mem-pool.h"  #include "glusterfs/libglusterfs-messages.h" @@ -19,6 +19,9 @@  #include <fcntl.h>  #include <unistd.h>  #include <stdarg.h> +#ifdef HAVE_COPY_FILE_RANGE_SYS +#include <sys/syscall.h> +#endif  #define FS_ERROR_LOG(result)                                                   \      do {                                                                       \ @@ -802,3 +805,30 @@ err:  #endif      return newsock;  } + +ssize_t +sys_copy_file_range(int fd_in, off64_t *off_in, int fd_out, off64_t *off_out, +                    size_t len, unsigned int flags) +{ +    /* +     * TODO: Add check for other platofrms like freebsd etc if this syscall is +     *       not generic. +     * This is what the function does. +     *       1) Check whether copy_file_range API is present. If so call it. +     *       2) If copy_file_range API is not present, then check whether +     *          the system call is there. If so, then use syscall to invoke +     *          SYS_copy_file_range system call. +     *       3) If neither of the above is present, then return ENOSYS. +     */ +#ifdef HAVE_COPY_FILE_RANGE +    return FS_RET_CHECK( +        copy_file_range(fd_in, off_in, fd_out, off_out, len, flags), errno); +#else +#ifdef HAVE_COPY_FILE_RANGE_SYS +    return syscall(SYS_copy_file_range, fd_in, off_in, fd_out, off_out, len, +                   flags); +#else +    return -ENOSYS; +#endif /* HAVE_COPY_FILE_RANGE_SYS */ +#endif /* HAVE_COPY_FILE_RANGE */ +} diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c index 1b7c9d46f88..b50848b3476 100644 --- a/libglusterfs/src/xlator.c +++ b/libglusterfs/src/xlator.c @@ -143,6 +143,7 @@ fill_defaults(xlator_t *xl)      SET_DEFAULT_FOP(getspec);      SET_DEFAULT_FOP(icreate);      SET_DEFAULT_FOP(namelink); +    SET_DEFAULT_FOP(copy_file_range);      if (!xl->cbks)          xl->cbks = &default_cbks;  | 
