diff options
| -rw-r--r-- | xlators/nfs/server/src/nfs3-fh.c | 30 | ||||
| -rw-r--r-- | xlators/nfs/server/src/nfs3-fh.h | 1 | 
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 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 diff --git a/xlators/nfs/server/src/nfs3-fh.h b/xlators/nfs/server/src/nfs3-fh.h index 73e4b7817c9..4ee4423951c 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.  | 
