From 1cd5a6fbd345b450a0e69041b53d92fb04fdcc5a Mon Sep 17 00:00:00 2001 From: Shehjar Tikoo Date: Tue, 31 Aug 2010 06:50:29 +0000 Subject: nfs3: Support hashcounts larger than hash array size Signed-off-by: Shehjar Tikoo Signed-off-by: Vijay Bellur BUG: 1378 (Deep directory creation crashes gnfs) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=1378 --- xlators/nfs/server/src/nfs3-fh.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'xlators/nfs/server/src/nfs3-fh.c') diff --git a/xlators/nfs/server/src/nfs3-fh.c b/xlators/nfs/server/src/nfs3-fh.c index 59a78641105..5a5d9aaa6e4 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 -- cgit