summaryrefslogtreecommitdiffstats
path: root/xlators/nfs
diff options
context:
space:
mode:
authorShehjar Tikoo <shehjart@gluster.com>2010-08-31 06:50:29 +0000
committerVijay Bellur <vijay@dev.gluster.com>2010-08-31 07:44:27 -0700
commit1cd5a6fbd345b450a0e69041b53d92fb04fdcc5a (patch)
tree0c04e76197244301d64b83b4828b40903928c09f /xlators/nfs
parent217fb3e2acbb221668ad5d54ef4067a2bac47c4a (diff)
nfs3: Support hashcounts larger than hash array size
Signed-off-by: Shehjar Tikoo <shehjart@gluster.com> Signed-off-by: Vijay Bellur <vijay@dev.gluster.com> BUG: 1378 (Deep directory creation crashes gnfs) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1378
Diffstat (limited to 'xlators/nfs')
-rw-r--r--xlators/nfs/server/src/nfs3-fh.c30
-rw-r--r--xlators/nfs/server/src/nfs3-fh.h1
2 files changed, 26 insertions, 5 deletions
diff --git a/xlators/nfs/server/src/nfs3-fh.c b/xlators/nfs/server/src/nfs3-fh.c
index 59a786411..5a5d9aaa6 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 73e4b7817..4ee442395 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.