diff options
Diffstat (limited to 'xlators')
| -rw-r--r-- | xlators/features/index/src/index.c | 4 | ||||
| -rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 35 | ||||
| -rw-r--r-- | xlators/protocol/server/src/authenticate.c | 45 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-helpers.c | 10 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-rpc-fops.c | 76 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server.c | 134 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix-helpers.c | 58 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 389 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.h | 12 | 
9 files changed, 413 insertions, 350 deletions
diff --git a/xlators/features/index/src/index.c b/xlators/features/index/src/index.c index d1eb763d..d061c410 100644 --- a/xlators/features/index/src/index.c +++ b/xlators/features/index/src/index.c @@ -430,7 +430,8 @@ index_del (xlator_t *this, uuid_t gfid, const char *subdir)  out:          return ret;  } -int + +static int  _check_key_is_zero_filled (dict_t *d, char *k, data_t *v,                             void *tmp)  { @@ -441,6 +442,7 @@ _check_key_is_zero_filled (dict_t *d, char *k, data_t *v,          return 0;  } +  void  _xattrop_index_action (xlator_t *this, inode_t *inode,  dict_t *xattr)  { diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index a6d02210..214923de 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -2868,10 +2868,10 @@ send_fuse_xattr (xlator_t *this, fuse_in_header_t *finh, const char *value,   * when it tries to setxattr() for selinux xattrs   */  static int -fuse_filter_xattr(xlator_t *this, char *key) +fuse_filter_xattr(char *key)  {          int need_filter = 0; -        struct fuse_private *priv = this->private; +        struct fuse_private *priv = THIS->private;          if ((priv->client_pid == GF_CLIENT_PID_GSYNCD)              && fnmatch ("*.selinux*", key, FNM_PERIOD) == 0) @@ -2892,6 +2892,7 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          data_t         *value_data = NULL;          int             ret = -1;          int32_t         len = 0; +        int32_t         len_next = 0;          state = frame->root->state;          finh  = state->finh; @@ -2922,32 +2923,20 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                          /* we need to invoke fuse_filter_xattr() twice. Once                           * while counting size and then while filling buffer                           */ -                        int _get_total_len (dict_t *d, char *k, data_t *v, -                                            void *tmp) -                        { -                                if (!fuse_filter_xattr (this, k)) -                                        len += strlen (k) + 1; -                                return 0; -                        } -                        dict_foreach (dict, _get_total_len, NULL); +                        len = dict_keys_join (NULL, 0, dict, fuse_filter_xattr); +                        if (len < 0) +                                goto out;                          value = alloca (len + 1);                          if (!value)                                  goto out; -                        len = 0; - -                        int _set_listxattr_keys (dict_t *d, char *k, data_t *v, -                                                 void *tmp) -                        { -                                if (!fuse_filter_xattr (this, k)) { -                                        strcpy (value + len, k); -                                        value[len + strlen (k)] = '\0'; -                                        len += strlen (k) + 1; -                                } -                                return 0; -                        } -                        dict_foreach (dict, _set_listxattr_keys, NULL); +                        len_next = dict_keys_join (value, len, dict, +                                                   fuse_filter_xattr); +                        if (len_next != len) +                                gf_log (THIS->name, GF_LOG_ERROR, +                                        "sizes not equal %d != %d", +                                        len, len_next);                          send_fuse_xattr (this, finh, value, len, state->size);                  } /* if(state->name)...else */ diff --git a/xlators/protocol/server/src/authenticate.c b/xlators/protocol/server/src/authenticate.c index 9c843d0b..eb6deb80 100644 --- a/xlators/protocol/server/src/authenticate.c +++ b/xlators/protocol/server/src/authenticate.c @@ -124,34 +124,41 @@ fini (dict_t *this, char *key, data_t *value, void *data)          return 0;  } +static int +_gf_auth_option_validate (dict_t *d, char *k, data_t *v, void *tmp) +{ +        auth_handle_t *handle = NULL; +        xlator_t      *xl = NULL; +        int ret = 0; + +        xl = tmp; + +        handle = data_to_ptr (v); +        if (!handle) +                return 0; + +        list_add_tail (&(handle->vol_opt->list), &(xl->volume_options)); + +        ret = xlator_options_validate_list (xl, xl->options, +                                            handle->vol_opt, NULL); +        if (ret) { +                gf_log ("authenticate", GF_LOG_ERROR, +                        "volume option validation failed"); +                return -1; +        } +        return 0; +} +  int32_t  gf_auth_init (xlator_t *xl, dict_t *auth_modules)  {          int ret = 0; -        auth_handle_t *handle = NULL;          dict_foreach (auth_modules, init, &ret);          if (ret)                  goto out; -        int _auth_option_validate (dict_t *d, char *k, data_t *v, void *tmp) -        { -                handle = data_to_ptr (v); -                if (!handle) -                        return 0; - -                list_add_tail (&(handle->vol_opt->list), -                               &(xl->volume_options)); -                ret = xlator_options_validate_list (xl, xl->options, -                                                    handle->vol_opt, NULL); -                if (ret) { -                        gf_log ("authenticate", GF_LOG_ERROR, -                                "volume option validation failed"); -                        return -1; -                } -                return 0; -        } -        ret = dict_foreach (auth_modules, _auth_option_validate, NULL); +        ret = dict_foreach (auth_modules, _gf_auth_option_validate, xl);  out:          if (ret) { diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c index 0adcd1cf..28b912ee 100644 --- a/xlators/protocol/server/src/server-helpers.c +++ b/xlators/protocol/server/src/server-helpers.c @@ -1397,16 +1397,8 @@ gf_server_check_setxattr_cmd (call_frame_t *frame, dict_t *dict)          if (!conf || !dict)                  return 0; -        /* this exact key is used in 'io-stats' too. -         * But this is better place for this information dump. -         */ -        int _handle_keyvalue_pair (dict_t *d, char *k, -                                   data_t *v, void *tmp) -        { -                return 0; -        }          if (dict_foreach_fnmatch (dict, "*io*stat*dump", -                                  _handle_keyvalue_pair, NULL ) > 0) { +                                  dict_null_foreach_fn, NULL ) > 0) {                  list_for_each_entry (xprt, &conf->xprt_list, list) {                          total_read  += xprt->total_bytes_read;                          total_write += xprt->total_bytes_write; diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c index 286befc4..f44ced41 100644 --- a/xlators/protocol/server/src/server-rpc-fops.c +++ b/xlators/protocol/server/src/server-rpc-fops.c @@ -890,6 +890,24 @@ out:          return 0;  } +/* print every key */ +static int +_gf_server_log_setxattr_failure (dict_t *d, char *k, data_t *v, +                                 void *tmp) +{ +        server_state_t *state = NULL; +        call_frame_t   *frame = NULL; + +        frame = tmp; +        state = CALL_STATE(frame); + +        gf_log (THIS->name, GF_LOG_INFO, +                "%"PRId64": SETXATTR %s (%s) ==> %s", +                frame->root->unique, state->loc.path, +                uuid_utoa (state->resolve.gfid), k); +        return 0; +} +  int  server_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                       int32_t op_ret, int32_t op_errno, dict_t *xdata) @@ -905,19 +923,14 @@ server_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                                      rsp.xdata.xdata_len, op_errno, out);          if (op_ret == -1) { -                /* print every key */ -                int _log_setxattr_failure (dict_t *d, char *k, data_t *v, -                                           void *tmp) -                { -                        gf_log (this->name, ((op_errno == ENOTSUP) ? -                                             GF_LOG_DEBUG : GF_LOG_INFO), -                                "%"PRId64": SETXATTR %s (%s) ==> %s (%s)", -                                frame->root->unique, state->loc.path, -                                uuid_utoa (state->resolve.gfid), k, -                                strerror (op_errno)); -                        return 0; -                } -                dict_foreach (state->dict, _log_setxattr_failure, NULL); +                if (op_errno != ENOTSUP) +                        dict_foreach (state->dict, +                                      _gf_server_log_setxattr_failure, +                                      frame); + +                gf_log (THIS->name, ((op_errno == ENOTSUP) ? +                                     GF_LOG_DEBUG : GF_LOG_INFO), +                        "%s", strerror (op_errno));                  goto out;          } @@ -933,6 +946,24 @@ out:          return 0;  } +/* print every key here */ +static int +_gf_server_log_fsetxattr_failure (dict_t *d, char *k, data_t *v, +                                 void *tmp) +{ +        call_frame_t   *frame = NULL; +        server_state_t *state = NULL; + +        frame = tmp; +        state = CALL_STATE(frame); + +        gf_log (THIS->name, GF_LOG_INFO, +                "%"PRId64": FSETXATTR %"PRId64" (%s) ==> %s", +                frame->root->unique, state->resolve.fd_no, +                uuid_utoa (state->resolve.gfid), k); + +        return 0; +}  int  server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, @@ -949,19 +980,14 @@ server_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                                      rsp.xdata.xdata_len, op_errno, out);          if (op_ret == -1) { -                /* print every key here */ -                int _log_setxattr_failure (dict_t *d, char *k, data_t *v, -                                           void *tmp) -                { -                        gf_log (this->name, ((op_errno == ENOTSUP) ? -                                             GF_LOG_DEBUG : GF_LOG_INFO), -                                "%"PRId64": FSETXATTR %"PRId64" (%s) ==> %s (%s)", -                                frame->root->unique, state->resolve.fd_no, -                                uuid_utoa (state->resolve.gfid), k, -                                strerror (op_errno)); -                        return 0; +                if (op_errno != ENOTSUP) { +                        dict_foreach (state->dict, +                                      _gf_server_log_fsetxattr_failure, +                                      frame);                  } -                dict_foreach (state->dict, _log_setxattr_failure, NULL); +                gf_log (THIS->name, ((op_errno == ENOTSUP) ? +                                     GF_LOG_DEBUG : GF_LOG_INFO), +                        "%s", strerror (op_errno));                  goto out;          } diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c index 19f09a82..d2bc4876 100644 --- a/xlators/protocol/server/src/server.c +++ b/xlators/protocol/server/src/server.c @@ -616,84 +616,85 @@ out:          return 0;  } +int +_check_for_auth_option (dict_t *d, char *k, data_t *v, +                        void *tmp) +{ +        int       ret           = 0; +        xlator_t *xl            = NULL; +        char     *tail          = NULL; +        char     *tmp_addr_list = NULL; +        char     *addr          = NULL; +        char     *tmp_str       = NULL; + +        xl = tmp; + +        tail = strtail (k, "auth."); +        if (!tail) +                goto out; + +        /* fast fwd thru module type */ +        tail = strchr (tail, '.'); +        if (!tail) +                goto out; +        tail++; + +        tail = strtail (tail, xl->name); +        if (!tail) +                goto out; + +        if (*tail == '.') { +                /* when we are here, the key is checked for +                 * valid auth.allow.<xlator> +                 * Now we verify the ip address +                 */ +                if (!strcmp (v->data, "*")) { +                        ret = 0; +                        goto out; +                } + +                tmp_addr_list = gf_strdup (v->data); +                addr = strtok_r (tmp_addr_list, ",", &tmp_str); +                if (!addr) +                        addr = v->data; + +                while (addr) { +                        if (valid_internet_address (addr, _gf_true)) { +                                ret = 0; +                        } else { +                                ret = -1; +                                gf_log (xl->name, GF_LOG_ERROR, +                                        "internet address '%s'" +                                        " does not conform to" +                                        " standards.", addr); +                                goto out; +                        } +                        if (tmp_str) +                                addr = strtok_r (NULL, ",", &tmp_str); +                        else +                                addr = NULL; +                } + +                GF_FREE (tmp_addr_list); +                tmp_addr_list = NULL; +        } +out: +        return ret; +}  int  validate_auth_options (xlator_t *this, dict_t *dict)  {          int            error = -1;          xlator_list_t *trav = NULL; -        char          *tail = NULL; -        char          *tmp_addr_list = NULL; -        char          *addr = NULL; -        char          *tmp_str = NULL;          GF_VALIDATE_OR_GOTO ("server", this, out);          GF_VALIDATE_OR_GOTO ("server", dict, out);          trav = this->children;          while (trav) { -                int _check_for_auth_option (dict_t *d, char *k, data_t *v, -                                            void *tmp) -                { -                        int ret = 0; -                        tail = strtail (k, "auth."); -                        if (!tail) -                                goto internal_out; - -                        /* fast fwd thru module type */ -                        tail = strchr (tail, '.'); -                        if (!tail) -                                goto internal_out; -                        tail++; - -                        tail = strtail (tail, trav->xlator->name); -                        if (!tail) -                                goto internal_out; - -                        if (*tail == '.') { - -                                /* when we are here, the key is checked for -                                 * valid auth.allow.<xlator> -                                 * Now we verify the ip address -                                 */ -                                if (!strcmp (v->data, "*")) { -                                        ret = 0; -                                        goto internal_out; -                                } - -                                tmp_addr_list = gf_strdup (v->data); -                                addr = strtok_r (tmp_addr_list, ",", &tmp_str); -                                if (!addr) -                                        addr = v->data; - -                                while (addr) { - -                                        if (valid_internet_address (addr, -                                                                    _gf_true)) { -                                                ret = 0; -                                        } else { -                                                ret = -1; -                                                gf_log (this->name, GF_LOG_ERROR, -                                                        "internet address '%s'" -                                                        " does not conform to" -                                                        " standards.", addr); -                                                goto internal_out; - -                                        } -                                        if (tmp_str) -                                                addr = strtok_r (NULL, ",", -                                                                 &tmp_str); -                                        else -                                                addr = NULL; -                                } - -                                GF_FREE (tmp_addr_list); -                                tmp_addr_list = NULL; -                        } -                internal_out: -                        return ret; -                } -                error = dict_foreach (dict, _check_for_auth_option, NULL); +                error = dict_foreach (dict, _check_for_auth_option, +                                      trav->xlator);                  if (-1 == error) {                          gf_log (this->name, GF_LOG_ERROR, @@ -706,7 +707,6 @@ validate_auth_options (xlator_t *this, dict_t *dict)          }  out: -        GF_FREE (tmp_addr_list);          return error;  } diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c index 58708a34..7e8d5838 100644 --- a/xlators/storage/posix/src/posix-helpers.c +++ b/xlators/storage/posix/src/posix-helpers.c @@ -46,14 +46,6 @@  #include "hashfn.h"  #include <fnmatch.h> -typedef struct { -        xlator_t    *this; -        const char  *real_path; -        dict_t      *xattr; -        struct iatt *stbuf; -        loc_t       *loc; -} posix_xattr_filler_t; -  char *marker_xattrs[] = {"trusted.glusterfs.quota.*",                           "trusted.glusterfs.*.xtime",                           NULL}; @@ -946,35 +938,47 @@ out:          return ret;  } +static int +_handle_entry_create_keyvalue_pair (dict_t *d, char *k, data_t *v, +                                    void *tmp) +{ +        int                   ret = -1; +        posix_xattr_filler_t *filler = NULL; + +        filler = tmp; + +        if (!strcmp (GFID_XATTR_KEY, k) || +            !strcmp ("gfid-req", k) || +            !strcmp ("system.posix_acl_default", k) || +            !strcmp ("system.posix_acl_access", k) || +            ZR_FILE_CONTENT_REQUEST(k)) { +                return 0; +        } + +        ret = posix_handle_pair (filler->this, filler->real_path, k, v, +                                 XATTR_CREATE); +        if (ret < 0) { +                errno = -ret; +                return -1; +        } +        return 0; +} +  int  posix_entry_create_xattr_set (xlator_t *this, const char *path,                               dict_t *dict)  {          int ret = -1; +        posix_xattr_filler_t filler = {0,}; +          if (!dict)                  goto out; -        int _handle_keyvalue_pair (dict_t *d, char *k, data_t *v, -                                   void *tmp) -        { -                if (!strcmp (GFID_XATTR_KEY, k) || -                    !strcmp ("gfid-req", k) || -                    !strcmp ("system.posix_acl_default", k) || -                    !strcmp ("system.posix_acl_access", k) || -                    ZR_FILE_CONTENT_REQUEST(k)) { -                        return 0; -                } - -                ret = posix_handle_pair (this, path, k, v, XATTR_CREATE); -                if (ret < 0) { -                        errno = -ret; -                        return -1; -                } -                return 0; -        } +        filler.this = this; +        filler.real_path = path; -        ret = dict_foreach (dict, _handle_keyvalue_pair, NULL); +        ret = dict_foreach (dict, _handle_entry_create_keyvalue_pair, &filler);  out:          return ret; diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 81601154..258ce524 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -2382,6 +2382,17 @@ out:  }  static int gf_posix_xattr_enotsup_log; +static int +_handle_setxattr_keyvalue_pair (dict_t *d, char *k, data_t *v, +                                void *tmp) +{ +        posix_xattr_filler_t *filler = NULL; + +        filler = tmp; + +        return posix_handle_pair (filler->this, filler->real_path, k, v, +                                  filler->flags); +}  int32_t  posix_setxattr (call_frame_t *frame, xlator_t *this, @@ -2390,7 +2401,8 @@ posix_setxattr (call_frame_t *frame, xlator_t *this,          int32_t       op_ret                  = -1;          int32_t       op_errno                = 0;          char *        real_path               = NULL; -        int           ret                     = -1; + +        posix_xattr_filler_t filler = {0,};          DECLARE_OLD_FS_ID_VAR;          SET_FS_ID (frame->root->uid, frame->root->gid); @@ -2405,17 +2417,13 @@ posix_setxattr (call_frame_t *frame, xlator_t *this,          op_ret = -1;          dict_del (dict, GFID_XATTR_KEY); - -        int _handle_every_keyvalue_pair (dict_t *d, char *k, data_t *v, -                                         void *tmp) -        { -                ret = posix_handle_pair (this, real_path, k, v, flags); -                if (ret < 0) { -                        op_errno = -ret; -                } -                return ret; -        } -        op_ret = dict_foreach (dict, _handle_every_keyvalue_pair, NULL); +        filler.real_path = real_path; +        filler.this = this; +        filler.flags = flags; +        op_ret = dict_foreach (dict, _handle_setxattr_keyvalue_pair, +                               &filler); +        if (op_ret < 0) +                op_errno = -op_ret;  out:          SET_TO_OLD_FS_ID (); @@ -2899,6 +2907,17 @@ out:          return 0;  } +static int +_handle_fsetxattr_keyvalue_pair (dict_t *d, char *k, data_t *v, +                                void *tmp) +{ +        posix_xattr_filler_t *filler = NULL; + +        filler = tmp; + +        return posix_fhandle_pair (filler->this, filler->fd, k, v, +                                   filler->flags); +}  int32_t  posix_fsetxattr (call_frame_t *frame, xlator_t *this, @@ -2908,7 +2927,9 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this,          int32_t            op_errno     = 0;          struct posix_fd *  pfd          = NULL;          int                _fd          = -1; -        int           ret               = -1; +        int                ret          = -1; + +        posix_xattr_filler_t filler = {0,};          DECLARE_OLD_FS_ID_VAR;          SET_FS_ID (frame->root->uid, frame->root->gid); @@ -2929,17 +2950,13 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this,          dict_del (dict, GFID_XATTR_KEY); -        int _handle_every_keyvalue_pair (dict_t *d, char *k, data_t *v, -                                         void *tmp) -        { -                ret = posix_fhandle_pair (this, _fd, k, v, flags); -                if (ret < 0) { -                        op_errno = -ret; -                } -                return ret; -        } - -        op_ret = dict_foreach (dict, _handle_every_keyvalue_pair, NULL); +        filler.fd = _fd; +        filler.this = this; +        filler.flags = flags; +        op_ret = dict_foreach (dict, _handle_fsetxattr_keyvalue_pair, +                               &filler); +        if (op_ret < 0) +                op_errno = -op_ret;  out:          SET_TO_OLD_FS_ID (); @@ -3130,6 +3147,159 @@ __add_long_array (int64_t *dest, int64_t *src, int count)          }  } +static int +_posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v, +                                   void *tmp) +{ +        int                   size     = 0; +        int                   count    = 0; +        int                   op_ret   = 0; +        int                   op_errno = 0; +        gf_xattrop_flags_t    optype   = 0; +        char                 *array    = NULL; +        inode_t              *inode    = NULL; +        xlator_t             *this     = NULL; +        posix_xattr_filler_t *filler   = NULL; + +        filler = tmp; + +        optype = (gf_xattrop_flags_t)(filler->flags); +        this = filler->this; +        inode = filler->inode; + +        count = v->len; +        array = GF_CALLOC (count, sizeof (char), gf_posix_mt_char); + +        LOCK (&inode->lock); +        { +                if (filler->real_path) { +                        size = sys_lgetxattr (filler->real_path, k, +                                              (char *)array, v->len); +                } else { +                        size = sys_fgetxattr (filler->fd, k, (char *)array, +                                              v->len); +                } + +                op_errno = errno; +                if ((size == -1) && (op_errno != ENODATA) && +                    (op_errno != ENOATTR)) { +                        if (op_errno == ENOTSUP) { +                                GF_LOG_OCCASIONALLY(gf_posix_xattr_enotsup_log, +                                                    this->name, GF_LOG_WARNING, +                                                    "Extended attributes not " +                                                    "supported by filesystem"); +                        } else if (op_errno != ENOENT || +                                   !posix_special_xattr (marker_xattrs, +                                                         k)) { +                                if (filler->real_path) +                                        gf_log (this->name, GF_LOG_ERROR, +                                                "getxattr failed on %s while doing " +                                                "xattrop: Key:%s (%s)", +                                                filler->real_path, +                                                k, strerror (op_errno)); +                                else +                                        gf_log (this->name, GF_LOG_ERROR, +                                                "fgetxattr failed on fd=%d while doing " +                                                "xattrop: Key:%s (%s)", +                                                filler->fd, +                                                k, strerror (op_errno)); +                        } + +                        op_ret = -1; +                        goto unlock; +                } + +                switch (optype) { + +                case GF_XATTROP_ADD_ARRAY: +                        __add_array ((int32_t *) array, (int32_t *) v->data, +                                     v->len / 4); +                        break; + +                case GF_XATTROP_ADD_ARRAY64: +                        __add_long_array ((int64_t *) array, (int64_t *) v->data, +                                          v->len / 8); +                        break; + +                case GF_XATTROP_OR_ARRAY: +                        __or_array ((int32_t *) array, +                                    (int32_t *) v->data, +                                    v->len / 4); +                        break; + +                case GF_XATTROP_AND_ARRAY: +                        __and_array ((int32_t *) array, +                                     (int32_t *) v->data, +                                     v->len / 4); +                        break; + +                default: +                        gf_log (this->name, GF_LOG_ERROR, +                                "Unknown xattrop type (%d) on %s. Please send " +                                "a bug report to gluster-devel@nongnu.org", +                                optype, filler->real_path); +                        op_ret = -1; +                        op_errno = EINVAL; +                        goto unlock; +                } + +                if (filler->real_path) { +                        size = sys_lsetxattr (filler->real_path, k, array, +                                              v->len, 0); +                } else { +                        size = sys_fsetxattr (filler->fd, k, (char *)array, +                                              v->len, 0); +                } +        } +unlock: +        UNLOCK (&inode->lock); + +        if (op_ret == -1) +                goto out; + +        op_errno = errno; +        if (size == -1) { +                if (filler->real_path) +                        gf_log (this->name, GF_LOG_ERROR, +                                "setxattr failed on %s while doing xattrop: " +                                "key=%s (%s)", filler->real_path, +                                k, strerror (op_errno)); +                else +                        gf_log (this->name, GF_LOG_ERROR, +                                "fsetxattr failed on fd=%d while doing xattrop: " +                                "key=%s (%s)", filler->fd, +                                k, strerror (op_errno)); + +                op_ret = -1; +                goto out; +        } else { +                size = dict_set_bin (d, k, array, v->len); + +                if (size != 0) { +                        if (filler->real_path) +                                gf_log (this->name, GF_LOG_DEBUG, +                                        "dict_set_bin failed (path=%s): " +                                        "key=%s (%s)", filler->real_path, +                                        k, strerror (-size)); +                        else +                                gf_log (this->name, GF_LOG_DEBUG, +                                        "dict_set_bin failed (fd=%d): " +                                        "key=%s (%s)", filler->fd, +                                        k, strerror (-size)); + +                        op_ret = -1; +                        op_errno = EINVAL; +                        goto out; +                } +                array = NULL; +        } + +        array = NULL; + +out: +        return op_ret; +} +  /**   * xattrop - xattr operations - for internal use by GlusterFS   * @optype: ADD_ARRAY: @@ -3141,32 +3311,24 @@ int  do_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,              gf_xattrop_flags_t optype, dict_t *xattr)  { -        char            *real_path = NULL; -        char            *array = NULL; -        int              size = 0; -        int              count = 0; - -        int              op_ret = 0; -        int              op_errno = 0; - -        int              ret = 0; -        int              _fd = -1; -        struct posix_fd *pfd = NULL; - -        char *    path  = NULL; -        inode_t * inode = NULL; +        int                   op_ret    = 0; +        int                   op_errno  = 0; +        int                   _fd       = -1; +        char                 *real_path = NULL; +        struct posix_fd      *pfd       = NULL; +        inode_t              *inode     = NULL; +        posix_xattr_filler_t  filler    = {0,};          VALIDATE_OR_GOTO (frame, out);          VALIDATE_OR_GOTO (xattr, out);          VALIDATE_OR_GOTO (this, out);          if (fd) { -                ret = posix_fd_ctx_get (fd, this, &pfd); -                if (ret < 0) { +                op_ret = posix_fd_ctx_get (fd, this, &pfd); +                if (op_ret < 0) {                          gf_log (this->name, GF_LOG_WARNING,                                  "failed to get pfd from fd=%p",                                  fd); -                        op_ret = -1;                          op_errno = EBADFD;                          goto out;                  } @@ -3177,152 +3339,21 @@ do_xattrop (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,                  MAKE_INODE_HANDLE (real_path, this, loc, NULL);          if (real_path) { -                path  = gf_strdup (real_path);                  inode = loc->inode;          } else if (fd) {                  inode = fd->inode;          } -        int _handle_every_keyvalue_pair (dict_t *d, char *k, data_t *v, -                                         void *tmp) -        { - -                count = v->len; -                array = GF_CALLOC (count, sizeof (char), gf_posix_mt_char); - -                LOCK (&inode->lock); -                { -                        if (loc) { -                                size = sys_lgetxattr (real_path, k, -                                                      (char *)array, v->len); -                        } else { -                                size = sys_fgetxattr (_fd, k, (char *)array, -                                                      v->len); -                        } - -                        op_errno = errno; -                        if ((size == -1) && (op_errno != ENODATA) && -                            (op_errno != ENOATTR)) { -                                if (op_errno == ENOTSUP) { -                                        GF_LOG_OCCASIONALLY(gf_posix_xattr_enotsup_log, -                                                            this->name,GF_LOG_WARNING, -                                                            "Extended attributes not " -                                                            "supported by filesystem"); -                                } else if (op_errno != ENOENT || -                                           !posix_special_xattr (marker_xattrs, -                                                                 k)) { -                                        if (loc) -                                                gf_log (this->name, GF_LOG_ERROR, -                                                        "getxattr failed on %s while doing " -                                                        "xattrop: Key:%s (%s)", path, -                                                        k, strerror (op_errno)); -                                        else -                                                gf_log (this->name, GF_LOG_ERROR, -                                                        "fgetxattr failed on fd=%d while doing " -                                                        "xattrop: Key:%s (%s)", _fd, -                                                        k, strerror (op_errno)); -                                } - -                                op_ret = -1; -                                goto unlock; -                        } - -                        switch (optype) { - -                        case GF_XATTROP_ADD_ARRAY: -                                __add_array ((int32_t *) array, (int32_t *) v->data, -                                             v->len / 4); -                                break; +        filler.this = this; +        filler.fd = _fd; +        filler.real_path = real_path; +        filler.flags = (int)optype; +        filler.inode = inode; -                        case GF_XATTROP_ADD_ARRAY64: -                                __add_long_array ((int64_t *) array, (int64_t *) v->data, -                                                  v->len / 8); -                                break; - -                        case GF_XATTROP_OR_ARRAY: -                                __or_array ((int32_t *) array, -                                            (int32_t *) v->data, -                                            v->len / 4); -                                break; - -                        case GF_XATTROP_AND_ARRAY: -                                __and_array ((int32_t *) array, -                                             (int32_t *) v->data, -                                             v->len / 4); -                                break; - -                        default: -                                gf_log (this->name, GF_LOG_ERROR, -                                        "Unknown xattrop type (%d) on %s. Please send " -                                        "a bug report to gluster-devel@nongnu.org", -                                        optype, path); -                                op_ret = -1; -                                op_errno = EINVAL; -                                goto unlock; -                        } - -                        if (loc) { -                                size = sys_lsetxattr (real_path, k, array, -                                                      v->len, 0); -                        } else { -                                size = sys_fsetxattr (_fd, k, (char *)array, -                                                      v->len, 0); -                        } -                } -        unlock: -                UNLOCK (&inode->lock); - -                if (op_ret == -1) -                        goto out; - -                op_errno = errno; -                if (size == -1) { -                        if (loc) -                                gf_log (this->name, GF_LOG_ERROR, -                                        "setxattr failed on %s while doing xattrop: " -                                        "key=%s (%s)", path, -                                        k, strerror (op_errno)); -                        else -                                gf_log (this->name, GF_LOG_ERROR, -                                        "fsetxattr failed on fd=%d while doing xattrop: " -                                        "key=%s (%s)", _fd, -                                        k, strerror (op_errno)); - -                        op_ret = -1; -                        goto out; -                } else { -                        size = dict_set_bin (xattr, k, array, v->len); - -                        if (size != 0) { -                                if (loc) -                                        gf_log (this->name, GF_LOG_DEBUG, -                                                "dict_set_bin failed (path=%s): " -                                                "key=%s (%s)", path, -                                                k, strerror (-size)); -                                else -                                        gf_log (this->name, GF_LOG_DEBUG, -                                                "dict_set_bin failed (fd=%d): " -                                                "key=%s (%s)", _fd, -                                                k, strerror (-size)); - -                                op_ret = -1; -                                op_errno = EINVAL; -                                goto out; -                        } -                        array = NULL; -                } - -                array = NULL; - -        out: -                return op_ret; -        } -        op_ret = dict_foreach (xattr, _handle_every_keyvalue_pair, NULL); +        op_ret = dict_foreach (xattr, _posix_handle_xattr_keyvalue_pair, +                               &filler);  out: -        GF_FREE (array); - -        GF_FREE (path);          STACK_UNWIND_STRICT (xattrop, frame, op_ret, op_errno, xattr, NULL);          return 0; diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index 45ee3596..4703a1fd 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -127,6 +127,18 @@ struct posix_private {  #endif  }; +typedef struct { +        xlator_t    *this; +        const char  *real_path; +        dict_t      *xattr; +        struct iatt *stbuf; +        loc_t       *loc; +        inode_t     *inode; /* for all do_xattrop() key handling */ +        int          fd; +        int          flags; +} posix_xattr_filler_t; + +  #define POSIX_BASE_PATH(this) (((struct posix_private *)this->private)->base_path)  #define POSIX_BASE_PATH_LEN(this) (((struct posix_private *)this->private)->base_path_length)  | 
