summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/nfs/server/src/mount3.c125
-rw-r--r--xlators/nfs/server/src/mount3.h5
-rw-r--r--xlators/nfs/server/src/nfs-common.c20
-rw-r--r--xlators/nfs/server/src/nfs-common.h7
-rw-r--r--xlators/nfs/server/src/nfs-fops.c61
-rw-r--r--xlators/nfs/server/src/nfs-fops.h1
-rw-r--r--xlators/nfs/server/src/nfs.c107
-rw-r--r--xlators/nfs/server/src/nfs.h6
-rw-r--r--xlators/nfs/server/src/nfs3-fh.c83
-rw-r--r--xlators/nfs/server/src/nfs3-fh.h36
-rw-r--r--xlators/nfs/server/src/nfs3-helpers.c239
-rw-r--r--xlators/nfs/server/src/nfs3-helpers.h52
-rw-r--r--xlators/nfs/server/src/nfs3.c467
-rw-r--r--xlators/nfs/server/src/nfs3.h4
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;
@@ -290,6 +289,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 <sys/types.h>
+#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;