diff options
Diffstat (limited to 'xlators/nfs/server/src/nfs-common.c')
| -rw-r--r-- | xlators/nfs/server/src/nfs-common.c | 643 | 
1 files changed, 314 insertions, 329 deletions
diff --git a/xlators/nfs/server/src/nfs-common.c b/xlators/nfs/server/src/nfs-common.c index 2f742d44366..2e8d401ba52 100644 --- a/xlators/nfs/server/src/nfs-common.c +++ b/xlators/nfs/server/src/nfs-common.c @@ -24,293 +24,285 @@  #include <libgen.h>  xlator_t * -nfs_xlid_to_xlator (xlator_list_t *cl, uint8_t xlid) +nfs_xlid_to_xlator(xlator_list_t *cl, uint8_t xlid)  { -        xlator_t        *xl = NULL; -        uint8_t         id = 0; - -        while (id <= xlid) { -                if (!cl) { -                        xl = NULL; -                        break; -                } - -                xl = cl->xlator; -                cl = cl->next; -                id++; +    xlator_t *xl = NULL; +    uint8_t id = 0; + +    while (id <= xlid) { +        if (!cl) { +            xl = NULL; +            break;          } -        return xl; -} +        xl = cl->xlator; +        cl = cl->next; +        id++; +    } +    return xl; +}  xlator_t * -nfs_path_to_xlator (xlator_list_t *cl, char *path) +nfs_path_to_xlator(xlator_list_t *cl, char *path)  { -        return NULL; +    return NULL;  } -  uint16_t -nfs_xlator_to_xlid (xlator_list_t *cl, xlator_t *xl) +nfs_xlator_to_xlid(xlator_list_t *cl, xlator_t *xl)  { -        uint16_t        xlid = 0; +    uint16_t xlid = 0; -        if ((!cl) || (!xl)) -                return 0; +    if ((!cl) || (!xl)) +        return 0; -        while (cl) { -                if (xl == cl->xlator) -                        break; -                cl = cl->next; -                ++xlid; -        } +    while (cl) { +        if (xl == cl->xlator) +            break; +        cl = cl->next; +        ++xlid; +    } -        return xlid; +    return xlid;  } -  xlator_t * -nfs_mntpath_to_xlator (xlator_list_t *cl, char *path) +nfs_mntpath_to_xlator(xlator_list_t *cl, char *path)  { -        char            *volname  = NULL; /* volume name only */ -        char            *volptr   = NULL; /* ptr to original volname */ -        size_t           pathlen  = -1; -        xlator_t        *targetxl = NULL; -        int              i        = 0; - -        if ((!cl) || (!path)) -                return NULL; - -        gf_msg_trace (GF_NFS, 0, "Subvolume search: %s", path); - -        volname = volptr = gf_strdup (path); -        if (!volname) -                return NULL; - -        if (volname[0] == '/') -                volname++; - -        pathlen = strlen (volname); -        for (i = 0; i < pathlen; i++) { -                if (volname[i] == '/') { -                        volname[i] = '\0'; -                        break; -                } -        } +    char *volname = NULL; /* volume name only */ +    char *volptr = NULL;  /* ptr to original volname */ +    size_t pathlen = -1; +    xlator_t *targetxl = NULL; +    int i = 0; -        while (cl) { -                gf_msg_trace (GF_NFS, 0, "Volname: %s and cl->xlator->name: %s", -                              volname, cl->xlator->name); +    if ((!cl) || (!path)) +        return NULL; -                if (strcmp (volname, cl->xlator->name) == 0) { -                        targetxl = cl->xlator; -                        break; -                } +    gf_msg_trace(GF_NFS, 0, "Subvolume search: %s", path); -                cl = cl->next; +    volname = volptr = gf_strdup(path); +    if (!volname) +        return NULL; + +    if (volname[0] == '/') +        volname++; + +    pathlen = strlen(volname); +    for (i = 0; i < pathlen; i++) { +        if (volname[i] == '/') { +            volname[i] = '\0'; +            break;          } +    } -        GF_FREE (volptr); +    while (cl) { +        gf_msg_trace(GF_NFS, 0, "Volname: %s and cl->xlator->name: %s", volname, +                     cl->xlator->name); -        return targetxl; -} +        if (strcmp(volname, cl->xlator->name) == 0) { +            targetxl = cl->xlator; +            break; +        } + +        cl = cl->next; +    } +    GF_FREE(volptr); + +    return targetxl; +}  void -nfs_loc_wipe (loc_t *loc) +nfs_loc_wipe(loc_t *loc)  { -        loc_wipe (loc); +    loc_wipe(loc);  } -  int -nfs_loc_copy (loc_t *dst, loc_t *src) +nfs_loc_copy(loc_t *dst, loc_t *src)  { -        int  ret = -1; +    int ret = -1; -        ret = loc_copy (dst, src); +    ret = loc_copy(dst, src); -        return ret; +    return ret;  } -  int -nfs_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path) +nfs_loc_fill(loc_t *loc, inode_t *inode, inode_t *parent, char *path)  { -        int     ret = -EFAULT; +    int ret = -EFAULT; -        if (!loc) -                return ret; - -        if (inode) { -                loc->inode = inode_ref (inode); -                if (!gf_uuid_is_null (inode->gfid)) -                        gf_uuid_copy (loc->gfid, inode->gfid); -        } +    if (!loc) +        return ret; -        if (parent) -                loc->parent = inode_ref (parent); - -        if (path) { -                loc->path = gf_strdup (path); -                if (!loc->path) { -                        gf_msg (GF_NFS, GF_LOG_ERROR, ENOMEM, -                                NFS_MSG_NO_MEMORY, "strdup failed"); -                        goto loc_wipe; -                } -                loc->name = strrchr (loc->path, '/'); -                if (loc->name) -                        loc->name++; +    if (inode) { +        loc->inode = inode_ref(inode); +        if (!gf_uuid_is_null(inode->gfid)) +            gf_uuid_copy(loc->gfid, inode->gfid); +    } + +    if (parent) +        loc->parent = inode_ref(parent); + +    if (path) { +        loc->path = gf_strdup(path); +        if (!loc->path) { +            gf_msg(GF_NFS, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY, +                   "strdup failed"); +            goto loc_wipe;          } +        loc->name = strrchr(loc->path, '/'); +        if (loc->name) +            loc->name++; +    } -        ret = 0; +    ret = 0;  loc_wipe: -        if (ret < 0) -                nfs_loc_wipe (loc); +    if (ret < 0) +        nfs_loc_wipe(loc); -        return ret; +    return ret;  } -  int -nfs_inode_loc_fill (inode_t *inode, loc_t *loc, int how) +nfs_inode_loc_fill(inode_t *inode, loc_t *loc, int how)  { -        char            *resolvedpath = NULL; -        inode_t         *parent = NULL; -        int             ret = -EFAULT; - -        if ((!inode) || (!loc)) -                return ret; - -        /* If gfid is not null, then the inode is already linked to -         * the inode table, and not a newly created one. For newly -         * created inode, inode_path returns null gfid as the path. -         */ -        if (!gf_uuid_is_null (inode->gfid)) { -                ret = inode_path (inode, NULL, &resolvedpath); -                if (ret < 0) { -                        gf_msg (GF_NFS, GF_LOG_ERROR, 0, -                                NFS_MSG_PATH_RESOLVE_FAIL, "path resolution " -                                "failed %s", resolvedpath); -                        goto err; -                } -        } +    char *resolvedpath = NULL; +    inode_t *parent = NULL; +    int ret = -EFAULT; -        if (resolvedpath == NULL) { -                char tmp_path[GFID_STR_PFX_LEN + 1] = {0,}; -                snprintf (tmp_path, sizeof (tmp_path), "<gfid:%s>", -                          uuid_utoa (loc->gfid)); -                resolvedpath = gf_strdup (tmp_path); -        } else { -                parent = inode_parent (inode, loc->pargfid, NULL); -        } +    if ((!inode) || (!loc)) +        return ret; -        ret = nfs_loc_fill (loc, inode, parent, resolvedpath); +    /* If gfid is not null, then the inode is already linked to +     * the inode table, and not a newly created one. For newly +     * created inode, inode_path returns null gfid as the path. +     */ +    if (!gf_uuid_is_null(inode->gfid)) { +        ret = inode_path(inode, NULL, &resolvedpath);          if (ret < 0) { -                gf_msg (GF_NFS, GF_LOG_ERROR, -ret, -                        NFS_MSG_LOC_FILL_RESOLVE_FAIL, -                        "loc fill resolution failed %s", resolvedpath); -                goto err; +            gf_msg(GF_NFS, GF_LOG_ERROR, 0, NFS_MSG_PATH_RESOLVE_FAIL, +                   "path resolution " +                   "failed %s", +                   resolvedpath); +            goto err;          } - -        ret = 0; +    } + +    if (resolvedpath == NULL) { +        char tmp_path[GFID_STR_PFX_LEN + 1] = { +            0, +        }; +        snprintf(tmp_path, sizeof(tmp_path), "<gfid:%s>", uuid_utoa(loc->gfid)); +        resolvedpath = gf_strdup(tmp_path); +    } else { +        parent = inode_parent(inode, loc->pargfid, NULL); +    } + +    ret = nfs_loc_fill(loc, inode, parent, resolvedpath); +    if (ret < 0) { +        gf_msg(GF_NFS, GF_LOG_ERROR, -ret, NFS_MSG_LOC_FILL_RESOLVE_FAIL, +               "loc fill resolution failed %s", resolvedpath); +        goto err; +    } + +    ret = 0;  err: -        if (parent) -                inode_unref (parent); +    if (parent) +        inode_unref(parent); -        GF_FREE (resolvedpath); +    GF_FREE(resolvedpath); -        return ret; +    return ret;  }  int -nfs_gfid_loc_fill (inode_table_t *itable, uuid_t gfid, loc_t *loc, int how) +nfs_gfid_loc_fill(inode_table_t *itable, uuid_t gfid, loc_t *loc, int how)  { -        int             ret = -EFAULT; -        inode_t         *inode = NULL; - -        if (!loc) -                return ret; - -        inode = inode_find (itable, gfid); -        if (!inode) { -		gf_msg_trace (GF_NFS, 0, "Inode not found in itable, will " -                              "try to create one."); -                if (how == NFS_RESOLVE_CREATE) { -			gf_msg_trace (GF_NFS, 0, "Inode needs to be created."); -                        inode = inode_new (itable); -                        if (!inode) { -                                gf_msg (GF_NFS, GF_LOG_ERROR, ENOMEM, -                                        NFS_MSG_NO_MEMORY, "Failed to " -                                        "allocate memory"); -                                ret = -ENOMEM; -                                goto err; -                        } - -                } else { -			gf_msg (GF_NFS, GF_LOG_ERROR, ENOENT, -                                NFS_MSG_INODE_NOT_FOUND, "Inode not found in " -                                "itable and no creation was requested."); -                        ret = -ENOENT; -                        goto err; -                } +    int ret = -EFAULT; +    inode_t *inode = NULL; + +    if (!loc) +        return ret; + +    inode = inode_find(itable, gfid); +    if (!inode) { +        gf_msg_trace(GF_NFS, 0, +                     "Inode not found in itable, will " +                     "try to create one."); +        if (how == NFS_RESOLVE_CREATE) { +            gf_msg_trace(GF_NFS, 0, "Inode needs to be created."); +            inode = inode_new(itable); +            if (!inode) { +                gf_msg(GF_NFS, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY, +                       "Failed to " +                       "allocate memory"); +                ret = -ENOMEM; +                goto err; +            } +          } else { -		gf_msg_trace (GF_NFS, 0, "Inode was found in the itable."); -	} +            gf_msg(GF_NFS, GF_LOG_ERROR, ENOENT, NFS_MSG_INODE_NOT_FOUND, +                   "Inode not found in " +                   "itable and no creation was requested."); +            ret = -ENOENT; +            goto err; +        } +    } else { +        gf_msg_trace(GF_NFS, 0, "Inode was found in the itable."); +    } -        gf_uuid_copy (loc->gfid, gfid); +    gf_uuid_copy(loc->gfid, gfid); -        ret = nfs_inode_loc_fill (inode, loc, how); -	if (ret < 0) { -		gf_msg (GF_NFS, GF_LOG_ERROR, -ret, -                        NFS_MSG_INODE_LOC_FILL_ERROR, -                        "Inode loc filling failed.: %s", strerror (-ret)); -		goto err; -	} +    ret = nfs_inode_loc_fill(inode, loc, how); +    if (ret < 0) { +        gf_msg(GF_NFS, GF_LOG_ERROR, -ret, NFS_MSG_INODE_LOC_FILL_ERROR, +               "Inode loc filling failed.: %s", strerror(-ret)); +        goto err; +    }  err: -        if (inode) -                inode_unref (inode); -        return ret; +    if (inode) +        inode_unref(inode); +    return ret;  } -  int -nfs_root_loc_fill (inode_table_t *itable, loc_t *loc) +nfs_root_loc_fill(inode_table_t *itable, loc_t *loc)  { -        uuid_t  rootgfid = {0, }; +    uuid_t rootgfid = { +        0, +    }; -        rootgfid[15] = 1; -        return nfs_gfid_loc_fill (itable, rootgfid, loc, NFS_RESOLVE_EXIST); +    rootgfid[15] = 1; +    return nfs_gfid_loc_fill(itable, rootgfid, loc, NFS_RESOLVE_EXIST);  } - -  int -nfs_parent_inode_loc_fill (inode_t *parent, inode_t *entryinode, char *entry, -                           loc_t *loc) +nfs_parent_inode_loc_fill(inode_t *parent, inode_t *entryinode, char *entry, +                          loc_t *loc)  { -        int             ret = -EFAULT; -        char            *path = NULL; +    int ret = -EFAULT; +    char *path = NULL; -        if ((!parent) || (!entry) || (!loc) || (!entryinode)) -                return ret; +    if ((!parent) || (!entry) || (!loc) || (!entryinode)) +        return ret; -        ret = inode_path (parent, entry, &path); -        if (ret < 0) { -                gf_msg (GF_NFS, GF_LOG_ERROR, -ret, NFS_MSG_PATH_RESOLVE_FAIL, -                        "path resolution failed %s", path); -                goto err; -        } +    ret = inode_path(parent, entry, &path); +    if (ret < 0) { +        gf_msg(GF_NFS, GF_LOG_ERROR, -ret, NFS_MSG_PATH_RESOLVE_FAIL, +               "path resolution failed %s", path); +        goto err; +    } -        ret = nfs_loc_fill (loc, entryinode, parent, path); -        GF_FREE (path); +    ret = nfs_loc_fill(loc, entryinode, parent, path); +    GF_FREE(path);  err: -        return ret; +    return ret;  } -  /* Returns -1 if parent is not available, return -2 if the entry is not   * available. In case the return is going to be -2, and how = NFS_RESOLVE_CREATE   * it does however fill in the loc so that it can be used to perform a lookup @@ -318,151 +310,144 @@ err:   * On other errors, return -3. 0 on success.   */  int -nfs_entry_loc_fill (xlator_t *this, inode_table_t *itable, uuid_t pargfid, -                    char *entry, loc_t *loc, int how, gf_boolean_t *freshlookup) +nfs_entry_loc_fill(xlator_t *this, inode_table_t *itable, uuid_t pargfid, +                   char *entry, loc_t *loc, int how, gf_boolean_t *freshlookup)  { -        inode_t         *parent = NULL; -        inode_t         *entryinode = NULL; -        int             ret = -3; -        char            *resolvedpath = NULL; -        int             pret = -3; - -        if ((!itable) || (!entry) || (!loc)) -                return ret; +    inode_t *parent = NULL; +    inode_t *entryinode = NULL; +    int ret = -3; +    char *resolvedpath = NULL; +    int pret = -3; -        parent = inode_find (itable, pargfid); - -        ret = -1; -        /* Will need hard resolution now */ -        if (!parent || inode_ctx_get (parent, this, NULL)) -                goto err; - -        gf_uuid_copy (loc->pargfid, pargfid); - -        ret = -2; -        entryinode = inode_grep (itable, parent, entry); -        if (!entryinode || inode_ctx_get (entryinode, this, NULL)) { -                if (how == NFS_RESOLVE_CREATE) { -                        /* Even though we'll create the inode and the loc for -                         * a missing inode, we still need to return -2 so -                         * that the caller can use the filled loc to call -                         * lookup. -                         */ -                        if (!entryinode) { -                                entryinode = inode_new (itable); -                                if (freshlookup) -                                        *freshlookup = _gf_true; -                        } -                        /* Cannot change ret because that must -                         * continue to have -2. -                         */ -                        pret = nfs_parent_inode_loc_fill (parent, entryinode, -                                                          entry, loc); -                        /* Only if parent loc fill fails, should we notify error -                         * through ret, otherwise, we still need to force a -                         * lookup by returning -2. -                         */ -                        if (pret < 0) -			         ret = -3; -                } -                goto err; -        } - -        ret = inode_path (parent, entry, &resolvedpath); -        if (ret < 0) { -                gf_msg (GF_NFS, GF_LOG_ERROR, -ret, NFS_MSG_PATH_RESOLVE_FAIL, -                        "path resolution failed %s", resolvedpath); -                ret = -3; -                goto err; -        } +    if ((!itable) || (!entry) || (!loc)) +        return ret; -        ret = nfs_loc_fill (loc, entryinode, parent, resolvedpath); -        if (ret < 0) { -                gf_msg (GF_NFS, GF_LOG_ERROR, 0, NFS_MSG_INODE_LOC_FILL_ERROR, -                        "loc_fill failed %s", resolvedpath); +    parent = inode_find(itable, pargfid); + +    ret = -1; +    /* Will need hard resolution now */ +    if (!parent || inode_ctx_get(parent, this, NULL)) +        goto err; + +    gf_uuid_copy(loc->pargfid, pargfid); + +    ret = -2; +    entryinode = inode_grep(itable, parent, entry); +    if (!entryinode || inode_ctx_get(entryinode, this, NULL)) { +        if (how == NFS_RESOLVE_CREATE) { +            /* Even though we'll create the inode and the loc for +             * a missing inode, we still need to return -2 so +             * that the caller can use the filled loc to call +             * lookup. +             */ +            if (!entryinode) { +                entryinode = inode_new(itable); +                if (freshlookup) +                    *freshlookup = _gf_true; +            } +            /* Cannot change ret because that must +             * continue to have -2. +             */ +            pret = nfs_parent_inode_loc_fill(parent, entryinode, entry, loc); +            /* Only if parent loc fill fails, should we notify error +             * through ret, otherwise, we still need to force a +             * lookup by returning -2. +             */ +            if (pret < 0)                  ret = -3;          } +        goto err; +    } + +    ret = inode_path(parent, entry, &resolvedpath); +    if (ret < 0) { +        gf_msg(GF_NFS, GF_LOG_ERROR, -ret, NFS_MSG_PATH_RESOLVE_FAIL, +               "path resolution failed %s", resolvedpath); +        ret = -3; +        goto err; +    } + +    ret = nfs_loc_fill(loc, entryinode, parent, resolvedpath); +    if (ret < 0) { +        gf_msg(GF_NFS, GF_LOG_ERROR, 0, NFS_MSG_INODE_LOC_FILL_ERROR, +               "loc_fill failed %s", resolvedpath); +        ret = -3; +    }  err: -        if (parent) -                inode_unref (parent); +    if (parent) +        inode_unref(parent); -        if (entryinode) -                inode_unref (entryinode); +    if (entryinode) +        inode_unref(entryinode); -        GF_FREE (resolvedpath); +    GF_FREE(resolvedpath); -        return ret; +    return ret;  } -  uint32_t -nfs_hash_gfid (uuid_t gfid) +nfs_hash_gfid(uuid_t gfid)  { -        uint32_t                hash = 0; -        uint64_t                msb64 = 0; -        uint64_t                lsb64 = 0; -        uint32_t                a1 = 0; -        uint32_t                a2 = 0; -        uint32_t                a3 = 0; -        uint32_t                a4 = 0; -        uint32_t                b1 = 0; -        uint32_t                b2 = 0; +    uint32_t hash = 0; +    uint64_t msb64 = 0; +    uint64_t lsb64 = 0; +    uint32_t a1 = 0; +    uint32_t a2 = 0; +    uint32_t a3 = 0; +    uint32_t a4 = 0; +    uint32_t b1 = 0; +    uint32_t b2 = 0; -        if (__is_root_gfid (gfid)) -                return 0x1; +    if (__is_root_gfid(gfid)) +        return 0x1; -        memcpy (&msb64, &gfid[8], 8); -        memcpy (&lsb64, &gfid[0], 8); +    memcpy(&msb64, &gfid[8], 8); +    memcpy(&lsb64, &gfid[0], 8); -        a1 = (msb64 << 32); -        a2 = (msb64 >> 32); -        a3 = (lsb64 << 32); -        a4 = (lsb64 >> 32); +    a1 = (msb64 << 32); +    a2 = (msb64 >> 32); +    a3 = (lsb64 << 32); +    a4 = (lsb64 >> 32); -        b1 = a1 ^ a4; -        b2 = a2 ^ a3; +    b1 = a1 ^ a4; +    b2 = a2 ^ a3; -        hash = b1 ^ b2; +    hash = b1 ^ b2; -        return hash; +    return hash;  } -  void -nfs_fix_generation (xlator_t *this, inode_t *inode) +nfs_fix_generation(xlator_t *this, inode_t *inode)  { -        uint64_t                 raw_ctx        = 0; -        struct nfs_inode_ctx    *ictx           = NULL; -        struct nfs_state        *priv           = NULL; -        int                      ret            = -1; - -        if (!inode) { -                return; -        } -        priv = this->private; - -        if (inode_ctx_get(inode,this,&raw_ctx) == 0) { -                ictx = (struct nfs_inode_ctx *)raw_ctx; -                ictx->generation = priv->generation; +    uint64_t raw_ctx = 0; +    struct nfs_inode_ctx *ictx = NULL; +    struct nfs_state *priv = NULL; +    int ret = -1; + +    if (!inode) { +        return; +    } +    priv = this->private; + +    if (inode_ctx_get(inode, this, &raw_ctx) == 0) { +        ictx = (struct nfs_inode_ctx *)raw_ctx; +        ictx->generation = priv->generation; +    } else { +        ictx = GF_CALLOC(1, sizeof(struct nfs_inode_ctx), gf_nfs_mt_inode_ctx); +        if (!ictx) { +            gf_msg(this->name, GF_LOG_ERROR, ENOMEM, NFS_MSG_NO_MEMORY, +                   "could not allocate nfs inode ctx"); +            return;          } -        else { -                ictx = GF_CALLOC (1, sizeof (struct nfs_inode_ctx), -                                  gf_nfs_mt_inode_ctx); -                if (!ictx) { -                        gf_msg (this->name, GF_LOG_ERROR, ENOMEM, -                                NFS_MSG_NO_MEMORY, -                                "could not allocate nfs inode ctx"); -                        return; -                } -                INIT_LIST_HEAD(&ictx->shares); -                ictx->generation = priv->generation; -                ret = inode_ctx_put (inode, this, (uint64_t)ictx); -                if (ret) { -                        gf_msg (this->name, GF_LOG_ERROR, 0, -                                NFS_MSG_INODE_CTX_STORE_FAIL, -                                "could not store nfs inode ctx"); -                        return; -                } +        INIT_LIST_HEAD(&ictx->shares); +        ictx->generation = priv->generation; +        ret = inode_ctx_put(inode, this, (uint64_t)ictx); +        if (ret) { +            gf_msg(this->name, GF_LOG_ERROR, 0, NFS_MSG_INODE_CTX_STORE_FAIL, +                   "could not store nfs inode ctx"); +            return;          } +    }  }  | 
