diff options
Diffstat (limited to 'xlators/nfs/server/src/auth-cache.c')
| -rw-r--r-- | xlators/nfs/server/src/auth-cache.c | 543 | 
1 files changed, 273 insertions, 270 deletions
diff --git a/xlators/nfs/server/src/auth-cache.c b/xlators/nfs/server/src/auth-cache.c index a1aacaba61a..248a90b0587 100644 --- a/xlators/nfs/server/src/auth-cache.c +++ b/xlators/nfs/server/src/auth-cache.c @@ -18,44 +18,48 @@  #include "nfs-messages.h"  enum auth_cache_lookup_results { -        ENTRY_FOUND     =  0, -        ENTRY_NOT_FOUND = -1, -        ENTRY_EXPIRED   = -2, +    ENTRY_FOUND = 0, +    ENTRY_NOT_FOUND = -1, +    ENTRY_EXPIRED = -2,  };  struct auth_cache_entry { -        GF_REF_DECL;                    /* refcounting */ -        data_t             *data;       /* data_unref() on refcount == 0 */ +    GF_REF_DECL;  /* refcounting */ +    data_t *data; /* data_unref() on refcount == 0 */ -        time_t              timestamp; -        struct export_item *item; +    time_t timestamp; +    struct export_item *item;  };  /* Given a filehandle and an ip, creates a colon delimited hashkey.   */ -static char* +static char *  make_hashkey(struct nfs3_fh *fh, const char *host)  { -        char   *hashkey          = NULL; -        char    exportid[256]    = {0, }; -        char    gfid[256]        = {0, }; -        char    mountid[256]     = {0, }; -        size_t  nbytes           = 0; - -        gf_uuid_unparse (fh->exportid, exportid); -        gf_uuid_unparse (fh->gfid, gfid); -        gf_uuid_unparse (fh->mountid, mountid); - -        nbytes = strlen (exportid) + strlen (host) -                 + strlen (mountid) + 3; -        hashkey = GF_MALLOC (nbytes, gf_common_mt_char); -        if (!hashkey) -                return NULL; - -        snprintf (hashkey, nbytes, "%s:%s:%s", exportid, -                  mountid, host); - -        return hashkey; +    char *hashkey = NULL; +    char exportid[256] = { +        0, +    }; +    char gfid[256] = { +        0, +    }; +    char mountid[256] = { +        0, +    }; +    size_t nbytes = 0; + +    gf_uuid_unparse(fh->exportid, exportid); +    gf_uuid_unparse(fh->gfid, gfid); +    gf_uuid_unparse(fh->mountid, mountid); + +    nbytes = strlen(exportid) + strlen(host) + strlen(mountid) + 3; +    hashkey = GF_MALLOC(nbytes, gf_common_mt_char); +    if (!hashkey) +        return NULL; + +    snprintf(hashkey, nbytes, "%s:%s:%s", exportid, mountid, host); + +    return hashkey;  }  /** @@ -66,24 +70,24 @@ make_hashkey(struct nfs3_fh *fh, const char *host)   * @return : allocated auth cache struct, NULL if allocation failed.   */  struct auth_cache * -auth_cache_init (time_t ttl_sec) +auth_cache_init(time_t ttl_sec)  { -        struct auth_cache *cache = GF_CALLOC (1, sizeof (*cache), -                                              gf_nfs_mt_auth_cache); +    struct auth_cache *cache = GF_CALLOC(1, sizeof(*cache), +                                         gf_nfs_mt_auth_cache); -        GF_VALIDATE_OR_GOTO ("auth-cache", cache, out); +    GF_VALIDATE_OR_GOTO("auth-cache", cache, out); -        cache->cache_dict = dict_new (); -        if (!cache->cache_dict) { -                GF_FREE (cache); -                cache = NULL; -                goto out; -        } +    cache->cache_dict = dict_new(); +    if (!cache->cache_dict) { +        GF_FREE(cache); +        cache = NULL; +        goto out; +    } -        LOCK_INIT (&cache->lock); -        cache->ttl_sec = ttl_sec; +    LOCK_INIT(&cache->lock); +    cache->ttl_sec = ttl_sec;  out: -        return cache; +    return cache;  }  /* auth_cache_entry_free -- called by refcounting subsystem on refcount == 0 @@ -91,22 +95,22 @@ out:   * @to_free: auth_cache_entry that has refcount == 0 and needs to get free'd   */  void -auth_cache_entry_free (void *to_free) +auth_cache_entry_free(void *to_free)  { -        struct auth_cache_entry *entry      = to_free; -        data_t                  *entry_data = NULL; +    struct auth_cache_entry *entry = to_free; +    data_t *entry_data = NULL; -        GF_VALIDATE_OR_GOTO (GF_NFS, entry, out); -        GF_VALIDATE_OR_GOTO (GF_NFS, entry->data, out); +    GF_VALIDATE_OR_GOTO(GF_NFS, entry, out); +    GF_VALIDATE_OR_GOTO(GF_NFS, entry->data, out); -        entry_data = entry->data; -        /* set data_t->data to NULL, otherwise data_unref() tries to free it */ -        entry_data->data = NULL; -        data_unref (entry_data); +    entry_data = entry->data; +    /* set data_t->data to NULL, otherwise data_unref() tries to free it */ +    entry_data->data = NULL; +    data_unref(entry_data); -        GF_FREE (entry); +    GF_FREE(entry);  out: -        return; +    return;  }  /** @@ -116,18 +120,18 @@ out:   *          failed.   */  static struct auth_cache_entry * -auth_cache_entry_init () +auth_cache_entry_init()  { -        struct auth_cache_entry *entry = NULL; +    struct auth_cache_entry *entry = NULL; -        entry = GF_CALLOC (1, sizeof (*entry), gf_nfs_mt_auth_cache_entry); -        if (!entry) -                gf_msg (GF_NFS, GF_LOG_WARNING, ENOMEM, NFS_MSG_NO_MEMORY, -                        "failed to allocate entry"); -        else -                GF_REF_INIT (entry, auth_cache_entry_free); +    entry = GF_CALLOC(1, sizeof(*entry), gf_nfs_mt_auth_cache_entry); +    if (!entry) +        gf_msg(GF_NFS, GF_LOG_WARNING, ENOMEM, NFS_MSG_NO_MEMORY, +               "failed to allocate entry"); +    else +        GF_REF_INIT(entry, auth_cache_entry_free); -        return entry; +    return entry;  }  /** @@ -136,46 +140,46 @@ auth_cache_entry_init ()   * @return: 0 on success, non-zero otherwise.   */  static int -auth_cache_add (struct auth_cache *cache, char *hashkey, -                struct auth_cache_entry *entry) +auth_cache_add(struct auth_cache *cache, char *hashkey, +               struct auth_cache_entry *entry)  { -        int      ret        = -1; -        data_t  *entry_data = NULL; - -        GF_VALIDATE_OR_GOTO (GF_NFS, cache, out); -        GF_VALIDATE_OR_GOTO (GF_NFS, cache->cache_dict, out); - -        /* FIXME: entry is passed as parameter, this can never fail? */ -        entry = GF_REF_GET (entry); -        if (!entry) { -                /* entry does not have any references */ -                ret = -1; -                goto out; -        } - -        entry_data = bin_to_data (entry, sizeof (*entry)); -        if (!entry_data) { -                ret = -1; -                GF_REF_PUT (entry); -                goto out; -        } - -        /* we'll take an extra ref on the data_t, it gets unref'd when the -         * auth_cache_entry is released */ -        entry->data = data_ref (entry_data); - -        LOCK (&cache->lock); -        { -                ret = dict_set (cache->cache_dict, hashkey, entry_data); -        } -        UNLOCK (&cache->lock); - -        if (ret) { -                /* adding to dict failed */ -                GF_REF_PUT (entry); -        } +    int ret = -1; +    data_t *entry_data = NULL; + +    GF_VALIDATE_OR_GOTO(GF_NFS, cache, out); +    GF_VALIDATE_OR_GOTO(GF_NFS, cache->cache_dict, out); + +    /* FIXME: entry is passed as parameter, this can never fail? */ +    entry = GF_REF_GET(entry); +    if (!entry) { +        /* entry does not have any references */ +        ret = -1; +        goto out; +    } + +    entry_data = bin_to_data(entry, sizeof(*entry)); +    if (!entry_data) { +        ret = -1; +        GF_REF_PUT(entry); +        goto out; +    } + +    /* we'll take an extra ref on the data_t, it gets unref'd when the +     * auth_cache_entry is released */ +    entry->data = data_ref(entry_data); + +    LOCK(&cache->lock); +    { +        ret = dict_set(cache->cache_dict, hashkey, entry_data); +    } +    UNLOCK(&cache->lock); + +    if (ret) { +        /* adding to dict failed */ +        GF_REF_PUT(entry); +    }  out: -        return ret; +    return ret;  }  /** @@ -186,9 +190,9 @@ out:   * @return: true when the auth_cache_entry is expired, false otherwise.   */  static int -_auth_cache_expired (struct auth_cache *cache, struct auth_cache_entry *entry) +_auth_cache_expired(struct auth_cache *cache, struct auth_cache_entry *entry)  { -        return ((time (NULL) - entry->timestamp) > cache->ttl_sec); +    return ((time(NULL) - entry->timestamp) > cache->ttl_sec);  }  /** @@ -205,52 +209,52 @@ _auth_cache_expired (struct auth_cache *cache, struct auth_cache_entry *entry)   * @return: 0 when found, ENTRY_NOT_FOUND or ENTRY_EXPIRED otherwise.   */  static enum auth_cache_lookup_results -auth_cache_get (struct auth_cache *cache, char *hashkey, -                struct auth_cache_entry **entry) +auth_cache_get(struct auth_cache *cache, char *hashkey, +               struct auth_cache_entry **entry)  { -        enum auth_cache_lookup_results  ret        = ENTRY_NOT_FOUND; -        data_t                         *entry_data = NULL; -        struct auth_cache_entry        *lookup_res = NULL; - -        GF_VALIDATE_OR_GOTO (GF_NFS, cache, out); -        GF_VALIDATE_OR_GOTO (GF_NFS, cache->cache_dict, out); -        GF_VALIDATE_OR_GOTO (GF_NFS, hashkey, out); - -        LOCK (&cache->lock); -        { -                entry_data = dict_get (cache->cache_dict, hashkey); -                if (!entry_data) -                        goto unlock; - -                /* FIXME: this is dangerous use of entry_data */ -                lookup_res = GF_REF_GET ((struct auth_cache_entry *) entry_data->data); -                if (lookup_res == NULL) { -                        /* entry has been free'd */ -                        ret = ENTRY_EXPIRED; -                        goto unlock; -                } - -                if (_auth_cache_expired (cache, lookup_res)) { -                        ret = ENTRY_EXPIRED; -                        GF_REF_PUT (lookup_res->item); -                        lookup_res->item = NULL; - -                        /* free entry and remove from the cache */ -                        GF_FREE (lookup_res); -                        entry_data->data = NULL; -                        dict_del (cache->cache_dict, hashkey); - -                        goto unlock; -                } - -                *entry = lookup_res; -                ret = ENTRY_FOUND; +    enum auth_cache_lookup_results ret = ENTRY_NOT_FOUND; +    data_t *entry_data = NULL; +    struct auth_cache_entry *lookup_res = NULL; + +    GF_VALIDATE_OR_GOTO(GF_NFS, cache, out); +    GF_VALIDATE_OR_GOTO(GF_NFS, cache->cache_dict, out); +    GF_VALIDATE_OR_GOTO(GF_NFS, hashkey, out); + +    LOCK(&cache->lock); +    { +        entry_data = dict_get(cache->cache_dict, hashkey); +        if (!entry_data) +            goto unlock; + +        /* FIXME: this is dangerous use of entry_data */ +        lookup_res = GF_REF_GET((struct auth_cache_entry *)entry_data->data); +        if (lookup_res == NULL) { +            /* entry has been free'd */ +            ret = ENTRY_EXPIRED; +            goto unlock; +        } + +        if (_auth_cache_expired(cache, lookup_res)) { +            ret = ENTRY_EXPIRED; +            GF_REF_PUT(lookup_res->item); +            lookup_res->item = NULL; + +            /* free entry and remove from the cache */ +            GF_FREE(lookup_res); +            entry_data->data = NULL; +            dict_del(cache->cache_dict, hashkey); + +            goto unlock;          } + +        *entry = lookup_res; +        ret = ENTRY_FOUND; +    }  unlock: -        UNLOCK (&cache->lock); +    UNLOCK(&cache->lock);  out: -        return ret; +    return ret;  }  /** @@ -270,49 +274,47 @@ out:   *          0 if found   */  enum auth_cache_lookup_results -auth_cache_lookup (struct auth_cache *cache, struct nfs3_fh *fh, -                   const char *host_addr, time_t *timestamp, -                   gf_boolean_t *can_write) +auth_cache_lookup(struct auth_cache *cache, struct nfs3_fh *fh, +                  const char *host_addr, time_t *timestamp, +                  gf_boolean_t *can_write)  { -        char                           *hashkey    = NULL; -        struct auth_cache_entry        *lookup_res = NULL; -        enum auth_cache_lookup_results  ret        = ENTRY_NOT_FOUND; - -        GF_VALIDATE_OR_GOTO (GF_NFS, cache, out); -        GF_VALIDATE_OR_GOTO (GF_NFS, fh, out); -        GF_VALIDATE_OR_GOTO (GF_NFS, host_addr, out); -        GF_VALIDATE_OR_GOTO (GF_NFS, timestamp, out); -        GF_VALIDATE_OR_GOTO (GF_NFS, can_write, out); - -        hashkey = make_hashkey (fh, host_addr); -        if (!hashkey) { -                ret = -ENOMEM; -                goto out; -        } - -        ret = auth_cache_get (cache, hashkey, &lookup_res); -        switch (ret) { +    char *hashkey = NULL; +    struct auth_cache_entry *lookup_res = NULL; +    enum auth_cache_lookup_results ret = ENTRY_NOT_FOUND; + +    GF_VALIDATE_OR_GOTO(GF_NFS, cache, out); +    GF_VALIDATE_OR_GOTO(GF_NFS, fh, out); +    GF_VALIDATE_OR_GOTO(GF_NFS, host_addr, out); +    GF_VALIDATE_OR_GOTO(GF_NFS, timestamp, out); +    GF_VALIDATE_OR_GOTO(GF_NFS, can_write, out); + +    hashkey = make_hashkey(fh, host_addr); +    if (!hashkey) { +        ret = -ENOMEM; +        goto out; +    } + +    ret = auth_cache_get(cache, hashkey, &lookup_res); +    switch (ret) {          case ENTRY_FOUND: -                *timestamp = lookup_res->timestamp; -                *can_write = lookup_res->item->opts->rw; -                GF_REF_PUT (lookup_res); -                break; +            *timestamp = lookup_res->timestamp; +            *can_write = lookup_res->item->opts->rw; +            GF_REF_PUT(lookup_res); +            break;          case ENTRY_NOT_FOUND: -                gf_msg_debug (GF_NFS, 0, "could not find entry for %s", -                              host_addr); -                break; +            gf_msg_debug(GF_NFS, 0, "could not find entry for %s", host_addr); +            break;          case ENTRY_EXPIRED: -                gf_msg_debug (GF_NFS, 0, "entry for host %s has expired", -                              host_addr); -                break; -        } +            gf_msg_debug(GF_NFS, 0, "entry for host %s has expired", host_addr); +            break; +    }  out: -        GF_FREE (hashkey); +    GF_FREE(hashkey); -        return ret; +    return ret;  }  /* auth_cache_entry_purge -- free up the auth_cache_entry @@ -327,14 +329,14 @@ out:   * @v: data_t of the current entry   */  int -auth_cache_entry_purge (dict_t *d, char *k, data_t *v, void *_unused) +auth_cache_entry_purge(dict_t *d, char *k, data_t *v, void *_unused)  { -        struct auth_cache_entry *entry = (struct auth_cache_entry *) v->data; +    struct auth_cache_entry *entry = (struct auth_cache_entry *)v->data; -        if (entry) -                GF_REF_PUT (entry); +    if (entry) +        GF_REF_PUT(entry); -        return 0; +    return 0;  }  /** @@ -344,26 +346,26 @@ auth_cache_entry_purge (dict_t *d, char *k, data_t *v, void *_unused)   *   */  void -auth_cache_purge (struct auth_cache *cache) +auth_cache_purge(struct auth_cache *cache)  { -        dict_t *new_cache_dict = dict_new (); -        dict_t *old_cache_dict = NULL; - -        if (!cache || !new_cache_dict) -                goto out; - -        LOCK (&cache->lock); -        { -                old_cache_dict = cache->cache_dict; -                cache->cache_dict = new_cache_dict; -        } -        UNLOCK (&cache->lock); - -        /* walk all entries and refcount-- with GF_REF_PUT() */ -        dict_foreach (old_cache_dict, auth_cache_entry_purge, NULL); -        dict_unref (old_cache_dict); +    dict_t *new_cache_dict = dict_new(); +    dict_t *old_cache_dict = NULL; + +    if (!cache || !new_cache_dict) +        goto out; + +    LOCK(&cache->lock); +    { +        old_cache_dict = cache->cache_dict; +        cache->cache_dict = new_cache_dict; +    } +    UNLOCK(&cache->lock); + +    /* walk all entries and refcount-- with GF_REF_PUT() */ +    dict_foreach(old_cache_dict, auth_cache_entry_purge, NULL); +    dict_unref(old_cache_dict);  out: -        return; +    return;  }  /** @@ -378,25 +380,24 @@ out:   *   */  gf_boolean_t -is_nfs_fh_cached (struct auth_cache *cache, struct nfs3_fh *fh, -                  const char *host_addr) +is_nfs_fh_cached(struct auth_cache *cache, struct nfs3_fh *fh, +                 const char *host_addr)  { -        int          ret       = 0; -        time_t       timestamp = 0; -        gf_boolean_t cached    = _gf_false; -        gf_boolean_t can_write = _gf_false; +    int ret = 0; +    time_t timestamp = 0; +    gf_boolean_t cached = _gf_false; +    gf_boolean_t can_write = _gf_false; -        if (!fh) -                goto out; +    if (!fh) +        goto out; -        ret = auth_cache_lookup (cache, fh, host_addr, ×tamp, &can_write); -        cached = (ret == ENTRY_FOUND); +    ret = auth_cache_lookup(cache, fh, host_addr, ×tamp, &can_write); +    cached = (ret == ENTRY_FOUND);  out: -        return cached; +    return cached;  } -  /**   * is_nfs_fh_cached_and_writeable -- Checks if an NFS FH is cached for the given   *                                   host and writable @@ -409,22 +410,22 @@ out:   *   */  gf_boolean_t -is_nfs_fh_cached_and_writeable (struct auth_cache *cache, struct nfs3_fh *fh, -                                const char *host_addr) +is_nfs_fh_cached_and_writeable(struct auth_cache *cache, struct nfs3_fh *fh, +                               const char *host_addr)  { -        int          ret       = 0; -        time_t       timestamp = 0; -        gf_boolean_t cached    = _gf_false; -        gf_boolean_t writable  = _gf_false; +    int ret = 0; +    time_t timestamp = 0; +    gf_boolean_t cached = _gf_false; +    gf_boolean_t writable = _gf_false; -        if (!fh) -                goto out; +    if (!fh) +        goto out; -        ret = auth_cache_lookup (cache, fh, host_addr, ×tamp, &writable); -        cached = ((ret == ENTRY_FOUND) && writable); +    ret = auth_cache_lookup(cache, fh, host_addr, ×tamp, &writable); +    cached = ((ret == ENTRY_FOUND) && writable);  out: -        return cached; +    return cached;  }  /** @@ -441,56 +442,58 @@ out:   *   */  int -cache_nfs_fh (struct auth_cache *cache, struct nfs3_fh *fh, -              const char *host_addr, struct export_item *export_item) +cache_nfs_fh(struct auth_cache *cache, struct nfs3_fh *fh, +             const char *host_addr, struct export_item *export_item)  { -        int                      ret        = -EINVAL; -        char                    *hashkey    = NULL; -        time_t                   timestamp  = 0; -        gf_boolean_t             can_write  = _gf_false; -        struct auth_cache_entry *entry      = NULL; - -        GF_VALIDATE_OR_GOTO (GF_NFS, host_addr, out); -        GF_VALIDATE_OR_GOTO (GF_NFS, cache, out); -        GF_VALIDATE_OR_GOTO (GF_NFS, fh, out); - -        /* If we could already find it in the cache, just return */ -        ret = auth_cache_lookup (cache, fh, host_addr, ×tamp, &can_write); -        if (ret == 0) { -                gf_msg_trace (GF_NFS, 0, "found cached auth/fh for host " -                              "%s", host_addr); -                goto out; -        } - -        hashkey = make_hashkey (fh, host_addr); -        if (!hashkey) { -                ret = -ENOMEM; -                goto out; -        } - -        entry = auth_cache_entry_init (); -        if (!entry) { -                ret = -ENOMEM; -                goto out; -        } - -        entry->timestamp = time (NULL); -        /* Update entry->item if it is pointing to a different export_item */ -        if (entry->item && entry->item != export_item) { -                GF_REF_PUT (entry->item); -        } -        entry->item = GF_REF_GET (export_item); - -        ret = auth_cache_add (cache, hashkey, entry); -        GF_REF_PUT (entry); -        if (ret) -                goto out; - -        gf_msg_trace (GF_NFS, 0, "Caching file-handle (%s)", host_addr); -        ret = 0; +    int ret = -EINVAL; +    char *hashkey = NULL; +    time_t timestamp = 0; +    gf_boolean_t can_write = _gf_false; +    struct auth_cache_entry *entry = NULL; + +    GF_VALIDATE_OR_GOTO(GF_NFS, host_addr, out); +    GF_VALIDATE_OR_GOTO(GF_NFS, cache, out); +    GF_VALIDATE_OR_GOTO(GF_NFS, fh, out); + +    /* If we could already find it in the cache, just return */ +    ret = auth_cache_lookup(cache, fh, host_addr, ×tamp, &can_write); +    if (ret == 0) { +        gf_msg_trace(GF_NFS, 0, +                     "found cached auth/fh for host " +                     "%s", +                     host_addr); +        goto out; +    } + +    hashkey = make_hashkey(fh, host_addr); +    if (!hashkey) { +        ret = -ENOMEM; +        goto out; +    } + +    entry = auth_cache_entry_init(); +    if (!entry) { +        ret = -ENOMEM; +        goto out; +    } + +    entry->timestamp = time(NULL); +    /* Update entry->item if it is pointing to a different export_item */ +    if (entry->item && entry->item != export_item) { +        GF_REF_PUT(entry->item); +    } +    entry->item = GF_REF_GET(export_item); + +    ret = auth_cache_add(cache, hashkey, entry); +    GF_REF_PUT(entry); +    if (ret) +        goto out; + +    gf_msg_trace(GF_NFS, 0, "Caching file-handle (%s)", host_addr); +    ret = 0;  out: -        GF_FREE (hashkey); +    GF_FREE(hashkey); -        return ret; +    return ret;  }  | 
