Patchwork [BUG:1378,04/12] nfs3: Support hashcounts larger than hash array size

login
register
Submitter Shehjar Tikoo
Date 2010-08-31 12:20:29
Message ID <1283257237-18659-4-git-send-email-shehjart@gluster.com>
Download mbox | patch
Permalink /patch/4419/
State Accepted
Delegated to: Anand Avati
Headers show

Comments

Shehjar Tikoo - 2010-08-31 12:20:29
From: Shehjar Tikoo <shehjart@gluster.com>


Signed-off-by: Shehjar Tikoo <shehjart@gluster.com>
---
 xlators/nfs/server/src/nfs3-fh.c |   30 +++++++++++++++++++++++++-----
 xlators/nfs/server/src/nfs3-fh.h |    1 +
 2 files changed, 26 insertions(+), 5 deletions(-)

Patch

diff --git a/xlators/nfs/server/src/nfs3-fh.c b/xlators/nfs/server/src/nfs3-fh.c
index 59a7864..5a5d9aa 100644
--- a/xlators/nfs/server/src/nfs3-fh.c
+++ b/xlators/nfs/server/src/nfs3-fh.c
@@ -220,6 +220,7 @@  int
 nfs3_fh_build_child_fh (struct nfs3_fh *parent, struct iatt *newstat,
                         struct nfs3_fh *newfh)
 {
+        int             hashcount = 0;
         int             entry = 0;
 
         if ((!parent) || (!newstat) || (!newfh))
@@ -234,10 +235,23 @@  nfs3_fh_build_child_fh (struct nfs3_fh *parent, struct iatt *newstat,
         }
 
         newfh->hashcount = parent->hashcount + 1;
+        /* Only copy the hashes that are available in the parent file
+         * handle. */
+        if (parent->hashcount > GF_NFSFH_MAXHASHES)
+                hashcount = GF_NFSFH_MAXHASHES;
+        else
+                hashcount = parent->hashcount;
+
         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);
+                hashcount * GF_NFSFH_ENTRYHASH_SIZE);
+
+        /* Do not insert parent dir hash if there is no space left in the hash
+         * 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);
+        }
 
 done:
 //        nfs3_log_fh (newfh);
@@ -249,11 +263,17 @@  done:
 uint32_t
 nfs3_fh_compute_size (struct nfs3_fh *fh)
 {
+        uint32_t        fhlen = 0;
+
         if (!fh)
                 return 0;
 
-        return (GF_NFSFH_STATIC_SIZE +
-                        (fh->hashcount * GF_NFSFH_ENTRYHASH_SIZE));
+        if (fh->hashcount <= GF_NFSFH_MAXHASHES)
+                fhlen = nfs3_fh_hashcounted_size (fh->hashcount);
+        else
+                fhlen = nfs3_fh_hashcounted_size (GF_NFSFH_MAXHASHES);
+
+        return fhlen;
 }
 
 int
diff --git a/xlators/nfs/server/src/nfs3-fh.h b/xlators/nfs/server/src/nfs3-fh.h
index 73e4b78..4ee4423 100644
--- a/xlators/nfs/server/src/nfs3-fh.h
+++ b/xlators/nfs/server/src/nfs3-fh.h
@@ -44,6 +44,7 @@ 
 typedef uint16_t                nfs3_hash_entry_t;
 #define GF_NFSFH_ENTRYHASH_SIZE (sizeof (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))
 
 /* ATTENTION: Change in size of the structure below should be reflected in the
  * GF_NFSFH_STATIC_SIZE.