summaryrefslogtreecommitdiffstats
path: root/xlators/nfs/server/src/nfs3-fh.c
diff options
context:
space:
mode:
authorShehjar Tikoo <shehjart@gluster.com>2010-03-31 07:27:04 +0000
committerAnand V. Avati <avati@dev.gluster.com>2010-03-31 07:44:06 -0700
commite63053803dca86b4283b71bc4ef4cb180ec72d89 (patch)
tree05702e5e62f1596250106e3668e3d1062a0472b5 /xlators/nfs/server/src/nfs3-fh.c
parentc4fd1cf7325972d8ff64ef3a2bea70edcf4f1085 (diff)
nfs: Add MOUNTv3 protocol support
Signed-off-by: Shehjar Tikoo <shehjart@gluster.com> Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 399 (NFS translator with Mount v3 and NFS v3 support) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=399
Diffstat (limited to 'xlators/nfs/server/src/nfs3-fh.c')
-rw-r--r--xlators/nfs/server/src/nfs3-fh.c271
1 files changed, 271 insertions, 0 deletions
diff --git a/xlators/nfs/server/src/nfs3-fh.c b/xlators/nfs/server/src/nfs3-fh.c
new file mode 100644
index 00000000000..c7eb78fb378
--- /dev/null
+++ b/xlators/nfs/server/src/nfs3-fh.c
@@ -0,0 +1,271 @@
+/*
+ Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "rpcsvc.h"
+#include "dict.h"
+#include "xlator.h"
+#include "xdr-nfs3.h"
+#include "msg-nfs3.h"
+#include "iobuf.h"
+#include "nfs3-fh.h"
+#include "nfs-common.h"
+#include "iatt.h"
+
+
+int
+nfs3_fh_validate (struct nfs3_fh *fh)
+{
+ if (!fh)
+ return 0;
+
+ if (fh->ident[0] != GF_NFSFH_IDENT0)
+ return 0;
+
+ if (fh->ident[1] != GF_NFSFH_IDENT1)
+ return 0;
+
+ return 1;
+}
+
+
+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)
+{
+ if ((!fh) || (!buf))
+ return;
+
+ fh->ident[0] = GF_NFSFH_IDENT0;
+ fh->ident[1] = GF_NFSFH_IDENT1;
+
+ fh->hashcount = 0;
+ fh->gen = buf->ia_gen;
+ fh->ino = buf->ia_ino;
+
+}
+
+
+struct nfs3_fh
+nfs3_fh_build_root_fh (xlator_list_t *cl, xlator_t *xl, struct iatt buf)
+{
+ struct nfs3_fh fh = {{0}, };
+ if ((!cl) || (!xl))
+ return fh;
+
+ nfs3_fh_init (&fh, &buf);
+ fh.xlatorid = nfs_xlator_to_xlid (cl, xl);
+ fh.ino = 1;
+ fh.gen = 0;
+ return fh;
+}
+
+
+int
+nfs3_fh_is_root_fh (struct nfs3_fh *fh)
+{
+ if (!fh)
+ return 0;
+
+ if (fh->hashcount == 0)
+ return 1;
+
+ return 0;
+}
+
+
+nfs3_hash_entry_t
+nfs3_fh_hash_entry (ino_t ino, uint64_t gen)
+{
+ nfs3_hash_entry_t hash = 0;
+ int shiftsize = 48;
+ nfs3_hash_entry_t inomsb = 0;
+ nfs3_hash_entry_t inolsb = 0;
+ nfs3_hash_entry_t inols23b = 0;
+
+ nfs3_hash_entry_t genmsb = 0;
+ nfs3_hash_entry_t genlsb = 0;
+ nfs3_hash_entry_t genls23b = 0;
+
+ hash = ino;
+ while (shiftsize != 0) {
+ hash ^= (ino >> shiftsize);
+ shiftsize -= 16;
+ }
+/*
+ gf_log ("FILEHANDLE", GF_LOG_TRACE, "INO %"PRIu64, ino);
+ gf_log ("FILEHANDLE",GF_LOG_TRACE, "PRI HASH %d", hash);
+*/
+ inomsb = (ino >> 56);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inomsb %d", inomsb);
+
+ inolsb = ((ino << 56) >> 56);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inolsb %d", inolsb);
+
+ inolsb = (inolsb << 8);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inolsb to inomsb %d", inolsb);
+ inols23b = ((ino << 40) >> 48);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inols23b %d", inols23b);
+
+ inols23b = (inols23b << 8);
+// gf_log ("FILEHDNALE", GF_LOG_TRACE, "inols23b %d", inols23b);
+
+ genmsb = (gen >> 56);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inomsb %d", inomsb);
+
+ genlsb = ((gen << 56) >> 56);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inolsb %d", inolsb);
+
+ genlsb = (genlsb << 8);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inolsb to inomsb %d", inolsb);
+
+ genls23b = ((gen << 40) >> 48);
+// gf_log ("FILEHANDLE", GF_LOG_TRACE, "inols23b %d", inols23b);
+
+ genls23b = (genls23b << 8);
+// gf_log ("FILEHDNALE", GF_LOG_TRACE, "inols23b %d", inols23b);
+
+ hash ^= inolsb ^ inomsb ^ inols23b ^ genmsb ^ genlsb ^ genls23b;
+ return hash;
+
+}
+
+
+void
+nfs3_fh_to_str (struct nfs3_fh *fh, char *str)
+{
+ if ((!fh) || (!str))
+ return;
+
+ sprintf (str, "FH: hashcount %d, xlid %d, gen %"PRIu64", ino %"PRIu64,
+ fh->hashcount, fh->xlatorid, fh->gen, fh->ino);
+}
+
+
+void
+nfs3_log_fh (struct nfs3_fh *fh)
+{
+// int x = 0;
+ 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);
+/*
+ for (; x < fh->hashcount; ++x)
+ gf_log ("FILEHANDLE", GF_LOG_TRACE, "Hash %d: %d", x,
+ fh->entryhash[x]);
+*/
+}
+
+
+int
+nfs3_fh_build_parent_fh (struct nfs3_fh *child, struct iatt *newstat,
+ struct nfs3_fh *newfh)
+{
+ if ((!child) || (!newstat) || (!newfh))
+ 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;
+ goto done;
+ }
+
+ newfh->hashcount = child->hashcount - 1;
+ memcpy (newfh->entryhash, child->entryhash,
+ newfh->hashcount * GF_NFSFH_ENTRYHASH_SIZE);
+
+done:
+// nfs3_log_fh (newfh);
+
+ return 0;
+}
+
+
+
+int
+nfs3_fh_build_child_fh (struct nfs3_fh *parent, struct iatt *newstat,
+ struct nfs3_fh *newfh)
+{
+ int entry = 0;
+
+ if ((!parent) || (!newstat) || (!newfh))
+ 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;
+ }
+
+ newfh->hashcount = parent->hashcount + 1;
+ memcpy (newfh->entryhash, parent->entryhash,
+ parent->hashcount * GF_NFSFH_ENTRYHASH_SIZE);
+ entry = newfh->hashcount - 1;
+ newfh->entryhash[entry] = nfs3_fh_hash_entry (parent->ino, parent->gen);
+
+done:
+// nfs3_log_fh (newfh);
+
+ return 0;
+}
+
+
+uint32_t
+nfs3_fh_compute_size (struct nfs3_fh *fh)
+{
+ if (!fh)
+ return 0;
+
+ return (GF_NFSFH_STATIC_SIZE +
+ (fh->hashcount * GF_NFSFH_ENTRYHASH_SIZE));
+}
+
+int
+nfs3_fh_hash_index_is_beyond (struct nfs3_fh *fh, int hashidx)
+{
+ if (!fh)
+ return 1;
+
+ if (fh->hashcount >= hashidx)
+ return 0;
+ else
+ return 1;
+
+ return 1;
+}
+