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; } + } } |