[Bug Report] cfapi: CfUpdatePlaceholder may partially update a placeholder file

Max 1 Reputation point
2022-05-12T18:54:35.233+00:00

Hi, I've encountered a problem while using Cloud Filer API. If I'm trying to update a placeholder from zero to a bigger size with CfUpdatePlaceholder and this function returns 0x80070070 - (There is not enough space on the disk), I end up with partially updated placeholder: its size is unchanged while modification time passed via CF_FS_METADATA is changed to a newer value. The expectations are for the call to be atomic, it should either change a placeholder or leave it untouched.

Why this is bad. Real-world case:

  • user A creates an empty file with modification time mtime1
  • this empty file gets synced to user B
  • user A writes some data to a file and its modification time gets updated to mtime2
  • Sync Engine tries to update a placeholder file with new modification time and new size on user B device, but due to a lack of free space this operation fails with 0x80070070
  • Next time Sync Engine looks at this file it will consider it as updated by user B back to zero size with mtime2 value (and this could actually happen)

Of course, this problem can be workarounded in many ways, bot non of them looks reliable enough. So far I fetch and remember current placeholder state if operation fails to compare this state before re-trying to resize a placeholder file, but there is a potential race where user B actually updates the file back to zero in-between CfUpdatePlaceholder and "fetch" operations.

Minimal reproducible sample: https://github.com/Fukkei/CloudTest, kudos to @WebDAV , I took your code as a template to demonstrate my issue, hope you don't mind. My output is:

Cloud sample test!  
Succesfully called AddFolderToSearchIndexer on "file:///C:\Users\max\AppData\Local\Temp\cf-9D6A.tmp-dir"  
platform version is 19041.1682.800  
CfUpdatePlaceholder (with USN) for the file of size 9999999999999 returned hresult = 80070179 (The file is not in sync with the cloud.), usn = 3599343d0  
CfUpdatePlaceholder for the file of size 9184e729fff returned hresult = 80070070 (There is not enough space on the disk.)  
file mtime after updating placeholder is 1601-01-01 00:00:00.0000001  
file usn after updating placeholder is 3599344c0, prev usn was 3599343d0  
Press any key to continue . . .  
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,422 questions
{count} votes