From: Andrew Deason Date: Wed, 21 Dec 2011 22:01:16 +0000 (-0500) Subject: afs: Add afs_WriteDCache sanity checks X-Git-Tag: upstream/1.8.0_pre1^2~2896 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=79f69f2eb130c1c5cb6cdfa4e7a129f450a58339;p=packages%2Fo%2Fopenafs.git 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. Change-Id: Ib9602227e8cee324cb63a4a3dee28e53af69b446 Reviewed-on: http://gerrit.openafs.org/6419 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index 9d4a7e1e6..3fc0bb546 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; }