diff options
| author | Niels de Vos <ndevos@redhat.com> | 2015-12-07 16:24:15 +0000 | 
|---|---|---|
| committer | Niels de Vos <ndevos@redhat.com> | 2016-05-11 11:23:00 -0700 | 
| commit | b2222c1e13d3bff17fa04b8f9b4870cefd457fe2 (patch) | |
| tree | a2f5b7fca493f9c71a5906ec4e3763ebbd9e77bd | |
| parent | 163568951746f7a7af181bb8c592404581eced78 (diff) | |
upcall: Add support to invalidate xattrs
When SElinux is used, clients should get a notification that the
extended attributes have been updated. Other components (like md-cache)
will be able to use this too.
A big part of the implementation comes from Poornima through the first
version of http://review.gluster.org/12996.
Also moving the flags from upcall-cache-invalidation.h to the main
libglusterfs upcall-utils.h file, so that other places can easily use
them in future.
Change-Id: I525345bed8f22d029524ff19ccaf726a2c905454
BUG: 1211863
Signed-off-by: Niels de Vos <ndevos@redhat.com>
Signed-off-by: Poornima G <pgurusid@redhat.com>
Reviewed-on: http://review.gluster.org/12995
Reviewed-by: soumya k <skoduri@redhat.com>
Smoke: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
| -rw-r--r-- | libglusterfs/src/upcall-utils.h | 40 | ||||
| -rw-r--r-- | xlators/features/upcall/src/upcall-cache-invalidation.h | 34 | ||||
| -rw-r--r-- | xlators/features/upcall/src/upcall-internal.c | 22 | ||||
| -rw-r--r-- | xlators/features/upcall/src/upcall.c | 346 | ||||
| -rw-r--r-- | xlators/features/upcall/src/upcall.h | 2 | 
5 files changed, 381 insertions, 63 deletions
diff --git a/libglusterfs/src/upcall-utils.h b/libglusterfs/src/upcall-utils.h index 7acfff15a0b..a4eaabf2032 100644 --- a/libglusterfs/src/upcall-utils.h +++ b/libglusterfs/src/upcall-utils.h @@ -15,6 +15,46 @@  #include "compat-uuid.h"  #include "compat.h" +/* Flags sent for cache_invalidation */ +#define UP_NLINK         0x00000001   /* update nlink */ +#define UP_MODE          0x00000002   /* update mode and ctime */ +#define UP_OWN           0x00000004   /* update mode,uid,gid and ctime */ +#define UP_SIZE          0x00000008   /* update fsize */ +#define UP_TIMES         0x00000010   /* update all times */ +#define UP_ATIME         0x00000020   /* update atime only */ +#define UP_PERM          0x00000040   /* update fields needed for permission +                                         checking */ +#define UP_RENAME        0x00000080   /* this is a rename op - delete the cache +                                         entry */ +#define UP_FORGET        0x00000100   /* inode_forget on server side - +                                         invalidate the cache entry */ +#define UP_PARENT_TIMES  0x00000200   /* update parent dir times */ + +#define UP_XATTR         0x00000400   /* update the xattrs and ctime */ +#define UP_XATTR_RM      0x00000800   /* Remove the xattrs and update ctime */ + +/* for fops - open, read, lk, */ +#define UP_UPDATE_CLIENT        (UP_ATIME) + +/* for fop - write, truncate */ +#define UP_WRITE_FLAGS          (UP_SIZE | UP_TIMES) + +/* for fop - setattr */ +#define UP_ATTR_FLAGS           (UP_SIZE | UP_TIMES | UP_OWN | UP_MODE | \ +                                 UP_PERM) +/* for fop - rename */ +#define UP_RENAME_FLAGS         (UP_RENAME) + +/* to invalidate parent directory entries for fops -rename, unlink, rmdir, + * mkdir, create */ +#define UP_PARENT_DENTRY_FLAGS  (UP_PARENT_TIMES) + +/* for fop - unlink, link, rmdir, mkdir */ +#define UP_NLINK_FLAGS          (UP_NLINK | UP_TIMES) + +#define IATT_UPDATE_FLAGS       (UP_NLINK | UP_MODE | UP_OWN | UP_SIZE | \ +                                 UP_TIMES | UP_ATIME) +  typedef enum {          GF_UPCALL_EVENT_NULL,          GF_UPCALL_CACHE_INVALIDATION, diff --git a/xlators/features/upcall/src/upcall-cache-invalidation.h b/xlators/features/upcall/src/upcall-cache-invalidation.h index 964a72f63f2..62b458fa295 100644 --- a/xlators/features/upcall/src/upcall-cache-invalidation.h +++ b/xlators/features/upcall/src/upcall-cache-invalidation.h @@ -15,40 +15,6 @@   * events post its last access */  #define CACHE_INVALIDATION_TIMEOUT "60" -/* Flags sent for cache_invalidation */ -#define UP_NLINK   0x00000001   /* update nlink */ -#define UP_MODE    0x00000002   /* update mode and ctime */ -#define UP_OWN     0x00000004   /* update mode,uid,gid and ctime */ -#define UP_SIZE    0x00000008   /* update fsize */ -#define UP_TIMES   0x00000010   /* update all times */ -#define UP_ATIME   0x00000020   /* update atime only */ -#define UP_PERM    0x00000040   /* update fields needed for -                                   permission checking */ -#define UP_RENAME  0x00000080   /* this is a rename op - -                                   delete the cache entry */ -#define UP_FORGET  0x00000100   /* inode_forget on server side - -                                   invalidate the cache entry */ -#define UP_PARENT_TIMES   0x00000200   /* update parent dir times */ - -/* for fops - open, read, lk, */ -#define UP_UPDATE_CLIENT        (UP_ATIME) - -/* for fop - write, truncate */ -#define UP_WRITE_FLAGS          (UP_SIZE | UP_TIMES) - -/* for fop - setattr */ -#define UP_ATTR_FLAGS           (UP_SIZE | UP_TIMES | UP_OWN |        \ -                                 UP_MODE | UP_PERM) -/* for fop - rename */ -#define UP_RENAME_FLAGS         (UP_RENAME) - -/* to invalidate parent directory entries for fops -rename, unlink, - * rmdir, link */ -#define UP_PARENT_DENTRY_FLAGS  (UP_PARENT_TIMES) - -/* for fop - unlink, link, rmdir, mkdir */ -#define UP_NLINK_FLAGS          (UP_NLINK | UP_TIMES) -  /* xlator options */  gf_boolean_t is_cache_invalidation_enabled(xlator_t *this);  int32_t get_cache_invalidation_timeout(xlator_t *this); diff --git a/xlators/features/upcall/src/upcall-internal.c b/xlators/features/upcall/src/upcall-internal.c index 81199eb074c..f9005df2ed7 100644 --- a/xlators/features/upcall/src/upcall-internal.c +++ b/xlators/features/upcall/src/upcall-internal.c @@ -31,7 +31,6 @@  /*   * Check if any of the upcall options are enabled:   *     - cache_invalidation - *     - XXX: lease_lk   */  gf_boolean_t  is_upcall_enabled(xlator_t *this) { @@ -50,25 +49,6 @@ is_upcall_enabled(xlator_t *this) {  }  /* - * Check if any of cache_invalidation is enabled - */ -gf_boolean_t -is_cache_invalidation_enabled(xlator_t *this) { -        upcall_private_t *priv      = NULL; -        gf_boolean_t     is_enabled = _gf_false; - -        if (this->private) { -                priv = (upcall_private_t *)this->private; - -                if (priv->cache_invalidation_enabled) { -                        is_enabled = _gf_true; -                } -        } - -        return is_enabled; -} - -/*   * Get the cache_invalidation_timeout   */  int32_t @@ -476,7 +456,7 @@ upcall_cache_invalidate (call_frame_t *frame, xlator_t *this, client_t *client,          upcall_inode_ctx_t *up_inode_ctx = NULL;          gf_boolean_t     found           = _gf_false; -        if (!is_cache_invalidation_enabled(this)) +        if (!is_upcall_enabled(this))                  return;          /* server-side generated fops like quota/marker will not have any diff --git a/xlators/features/upcall/src/upcall.c b/xlators/features/upcall/src/upcall.c index 1822d9b119c..8c8219f273c 100644 --- a/xlators/features/upcall/src/upcall.c +++ b/xlators/features/upcall/src/upcall.c @@ -1579,6 +1579,338 @@ err:  int32_t +up_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +        client_t         *client        = NULL; +        uint32_t         flags          = 0; +        upcall_local_t   *local         = NULL; + +        EXIT_IF_UPCALL_OFF (this, out); + +        client = frame->root->client; +        local = frame->local; + +        if ((op_ret < 0) || !local) { +                goto out; +        } + +        flags = UP_XATTR; +        upcall_cache_invalidate (frame, this, client, local->inode, flags, +                                 NULL, NULL, NULL); + +out: +        UPCALL_STACK_UNWIND (setxattr, frame, op_ret, op_errno, xdata); + +        return 0; +} + + +int32_t +up_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, +             int32_t flags, dict_t *xdata) +{ +        int32_t          op_errno        = -1; +        upcall_local_t   *local          = NULL; + +        EXIT_IF_UPCALL_OFF (this, out); + +        local = upcall_local_init (frame, this, loc->inode); +        if (!local) { +                op_errno = ENOMEM; +                goto err; +        } + +out: +        STACK_WIND (frame, up_setxattr_cbk, FIRST_CHILD(this), +                    FIRST_CHILD(this)->fops->setxattr, loc, dict, flags, +                    xdata); + +        return 0; + +err: +        UPCALL_STACK_UNWIND (setxattr, frame, -1, op_errno, NULL); + +        return 0; +} + + +int32_t +up_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                  int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +        client_t         *client        = NULL; +        uint32_t         flags          = 0; +        upcall_local_t   *local         = NULL; + +        EXIT_IF_UPCALL_OFF (this, out); + +        client = frame->root->client; +        local = frame->local; + +        if ((op_ret < 0) || !local) { +                goto out; +        } + +        flags = UP_XATTR; +        upcall_cache_invalidate (frame, this, client, local->inode, flags, +                                 NULL, NULL, NULL); + +out: +        UPCALL_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno, xdata); + +        return 0; +} + + +int32_t +up_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *dict, +              int32_t flags, dict_t *xdata) +{ +        int32_t          op_errno        = -1; +        upcall_local_t   *local          = NULL; + +        EXIT_IF_UPCALL_OFF (this, out); + +        local = upcall_local_init (frame, this, fd->inode); +        if (!local) { +                op_errno = ENOMEM; +                goto err; +        } + +out: +        STACK_WIND (frame, up_fsetxattr_cbk, +                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->fsetxattr, +                    fd, dict, flags, xdata); + +        return 0; + +err: +        UPCALL_STACK_UNWIND (fsetxattr, frame, -1, op_errno, NULL); + +        return 0; +} + + +int32_t +up_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                     int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +        client_t         *client        = NULL; +        uint32_t         flags          = 0; +        upcall_local_t   *local         = NULL; + +        EXIT_IF_UPCALL_OFF (this, out); + +        client = frame->root->client; +        local = frame->local; + +        if ((op_ret < 0) || !local) { +                goto out; +        } +        flags = UP_XATTR_RM; +        upcall_cache_invalidate (frame, this, client, local->inode, flags, +                                 NULL, NULL, NULL); + +out: +        UPCALL_STACK_UNWIND (fremovexattr, frame, op_ret, op_errno, +                             xdata); +        return 0; +} + +int32_t +up_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd, +                 const char *name, dict_t *xdata) +{ +        int32_t          op_errno        = -1; +        upcall_local_t   *local          = NULL; + +        EXIT_IF_UPCALL_OFF (this, out); + +        local = upcall_local_init (frame, this, fd->inode); +        if (!local) { +                op_errno = ENOMEM; +                goto err; +        } + +out: +        STACK_WIND (frame, up_fremovexattr_cbk, +                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->fremovexattr, +                    fd, name, xdata); +        return 0; + +err: +        UPCALL_STACK_UNWIND (fremovexattr, frame, -1, op_errno, NULL); + +        return 0; +} + +int32_t +up_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                    int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ +        client_t         *client        = NULL; +        uint32_t         flags          = 0; +        upcall_local_t   *local         = NULL; + +        EXIT_IF_UPCALL_OFF (this, out); + +        client = frame->root->client; +        local = frame->local; + +        if ((op_ret < 0) || !local) { +                goto out; +        } +        flags = UP_XATTR_RM; +        upcall_cache_invalidate (frame, this, client, local->inode, flags, +                                 NULL, NULL, NULL); + +out: +        UPCALL_STACK_UNWIND (removexattr, frame, op_ret, op_errno, +                             xdata); +        return 0; +} + +int32_t +up_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc, +                const char *name, dict_t *xdata) +{ +        int32_t          op_errno        = -1; +        upcall_local_t   *local          = NULL; + +        EXIT_IF_UPCALL_OFF (this, out); + +        local = upcall_local_init (frame, this, loc->inode); +        if (!local) { +                op_errno = ENOMEM; +                goto err; +        } + +out: +        STACK_WIND (frame, up_removexattr_cbk, +                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->removexattr, +                    loc, name, xdata); +        return 0; + +err: +        UPCALL_STACK_UNWIND (removexattr, frame, -1, op_errno, NULL); + +        return 0; +} + + +int32_t +up_fgetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                  int32_t op_ret, int32_t op_errno, dict_t *dict, +                  dict_t *xdata) +{ +        client_t         *client        = NULL; +        uint32_t         flags          = 0; +        upcall_local_t   *local         = NULL; + +        EXIT_IF_UPCALL_OFF (this, out); + +        client = frame->root->client; +        local = frame->local; + +        if ((op_ret < 0) || !local) { +                goto out; +        } + +        flags = UP_UPDATE_CLIENT; +        upcall_cache_invalidate (frame, this, client, local->inode, flags, +                                 NULL, NULL, NULL); + +out: +        UPCALL_STACK_UNWIND (fgetxattr, frame, op_ret, op_errno, +                             dict, xdata); +        return 0; +} + + +int32_t +up_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, +              const char *name, dict_t *xdata) +{ +        int32_t          op_errno        = -1; +        upcall_local_t   *local          = NULL; + +        EXIT_IF_UPCALL_OFF (this, out); + +        local = upcall_local_init (frame, this, fd->inode); +        if (!local) { +                op_errno = ENOMEM; +                goto err; +        } + +out: +        STACK_WIND (frame, up_fgetxattr_cbk, +                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->fgetxattr, +                    fd, name, xdata); +        return 0; +err: +        UPCALL_STACK_UNWIND (fgetxattr, frame, -1, op_errno, +                             NULL, NULL); +        return 0; +} + + +int32_t +up_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                 int32_t op_ret, int32_t op_errno, dict_t *dict, +                 dict_t *xdata) +{ +        client_t         *client        = NULL; +        uint32_t         flags          = 0; +        upcall_local_t   *local         = NULL; + +        EXIT_IF_UPCALL_OFF (this, out); + +        client = frame->root->client; +        local = frame->local; + +        if ((op_ret < 0) || !local) { +                goto out; +        } + +        flags = UP_UPDATE_CLIENT; +        upcall_cache_invalidate (frame, this, client, local->inode, flags, +                                 NULL, NULL, NULL); + +out: +        UPCALL_STACK_UNWIND (getxattr, frame, op_ret, op_errno, +                             dict, xdata); +        return 0; +} + +int32_t +up_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, +             const char *name, dict_t *xdata) +{ +        int32_t          op_errno        = -1; +        upcall_local_t   *local          = NULL; + +        EXIT_IF_UPCALL_OFF (this, out); + +        local = upcall_local_init (frame, this, loc->inode); +        if (!local) { +                op_errno = ENOMEM; +                goto err; +        } + +out: +        STACK_WIND (frame, up_getxattr_cbk, +                    FIRST_CHILD(this), FIRST_CHILD(this)->fops->getxattr, +                    loc, name, xdata); +        return 0; +err: +        UPCALL_STACK_UNWIND (getxattr, frame, -1, op_errno, +                             NULL, NULL); +        return 0; +} + + +int32_t  mem_acct_init (xlator_t *this)  {          int     ret = -1; @@ -1841,6 +2173,13 @@ struct xlator_fops fops = {          .rmdir       = up_rmdir,          .rename      = up_rename, +        .setxattr    = up_setxattr, +        .fsetxattr   = up_fsetxattr, +        .getxattr    = up_getxattr, +        .fgetxattr   = up_fgetxattr, +        .fremovexattr = up_fremovexattr, +        .removexattr = up_removexattr, +  #ifdef NOT_SUPPORTED          /* internal lk fops */          .inodelk     = up_inodelk, @@ -1855,13 +2194,6 @@ struct xlator_fops fops = {          .fsync       = up_fsync,          .fsyncdir    = up_fsyncdir, -        /* XXX: Handle xattr fops (BZ-1211863) */ -        .getxattr    = up_getxattr, -        .fgetxattr   = up_fgetxattr, -        .fremovexattr = up_fremovexattr, -        .removexattr = up_removexattr, -        .setxattr    = up_setxattr, -        .fsetxattr   = up_fsetxattr,          .xattrop     = up_xattrop,          .fxattrop    = up_fxattrop,  #endif diff --git a/xlators/features/upcall/src/upcall.h b/xlators/features/upcall/src/upcall.h index 344c9c362eb..c96cc191ecc 100644 --- a/xlators/features/upcall/src/upcall.h +++ b/xlators/features/upcall/src/upcall.h @@ -111,7 +111,7 @@ void *upcall_reaper_thread (void *data);  int upcall_reaper_thread_init (xlator_t *this);  /* Xlator options */ -gf_boolean_t is_upcall_enabled(xlator_t *this); +gf_boolean_t is_upcall_enabled (xlator_t *this);  /* Cache invalidation specific */  void upcall_cache_invalidate (call_frame_t *frame, xlator_t *this,  | 
