From 4b68723f2efd2bb3f9f52ddb2fd455c1e977cd60 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Wed, 21 Dec 2011 17:01:16 -0500 Subject: [PATCH] afs: Add afs_WriteDCache sanity checks Writing a non-free non-discarded dcache entry with a zero volume id can easily cause hash table corruption later on, so make sure we don't do that. Also log something if the write itself fails, as this usually indicates an unusual situation involving I/O errors or something. Reviewed-on: http://gerrit.openafs.org/6419 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 79f69f2eb130c1c5cb6cdfa4e7a129f450a58339) Change-Id: I482ad6a1fef3896144855b58c70e73bdf896027f Reviewed-on: http://gerrit.openafs.org/7942 Reviewed-by: Derrick Brashear Tested-by: BuildBot --- src/afs/afs_dcache.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index 02a83ebec..3d06a5897 100644 --- a/src/afs/afs_dcache.c +++ b/src/afs/afs_dcache.c @@ -2829,6 +2829,19 @@ afs_WriteDCache(struct dcache *adc, int atime) osi_Assert(WriteLocked(&afs_xdcache)); if (atime) adc->f.modTime = osi_Time(); + + if ((afs_indexFlags[adc->index] & (IFFree | IFDiscarded)) == 0 && + adc->f.fid.Fid.Volume == 0) { + /* If a dcache slot is not on the free or discard list, it must be + * in the hash table. Thus, the volume must be non-zero, since that + * is how we determine whether or not to unhash the entry when kicking + * it out of the cache. Do this check now, since otherwise this can + * cause hash table corruption and a panic later on after we read the + * entry back in. */ + osi_Panic("afs_WriteDCache zero volume index %d flags 0x%x\n", + adc->index, (unsigned)afs_indexFlags[adc->index]); + } + /* * Seek to the right dcache slot and write the in-memory image out to disk. */ @@ -2838,8 +2851,12 @@ afs_WriteDCache(struct dcache *adc, int atime) sizeof(struct fcache) * adc->index + sizeof(struct afs_fheader), (char *)(&adc->f), sizeof(struct fcache)); - if (code != sizeof(struct fcache)) + if (code != sizeof(struct fcache)) { + afs_warn("afs: failed to write to CacheItems off %ld code %d/%d\n", + (long)(sizeof(struct fcache) * adc->index + sizeof(struct afs_fheader)), + (int)code, (int)sizeof(struct fcache)); return EIO; + } return 0; } -- 2.39.5