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 /xlators/nfs | |
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
Diffstat (limited to 'xlators/nfs')
-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 653b6ecaf..c10954ab9 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; |