From b3b267d16eefb993f52f66bf44f3e659c1017e58 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. Change-Id: Ifc3bfc21712ab37b1f2865ce59fa45bf03811dd8 Reviewed-on: http://gerrit.openafs.org/6937 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 47058f916..192a3d4b4 100644 --- a/src/afs/afs_segments.c +++ b/src/afs/afs_segments.c @@ -418,6 +418,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); } } @@ -775,6 +778,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); -- 2.39.5