summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShehjar Tikoo <shehjart@gluster.com>2010-08-31 06:50:31 +0000
committerVijay Bellur <vijay@dev.gluster.com>2010-08-31 07:44:38 -0700
commit83e7543be0bf8941cb6383c7e23b9bc0f54e67ba (patch)
treea37e4d6003df335f6d006875d0c20e54e4f03f3e
parent0f40d735c09f2fb09bcf0d1678250e70a40ca56f (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.c47
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;