From 9ff89d858075d8f916c76a9ade84b9844da4d23e Mon Sep 17 00:00:00 2001 From: Shehjar Tikoo Date: Tue, 14 Sep 2010 02:39:11 +0000 Subject: nfs,nfs3,mnt3: Transition fh resolution to gfid Signed-off-by: Shehjar Tikoo Signed-off-by: Vijay Bellur BUG: 971 (dynamic volume management) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=971 --- xlators/nfs/server/src/mount3.c | 125 +++++++-- xlators/nfs/server/src/mount3.h | 5 + xlators/nfs/server/src/nfs-common.c | 20 +- xlators/nfs/server/src/nfs-common.h | 7 +- xlators/nfs/server/src/nfs-fops.c | 61 ++++- xlators/nfs/server/src/nfs-fops.h | 1 + xlators/nfs/server/src/nfs.c | 107 ++++++-- xlators/nfs/server/src/nfs.h | 6 + xlators/nfs/server/src/nfs3-fh.c | 83 +++--- xlators/nfs/server/src/nfs3-fh.h | 36 ++- xlators/nfs/server/src/nfs3-helpers.c | 239 +++++++++-------- xlators/nfs/server/src/nfs3-helpers.h | 52 ++-- xlators/nfs/server/src/nfs3.c | 467 +++++++++++++++++++++++++--------- xlators/nfs/server/src/nfs3.h | 4 +- 14 files changed, 847 insertions(+), 366 deletions(-) diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c index c61cf0a488a..3ea4bc8e893 100644 --- a/xlators/nfs/server/src/mount3.c +++ b/xlators/nfs/server/src/mount3.c @@ -211,6 +211,29 @@ free_err: } +int +__mnt3_get_volume_id (struct mount3_state *ms, xlator_t *mntxl, + uuid_t volumeid) +{ + int ret = -1; + struct mnt3_export *exp = NULL; + + if ((!ms) || (!mntxl)) + return ret; + + list_for_each_entry (exp, &ms->exportlist, explist) { + if (exp->vol == mntxl) { + uuid_copy (volumeid, exp->volumeid); + ret = 0; + goto out; + } + } + +out: + return ret; +} + + int32_t mnt3svc_lookup_mount_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, @@ -226,6 +249,8 @@ mnt3svc_lookup_mount_cbk (call_frame_t *frame, void *cookie, int autharrlen = 0; rpcsvc_t *svc = NULL; xlator_t *mntxl = NULL; + uuid_t volumeid = {0, }; + char fhstr[1024]; req = (rpcsvc_request_t *)frame->local; @@ -246,10 +271,19 @@ mnt3svc_lookup_mount_cbk (call_frame_t *frame, void *cookie, if (status != MNT3_OK) goto xmit_res; - fh = nfs3_fh_build_root_fh (ms->nfsx->children, mntxl); mnt3svc_update_mountlist (ms, req, mntxl->name); + if (gf_nfs_dvm_off (nfs_state (ms->nfsx))) { + fh = nfs3_fh_build_indexed_root_fh (ms->nfsx->children, mntxl); + goto xmit_res; + } + + __mnt3_get_volume_id (ms, mntxl, volumeid); + fh = nfs3_fh_build_uuid_root_fh (volumeid); + xmit_res: - gf_log (GF_MNT, GF_LOG_DEBUG, "Mount reply status: %d", status); + nfs3_fh_to_str (&fh, fhstr); + gf_log (GF_MNT, GF_LOG_DEBUG, "MNT reply: fh %s, status: %d", fhstr, + status); if (op_ret == 0) { svc = nfs_rpcsvc_request_service (req); autharrlen = nfs_rpcsvc_auth_array (svc, mntxl->name, autharr, @@ -336,11 +370,13 @@ mnt3svc_volume_mount (rpcsvc_request_t *req, struct mount3_state *ms, { inode_t *exportinode = NULL; int ret = -EFAULT; + uuid_t rootgfid = {0, }; if ((!req) || (!exp) || (!ms)) return ret; - exportinode = inode_get (exp->vol->itable, 1, 0); + rootgfid[15] = 1; + exportinode = inode_find (exp->vol->itable, rootgfid); if (!exportinode) { gf_log (GF_MNT, GF_LOG_ERROR, "Faild to get root inode"); ret = -ENOENT; @@ -434,9 +470,8 @@ __mnt3_resolve_export_subdir_comp (mnt3_resolve_t *mres) char dupsubdir[MNTPATHLEN]; char *nextcomp = NULL; int ret = -EFAULT; - uint64_t parino = 0; - uint64_t pargen = 0; nfs_user_t nfu = {0, }; + char gfidstr[512]; if (!mres) return ret; @@ -445,17 +480,15 @@ __mnt3_resolve_export_subdir_comp (mnt3_resolve_t *mres) if (!nextcomp) goto err; - parino = mres->resolveloc.inode->ino; - /* Wipe the contents of the previous component */ nfs_loc_wipe (&mres->resolveloc); - ret = nfs_entry_loc_fill (mres->exp->vol->itable, parino, pargen, - nextcomp, &mres->resolveloc, - NFS_RESOLVE_CREATE); + ret = nfs_entry_loc_fill (mres->exp->vol->itable, + mres->resolveloc.inode->gfid, nextcomp, + &mres->resolveloc, NFS_RESOLVE_CREATE); if ((ret < 0) && (ret != -2)) { + uuid_unparse (mres->resolveloc.inode->gfid, gfidstr); gf_log (GF_MNT, GF_LOG_ERROR, "Failed to resolve and create " - "inode: parent %"PRIu64", gen: %"PRIu64", entry %s", - parino, pargen, nextcomp); + "inode: parent gfid %s, entry %s", gfidstr, nextcomp); ret = -EFAULT; goto err; } @@ -544,6 +577,7 @@ __mnt3_resolve_export_subdir (mnt3_resolve_t *mres) char *firstcomp = NULL; int ret = -EFAULT; nfs_user_t nfu = {0, }; + uuid_t rootgfid = {0, }; if (!mres) return ret; @@ -552,7 +586,8 @@ __mnt3_resolve_export_subdir (mnt3_resolve_t *mres) if (!firstcomp) goto err; - ret = nfs_entry_loc_fill (mres->exp->vol->itable, 1, 0, firstcomp, + rootgfid[15] = 1; + ret = nfs_entry_loc_fill (mres->exp->vol->itable, rootgfid, firstcomp, &mres->resolveloc, NFS_RESOLVE_CREATE); if ((ret < 0) && (ret != -2)) { gf_log (GF_MNT, GF_LOG_ERROR, "Failed to resolve and create " @@ -577,6 +612,7 @@ mnt3_resolve_export_subdir (rpcsvc_request_t *req, struct mount3_state *ms, mnt3_resolve_t *mres = NULL; char *volume_subdir = NULL; int ret = -EFAULT; + struct nfs3_fh pfh = GF_NFS3FH_STATIC_INITIALIZER; if ((!req) || (!ms) || (!exp)) return ret; @@ -595,9 +631,12 @@ mnt3_resolve_export_subdir (rpcsvc_request_t *req, struct mount3_state *ms, mres->mstate = ms; mres->req = req; strcpy (mres->remainingdir, volume_subdir); - mres->parentfh = nfs3_fh_build_root_fh (mres->mstate->nfsx->children, - mres->exp->vol); + if (gf_nfs_dvm_off (nfs_state (ms->nfsx))) + pfh = nfs3_fh_build_indexed_root_fh (mres->mstate->nfsx->children, mres->exp->vol); + else + pfh = nfs3_fh_build_uuid_root_fh (exp->volumeid); + mres->parentfh = pfh; ret = __mnt3_resolve_export_subdir (mres); if (ret < 0) { gf_log (GF_MNT, GF_LOG_ERROR, "Failed to resolve export dir: %s" @@ -1205,7 +1244,8 @@ err: struct mnt3_export * -mnt3_init_export_ent (struct mount3_state *ms, xlator_t *xl, char *exportpath) +mnt3_init_export_ent (struct mount3_state *ms, xlator_t *xl, char *exportpath, + uuid_t volumeid) { struct mnt3_export *exp = NULL; int alloclen = 0; @@ -1247,6 +1287,11 @@ mnt3_init_export_ent (struct mount3_state *ms, xlator_t *xl, char *exportpath) ret = snprintf (exp->expname, alloclen, "/%s", xl->name); } + /* Just copy without discrimination, we'll determine whether to + * actually use it when a mount request comes in and a file handle + * needs to be built. + */ + uuid_copy (exp->volumeid, volumeid); exp->vol = xl; err: return exp; @@ -1255,7 +1300,7 @@ err: int __mnt3_init_volume_direxports (struct mount3_state *ms, xlator_t *xlator, - char *optstr) + char *optstr, uuid_t volumeid) { struct mnt3_export *newexp = NULL; int ret = -1; @@ -1274,7 +1319,7 @@ __mnt3_init_volume_direxports (struct mount3_state *ms, xlator_t *xlator, token = strtok_r (dupopt, ",", &savptr); while (token) { - newexp = mnt3_init_export_ent (ms, xlator, token); + newexp = mnt3_init_export_ent (ms, xlator, token, volumeid); if (!newexp) { gf_log (GF_MNT, GF_LOG_ERROR, "Failed to init dir " "export: %s", token); @@ -1302,10 +1347,48 @@ __mnt3_init_volume (struct mount3_state *ms, dict_t *opts, xlator_t *xlator) int ret = -1; char searchstr[1024]; char *optstr = NULL; + uuid_t volumeid = {0, }; if ((!ms) || (!xlator) || (!opts)) return -1; + uuid_clear (volumeid); + if (gf_nfs_dvm_off (nfs_state (ms->nfsx))) + goto no_dvm; + + ret = snprintf (searchstr, 1024, "nfs3.%s.volume-id", xlator->name); + if (ret < 0) { + gf_log (GF_MNT, GF_LOG_ERROR, "snprintf failed"); + ret = -1; + goto err; + } + + if (dict_get (opts, searchstr)) { + ret = dict_get_str (opts, searchstr, &optstr); + if (ret < 0) { + gf_log (GF_MNT, GF_LOG_ERROR, "Failed to read option" + ": %s", searchstr); + ret = -1; + goto err; + } + } else { + gf_log (GF_MNT, GF_LOG_ERROR, "DVM is on but volume-id not " + "given for volume: %s", xlator->name); + ret = -1; + goto err; + } + + if (optstr) { + ret = uuid_parse (optstr, volumeid); + if (ret < 0) { + gf_log (GF_MNT, GF_LOG_ERROR, "Failed to parse volume " + "UUID"); + ret = -1; + goto err; + } + } + +no_dvm: ret = snprintf (searchstr, 1024, "nfs3.%s.export-dir", xlator->name); if (ret < 0) { gf_log (GF_MNT, GF_LOG_ERROR, "snprintf failed"); @@ -1322,17 +1405,17 @@ __mnt3_init_volume (struct mount3_state *ms, dict_t *opts, xlator_t *xlator) goto err; } - ret = __mnt3_init_volume_direxports (ms, xlator, optstr); + ret = __mnt3_init_volume_direxports (ms, xlator, optstr, + volumeid); if (ret == -1) { gf_log (GF_MNT, GF_LOG_ERROR, "Dir export setup failed" " for volume: %s", xlator->name); goto err; } - } if (ms->export_volumes) { - newexp = mnt3_init_export_ent (ms, xlator, NULL); + newexp = mnt3_init_export_ent (ms, xlator, NULL, volumeid); if (!newexp) { ret = -1; goto err; diff --git a/xlators/nfs/server/src/mount3.h b/xlators/nfs/server/src/mount3.h index f555bc7f18a..16b89f6da02 100644 --- a/xlators/nfs/server/src/mount3.h +++ b/xlators/nfs/server/src/mount3.h @@ -34,6 +34,7 @@ #include "xdr-nfs3.h" #include "locking.h" #include "nfs3-fh.h" +#include "uuid.h" /* Registered with portmap */ #define GF_MOUNTV3_PORT 38465 @@ -73,6 +74,10 @@ struct mnt3_export { char *expname; xlator_t *vol; int exptype; + + /* Extracted from nfs volume options if nfs.dynamicvolumes is on. + */ + uuid_t volumeid; }; struct mount3_state { diff --git a/xlators/nfs/server/src/nfs-common.c b/xlators/nfs/server/src/nfs-common.c index 9f68f714649..970eb41c571 100644 --- a/xlators/nfs/server/src/nfs-common.c +++ b/xlators/nfs/server/src/nfs-common.c @@ -264,9 +264,8 @@ err: return ret; } - int -nfs_ino_loc_fill (inode_table_t *itable, uint64_t ino, uint64_t gen, loc_t *loc) +nfs_gfid_loc_fill (inode_table_t *itable, uuid_t gfid, loc_t *loc) { int ret = -EFAULT; inode_t *inode = NULL; @@ -274,7 +273,7 @@ nfs_ino_loc_fill (inode_table_t *itable, uint64_t ino, uint64_t gen, loc_t *loc) if (!loc) return ret; - inode = inode_get (itable, ino, gen); + inode = inode_find (itable, gfid); if (!inode) { ret = -ENOENT; goto err; @@ -289,6 +288,17 @@ err: } +int +nfs_root_loc_fill (inode_table_t *itable, loc_t *loc) +{ + uuid_t rootgfid = {0, }; + + rootgfid[15] = 1; + return nfs_gfid_loc_fill (itable, rootgfid, loc); +} + + + int nfs_parent_inode_loc_fill (inode_t *parent, inode_t *entryinode, char *entry, loc_t *loc) @@ -317,7 +327,7 @@ err: * On other errors, return -3. 0 on success. */ int -nfs_entry_loc_fill (inode_table_t *itable, ino_t ino, uint64_t gen, char *entry, +nfs_entry_loc_fill (inode_table_t *itable, uuid_t pargfid, char *entry, loc_t *loc, int how) { inode_t *parent = NULL; @@ -329,7 +339,7 @@ nfs_entry_loc_fill (inode_table_t *itable, ino_t ino, uint64_t gen, char *entry, if ((!itable) || (!entry) || (!loc)) return ret; - parent = inode_get (itable, ino, gen); + parent = inode_find (itable, pargfid); ret = -1; /* Will need hard resolution now */ diff --git a/xlators/nfs/server/src/nfs-common.h b/xlators/nfs/server/src/nfs-common.h index 20003aa7130..25fc1cf405b 100644 --- a/xlators/nfs/server/src/nfs-common.h +++ b/xlators/nfs/server/src/nfs-common.h @@ -30,6 +30,7 @@ #include "xlator.h" #include "rpcsvc.h" #include "iatt.h" +#include "uuid.h" #define NFS_PATH_MAX PATH_MAX #define NFS_NAME_MAX NAME_MAX @@ -67,10 +68,12 @@ extern int nfs_inode_loc_fill (inode_t *inode, loc_t *loc); extern int -nfs_ino_loc_fill (inode_table_t *itable, uint64_t ino, uint64_t gen, loc_t *l); +nfs_ino_loc_fill (inode_table_t *itable, uuid_t gfid, loc_t *l); extern int -nfs_entry_loc_fill (inode_table_t *itable, ino_t ino, uint64_t gen, char *entry, +nfs_entry_loc_fill (inode_table_t *itable, uuid_t pargfid, char *entry, loc_t *loc, int how); +extern int +nfs_root_loc_fill (inode_table_t *itable, loc_t *loc); #endif diff --git a/xlators/nfs/server/src/nfs-fops.c b/xlators/nfs/server/src/nfs-fops.c index 544f6c9e6b1..3f342710b25 100644 --- a/xlators/nfs/server/src/nfs-fops.c +++ b/xlators/nfs/server/src/nfs-fops.c @@ -71,6 +71,9 @@ nfs_fop_local_wipe (xlator_t *nfsx, struct nfs_fop_local *l) if (l->newparent) inode_unref (l->newparent); + if (l->dictgfid) + dict_unref (l->dictgfid); + mem_put (nfs->foppool, l); return; @@ -222,6 +225,49 @@ err: } \ } while (0) \ +dict_t * +nfs_gfid_dict () +{ + uuid_t newgfid = {0, }; + char *dyngfid = NULL; + dict_t *dictgfid = NULL; + int ret = -1; + + dyngfid = GF_CALLOC (1, sizeof (uuid_t), gf_common_mt_char); + uuid_generate (newgfid); + memcpy (dyngfid, newgfid, sizeof (uuid_t)); + + dictgfid = dict_new (); + if (!dictgfid) { + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to create gfid dict"); + goto out; + } + + ret = dict_set_bin (dictgfid, "gfid-req", dyngfid, sizeof (uuid_t)); + if (ret < 0) { + dict_unref (dictgfid); + dictgfid = NULL; + } + +out: + return dictgfid; +} + +#define nfs_fop_gfid_setup(nflcl, retval, erlbl) \ + do { \ + if (nflcl) { \ + (nflcl)->dictgfid = nfs_gfid_dict (); \ + \ + if (!((nflcl)->dictgfid)) { \ + retval = -EFAULT; \ + goto erlbl; \ + } \ + } \ + } while (0) \ + + + + /* Fops Layer Explained * The fops layer has three types of functions. They can all be identified by * their names. Here are the three patterns: @@ -281,9 +327,10 @@ nfs_fop_lookup (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *loc, nfs_fop_handle_frame_create (frame, nfsx, nfu, ret, err); nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err); nfs_fop_save_root_ino (nfl, loc); + nfs_fop_gfid_setup (nfl, ret, err); STACK_WIND_COOKIE (frame, nfs_fop_lookup_cbk, xl, xl, - xl->fops->lookup, loc, NULL); + xl->fops->lookup, loc, nfl->dictgfid); ret = 0; err: @@ -603,9 +650,10 @@ nfs_fop_create (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, nfs_fop_handle_frame_create (frame, nfsx, nfu, ret, err); nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err); nfs_fop_save_root_ino (nfl, pathloc); + nfs_fop_gfid_setup (nfl, ret, err); STACK_WIND_COOKIE (frame, nfs_fop_create_cbk, xl, xl, xl->fops->create, - pathloc, flags, mode, fd, NULL); + pathloc, flags, mode, fd, nfl->dictgfid); ret = 0; err: @@ -700,9 +748,10 @@ nfs_fop_mkdir (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, nfs_fop_handle_frame_create (frame, nfsx, nfu, ret, err); nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err); nfs_fop_save_root_ino (nfl, pathloc); + nfs_fop_gfid_setup (nfl, ret, err); STACK_WIND_COOKIE (frame, nfs_fop_mkdir_cbk, xl, xl, xl->fops->mkdir, - pathloc, mode, NULL); + pathloc, mode, nfl->dictgfid); ret = 0; err: if (ret < 0) { @@ -747,9 +796,10 @@ nfs_fop_symlink (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, char *target, nfs_fop_handle_frame_create (frame, nfsx, nfu, ret, err); nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err); nfs_fop_save_root_ino (nfl, pathloc); + nfs_fop_gfid_setup (nfl, ret, err); STACK_WIND_COOKIE (frame, nfs_fop_symlink_cbk, xl, xl, - xl->fops->symlink, target, pathloc, NULL); + xl->fops->symlink, target, pathloc, nfl->dictgfid); ret = 0; err: if (ret < 0) { @@ -841,9 +891,10 @@ nfs_fop_mknod (xlator_t *nfsx, xlator_t *xl, nfs_user_t *nfu, loc_t *pathloc, nfs_fop_handle_frame_create (frame, nfsx, nfu, ret, err); nfs_fop_handle_local_init (frame, nfsx, nfl, cbk, local, ret, err); nfs_fop_save_root_ino (nfl, pathloc); + nfs_fop_gfid_setup (nfl, ret, err); STACK_WIND_COOKIE (frame, nfs_fop_mknod_cbk, xl, xl, xl->fops->mknod, - pathloc, mode, dev, NULL); + pathloc, mode, dev, nfl->dictgfid); ret = 0; err: if (ret < 0) { diff --git a/xlators/nfs/server/src/nfs-fops.h b/xlators/nfs/server/src/nfs-fops.h index be445a641eb..3fb157aebf3 100644 --- a/xlators/nfs/server/src/nfs-fops.h +++ b/xlators/nfs/server/src/nfs-fops.h @@ -99,6 +99,7 @@ struct nfs_fop_local { char path[NFS_NAME_MAX]; char newpath[NFS_NAME_MAX]; xlator_t *nfsx; + dict_t *dictgfid; }; extern struct nfs_fop_local * diff --git a/xlators/nfs/server/src/nfs.c b/xlators/nfs/server/src/nfs.c index 8f3c8b2f520..431765332ca 100644 --- a/xlators/nfs/server/src/nfs.c +++ b/xlators/nfs/server/src/nfs.c @@ -457,29 +457,33 @@ mem_acct_init (xlator_t *this) return ret; } -int -init (xlator_t *this) { +struct nfs_state * +nfs_init_state (xlator_t *this) +{ struct nfs_state *nfs = NULL; int ret = -1; unsigned int fopspoolsize = 0; + char *optstr = NULL; + gf_boolean_t boolt = _gf_false; if (!this) - return -1; + return NULL; if ((!this->children) || (!this->children->xlator)) { gf_log (GF_NFS, GF_LOG_ERROR, "nfs must have at least one" " child subvolume"); - return -1; + return NULL; } nfs = GF_CALLOC (1, sizeof (*nfs), gf_nfs_mt_nfs_state); if (!nfs) { gf_log (GF_NFS, GF_LOG_ERROR, "memory allocation failed"); - return -1; + return NULL; } - /* RPC service needs to be started before NFS versions can be inited. */ + /* RPC service needs to be started before NFS versions can be + * inited. */ nfs->rpcsvc = nfs_rpcsvc_init (this->ctx, this->options); if (!nfs->rpcsvc) { gf_log (GF_NFS, GF_LOG_ERROR, "RPC service init failed"); @@ -491,33 +495,86 @@ init (xlator_t *this) { /* FIXME: Really saddens me to see this as xlator wide. */ nfs->foppool = mem_pool_new (struct nfs_fop_local, fopspoolsize); if (!nfs->foppool) { - gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to allocate fops local" - " pool"); + gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to allocate fops " + "local pool"); goto free_rpcsvc; } + nfs->dynamicvolumes = GF_NFS_DVM_OFF; + if (dict_get (this->options, "nfs.dynamic-volumes")) { + ret = dict_get_str (this->options, "nfs.dynamic-volumes", + &optstr); + if (ret < 0) { + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse dict"); + goto free_foppool; + } + + ret = gf_string2boolean (optstr, &boolt); + if (ret < 0) { + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to parse bool " + "string"); + goto free_foppool; + } + + if (boolt == _gf_true) + nfs->dynamicvolumes = GF_NFS_DVM_ON; + } + this->private = (void *)nfs; INIT_LIST_HEAD (&nfs->versions); + + ret = 0; + +free_foppool: + if (ret < 0) + mem_pool_destroy (nfs->foppool); + +free_rpcsvc: + /* + * rpcsvc_deinit */ +free_nfs: + if (ret < 0) { + GF_FREE (nfs); + nfs = NULL; + } + + return nfs; +} + + +int +init (xlator_t *this) { + + struct nfs_state *nfs = NULL; + int ret = -1; + + if (!this) + return -1; + + nfs = nfs_init_state (this); + if (!nfs) { + gf_log (GF_NFS, GF_LOG_ERROR, "Failed to init nfs option"); + return -1; + } + ret = nfs_add_all_initiators (nfs); if (ret == -1) { gf_log (GF_NFS, GF_LOG_ERROR, "Failed to add initiators"); - goto free_nfs; + goto err; } ret = nfs_init_subvolumes (nfs, this->children); if (ret == -1) { - gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to init NFS exports"); - goto free_rpcsvc; + gf_log (GF_NFS, GF_LOG_CRITICAL, "Failed to init NFS " + "exports"); + goto err; } -free_rpcsvc: - /* - * rpcsvc_deinit */ -free_nfs: - if (ret == -1) - GF_FREE (nfs); + ret = 0; +err: + if (ret == 0) + gf_log (GF_NFS, GF_LOG_INFO, "NFS service started"); - gf_log (GF_NFS, GF_LOG_DEBUG, "NFS service started"); return ret; } @@ -731,6 +788,20 @@ struct volume_options options[] = { " using hostnames in rpc-auth.addr.* filters. By default, " " name lookup is on." }, + { .key = {"nfs.dynamic-volumes"}, + .type = GF_OPTION_TYPE_BOOL, + .description = "Internal option set to tell gnfs to use a different" + " scheme for encoding file handles when DVM is being" + " used." + }, + { .key = {"nfs3.%s.volume-id"}, + .type = GF_OPTION_TYPE_STR, + .description = "When nfs.dynamic-volumes is set, gnfs expects every " + "subvolume to have this option set for it, so that " + "gnfs can use this option to identify the volume. " + "If all subvolumes do not have this option set, an " + "error is reported." + }, { .key = {NULL} }, }; diff --git a/xlators/nfs/server/src/nfs.h b/xlators/nfs/server/src/nfs.h index b4973834558..baee0ce0f6a 100644 --- a/xlators/nfs/server/src/nfs.h +++ b/xlators/nfs/server/src/nfs.h @@ -42,6 +42,9 @@ #define GF_NFS_MIN_MEMFACTOR 1 #define GF_NFS_MAX_MEMFACTOR 30 +#define GF_NFS_DVM_ON 1 +#define GF_NFS_DVM_OFF 2 + /* Callback into a version-specific NFS protocol. * The return type is used by the nfs.c code to register the protocol. * with the RPC service. @@ -68,8 +71,11 @@ struct nfs_state { int upsubvols; xlator_t **initedxl; int subvols_started; + int dynamicvolumes; }; +#define gf_nfs_dvm_on(nfsstt) (((struct nfs_state *)nfsstt)->dynamicvolumes == GF_NFS_DVM_ON) +#define gf_nfs_dvm_off(nfsstt) (((struct nfs_state *)nfsstt)->dynamicvolumes == GF_NFS_DVM_OFF) /* We have one gid more than the glusterfs maximum since we pass the primary * gid as the first element of the array. diff --git a/xlators/nfs/server/src/nfs3-fh.c b/xlators/nfs/server/src/nfs3-fh.c index 7a7a06da058..10c00ba3287 100644 --- a/xlators/nfs/server/src/nfs3-fh.c +++ b/xlators/nfs/server/src/nfs3-fh.c @@ -49,15 +49,6 @@ nfs3_fh_validate (struct nfs3_fh *fh) } -xlator_t * -nfs3_fh_to_xlator (xlator_list_t *cl, struct nfs3_fh *fh) -{ - if ((!cl) || (!fh)) - return NULL; - - return nfs_xlid_to_xlator (cl, fh->xlatorid); -} - void nfs3_fh_init (struct nfs3_fh *fh, struct iatt *buf) { @@ -68,24 +59,35 @@ nfs3_fh_init (struct nfs3_fh *fh, struct iatt *buf) fh->ident[1] = GF_NFSFH_IDENT1; fh->hashcount = 0; - fh->gen = buf->ia_gen; - fh->ino = buf->ia_ino; - + uuid_copy (fh->gfid, buf->ia_gfid); } struct nfs3_fh -nfs3_fh_build_root_fh (xlator_list_t *cl, xlator_t *xl) +nfs3_fh_build_indexed_root_fh (xlator_list_t *cl, xlator_t *xl) { struct nfs3_fh fh = {{0}, }; struct iatt buf = {0, }; if ((!cl) || (!xl)) return fh; + buf.ia_gfid[15] = 1; nfs3_fh_init (&fh, &buf); - fh.xlatorid = nfs_xlator_to_xlid (cl, xl); - fh.ino = 1; - fh.gen = 0; + fh.exportid [15] = nfs_xlator_to_xlid (cl, xl); + + return fh; +} + + +struct nfs3_fh +nfs3_fh_build_uuid_root_fh (uuid_t volumeid) +{ + struct nfs3_fh fh = {{0}, }; + struct iatt buf = {0, }; + + nfs3_fh_init (&fh, &buf); + uuid_copy (fh.exportid, volumeid); + return fh; } @@ -93,10 +95,13 @@ nfs3_fh_build_root_fh (xlator_list_t *cl, xlator_t *xl) int nfs3_fh_is_root_fh (struct nfs3_fh *fh) { + uuid_t rootgfid = {0, 1}; + if (!fh) return 0; - if (fh->hashcount == 0) + rootgfid[15] = 1; + if (uuid_compare (fh->gfid, rootgfid) == 0) return 1; return 0; @@ -104,10 +109,12 @@ nfs3_fh_is_root_fh (struct nfs3_fh *fh) nfs3_hash_entry_t -nfs3_fh_hash_entry (ino_t ino, uint64_t gen) +nfs3_fh_hash_entry (uuid_t gfid) { nfs3_hash_entry_t hash = 0; int shiftsize = 48; + uint64_t ino = 0; + uint64_t gen = 0; nfs3_hash_entry_t inomsb = 0; nfs3_hash_entry_t inolsb = 0; nfs3_hash_entry_t inols23b = 0; @@ -116,6 +123,7 @@ nfs3_fh_hash_entry (ino_t ino, uint64_t gen) nfs3_hash_entry_t genlsb = 0; nfs3_hash_entry_t genls23b = 0; + memcpy (&ino, &gfid[8], 8); hash = ino; while (shiftsize != 0) { hash ^= (ino >> shiftsize); @@ -139,6 +147,7 @@ nfs3_fh_hash_entry (ino_t ino, uint64_t gen) inols23b = (inols23b << 8); // gf_log ("FILEHDNALE", GF_LOG_TRACE, "inols23b %d", inols23b); + memcpy (&gen, &gfid[0], 8); genmsb = (gen >> 56); // gf_log ("FILEHANDLE", GF_LOG_TRACE, "inomsb %d", inomsb); @@ -163,11 +172,16 @@ nfs3_fh_hash_entry (ino_t ino, uint64_t gen) void nfs3_fh_to_str (struct nfs3_fh *fh, char *str) { + char gfid[512]; + char exportid[512]; + if ((!fh) || (!str)) return; - sprintf (str, "FH: hashcount %d, xlid %d, gen %"PRIu64", ino %"PRIu64, - fh->hashcount, fh->xlatorid, fh->gen, fh->ino); + uuid_unparse (fh->gfid, gfid); + uuid_unparse (fh->exportid, exportid); + sprintf (str, "FH: hashcount %d, exportid %s, gfid %s", + fh->hashcount, exportid, gfid); } @@ -175,12 +189,16 @@ void nfs3_log_fh (struct nfs3_fh *fh) { // int x = 0; + char gfidstr[512]; + char exportidstr[512]; + if (!fh) return; - gf_log ("nfs3-fh", GF_LOG_TRACE, "filehandle: hashcount %d, xlid %d, " - "gen %"PRIu64", ino %"PRIu64, fh->hashcount, fh->xlatorid, - fh->gen, fh->ino); + uuid_unparse (fh->gfid, gfidstr); + uuid_unparse (fh->exportid, exportidstr); + gf_log ("nfs3-fh", GF_LOG_TRACE, "filehandle: hashcount %d, exportid %d" + ", gfid 0x%s", fh->hashcount, exportidstr, gfidstr); /* for (; x < fh->hashcount; ++x) gf_log ("FILEHANDLE", GF_LOG_TRACE, "Hash %d: %d", x, @@ -197,12 +215,9 @@ nfs3_fh_build_parent_fh (struct nfs3_fh *child, struct iatt *newstat, return -1; nfs3_fh_init (newfh, newstat); - newfh->xlatorid = child->xlatorid; - if ((newstat->ia_ino == 1) && (newstat->ia_gen == 0)) { - newfh->ino = 1; - newfh->gen = 0; + uuid_copy (newfh->exportid, child->exportid); + if (newstat->ia_ino == 1) goto done; - } newfh->hashcount = child->hashcount - 1; memcpy (newfh->entryhash, child->entryhash, @@ -215,7 +230,6 @@ done: } - int nfs3_fh_build_child_fh (struct nfs3_fh *parent, struct iatt *newstat, struct nfs3_fh *newfh) @@ -227,12 +241,7 @@ nfs3_fh_build_child_fh (struct nfs3_fh *parent, struct iatt *newstat, return -1; nfs3_fh_init (newfh, newstat); - newfh->xlatorid = parent->xlatorid; - if ((newstat->ia_ino == 1) && (newstat->ia_gen == 0)) { - newfh->ino = 1; - newfh->gen = 0; - goto done; - } + uuid_copy (newfh->exportid, parent->exportid); newfh->hashcount = parent->hashcount + 1; /* Only copy the hashes that are available in the parent file @@ -249,11 +258,9 @@ nfs3_fh_build_child_fh (struct nfs3_fh *parent, struct iatt *newstat, * array of the child entry. */ if (newfh->hashcount <= GF_NFSFH_MAXHASHES) { entry = newfh->hashcount - 1; - newfh->entryhash[entry] = nfs3_fh_hash_entry (parent->ino, - parent->gen); + newfh->entryhash[entry] = nfs3_fh_hash_entry (parent->gfid); } -done: // nfs3_log_fh (newfh); return 0; diff --git a/xlators/nfs/server/src/nfs3-fh.h b/xlators/nfs/server/src/nfs3-fh.h index 4ee4423951c..987063e7407 100644 --- a/xlators/nfs/server/src/nfs3-fh.h +++ b/xlators/nfs/server/src/nfs3-fh.h @@ -29,13 +29,14 @@ #include "xdr-nfs3.h" #include "iatt.h" #include +#include "uuid.h" /* BIG FAT WARNING: The file handle code is tightly coupled to NFSv3 file * handles for now. This will change if and when we need v4. */ #define GF_NFSFH_IDENT0 ':' #define GF_NFSFH_IDENT1 'O' #define GF_NFSFH_IDENT_SIZE (sizeof(char) * 2) -#define GF_NFSFH_STATIC_SIZE (GF_NFSFH_IDENT_SIZE + sizeof (uint16_t) + sizeof (uint16_t) + sizeof (uint64_t) + sizeof(uint64_t)) +#define GF_NFSFH_STATIC_SIZE (GF_NFSFH_IDENT_SIZE + (2*sizeof (uuid_t)) + sizeof (uint16_t)) #define GF_NFSFH_MAX_HASH_BYTES (NFS3_FHSIZE - GF_NFSFH_STATIC_SIZE) /* Each hash element in the file handle is of 2 bytes thus giving @@ -46,6 +47,7 @@ typedef uint16_t nfs3_hash_entry_t; #define GF_NFSFH_MAXHASHES ((int)(GF_NFSFH_MAX_HASH_BYTES / GF_NFSFH_ENTRYHASH_SIZE)) #define nfs3_fh_hashcounted_size(hcount) (GF_NFSFH_STATIC_SIZE + (hcount * GF_NFSFH_ENTRYHASH_SIZE)) +#define nfs3_fh_exportid_to_index(exprtid) ((uint16_t)exprtid[15]) /* ATTENTION: Change in size of the structure below should be reflected in the * GF_NFSFH_STATIC_SIZE. */ @@ -56,18 +58,28 @@ struct nfs3_fh { */ char ident[2]; + /* UUID that identifies an export. The value stored in exportid + * depends on the usage of gluster nfs. If the DVM is enabled using + * the nfs.dynamic-volumes option then exportid will contain the UUID + * of the volume so that gnfs is able to identify volumes uniquely + * through volume additions,deletions,migrations, etc. + * + * When not using dvm, exportid contains the index of the volume + * based on the position of the volume in the list of subvolumes + * for gnfs. + */ + uuid_t exportid; + + /* File/dir gfid. */ + uuid_t gfid; + /* Number of file/ino hash elements that follow the ino. */ uint16_t hashcount; - /* Basically, the position/index of an xlator among the children of - * the NFS xlator. - */ - uint16_t xlatorid; - uint64_t gen; - uint64_t ino; nfs3_hash_entry_t entryhash[GF_NFSFH_MAXHASHES]; } __attribute__((__packed__)); +#define GF_NFS3FH_STATIC_INITIALIZER {{0},} extern uint32_t nfs3_fh_compute_size (struct nfs3_fh *fh); @@ -76,16 +88,13 @@ extern int nfs3_fh_hash_index_is_beyond (struct nfs3_fh *fh, int hashidx); extern uint16_t -nfs3_fh_hash_entry (ino_t ino, uint64_t gen); +nfs3_fh_hash_entry (uuid_t gfid); extern int nfs3_fh_validate (struct nfs3_fh *fh); -extern xlator_t * -nfs3_fh_to_xlator (xlator_list_t *cl, struct nfs3_fh *fh); - extern struct nfs3_fh -nfs3_fh_build_root_fh (xlator_list_t *cl, xlator_t *xl); +nfs3_fh_build_indexed_root_fh (xlator_list_t *cl, xlator_t *xl); extern int nfs3_fh_is_root_fh (struct nfs3_fh *fh); @@ -103,4 +112,7 @@ nfs3_fh_to_str (struct nfs3_fh *fh, char *str); extern int nfs3_fh_build_parent_fh (struct nfs3_fh *child, struct iatt *newstat, struct nfs3_fh *newfh); + +extern struct nfs3_fh +nfs3_fh_build_uuid_root_fh (uuid_t volumeid); #endif diff --git a/xlators/nfs/server/src/nfs3-helpers.c b/xlators/nfs/server/src/nfs3-helpers.c index 5a5a0b29df3..9ccfb07ca40 100644 --- a/xlators/nfs/server/src/nfs3-helpers.c +++ b/xlators/nfs/server/src/nfs3-helpers.c @@ -92,12 +92,12 @@ struct nfs3stat_strerror nfs3stat_strerror_table[] = { void -nfs3_map_xlid_to_statdev (struct iatt *ia, uint16_t xlid) +nfs3_map_deviceid_to_statdev (struct iatt *ia, uint64_t deviceid) { if (!ia) return; - ia->ia_dev = xlid; + ia->ia_dev = deviceid; } @@ -395,15 +395,11 @@ nfs3_fill_lookup3res_success (lookup3res *res, nfsstat3 stat, obj.attributes_follow = FALSE; dir.attributes_follow = FALSE; - if (buf && fh) { - nfs3_map_xlid_to_statdev (buf, fh->xlatorid); + if (buf) obj = nfs3_stat_to_post_op_attr (buf); - } - if (postparent && fh) { - nfs3_map_xlid_to_statdev (postparent, fh->xlatorid); + if (postparent) dir = nfs3_stat_to_post_op_attr (postparent); - } res->lookup3res_u.resok.obj_attributes = obj; res->lookup3res_u.resok.dir_attributes = dir; @@ -412,10 +408,13 @@ nfs3_fill_lookup3res_success (lookup3res *res, nfsstat3 stat, void nfs3_fill_lookup3res (lookup3res *res, nfsstat3 stat, struct nfs3_fh *newfh, - struct iatt *buf, struct iatt *postparent) + struct iatt *buf, struct iatt *postparent, + uint64_t deviceid) { memset (res, 0, sizeof (*res)); + nfs3_map_deviceid_to_statdev (buf, deviceid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); if (stat != NFS3_OK) nfs3_fill_lookup3res_error (res, stat, postparent); else @@ -432,7 +431,7 @@ nfs3_extract_getattr_fh (getattr3args *args) void nfs3_fill_getattr3res (getattr3res *res, nfsstat3 stat, struct iatt *buf, - uint16_t xlid) + uint64_t deviceid) { memset (res, 0, sizeof (*res)); @@ -440,7 +439,7 @@ nfs3_fill_getattr3res (getattr3res *res, nfsstat3 stat, struct iatt *buf, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (buf, xlid); + nfs3_map_deviceid_to_statdev (buf, deviceid); res->getattr3res_u.resok.obj_attributes = nfs3_stat_to_fattr3 (buf); } @@ -455,7 +454,7 @@ nfs3_extract_fsinfo_fh (fsinfo3args *args) void nfs3_fill_fsinfo3res (struct nfs3_state *nfs3, fsinfo3res *res, - nfsstat3 status, struct iatt *fsroot, uint16_t xlid) + nfsstat3 status, struct iatt *fsroot, uint64_t deviceid) { fsinfo3resok resok = {{0}, }; nfstime3 tdelta = GF_NFS3_TIMEDELTA_SECS; @@ -465,7 +464,7 @@ nfs3_fill_fsinfo3res (struct nfs3_state *nfs3, fsinfo3res *res, if (status != NFS3_OK) return; - nfs3_map_xlid_to_statdev (fsroot, xlid); + nfs3_map_deviceid_to_statdev (fsroot, deviceid); resok.obj_attributes = nfs3_stat_to_post_op_attr (fsroot); resok.rtmax = nfs3->readsize; resok.rtpref = nfs3->readsize; @@ -677,7 +676,8 @@ nfs3_stat_to_accessbits (struct iatt *buf, uint32_t request, uid_t uid, void nfs3_fill_access3res (access3res *res, nfsstat3 status, struct iatt *buf, - uint32_t accbits, uid_t uid, gid_t gid, uint16_t xlid) + uint32_t accbits, uid_t uid, gid_t gid, + uint64_t deviceid) { post_op_attr objattr; uint32_t accres = 0; @@ -687,7 +687,7 @@ nfs3_fill_access3res (access3res *res, nfsstat3 status, struct iatt *buf, if (status != NFS3_OK) return; - nfs3_map_xlid_to_statdev (buf, xlid); + nfs3_map_deviceid_to_statdev (buf, deviceid); objattr = nfs3_stat_to_post_op_attr (buf); accres = nfs3_stat_to_accessbits (buf, accbits, uid, gid); @@ -829,7 +829,7 @@ nfs3_fh_to_post_op_fh3 (struct nfs3_fh *fh) entryp3 * -nfs3_fill_entryp3 (gf_dirent_t *entry, struct nfs3_fh *dirfh) +nfs3_fill_entryp3 (gf_dirent_t *entry, struct nfs3_fh *dirfh, uint64_t devid) { entryp3 *ent = NULL; struct nfs3_fh newfh = {{0}, }; @@ -862,7 +862,7 @@ nfs3_fill_entryp3 (gf_dirent_t *entry, struct nfs3_fh *dirfh) strcpy (ent->name, entry->d_name); nfs3_fh_build_child_fh (dirfh, &entry->d_stat, &newfh); - nfs3_map_xlid_to_statdev (&entry->d_stat, dirfh->xlatorid); + nfs3_map_deviceid_to_statdev (&entry->d_stat, devid); ent->name_attributes = nfs3_stat_to_post_op_attr (&entry->d_stat); ent->name_handle = nfs3_fh_to_post_op_fh3 (&newfh); err: @@ -873,7 +873,8 @@ err: void nfs3_fill_readdir3res (readdir3res *res, nfsstat3 stat, struct nfs3_fh *dirfh, uint64_t cverf, struct iatt *dirstat, - gf_dirent_t *entries, count3 count, int is_eof) + gf_dirent_t *entries, count3 count, int is_eof, + uint64_t deviceid) { post_op_attr dirattr; entry3 *ent = NULL; @@ -887,7 +888,7 @@ nfs3_fill_readdir3res (readdir3res *res, nfsstat3 stat, struct nfs3_fh *dirfh, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (dirstat, dirfh->xlatorid); + nfs3_map_deviceid_to_statdev (dirstat, deviceid); dirattr = nfs3_stat_to_post_op_attr (dirstat); res->readdir3res_u.resok.dir_attributes = dirattr; res->readdir3res_u.resok.reply.eof = (bool_t)is_eof; @@ -928,10 +929,11 @@ nfs3_fill_readdir3res (readdir3res *res, nfsstat3 stat, struct nfs3_fh *dirfh, void -nfs3_fill_readdirp3res (readdirp3res *res, nfsstat3 stat, struct nfs3_fh *dirfh, - uint64_t cverf, struct iatt *dirstat, - gf_dirent_t *entries, count3 dircount, count3 maxcount, - int is_eof) +nfs3_fill_readdirp3res (readdirp3res *res, nfsstat3 stat, + struct nfs3_fh *dirfh, uint64_t cverf, + struct iatt *dirstat, gf_dirent_t *entries, + count3 dircount, count3 maxcount, int is_eof, + uint64_t deviceid) { post_op_attr dirattr; entryp3 *ent = NULL; @@ -946,7 +948,7 @@ nfs3_fill_readdirp3res (readdirp3res *res, nfsstat3 stat, struct nfs3_fh *dirfh, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (dirstat, dirfh->xlatorid); + nfs3_map_deviceid_to_statdev (dirstat, deviceid); dirattr = nfs3_stat_to_post_op_attr (dirstat); res->readdirp3res_u.resok.dir_attributes = dirattr; res->readdirp3res_u.resok.reply.eof = (bool_t)is_eof; @@ -964,7 +966,7 @@ nfs3_fill_readdirp3res (readdirp3res *res, nfsstat3 stat, struct nfs3_fh *dirfh, (strcmp (entries->d_name, "..") == 0)) goto nextentry; */ - ent = nfs3_fill_entryp3 (entries, dirfh); + ent = nfs3_fill_entryp3 (entries, dirfh, deviceid); if (!ent) break; @@ -1050,7 +1052,7 @@ nfs3_prep_fsstat3args (fsstat3args *args, struct nfs3_fh *fh) void nfs3_fill_fsstat3res (fsstat3res *res, nfsstat3 stat, struct statvfs *fsbuf, - struct iatt *postbuf, uint16_t xlid) + struct iatt *postbuf, uint64_t deviceid) { post_op_attr poa; fsstat3resok resok; @@ -1060,7 +1062,7 @@ nfs3_fill_fsstat3res (fsstat3res *res, nfsstat3 stat, struct statvfs *fsbuf, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (postbuf, xlid); + nfs3_map_deviceid_to_statdev (postbuf, deviceid); poa = nfs3_stat_to_post_op_attr (postbuf); resok.tbytes = (size3)(fsbuf->f_frsize * fsbuf->f_blocks); resok.fbytes = (size3)(fsbuf->f_bsize * fsbuf->f_bfree); @@ -1209,7 +1211,7 @@ nfs3_stat_to_wcc_data (struct iatt *pre, struct iatt *post) void nfs3_fill_create3res (create3res *res, nfsstat3 stat, struct nfs3_fh *newfh, struct iatt *newbuf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, uint64_t deviceid) { post_op_attr poa = {0, }; wcc_data dirwcc = {{0}, }; @@ -1220,14 +1222,12 @@ nfs3_fill_create3res (create3res *res, nfsstat3 stat, struct nfs3_fh *newfh, return; nfs3_fill_post_op_fh3 (newfh, &res->create3res_u.resok.obj); - nfs3_map_xlid_to_statdev (newbuf, newfh->xlatorid); + nfs3_map_deviceid_to_statdev (newbuf, deviceid); poa = nfs3_stat_to_post_op_attr (newbuf); res->create3res_u.resok.obj_attributes = poa; - if (preparent) { - nfs3_map_xlid_to_statdev (preparent, newfh->xlatorid); - nfs3_map_xlid_to_statdev (postparent, newfh->xlatorid); - dirwcc = nfs3_stat_to_wcc_data (preparent, postparent); - } + nfs3_map_deviceid_to_statdev (preparent, deviceid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); + dirwcc = nfs3_stat_to_wcc_data (preparent, postparent); res->create3res_u.resok.dir_wcc = dirwcc; } @@ -1251,7 +1251,7 @@ nfs3_prep_setattr3args (setattr3args *args, struct nfs3_fh *fh) void nfs3_fill_setattr3res (setattr3res *res, nfsstat3 stat, struct iatt *preop, - struct iatt *postop, uint16_t xlid) + struct iatt *postop, uint64_t deviceid) { wcc_data wcc; memset (res, 0, sizeof (*res)); @@ -1259,8 +1259,8 @@ nfs3_fill_setattr3res (setattr3res *res, nfsstat3 stat, struct iatt *preop, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (preop, xlid); - nfs3_map_xlid_to_statdev (postop, xlid); + nfs3_map_deviceid_to_statdev (preop, deviceid); + nfs3_map_deviceid_to_statdev (postop, deviceid); wcc = nfs3_stat_to_wcc_data (preop, postop); res->setattr3res_u.resok.obj_wcc = wcc; } @@ -1279,7 +1279,7 @@ nfs3_prep_mkdir3args (mkdir3args *args, struct nfs3_fh *dirfh, char *name) void nfs3_fill_mkdir3res (mkdir3res *res, nfsstat3 stat, struct nfs3_fh *fh, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, uint64_t deviceid) { wcc_data dirwcc; post_op_attr poa; @@ -1290,10 +1290,10 @@ nfs3_fill_mkdir3res (mkdir3res *res, nfsstat3 stat, struct nfs3_fh *fh, return; nfs3_fill_post_op_fh3 (fh, &res->mkdir3res_u.resok.obj); - nfs3_map_xlid_to_statdev (buf, fh->xlatorid); + nfs3_map_deviceid_to_statdev (buf, deviceid); poa = nfs3_stat_to_post_op_attr (buf); - nfs3_map_xlid_to_statdev (preparent, fh->xlatorid); - nfs3_map_xlid_to_statdev (postparent, fh->xlatorid); + nfs3_map_deviceid_to_statdev (preparent, deviceid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); dirwcc = nfs3_stat_to_wcc_data (preparent, postparent); res->mkdir3res_u.resok.obj_attributes = poa; res->mkdir3res_u.resok.dir_wcc = dirwcc; @@ -1315,7 +1315,7 @@ nfs3_prep_symlink3args (symlink3args *args, struct nfs3_fh *dirfh, char *name, void nfs3_fill_symlink3res (symlink3res *res, nfsstat3 stat, struct nfs3_fh *fh, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, uint64_t deviceid) { wcc_data dirwcc; post_op_attr poa; @@ -1326,10 +1326,10 @@ nfs3_fill_symlink3res (symlink3res *res, nfsstat3 stat, struct nfs3_fh *fh, return; nfs3_fill_post_op_fh3 (fh, &res->symlink3res_u.resok.obj); - nfs3_map_xlid_to_statdev (buf, fh->xlatorid); + nfs3_map_deviceid_to_statdev (buf, deviceid); poa = nfs3_stat_to_post_op_attr (buf); - nfs3_map_xlid_to_statdev (postparent, fh->xlatorid); - nfs3_map_xlid_to_statdev (preparent, fh->xlatorid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); + nfs3_map_deviceid_to_statdev (preparent, deviceid); dirwcc = nfs3_stat_to_wcc_data (preparent, postparent); res->symlink3res_u.resok.obj_attributes = poa; res->symlink3res_u.resok.dir_wcc = dirwcc; @@ -1348,7 +1348,7 @@ nfs3_prep_readlink3args (readlink3args *args, struct nfs3_fh *fh) void nfs3_fill_readlink3res (readlink3res *res, nfsstat3 stat, char *path, - struct iatt *buf, uint16_t xlid) + struct iatt *buf, uint64_t deviceid) { post_op_attr poa; @@ -1358,7 +1358,7 @@ nfs3_fill_readlink3res (readlink3res *res, nfsstat3 stat, char *path, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (buf, xlid); + nfs3_map_deviceid_to_statdev (buf, deviceid); poa = nfs3_stat_to_post_op_attr (buf); res->readlink3res_u.resok.data = (void *)path; res->readlink3res_u.resok.symlink_attributes = poa; @@ -1377,7 +1377,7 @@ nfs3_prep_mknod3args (mknod3args *args, struct nfs3_fh *fh, char *name) void nfs3_fill_mknod3res (mknod3res *res, nfsstat3 stat, struct nfs3_fh *fh, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, uint64_t deviceid) { post_op_attr poa; wcc_data wccdir; @@ -1388,10 +1388,10 @@ nfs3_fill_mknod3res (mknod3res *res, nfsstat3 stat, struct nfs3_fh *fh, return; nfs3_fill_post_op_fh3 (fh, &res->mknod3res_u.resok.obj); - nfs3_map_xlid_to_statdev (buf, fh->xlatorid); + nfs3_map_deviceid_to_statdev (buf, deviceid); poa = nfs3_stat_to_post_op_attr (buf); - nfs3_map_xlid_to_statdev (preparent, fh->xlatorid); - nfs3_map_xlid_to_statdev (postparent, fh->xlatorid); + nfs3_map_deviceid_to_statdev (preparent, deviceid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); wccdir = nfs3_stat_to_wcc_data (preparent, postparent); res->mknod3res_u.resok.obj_attributes = poa; res->mknod3res_u.resok.dir_wcc = wccdir; @@ -1401,7 +1401,7 @@ nfs3_fill_mknod3res (mknod3res *res, nfsstat3 stat, struct nfs3_fh *fh, void nfs3_fill_remove3res (remove3res *res, nfsstat3 stat, struct iatt *preparent, - struct iatt *postparent, uint16_t xlid) + struct iatt *postparent, uint64_t deviceid) { wcc_data dirwcc; @@ -1410,8 +1410,8 @@ nfs3_fill_remove3res (remove3res *res, nfsstat3 stat, struct iatt *preparent, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (preparent, xlid); - nfs3_map_xlid_to_statdev (postparent, xlid); + nfs3_map_deviceid_to_statdev (preparent, deviceid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); dirwcc = nfs3_stat_to_wcc_data (preparent, postparent); res->remove3res_u.resok.dir_wcc = dirwcc; } @@ -1437,7 +1437,7 @@ nfs3_prep_rmdir3args (rmdir3args *args, struct nfs3_fh *fh, char *name) void nfs3_fill_rmdir3res (rmdir3res *res, nfsstat3 stat, struct iatt *preparent, - struct iatt *postparent, uint16_t xlid) + struct iatt *postparent, uint64_t deviceid) { wcc_data dirwcc; memset (res, 0, sizeof (*res)); @@ -1446,8 +1446,8 @@ nfs3_fill_rmdir3res (rmdir3res *res, nfsstat3 stat, struct iatt *preparent, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (postparent, xlid); - nfs3_map_xlid_to_statdev (preparent, xlid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); + nfs3_map_deviceid_to_statdev (preparent, deviceid); dirwcc = nfs3_stat_to_wcc_data (preparent, postparent); res->rmdir3res_u.resok.dir_wcc = dirwcc; } @@ -1467,7 +1467,7 @@ nfs3_prep_link3args (link3args *args, struct nfs3_fh *target, void nfs3_fill_link3res (link3res *res, nfsstat3 stat, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, - uint16_t xlid) + uint64_t deviceid) { post_op_attr poa; wcc_data dirwcc; @@ -1477,9 +1477,9 @@ nfs3_fill_link3res (link3res *res, nfsstat3 stat, struct iatt *buf, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (preparent, xlid); - nfs3_map_xlid_to_statdev (postparent, xlid); - nfs3_map_xlid_to_statdev (buf, xlid); + nfs3_map_deviceid_to_statdev (preparent, deviceid); + nfs3_map_deviceid_to_statdev (postparent, deviceid); + nfs3_map_deviceid_to_statdev (buf,deviceid); poa = nfs3_stat_to_post_op_attr (buf); dirwcc = nfs3_stat_to_wcc_data (preparent, postparent); res->link3res_u.resok.file_attributes = poa; @@ -1506,7 +1506,7 @@ void nfs3_fill_rename3res (rename3res *res, nfsstat3 stat, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, - uint16_t xlid) + uint64_t deviceid) { wcc_data dirwcc; @@ -1516,11 +1516,11 @@ nfs3_fill_rename3res (rename3res *res, nfsstat3 stat, struct iatt *buf, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (preoldparent, xlid); - nfs3_map_xlid_to_statdev (postoldparent, xlid); - nfs3_map_xlid_to_statdev (prenewparent, xlid); - nfs3_map_xlid_to_statdev (postnewparent, xlid); - nfs3_map_xlid_to_statdev (buf, xlid); + nfs3_map_deviceid_to_statdev (preoldparent, deviceid); + nfs3_map_deviceid_to_statdev (postoldparent, deviceid); + nfs3_map_deviceid_to_statdev (prenewparent, deviceid); + nfs3_map_deviceid_to_statdev (postnewparent, deviceid); + nfs3_map_deviceid_to_statdev (buf, deviceid); dirwcc = nfs3_stat_to_wcc_data (preoldparent, postoldparent); res->rename3res_u.resok.fromdir_wcc = dirwcc; dirwcc = nfs3_stat_to_wcc_data (prenewparent, postnewparent); @@ -1539,7 +1539,7 @@ nfs3_prep_write3args (write3args *args, struct nfs3_fh *fh) void nfs3_fill_write3res (write3res *res, nfsstat3 stat, count3 count, stable_how stable, uint64_t wverf, struct iatt *prestat, - struct iatt *poststat, uint16_t xlid) + struct iatt *poststat, uint64_t deviceid) { write3resok resok; memset (res, 0, sizeof (*res)); @@ -1547,8 +1547,8 @@ nfs3_fill_write3res (write3res *res, nfsstat3 stat, count3 count, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (prestat, xlid); - nfs3_map_xlid_to_statdev (poststat, xlid); + nfs3_map_deviceid_to_statdev (prestat, deviceid); + nfs3_map_deviceid_to_statdev (poststat, deviceid); resok.file_wcc = nfs3_stat_to_wcc_data (prestat, poststat); resok.count = count; resok.committed = stable; @@ -1568,15 +1568,16 @@ nfs3_prep_commit3args (commit3args *args, struct nfs3_fh *fh) void nfs3_fill_commit3res (commit3res *res, nfsstat3 stat, uint64_t wverf, - struct iatt *prestat, struct iatt *poststat,uint16_t xlid) + struct iatt *prestat, struct iatt *poststat, + uint64_t deviceid) { memset (res, 0, sizeof (*res)); res->status = stat; if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (poststat, xlid); - nfs3_map_xlid_to_statdev (prestat, xlid); + nfs3_map_deviceid_to_statdev (poststat, deviceid); + nfs3_map_deviceid_to_statdev (prestat, deviceid); res->commit3res_u.resok.file_wcc = nfs3_stat_to_wcc_data (prestat, poststat); memcpy (res->commit3res_u.resok.verf, &wverf, sizeof (wverf)); @@ -1584,7 +1585,7 @@ nfs3_fill_commit3res (commit3res *res, nfsstat3 stat, uint64_t wverf, void nfs3_fill_read3res (read3res *res, nfsstat3 stat, count3 count, - struct iatt *poststat, int is_eof, uint16_t xlid) + struct iatt *poststat, int is_eof, uint64_t deviceid) { post_op_attr poa; @@ -1593,7 +1594,7 @@ nfs3_fill_read3res (read3res *res, nfsstat3 stat, count3 count, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (poststat, xlid); + nfs3_map_deviceid_to_statdev (poststat, deviceid); poa = nfs3_stat_to_post_op_attr (poststat); res->read3res_u.resok.file_attributes = poa; res->read3res_u.resok.count = count; @@ -1612,7 +1613,7 @@ nfs3_prep_read3args (read3args *args, struct nfs3_fh *fh) void nfs3_fill_pathconf3res (pathconf3res *res, nfsstat3 stat, struct iatt *buf, - uint16_t xlid) + uint64_t deviceid) { pathconf3resok resok; @@ -1621,7 +1622,7 @@ nfs3_fill_pathconf3res (pathconf3res *res, nfsstat3 stat, struct iatt *buf, if (stat != NFS3_OK) return; - nfs3_map_xlid_to_statdev (buf, xlid); + nfs3_map_deviceid_to_statdev (buf, deviceid); resok.obj_attributes = nfs3_stat_to_post_op_attr (buf); resok.linkmax = 256; resok.name_max = NFS_NAME_MAX; @@ -2496,6 +2497,7 @@ nfs3_fh_resolve_check_entry (struct nfs3_fh *fh, gf_dirent_t *candidate, struct iatt *ia = NULL; int ret = GF_NFS3_FHRESOLVE_NOTFOUND; nfs3_hash_entry_t entryhash = 0; + char gfidstr[512]; if ((!fh) || (!candidate)) return ret; @@ -2505,10 +2507,11 @@ nfs3_fh_resolve_check_entry (struct nfs3_fh *fh, gf_dirent_t *candidate, goto found_entry; ia = &candidate->d_stat; - if ((ia->ia_gen == fh->gen) && (ia->ia_ino == fh->ino)) { - gf_log (GF_NFS3, GF_LOG_TRACE, "Found entry: gen: %"PRId64 - " ino: %"PRId64", name: %s, hashcount %d", ia->ia_gen, - ia->ia_ino, candidate->d_name, hashidx); + if ((uuid_compare (candidate->d_stat.ia_gfid, fh->gfid)) == 0) { + uuid_unparse (candidate->d_stat.ia_gfid, gfidstr); + gf_log (GF_NFS3, GF_LOG_TRACE, "Found entry: gfid: %s, " + "name: %s, hashcount %d", gfidstr, candidate->d_name, + hashidx); ret = GF_NFS3_FHRESOLVE_FOUND; goto found_entry; } @@ -2521,7 +2524,7 @@ nfs3_fh_resolve_check_entry (struct nfs3_fh *fh, gf_dirent_t *candidate, if (!IA_ISDIR (candidate->d_stat.ia_type)) goto found_entry; entryhash = fh->entryhash[hashidx]; - if (entryhash == nfs3_fh_hash_entry (ia->ia_ino, ia->ia_gen)) { + if (entryhash == nfs3_fh_hash_entry (ia->ia_gfid)) { gf_log (GF_NFS3, GF_LOG_TRACE, "Found hash match: %s: %d, " "hashidx: %d", candidate->d_name, entryhash, hashidx); ret = GF_NFS3_FHRESOLVE_DIRFOUND; @@ -2571,20 +2574,17 @@ nfs3_fh_resolve_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int nfs3_fh_resolve_found_entry (nfs3_call_state_t *cs, gf_dirent_t *candidate) { - uint64_t dirino = 0; - uint64_t dirgen = 0; int ret = 0; nfs_user_t nfu = {0, }; + uuid_t gfid = {0, }; if ((!cs) || (!candidate)) return -EFAULT; - dirino = cs->resolvedloc.inode->ino; - + uuid_copy (gfid, cs->resolvedloc.inode->gfid); nfs_loc_wipe (&cs->resolvedloc); - ret = nfs_entry_loc_fill (cs->vol->itable, dirino, dirgen, - candidate->d_name, &cs->resolvedloc, - NFS_RESOLVE_CREATE); + ret = nfs_entry_loc_fill (cs->vol->itable, gfid, candidate->d_name, + &cs->resolvedloc, NFS_RESOLVE_CREATE); if (ret == -ENOENT) { gf_log (GF_NFS3, GF_LOG_TRACE, "Entry not in itable, needs" " lookup"); @@ -2634,20 +2634,17 @@ err: int nfs3_fh_resolve_found_parent (nfs3_call_state_t *cs, gf_dirent_t *candidate) { - uint64_t dirino = 0; - uint64_t dirgen = 0; int ret = 0; nfs_user_t nfu = {0, }; + uuid_t gfid = {0, }; if ((!cs) || (!candidate)) return -EFAULT; - dirino = cs->resolvedloc.inode->ino; - + uuid_copy (gfid, cs->resolvedloc.inode->gfid); nfs_loc_wipe (&cs->resolvedloc); - ret = nfs_entry_loc_fill (cs->vol->itable, dirino, dirgen, - candidate->d_name, &cs->resolvedloc, - NFS_RESOLVE_CREATE); + ret = nfs_entry_loc_fill (cs->vol->itable, gfid, candidate->d_name, + &cs->resolvedloc, NFS_RESOLVE_CREATE); if (ret == -ENOENT) { nfs_user_root_create (&nfu); ret = nfs_lookup (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc, @@ -2789,11 +2786,11 @@ out: int -nfs3_fh_resolve_dir_hard (nfs3_call_state_t *cs, uint64_t ino, uint64_t gen, - char *entry) +nfs3_fh_resolve_dir_hard (nfs3_call_state_t *cs, uuid_t dirgfid, char *entry) { int ret = -EFAULT; nfs_user_t nfu = {0, }; + char gfidstr[512]; if (!cs) return ret; @@ -2808,10 +2805,10 @@ nfs3_fh_resolve_dir_hard (nfs3_call_state_t *cs, uint64_t ino, uint64_t gen, } nfs_user_root_create (&nfu); - gf_log (GF_NFS3, GF_LOG_TRACE, "FH hard dir resolution: ino:" - " %"PRIu64", gen: %"PRIu64", entry: %s, next hashcount: %d", - ino, gen, entry, cs->hashidx); - ret = nfs_entry_loc_fill (cs->vol->itable, ino, gen, entry, + uuid_unparse (dirgfid, gfidstr); + gf_log (GF_NFS3, GF_LOG_TRACE, "FH hard dir resolution: gfid: %s, " + "entry: %s, next hashcount: %d", gfidstr, entry, cs->hashidx); + ret = nfs_entry_loc_fill (cs->vol->itable, dirgfid, entry, &cs->resolvedloc, NFS_RESOLVE_CREATE); if (ret == 0) { @@ -2851,21 +2848,17 @@ int nfs3_fh_resolve_check_response (nfs3_call_state_t *cs, gf_dirent_t *candidate, int response, off_t last_offt) { - uint64_t dirino = 0; - uint64_t dirgen = 0; int ret = -EFAULT; nfs_user_t nfu = {0, }; if (!cs) return ret; - dirino = cs->resolvedloc.inode->ino; - switch (response) { case GF_NFS3_FHRESOLVE_DIRFOUND: nfs3_fh_resolve_close_cwd (cs); - nfs3_fh_resolve_dir_hard (cs, dirino, dirgen, + nfs3_fh_resolve_dir_hard (cs, cs->resolvedloc.inode->gfid, candidate->d_name); break; @@ -2891,6 +2884,7 @@ nfs3_fh_resolve_search_dir (nfs3_call_state_t *cs, gf_dirent_t *entries) gf_dirent_t *candidate = NULL; int ret = GF_NFS3_FHRESOLVE_NOTFOUND; off_t lastoff = 0; + char gfidstr[512]; if ((!cs) || (!entries)) return -EFAULT; @@ -2900,9 +2894,9 @@ nfs3_fh_resolve_search_dir (nfs3_call_state_t *cs, gf_dirent_t *entries) list_for_each_entry (candidate, &entries->list, list) { lastoff = candidate->d_off; - gf_log (GF_NFS3, GF_LOG_TRACE, "Candidate: %s, ino: %"PRIu64 - ", gen: %"PRIu64, candidate->d_name, candidate->d_ino, - candidate->d_stat.ia_gen); + uuid_unparse (candidate->d_stat.ia_gfid, gfidstr); + gf_log (GF_NFS3, GF_LOG_TRACE, "Candidate: %s, gfid: %s", + PRIu64, candidate->d_name, gfidstr); ret = nfs3_fh_resolve_check_entry (&cs->resolvefh, candidate, cs->hashidx); if (ret != GF_NFS3_FHRESOLVE_NOTFOUND) @@ -2946,6 +2940,7 @@ nfs3_fh_resolve_inode_hard (nfs3_call_state_t *cs) { int ret = -EFAULT; nfs_user_t nfu = {0, }; + char gfidstr[512]; if (!cs) return ret; @@ -2960,11 +2955,11 @@ nfs3_fh_resolve_inode_hard (nfs3_call_state_t *cs) } nfs_user_root_create (&nfu); - gf_log (GF_NFS3, GF_LOG_TRACE, "FH hard resolution for: ino:" - " %"PRIu64", gen: %"PRIu64", hashcount: %d, current hashidx " - "%d", cs->resolvefh.ino, cs->resolvefh.gen, + uuid_unparse (cs->resolvefh.gfid, gfidstr); + gf_log (GF_NFS3, GF_LOG_TRACE, "FH hard resolution for: gfid 0x%s", + ", hashcount: %d, current hashidx %d", gfidstr, cs->resolvefh.hashcount, cs->hashidx); - ret = nfs_ino_loc_fill (cs->vol->itable, 1, 0, &cs->resolvedloc); + ret = nfs_root_loc_fill (cs->vol->itable, &cs->resolvedloc); if (ret == 0) { gf_log (GF_NFS3, GF_LOG_TRACE, "Dir will be opened: %s", @@ -2988,20 +2983,21 @@ nfs3_fh_resolve_entry_hard (nfs3_call_state_t *cs) { int ret = -EFAULT; nfs_user_t nfu = {0, }; + char gfidstr[512]; if (!cs) return ret; nfs_loc_wipe (&cs->resolvedloc); nfs_user_root_create (&nfu); - gf_log (GF_NFS3, GF_LOG_TRACE, "FH hard resolution: ino:" - " %"PRIu64", gen: %"PRIu64", entry: %s, hashidx: %d", - cs->resolvefh.ino, cs->resolvefh.gen, cs->resolventry, + uuid_unparse (cs->resolvefh.gfid, gfidstr); + gf_log (GF_NFS3, GF_LOG_TRACE, "FH hard resolution: gfid: %s " + ", entry: %s, hashidx: %d", gfidstr, cs->resolventry, cs->hashidx); - ret = nfs_entry_loc_fill (cs->vol->itable, cs->resolvefh.ino, - cs->resolvefh.gen, cs->resolventry, - &cs->resolvedloc, NFS_RESOLVE_CREATE); + ret = nfs_entry_loc_fill (cs->vol->itable, cs->resolvefh.gfid, + cs->resolventry, &cs->resolvedloc, + NFS_RESOLVE_CREATE); if (ret == -2) { gf_log (GF_NFS3, GF_LOG_TRACE, "Entry needs lookup: %s", @@ -3031,8 +3027,7 @@ nfs3_fh_resolve_inode (nfs3_call_state_t *cs) return ret; gf_log (GF_NFS3, GF_LOG_TRACE, "FH needs inode resolution"); - inode = inode_get (cs->vol->itable, cs->resolvefh.ino, - cs->resolvefh.gen); + inode = inode_find (cs->vol->itable, cs->resolvefh.gfid); if (!inode) ret = nfs3_fh_resolve_inode_hard (cs); else diff --git a/xlators/nfs/server/src/nfs3-helpers.h b/xlators/nfs/server/src/nfs3-helpers.h index db76b5cce77..b708993c400 100644 --- a/xlators/nfs/server/src/nfs3-helpers.h +++ b/xlators/nfs/server/src/nfs3-helpers.h @@ -46,7 +46,8 @@ nfs3_errno_to_nfsstat3 (int errnum); extern void nfs3_fill_lookup3res (lookup3res *res, nfsstat3 stat, struct nfs3_fh *newfh, - struct iatt *stbuf, struct iatt *postparent); + struct iatt *stbuf, struct iatt *postparent, + uint64_t deviceid); extern post_op_attr nfs3_stat_to_post_op_attr (struct iatt *buf); @@ -56,14 +57,14 @@ nfs3_extract_getattr_fh (getattr3args *args); extern void nfs3_fill_getattr3res (getattr3res *res, nfsstat3 stat, struct iatt *buf, - uint16_t xlid); + uint64_t deviceid); extern struct nfs3_fh nfs3_extract_fsinfo_fh (fsinfo3args *args); extern void nfs3_fill_fsinfo3res (struct nfs3_state *nfs3, fsinfo3res *res, - nfsstat3 status, struct iatt *fsroot, uint16_t xlid); + nfsstat3 status, struct iatt *fsroot,uint64_t deviceid); /* Functions containing _prep_ are used specifically to work around * the memory allocations that happen inside Sun RPC library. @@ -99,7 +100,8 @@ nfs3_prep_access3args (access3args *args, struct nfs3_fh *fh); extern void nfs3_fill_access3res (access3res *res, nfsstat3 status, struct iatt *buf, - uint32_t accbits, uid_t uid, gid_t gid, uint16_t xlid); + uint32_t accbits, uid_t uid, gid_t gid, + uint64_t deviceid); extern char * nfs3_fhcache_getpath (struct nfs3_state *nfs3, struct nfs3_fh *fh); @@ -113,16 +115,18 @@ nfs3_prep_readdir3args (readdir3args *ra, struct nfs3_fh *fh); extern void nfs3_fill_readdir3res (readdir3res *res, nfsstat3 stat, struct nfs3_fh *dfh, uint64_t cverf, struct iatt *dirstat, - gf_dirent_t *entries, count3 count, int is_eof); + gf_dirent_t *entries, count3 count, int is_eof, + uint64_t deviceid); extern void nfs3_prep_readdirp3args (readdirp3args *ra, struct nfs3_fh *fh); extern void -nfs3_fill_readdirp3res (readdirp3res *res, nfsstat3 stat, struct nfs3_fh *dirfh, - uint64_t cverf, struct iatt *dirstat, - gf_dirent_t *entries, count3 dircount, count3 maxcount, - int is_eof); +nfs3_fill_readdirp3res (readdirp3res *res, nfsstat3 stat, + struct nfs3_fh *dirfh, uint64_t cverf, + struct iatt *dirstat, gf_dirent_t *entries, + count3 dircount, count3 maxcount, int is_eof, + uint64_t deviceid); extern void nfs3_free_readdirp3res (readdirp3res *res); @@ -135,14 +139,14 @@ nfs3_prep_fsstat3args (fsstat3args *args, struct nfs3_fh *fh); extern void nfs3_fill_fsstat3res (fsstat3res *res, nfsstat3 stat, struct statvfs *fsbuf, - struct iatt *postbuf, uint16_t xlid); + struct iatt *postbuf, uint64_t deviceid); extern int32_t nfs3_sattr3_to_setattr_valid (sattr3 *sattr, struct iatt *buf, mode_t *omode); extern void nfs3_fill_create3res (create3res *res, nfsstat3 stat, struct nfs3_fh *newfh, struct iatt *newbuf, struct iatt *preparent, - struct iatt *postparent); + struct iatt *postparent, uint64_t deviceid); extern void nfs3_prep_create3args (create3args *args, struct nfs3_fh *fh, char *name); @@ -152,7 +156,7 @@ nfs3_prep_setattr3args (setattr3args *args, struct nfs3_fh *fh); extern void nfs3_fill_setattr3res (setattr3res *res, nfsstat3 stat, struct iatt *preop, - struct iatt *postop, uint16_t xlid); + struct iatt *postop, uint64_t deviceid); extern void nfs3_prep_mkdir3args (mkdir3args *args, struct nfs3_fh *dirfh, char *name); @@ -160,7 +164,7 @@ nfs3_prep_mkdir3args (mkdir3args *args, struct nfs3_fh *dirfh, char *name); extern void nfs3_fill_mkdir3res (mkdir3res *res, nfsstat3 stat, struct nfs3_fh *fh, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent); + struct iatt *postparent, uint64_t deviceid); extern void nfs3_prep_symlink3args (symlink3args *args, struct nfs3_fh *dirfh, char *name, @@ -169,14 +173,14 @@ nfs3_prep_symlink3args (symlink3args *args, struct nfs3_fh *dirfh, char *name, extern void nfs3_fill_symlink3res (symlink3res *res, nfsstat3 stat, struct nfs3_fh *fh, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent); + struct iatt *postparent, uint64_t deviceid); extern void nfs3_prep_readlink3args (readlink3args *args, struct nfs3_fh *fh); extern void nfs3_fill_readlink3res (readlink3res *res, nfsstat3 stat, char *path, - struct iatt *buf, uint16_t xlid); + struct iatt *buf, uint64_t deviceid); extern void nfs3_prep_mknod3args (mknod3args *args, struct nfs3_fh *fh, char *name); @@ -184,17 +188,17 @@ nfs3_prep_mknod3args (mknod3args *args, struct nfs3_fh *fh, char *name); extern void nfs3_fill_mknod3res (mknod3res *res, nfsstat3 stat, struct nfs3_fh *fh, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent); + struct iatt *postparent, uint64_t deviceid); extern void nfs3_fill_remove3res (remove3res *res, nfsstat3 stat, struct iatt *preparent, - struct iatt *postparent, uint16_t xlid); + struct iatt *postparent, uint64_t deviceid); extern void nfs3_prep_remove3args (remove3args *args, struct nfs3_fh *fh, char *name); extern void nfs3_fill_rmdir3res (rmdir3res *res, nfsstat3 stat, struct iatt *preparent, - struct iatt *postparent, uint16_t xlid); + struct iatt *postparent, uint64_t deviceid); extern void nfs3_prep_rmdir3args (rmdir3args *args, struct nfs3_fh *fh, char *name); @@ -202,7 +206,7 @@ nfs3_prep_rmdir3args (rmdir3args *args, struct nfs3_fh *fh, char *name); extern void nfs3_fill_link3res (link3res *res, nfsstat3 stat, struct iatt *buf, struct iatt *preparent, struct iatt *postparent, - uint16_t xlid); + uint64_t deviceid); extern void nfs3_prep_link3args (link3args *args, struct nfs3_fh *target, @@ -217,7 +221,7 @@ extern void nfs3_fill_rename3res (rename3res *res, nfsstat3 stat, struct iatt *buf, struct iatt *preoldparent, struct iatt *postoldparent, struct iatt *prenewparent, struct iatt *postnewparent, - uint16_t xlid); + uint64_t deviceid); extern void nfs3_prep_write3args (write3args *args, struct nfs3_fh *fh); @@ -225,7 +229,7 @@ nfs3_prep_write3args (write3args *args, struct nfs3_fh *fh); extern void nfs3_fill_write3res (write3res *res, nfsstat3 stat, count3 count, stable_how stable, uint64_t wverf, struct iatt *prestat, - struct iatt *poststat, uint16_t xlid); + struct iatt *poststat, uint64_t deviceid); extern void nfs3_prep_commit3args (commit3args *args, struct nfs3_fh *fh); @@ -233,11 +237,11 @@ nfs3_prep_commit3args (commit3args *args, struct nfs3_fh *fh); extern void nfs3_fill_commit3res (commit3res *res, nfsstat3 stat, uint64_t wverf, struct iatt *prestat, struct iatt *poststat, - uint16_t xlid); + uint64_t deviceid); extern void nfs3_fill_read3res (read3res *res, nfsstat3 stat, count3 count, - struct iatt *poststat, int is_eof, uint16_t xlid); + struct iatt *poststat, int is_eof, uint64_t deviceid); extern void nfs3_prep_read3args (read3args *args, struct nfs3_fh *fh); @@ -247,7 +251,7 @@ nfs3_prep_pathconf3args (pathconf3args *args, struct nfs3_fh *fh); extern void nfs3_fill_pathconf3res (pathconf3res *res, nfsstat3 stat, struct iatt *buf, - uint16_t xlid); + uint64_t deviceid); extern int nfs3_cached_inode_opened (xlator_t *nfsxl, inode_t *inode); diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c index 057ccb60e25..c4aaef3c308 100644 --- a/xlators/nfs/server/src/nfs3.c +++ b/xlators/nfs/server/src/nfs3.c @@ -67,11 +67,86 @@ } \ } while (0); \ -#define nfs3_export_access(nfs3state, xlid) ((nfs3state)->exports[xlid]).access -#define nfs3_check_rw_volaccess(nfs3state, xlid, status, label) \ - do { \ - if (nfs3_export_access (nfs3state,xlid)!=GF_NFS3_VOLACCESS_RW){\ +struct nfs3_export * +__nfs3_get_export_by_index (struct nfs3_state *nfs3, uuid_t exportid) +{ + struct nfs3_export *exp = NULL; + int index = 0; + int searchindex = 0; + + searchindex = nfs3_fh_exportid_to_index (exportid); + list_for_each_entry (exp, &nfs3->exports, explist) { + if (searchindex == index) + goto found; + + ++index; + } + + exp = NULL; +found: + return exp; +} + + +struct nfs3_export * +__nfs3_get_export_by_volumeid (struct nfs3_state *nfs3, uuid_t exportid) +{ + struct nfs3_export *exp = NULL; + + list_for_each_entry (exp, &nfs3->exports, explist) { + if (!uuid_compare (exportid, exp->volumeid)) + goto found; + } + + exp = NULL; +found: + return exp; +} + + +struct nfs3_export * +__nfs3_get_export_by_exportid (struct nfs3_state *nfs3, uuid_t exportid) +{ + struct nfs3_export *exp = NULL; + + if (!nfs3) + return exp; + + if (gf_nfs_dvm_off (nfs_state(nfs3->nfsx))) + exp = __nfs3_get_export_by_index (nfs3, exportid); + else + exp = __nfs3_get_export_by_volumeid (nfs3, exportid); + + return exp; +} + + +int +nfs3_export_access (struct nfs3_state *nfs3, uuid_t exportid) +{ + int ret = GF_NFS3_VOLACCESS_RO; + struct nfs3_export *exp = NULL; + + if (!nfs3) + return ret; + + exp = __nfs3_get_export_by_exportid (nfs3, exportid); + + if (!exp) { + gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to get export by ID"); + goto err; + } + + ret = exp->access; + +err: + return ret; +} + +#define nfs3_check_rw_volaccess(nfs3state, exid, status, label) \ + do { \ + if (nfs3_export_access (nfs3state,exid)!=GF_NFS3_VOLACCESS_RW){\ gf_log (GF_NFS3, GF_LOG_TRACE, "No read-write access");\ status = NFS3ERR_ROFS; \ goto label; \ @@ -80,9 +155,28 @@ +xlator_t * +nfs3_fh_to_xlator (struct nfs3_state *nfs3, struct nfs3_fh *fh) +{ + xlator_t *vol = NULL; + struct nfs3_export *exp = NULL; + + if ((!nfs3) || (!fh)) + return vol; + + exp = __nfs3_get_export_by_exportid (nfs3, fh->exportid); + if (!exp) + goto out; + + vol = exp->subvol; +out: + return vol; +} + + #define nfs3_map_fh_to_volume(nfs3state, handle, rqst, volume, status, label) \ do { \ - volume = nfs3_fh_to_xlator ((nfs3state)->exportslist, handle); \ + volume = nfs3_fh_to_xlator ((nfs3state), handle); \ if (!volume) { \ gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to map " \ "FH to vol"); \ @@ -124,6 +218,29 @@ } while (0) \ +int +__nfs3_get_volume_id (struct nfs3_state *nfs3, xlator_t *xl, + uuid_t volumeid) +{ + int ret = -1; + struct nfs3_export *exp = NULL; + + if ((!nfs3) || (!xl)) + return ret; + + list_for_each_entry (exp, &nfs3->exports, explist) { + if (exp->subvol == xl) { + uuid_copy (volumeid, exp->volumeid); + ret = 0; + goto out; + } + } + +out: + return ret; +} + + #define nfs3_funge_solaris_zerolen_fh(nfs3st, fhd, enam, nfsst, erl) \ do { \ xlator_t *fungexl = NULL; \ @@ -133,16 +250,56 @@ goto erl; \ } \ \ - (fhd)->xlatorid = nfs_xlator_to_xlid ((nfs3st)->exportslist, \ - fungexl); \ - (fhd)->gen = 0; \ - (fhd)->ino = 1; \ - (enam) = NULL; \ + if ((gf_nfs_dvm_off (nfs_state (nfs3st->nfsx)))) { \ + (fhd)->exportid[15] = nfs_xlator_to_xlid ((nfs3st)->exportslist, fungexl); \ + (fhd)->gfid[15] = 1; \ + (enam) = NULL; \ + } else { \ + if(!__nfs3_get_volume_id ((nfs3st), fungexl, (fhd)->exportid)) { \ + (nfsst) = NFS3ERR_STALE; \ + goto erl; \ + } \ + } \ } while (0) \ -#define nfs3_export_sync_trusted(nf3stt, xlid) ((nf3stt)->exports[xlid]).trusted_sync -#define nfs3_export_write_trusted(nf3stt, xlid) ((nf3stt)->exports[xlid]).trusted_write + +int +nfs3_export_sync_trusted (struct nfs3_state *nfs3, uuid_t exportid) +{ + struct nfs3_export *exp = NULL; + int ret = 0; + + if (!nfs3) + return ret; + + exp = __nfs3_get_export_by_exportid (nfs3, exportid); + if (!exp) + goto err; + + ret = exp->trusted_sync; +err: + return ret; +} + + +int +nfs3_export_write_trusted (struct nfs3_state *nfs3, uuid_t exportid) +{ + struct nfs3_export *exp = NULL; + int ret = 0; + + if (!nfs3) + return ret; + + exp = __nfs3_get_export_by_exportid (nfs3, exportid); + if (!exp) + goto err; + + ret = exp->trusted_write; +err: + return ret; +} int nfs3_solaris_zerolen_fh (struct nfs3_fh *fh, int fhlen) @@ -355,18 +512,27 @@ err: } -uint16_t -nfs3_request_xlator_id (rpcsvc_request_t *rq) +uint64_t +nfs3_request_xlator_deviceid (rpcsvc_request_t *rq) { struct nfs3_state *nfs3 = NULL; xlator_t *xl = NULL; + uint64_t devid = 0; + uuid_t volumeid = {0, }; if (!rq) return 0; xl = nfs_rpcsvc_request_private (rq); nfs3 = nfs_rpcsvc_request_program_private (rq); - return nfs_xlator_to_xlid (nfs3->exportslist, xl); + if (gf_nfs_dvm_off (nfs_state (nfs3->nfsx))) + devid = (uint64_t)nfs_xlator_to_xlid (nfs3->exportslist, xl); + else { + __nfs3_get_volume_id (nfs3, xl, volumeid); + memcpy (&devid, &volumeid[15], sizeof (devid)); + } + + return devid; } @@ -386,10 +552,10 @@ int nfs3_getattr_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *buf) { getattr3res res; - uint16_t xlid = 0; + uint64_t deviceid = 0; - xlid = nfs3_request_xlator_id (req); - nfs3_fill_getattr3res (&res, status, buf, xlid); + deviceid = nfs3_request_xlator_deviceid (req); + nfs3_fill_getattr3res (&res, status, buf, deviceid); nfs3svc_submit_reply (req, &res, (nfs3_serializer)xdr_serialize_getattr3res); @@ -558,10 +724,10 @@ nfs3_setattr_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *preop, struct iatt *postop) { setattr3res res = {0, }; - uint16_t xlid = 0; + uint64_t deviceid = 0; - xlid = nfs3_request_xlator_id (req); - nfs3_fill_setattr3res (&res, stat, preop, postop, xlid); + deviceid = nfs3_request_xlator_deviceid (req); + nfs3_fill_setattr3res (&res, stat, preop, postop, deviceid); nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer) xdr_serialize_setattr3res); return 0; @@ -761,7 +927,7 @@ nfs3_setattr (rpcsvc_request_t *req, struct nfs3_fh *fh, sattr3 *sattr, nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); - nfs3_check_rw_volaccess (nfs3, fh->xlatorid, stat, nfs3err); + nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err); nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err); cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, &cs->stbuf, @@ -837,8 +1003,10 @@ nfs3_lookup_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *newfh, struct iatt *stbuf, struct iatt *postparent) { lookup3res res = {0, }; + uint64_t deviceid = 0; - nfs3_fill_lookup3res (&res, stat, newfh, stbuf, postparent); + deviceid = nfs3_request_xlator_deviceid (req); + nfs3_fill_lookup3res (&res, stat, newfh, stbuf, postparent, deviceid); return nfs3svc_submit_reply (req, &res, (nfs3_serializer)xdr_serialize_lookup3res); } @@ -880,6 +1048,8 @@ nfs3svc_lookup_parentdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, struct nfs3_fh newfh = {{0}, }; nfsstat3 status = NFS3_OK; nfs3_call_state_t *cs = NULL; + uuid_t volumeid = {0, }; + struct nfs3_state *nfs3 = NULL; cs = frame->local; if (op_ret == -1) { @@ -887,15 +1057,23 @@ nfs3svc_lookup_parentdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, goto xmit_res; } + nfs3 = cs->nfs3state; /* If the buf inode shows that this is a root dir's buf, then the file * handle needs to be specially crafted, in all other cases, we'll just * create the handle normally using the buffer of the parent dir. */ - if (buf->ia_ino != 1) + if (buf->ia_ino != 1) { nfs3_fh_build_parent_fh (&cs->fh, buf, &newfh); - else - newfh = nfs3_fh_build_root_fh (cs->nfs3state->exportslist, - cs->vol); + goto xmit_res; + } + + if (gf_nfs_dvm_off (nfs_state (nfs3->nfsx))) + newfh = nfs3_fh_build_indexed_root_fh (nfs3->exportslist, + cs->vol); + else { + __nfs3_get_volume_id (nfs3, cs->vol, volumeid); + newfh = nfs3_fh_build_uuid_root_fh (volumeid); + } xmit_res: nfs3_log_newfh_res (nfs_rpcsvc_request_xid (cs->req), "LOOKUP", status, @@ -1095,13 +1273,12 @@ nfs3_access_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *buf, uint32_t accbits) { access3res res; - uint16_t xlid = 0; + uint64_t deviceid = 0; - xlid = nfs3_request_xlator_id (req); + deviceid = nfs3_request_xlator_deviceid (req); nfs3_fill_access3res (&res, status, buf, accbits, nfs_rpcsvc_request_uid (req), - nfs_rpcsvc_request_gid (req) - , xlid); + nfs_rpcsvc_request_gid (req), deviceid); nfs3svc_submit_reply (req, &res, (nfs3_serializer)xdr_serialize_access3res); return 0; @@ -1231,10 +1408,10 @@ nfs3_readlink_reply (rpcsvc_request_t *req, nfsstat3 stat, char *path, struct iatt *buf) { readlink3res res = {0, }; - uint16_t xlid = 0; + uint64_t deviceid = 0; - xlid = nfs3_request_xlator_id (req); - nfs3_fill_readlink3res (&res, stat, path, buf, xlid); + deviceid = nfs3_request_xlator_deviceid (req); + nfs3_fill_readlink3res (&res, stat, path, buf, deviceid); nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer)xdr_serialize_readlink3res); @@ -1374,10 +1551,10 @@ nfs3_read_reply (rpcsvc_request_t *req, nfsstat3 stat, count3 count, struct iatt *poststat, int is_eof) { read3res res = {0, }; - uint16_t xlid = 0; + uint64_t deviceid = 0; - xlid = nfs3_request_xlator_id (req); - nfs3_fill_read3res (&res, stat, count, poststat, is_eof, xlid); + deviceid = nfs3_request_xlator_deviceid (req); + nfs3_fill_read3res (&res, stat, count, poststat, is_eof, deviceid); if (stat == NFS3_OK) { nfs_xdr_vector_round_up (vec, vcount, count); /* iob can be zero if the file size was zero. If so, op_ret @@ -1564,11 +1741,11 @@ nfs3_write_reply (rpcsvc_request_t *req, nfsstat3 stat, count3 count, struct iatt *poststat) { write3res res = {0, }; - uint16_t xlid = 0; + uint64_t deviceid = 0; - xlid = nfs3_request_xlator_id (req); + deviceid = nfs3_request_xlator_deviceid (req); nfs3_fill_write3res (&res, stat, count, stable, wverf, prestat, - poststat, xlid); + poststat, deviceid); nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer)xdr_serialize_write3res); @@ -1692,9 +1869,9 @@ nfs3svc_write_cbk (call_frame_t *frame, void *cookie, xlator_t *this, cs->maxcount = op_ret; write_trusted = nfs3_export_write_trusted (cs->nfs3state, - cs->resolvefh.xlatorid); + cs->resolvefh.exportid); sync_trusted = nfs3_export_sync_trusted (cs->nfs3state, - cs->resolvefh.xlatorid); + cs->resolvefh.exportid); ret = nfs3_write_how (&cs->writetype, write_trusted, sync_trusted); if (ret == -1) goto err; @@ -1831,7 +2008,7 @@ nfs3_write (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); - nfs3_check_rw_volaccess (nfs3, fh->xlatorid, stat, nfs3err); + nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err); nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err); cs->datacount = count; cs->dataoffset = offset; @@ -1983,8 +2160,11 @@ nfs3_create_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *newfh, struct iatt *postparent) { create3res res = {0, }; + uint64_t deviceid = 0; - nfs3_fill_create3res (&res, stat, newfh, newbuf, preparent, postparent); + deviceid = nfs3_request_xlator_deviceid (req); + nfs3_fill_create3res (&res, stat, newfh, newbuf, preparent, postparent, + deviceid); nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer)xdr_serialize_create3res); return 0; @@ -2219,7 +2399,7 @@ nfs3_create (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret); nfs3_map_fh_to_volume (nfs3, dirfh, req, vol, stat, nfs3err); - nfs3_check_rw_volaccess (nfs3, dirfh->xlatorid, stat, nfs3err); + nfs3_check_rw_volaccess (nfs3, dirfh->exportid, stat, nfs3err); nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err); cs->cookieverf = cverf; @@ -2284,8 +2464,11 @@ nfs3_mkdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *fh, struct iatt *postparent) { mkdir3res res = {0, }; + uint64_t deviceid = 0; - nfs3_fill_mkdir3res (&res, stat, fh, buf, preparent, postparent); + deviceid = nfs3_request_xlator_deviceid (req); + nfs3_fill_mkdir3res (&res, stat, fh, buf, preparent, postparent, + deviceid); nfs3svc_submit_reply (req, &res, (nfs3_serializer)xdr_serialize_mkdir3res); return 0; @@ -2423,7 +2606,7 @@ nfs3_mkdir (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret); nfs3_map_fh_to_volume (nfs3, dirfh, req, vol, stat, nfs3err); - nfs3_check_rw_volaccess (nfs3, dirfh->xlatorid, stat, nfs3err); + nfs3_check_rw_volaccess (nfs3, dirfh->exportid, stat, nfs3err); nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err); cs->parent = *dirfh; @@ -2481,8 +2664,11 @@ nfs3_symlink_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *fh, struct iatt *postparent) { symlink3res res = {0, }; + uint64_t deviceid = 0; - nfs3_fill_symlink3res (&res, stat, fh, buf, preparent, postparent); + deviceid = nfs3_request_xlator_deviceid (req); + nfs3_fill_symlink3res (&res, stat, fh, buf, preparent, postparent, + deviceid); nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer)xdr_serialize_symlink3res); @@ -2570,7 +2756,7 @@ nfs3_symlink (rpcsvc_request_t *req, struct nfs3_fh *dirfh, char *name, nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret); nfs3_map_fh_to_volume (nfs3, dirfh, req, vol, stat, nfs3err); - nfs3_check_rw_volaccess (nfs3, dirfh->xlatorid, stat, nfs3err); + nfs3_check_rw_volaccess (nfs3, dirfh->exportid, stat, nfs3err); nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err); cs->parent = *dirfh; @@ -2638,7 +2824,11 @@ nfs3_mknod_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *fh, struct iatt *postparent) { mknod3res res = {0, }; - nfs3_fill_mknod3res (&res, stat, fh, buf, preparent, postparent); + uint64_t deviceid = 0; + + deviceid = nfs3_request_xlator_deviceid (req); + nfs3_fill_mknod3res (&res, stat, fh, buf, preparent, postparent, + deviceid); nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer)xdr_serialize_mknod3res); @@ -2838,7 +3028,7 @@ nfs3_mknod (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name, nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); - nfs3_check_rw_volaccess (nfs3, fh->xlatorid, stat, nfs3err); + nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err); nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err); cs->mknodtype = nodedata->type; @@ -2915,10 +3105,10 @@ nfs3_remove_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *preparent , struct iatt *postparent) { remove3res res = {0, }; - uint16_t xlid = 0; + uint64_t deviceid = 0; - xlid = nfs3_request_xlator_id (req); - nfs3_fill_remove3res (&res, stat, preparent, postparent, xlid); + deviceid = nfs3_request_xlator_deviceid (req); + nfs3_fill_remove3res (&res, stat, preparent, postparent, deviceid); nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer)xdr_serialize_remove3res); return 0; @@ -3037,7 +3227,7 @@ nfs3_remove (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name) nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); - nfs3_check_rw_volaccess (nfs3, fh->xlatorid, stat, nfs3err); + nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err); nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err); ret = nfs3_fh_resolve_and_resume (cs, fh, name, nfs3_remove_resume); @@ -3094,10 +3284,10 @@ nfs3_rmdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *preparent, struct iatt *postparent) { rmdir3res res = {0, }; - uint16_t xlid = 0; + uint64_t deviceid = 0; - xlid = nfs3_request_xlator_id (req); - nfs3_fill_rmdir3res (&res, stat, preparent, postparent, xlid); + deviceid = nfs3_request_xlator_deviceid (req); + nfs3_fill_rmdir3res (&res, stat, preparent, postparent, deviceid); nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer)xdr_serialize_rmdir3res); return 0; @@ -3180,7 +3370,7 @@ nfs3_rmdir (rpcsvc_request_t *req, struct nfs3_fh *fh, char *name) nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_validate_strlen_or_goto (name, NFS_NAME_MAX, nfs3err, stat, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); - nfs3_check_rw_volaccess (nfs3, fh->xlatorid, stat, nfs3err); + nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err); nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err); ret = nfs3_fh_resolve_and_resume (cs, fh, name, nfs3_rmdir_resume); @@ -3238,11 +3428,11 @@ nfs3_rename_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *buf, struct iatt *prenewparent, struct iatt *postnewparent) { rename3res res = {0, }; - uint16_t xlid = 0; + uint64_t deviceid = 0; - xlid = nfs3_request_xlator_id (req); + deviceid = nfs3_request_xlator_deviceid (req); nfs3_fill_rename3res (&res, stat, buf, preoldparent, postoldparent, - prenewparent, postnewparent, xlid); + prenewparent, postnewparent, deviceid); nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer) xdr_serialize_rename3res); @@ -3383,7 +3573,7 @@ nfs3_rename (rpcsvc_request_t *req, struct nfs3_fh *olddirfh, char *oldname, nfs3_validate_strlen_or_goto(oldname, NFS_NAME_MAX, nfs3err, stat, ret); nfs3_validate_strlen_or_goto(newname, NFS_NAME_MAX, nfs3err, stat, ret); nfs3_map_fh_to_volume (nfs3, olddirfh, req, vol, stat, nfs3err); - nfs3_check_rw_volaccess (nfs3, olddirfh->xlatorid, stat, nfs3err); + nfs3_check_rw_volaccess (nfs3, olddirfh->exportid, stat, nfs3err); nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err); /* While we resolve the source (fh, name) pair, we need to keep a copy @@ -3454,10 +3644,10 @@ nfs3_link_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *buf, struct iatt *preparent, struct iatt *postparent) { link3res res = {0, }; - uint16_t xlid = 0; + uint64_t deviceid = 0; - xlid = nfs3_request_xlator_id (req); - nfs3_fill_link3res (&res, stat, buf, preparent, postparent, xlid); + deviceid = nfs3_request_xlator_deviceid (req); + nfs3_fill_link3res (&res, stat, buf, preparent, postparent, deviceid); nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer)xdr_serialize_link3res); @@ -3572,7 +3762,7 @@ nfs3_link (rpcsvc_request_t *req, struct nfs3_fh *targetfh, nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_validate_strlen_or_goto(newname, NFS_NAME_MAX, nfs3err, stat, ret); nfs3_map_fh_to_volume (nfs3, dirfh, req, vol, stat, nfs3err); - nfs3_check_rw_volaccess (nfs3, dirfh->xlatorid, stat, nfs3err); + nfs3_check_rw_volaccess (nfs3, dirfh->exportid, stat, nfs3err); nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err); cs->fh = *dirfh; @@ -3638,10 +3828,12 @@ nfs3_readdirp_reply (rpcsvc_request_t *req, nfsstat3 stat,struct nfs3_fh *dirfh, uint64_t cverf, struct iatt *dirstat, gf_dirent_t *entries, count3 dircount, count3 maxcount, int is_eof) { - readdirp3res res = {0, }; + readdirp3res res = {0, }; + uint64_t deviceid = 0; + deviceid = nfs3_request_xlator_deviceid (req); nfs3_fill_readdirp3res (&res, stat, dirfh, cverf, dirstat, entries, - dircount, maxcount, is_eof); + dircount, maxcount, is_eof, deviceid); nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer) xdr_serialize_readdirp3res); nfs3_free_readdirp3res (&res); @@ -3656,9 +3848,11 @@ nfs3_readdir_reply (rpcsvc_request_t *req, nfsstat3 stat, struct nfs3_fh *dirfh, count3 count, int is_eof) { readdir3res res = {0, }; + uint64_t deviceid = 0; + deviceid = nfs3_request_xlator_deviceid (req); nfs3_fill_readdir3res (&res, stat, dirfh, cverf, dirstat, entries, count - , is_eof); + , is_eof, deviceid); nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer) xdr_serialize_readdir3res); nfs3_free_readdir3res (&res); @@ -3987,10 +4181,10 @@ nfs3_fsstat_reply (rpcsvc_request_t *req, nfsstat3 stat, struct statvfs *fsbuf, struct iatt *postbuf) { fsstat3res res = {0, }; - uint16_t xlid = 0; + uint64_t deviceid = 0; - xlid = nfs3_request_xlator_id (req); - nfs3_fill_fsstat3res (&res, stat, fsbuf, postbuf, xlid); + deviceid = nfs3_request_xlator_deviceid (req); + nfs3_fill_fsstat3res (&res, stat, fsbuf, postbuf, deviceid); return nfs3svc_submit_reply (req, &res, (nfs3_serializer)xdr_serialize_fsstat3res); @@ -4162,11 +4356,11 @@ nfs3_fsinfo_reply (rpcsvc_request_t *req, nfsstat3 status, struct iatt *fsroot) { fsinfo3res res; struct nfs3_state *nfs3 = NULL; - uint16_t xlid = 0; + uint64_t deviceid = 0; - xlid = nfs3_request_xlator_id (req); + deviceid = nfs3_request_xlator_deviceid (req); nfs3 = nfs_rpcsvc_request_program_private (req); - nfs3_fill_fsinfo3res (nfs3, &res, status, fsroot, xlid); + nfs3_fill_fsinfo3res (nfs3, &res, status, fsroot, deviceid); nfs3svc_submit_reply (req, &res, (nfs3_serializer)xdr_serialize_fsinfo3res); @@ -4301,10 +4495,10 @@ int nfs3_pathconf_reply (rpcsvc_request_t *req, nfsstat3 stat, struct iatt *buf) { pathconf3res res = {0, }; - uint16_t xlid = 0; + uint64_t deviceid = 0; - xlid = nfs3_request_xlator_id (req); - nfs3_fill_pathconf3res (&res, stat, buf, xlid); + deviceid = nfs3_request_xlator_deviceid (req); + nfs3_fill_pathconf3res (&res, stat, buf, deviceid); nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer)xdr_serialize_pathconf3res); return 0; @@ -4440,10 +4634,10 @@ nfs3_commit_reply (rpcsvc_request_t *req, nfsstat3 stat, uint64_t wverf, struct iatt *prestat, struct iatt *poststat) { commit3res res = {0, }; - uint16_t xlid = 0; + uint64_t deviceid = 0; - xlid = nfs3_request_xlator_id (req); - nfs3_fill_commit3res (&res, stat, wverf, prestat, poststat, xlid); + deviceid = nfs3_request_xlator_deviceid (req); + nfs3_fill_commit3res (&res, stat, wverf, prestat, poststat, deviceid); nfs3svc_submit_reply (req, (void *)&res, (nfs3_serializer)xdr_serialize_commit3res); @@ -4489,7 +4683,7 @@ nfs3_commit_resume (void *carg) cs = (nfs3_call_state_t *)carg; nfs3_check_fh_resolve_status (cs, stat, nfs3err); - if (nfs3_export_sync_trusted (cs->nfs3state, cs->resolvefh.xlatorid)) { + if (nfs3_export_sync_trusted (cs->nfs3state, cs->resolvefh.exportid)) { ret = -1; stat = NFS3_OK; goto nfs3err; @@ -4564,7 +4758,7 @@ nfs3_commit (rpcsvc_request_t *req, struct nfs3_fh *fh, offset3 offset, nfs3_validate_gluster_fh (fh, stat, nfs3err); nfs3_validate_nfs3_state (req, nfs3, stat, nfs3err, ret); nfs3_map_fh_to_volume (nfs3, fh, req, vol, stat, nfs3err); - nfs3_check_rw_volaccess (nfs3, fh->xlatorid, stat, nfs3err); + nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err); nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err); cs->datacount = count; @@ -4753,18 +4947,60 @@ err: return ret; } + int -nfs3_init_subvolume_options (struct nfs3_export *exp, dict_t *options) +nfs3_init_subvolume_options (struct nfs3_state *nfs3, struct nfs3_export *exp) { int ret = -1; char *optstr = NULL; char searchkey[1024]; char *name = NULL; gf_boolean_t boolt = _gf_false; + uuid_t volumeid = {0, }; + dict_t *options = NULL; - if ((!exp) || (!options)) + if ((!exp) || (!nfs3)) return -1; + options = nfs3->nfsx->options; + uuid_clear (volumeid); + if (gf_nfs_dvm_off (nfs_state (nfs3->nfsx))) + goto no_dvm; + + ret = snprintf (searchkey, 1024, "nfs3.%s.volume-id",exp->subvol->name); + if (ret < 0) { + gf_log (GF_MNT, GF_LOG_ERROR, "snprintf failed"); + ret = -1; + goto err; + } + + if (dict_get (options, searchkey)) { + ret = dict_get_str (options, searchkey, &optstr); + if (ret < 0) { + gf_log (GF_MNT, GF_LOG_ERROR, "Failed to read option" + ": %s", searchkey); + ret = -1; + goto err; + } + } else { + gf_log (GF_MNT, GF_LOG_ERROR, "DVM is on but volume-id not " + "given for volume: %s", exp->subvol->name); + ret = -1; + goto err; + } + + if (optstr) { + ret = uuid_parse (optstr, volumeid); + if (ret < 0) { + gf_log (GF_MNT, GF_LOG_ERROR, "Failed to parse volume " + "UUID"); + ret = -1; + goto err; + } + uuid_copy (exp->volumeid, volumeid); + } + +no_dvm: /* Volume Access */ name = exp->subvol->name; ret = snprintf (searchkey, 1024, "nfs3.%s.volume-access", name); @@ -4880,64 +5116,58 @@ err: } -int -nfs3_init_subvolume (struct nfs3_state *nfs3, xlator_t *nfsx, xlator_t *subvol, - int xlid) +struct nfs3_export * +nfs3_init_subvolume (struct nfs3_state *nfs3, xlator_t *subvol) { int ret = -1; struct nfs3_export *exp = NULL; - if ((!nfs3) || (!nfsx) || (!subvol)) - return -1; + if ((!nfs3) || (!subvol)) + return NULL; - exp = &nfs3->exports[xlid]; + exp = GF_CALLOC (1, sizeof (*exp), gf_nfs_mt_nfs3_export); exp->subvol = subvol; - + INIT_LIST_HEAD (&exp->explist); gf_log (GF_NFS3, GF_LOG_TRACE, "Initing state: %s", exp->subvol->name); - ret = nfs3_init_subvolume_options (exp, nfsx->options); - if (ret == -1) + ret = nfs3_init_subvolume_options (nfs3, exp); + if (ret == -1) { gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to init subvol"); + goto exp_free; + } - return ret; + ret = 0; +exp_free: + if (ret < 0) { + GF_FREE (exp); + exp = NULL; + } + + return exp; } int -nfs3_init_subvolumes (struct nfs3_state *nfs3, xlator_t *nfsx) +nfs3_init_subvolumes (struct nfs3_state *nfs3) { - int xl_count = 0; int ret = -1; struct xlator_list *xl_list = NULL; + struct nfs3_export *exp = NULL; - if ((!nfs3) || (!nfsx)) + if (!nfs3) return -1; - xl_list = nfsx->children; - while (xl_list) { - ++xl_count; - xl_list = xl_list->next; - } + xl_list = nfs3->nfsx->children; - nfs3->exports = GF_CALLOC (xl_count, sizeof (struct nfs3_export), - gf_nfs_mt_nfs3_export); - if (!nfs3->exports) { - gf_log (GF_NFS3, GF_LOG_ERROR, "Memory allocation failed"); - goto err; - } - - xl_list = nfsx->children; - xl_count = 0; /* Re-using xl_count. */ while (xl_list) { - ret = nfs3_init_subvolume (nfs3, nfsx, xl_list->xlator, - xl_count); - if (ret == -1) { + exp = nfs3_init_subvolume (nfs3, xl_list->xlator); + if (!exp) { gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to init subvol: " "%s", xl_list->xlator->name); goto err; } + list_add_tail (&exp->explist, &nfs3->exports); xl_list = xl_list->next; - ++xl_count; } ret = 0; @@ -4983,7 +5213,8 @@ nfs3_init_state (xlator_t *nfsx) nfs3->nfsx = nfsx; nfs3->exportslist = nfsx->children; - ret = nfs3_init_subvolumes (nfs3, nfsx); + INIT_LIST_HEAD (&nfs3->exports); + ret = nfs3_init_subvolumes (nfs3); if (ret == -1) { gf_log (GF_NFS3, GF_LOG_ERROR, "Failed to init per-subvolume " "state"); diff --git a/xlators/nfs/server/src/nfs3.h b/xlators/nfs/server/src/nfs3.h index 1565f26345b..f7683eaa789 100644 --- a/xlators/nfs/server/src/nfs3.h +++ b/xlators/nfs/server/src/nfs3.h @@ -82,7 +82,9 @@ struct nfs3_fd_entry { /* Per subvolume nfs3 specific state */ struct nfs3_export { + struct list_head explist; xlator_t *subvol; + uuid_t volumeid; int access; int trusted_sync; int trusted_write; @@ -108,7 +110,7 @@ struct nfs3_state { */ xlator_list_t *exportslist; - struct nfs3_export *exports; + struct list_head exports; /* Mempool for allocations of struct nfs3_local */ struct mem_pool *localpool; -- cgit