From b623d13f0f95084a0502af2cd2ee1849f8f80654 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Thu, 22 Mar 2012 10:42:38 -0500 Subject: [PATCH] afs: Set DWriting when truncating a dcache entry When we truncate a file, we truncate the contents of the relevant dcache entry chunks, and prevent future FetchData operations from fetching data beyond the truncation offset. If we never write anything to that chunk, we never set DWriting, and so on disk it looks like that dcache entry has valid data for the specified DV. However, since the data is truncated, this is not true. If a process holds a file open, truncates it without writing to it, and then the client crashes (or we have trouble contacting the fileserver when we close the file), the dcache entry will appear valid on disk. So the next time we read the dcache entry, we will use the incorrect cache contents as if they were accurate for the specified DV. To avoid this, set DWriting when we truncate a chunk. Normally we only clear DWriting when we actually send data to the fileserver, so to clear DWriting in this case, add an additional line to clear it in afs_StoreAllSegments, after the StoreMini has completed. Reviewed-on: http://gerrit.openafs.org/6937 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit b3b267d16eefb993f52f66bf44f3e659c1017e58) Change-Id: I5602db9687f3f005f68200a4208a3c7012933efa Reviewed-on: http://gerrit.openafs.org/7996 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- src/afs/afs_segments.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/afs/afs_segments.c b/src/afs/afs_segments.c index c9308eddf4..0c32462845 100644 --- a/src/afs/afs_segments.c +++ b/src/afs/afs_segments.c @@ -420,6 +420,9 @@ afs_StoreAllSegments(struct vcache *avc, struct vrequest *areq, UpgradeSToWLock(&tdc->lock, 678); hset(tdc->f.versionNo, avc->f.m.DataVersion); tdc->dflags |= DFEntryMod; + /* DWriting may not have gotten cleared above, if all + * we did was a StoreMini */ + tdc->f.states &= ~DWriting; ConvertWToSLock(&tdc->lock); } } @@ -777,6 +780,7 @@ afs_TruncateAllSegments(struct vcache *avc, afs_size_t alen, ObtainSharedLock(&tdc->lock, 672); if (newSize < tdc->f.chunkBytes && newSize < MAX_AFS_UINT32) { UpgradeSToWLock(&tdc->lock, 673); + tdc->f.states |= DWriting; tfile = afs_CFileOpen(&tdc->f.inode); afs_CFileTruncate(tfile, (afs_int32)newSize); afs_CFileClose(tfile);