diff options
| author | Shehjar Tikoo <shehjart@gluster.com> | 2010-08-31 06:50:31 +0000 | 
|---|---|---|
| committer | Vijay Bellur <vijay@dev.gluster.com> | 2010-08-31 07:44:38 -0700 | 
| commit | 83e7543be0bf8941cb6383c7e23b9bc0f54e67ba (patch) | |
| tree | a37e4d6003df335f6d006875d0c20e54e4f03f3e | |
| parent | 0f40d735c09f2fb09bcf0d1678250e70a40ca56f (diff) | |
nfs3: Return ESTALE when going beyond fh-hashcount or max-hashes
During fh resolution, if we go beyond the max hashes support by
gnfs or if we go beyond the dir depth specified in the filehandle,
then return ESTALE.
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
| -rw-r--r-- | xlators/nfs/server/src/nfs3-helpers.c | 47 | 
1 files changed, 40 insertions, 7 deletions
diff --git a/xlators/nfs/server/src/nfs3-helpers.c b/xlators/nfs/server/src/nfs3-helpers.c index 653b6ecaf5c..c10954ab996 100644 --- a/xlators/nfs/server/src/nfs3-helpers.c +++ b/xlators/nfs/server/src/nfs3-helpers.c @@ -2753,6 +2753,42 @@ err:  } +/* Validate the depth of the dir such that we do not end up opening and + * reading directories beyond those that are needed for resolving the file + * handle. + * Returns 1 if fh resolution can continue, 0 otherwise. + */ +int +nfs3_fh_resolve_validate_dirdepth (nfs3_call_state_t *cs) +{ +        int     ret = 1; + +        if (!cs) +                return 0; + +        /* This condition will generally never be hit because the +         * hash-matching scheme will prevent us from going into a +         * directory that is not part of the hash-array. +         */ +        if (nfs3_fh_hash_index_is_beyond (&cs->resolvefh, cs->hashidx)) { +                gf_log (GF_NFS3, GF_LOG_TRACE, "Hash index is beyond: idx %d," +                        " fh idx: %d", cs->hashidx, cs->resolvefh.hashcount); +                ret = 0; +                goto out; +        } + +        if (cs->hashidx >= GF_NFSFH_MAXHASHES) { +                gf_log (GF_NFS3, GF_LOG_TRACE, "Hash index beyond max hashes:" +                        " hashidx %d, max: %d", cs->hashidx, +                        GF_NFSFH_MAXHASHES); +                ret = 0; +                goto out; +        } + +out: +        return ret; +} +  int  nfs3_fh_resolve_dir_hard (nfs3_call_state_t *cs, uint64_t ino, uint64_t gen, @@ -2766,9 +2802,8 @@ nfs3_fh_resolve_dir_hard (nfs3_call_state_t *cs, uint64_t ino, uint64_t gen,          cs->hashidx++;          nfs_loc_wipe (&cs->resolvedloc); -        if (nfs3_fh_hash_index_is_beyond (&cs->resolvefh, cs->hashidx)) { -                gf_log (GF_NFS3, GF_LOG_TRACE, "Hash index is beyond: idx %d, " -                        " fh idx: %d", cs->hashidx, cs->resolvefh.hashcount); +        if (!nfs3_fh_resolve_validate_dirdepth (cs)) { +                gf_log (GF_NFS3, GF_LOG_TRACE, "Dir depth validation failed");                  nfs3_call_resume_estale (cs);                  ret = 0;                  goto out; @@ -2920,10 +2955,8 @@ nfs3_fh_resolve_inode_hard (nfs3_call_state_t *cs)          cs->hashidx++;          nfs_loc_wipe (&cs->resolvedloc); -        if (nfs3_fh_hash_index_is_beyond (&cs->resolvefh, cs->hashidx)) { -                gf_log (GF_NFS3, GF_LOG_TRACE, "Hash index is beyond: idx %d, " -                        " fh hashcount: %d", cs->hashidx, -                        cs->resolvefh.hashcount); +        if (!nfs3_fh_resolve_validate_dirdepth (cs)) { +                gf_log (GF_NFS3, GF_LOG_TRACE, "Dir depth validation failed");                  nfs3_call_resume_estale (cs);                  ret = 0;                  goto out;  | 
