2

I need to remove write behind caching on the disk drives of our servers. Doing so in windows ==> Device Manager ==> Disk Drives ==> (right click) Properties ==> Policies ==> (CheckBox) Enable write behind caching | is easy but windows re-enables it automatically. I believe this happens with updates.

I want to know if I can access these policies using C# to disable them on a daily basis.

Anyone know of a way?

I have looked at DriveInfo but found no methods to access the policies.

Christopher
  • 9,634
  • 2
  • 17
  • 31
Blixem
  • 59
  • 6
  • 1
    In C: https://blogs.msdn.microsoft.com/winsdk/2009/10/09/enable-or-disable-enable-write-caching-on-disk-behavior-on-disk/ –  Nov 08 '19 at 07:43
  • gpo? surely would be easiest – BugFinder Nov 08 '19 at 07:49
  • @OlivierRogier, I found that link as well. I am going to use the registry key combined with a system restart to switch off the Write Behind Caching. Will keep this post updated if it works like I expect. This behavior really hurts database integrity. – Blixem Nov 11 '19 at 12:09

2 Answers2

2

I got 2 possible solutions, which both aim at solving the issue on the per-file level rather then OS settings level.

If you wanted to change a Policy for Policies sake, then the Windows Policy Management maay have an option for this.

WriteThrough

Now there is a whole host of caches in play here - Application/Class, OS, the RAM in the Disk Eletronics. And I am unsure if it can affect the specific cache(s) you are worried about. But FileStream has a option called "WriteThrough":

Indicates that the system should write through any intermediate cache and go directly to disk.

https://learn.microsoft.com/en-us/dotnet/api/system.io.fileoptions

The Application/Class cache is trivial and to 99% disabeled by this.

The mention of "System" indicates to me that it will get to the OS cache (wich you seem worried about). But this is only a single line in the Documentation, so I can not say with certain it goes down to OS Level. But if there is one Option I would define for logging to a file and asume to be enabeled on all existing loggers, it this is it.

Asuming this is not for logging or similar streaming work and the core issue is the danger of corrupting file with partial writes, a minor redesign can fix that issue.

Writing to Tempfile -> Move

One surefire way to avoid corrupting a file when (re)writing it, is to write to a different temporary file - and then just swap those files out with a move (wich ideally will only change the File System Name entries). I did write some example code for this not to long ago after seeing this behavior in anything down to Word Processors:

string sourcepath; //containts the source file path, set by other code
string temppath; //containts the path of the tempfile. Should be in the same folder, and thus same partiion

//Open both Streams, can use a single using for this
//The supression of any Buffering on the output should be optional and will be detrimental to performance
using(var sourceStream = File.OpenRead(sourcepath), 
  outStream = File.Create(temppath, 0, FileOptions.WriteThrough )){

    string line = "";

    //itterte over the input
    while((line = streamReader.ReadLine()) != null){
        //do processing on line here

        outStream.Write(line);
    }
}

//replace the files. Pretty sure it will just overwrite without asking
File.Move(temppath, sourcepath);

The downside is of course you will temporarily need twice the Disk Space and it will cause a lot of extra write work on some modifications.

Christopher
  • 9,634
  • 2
  • 17
  • 31
  • Thank you for the quick reply Christopher, I should have explained myself a bit better. The program that is affected by the write behind caching is not my own or one I can edit. Its medical software and its data integrity is being affected by Windows switching on the Write behind caching. For example, two users might use the same function at once. Without write behind caching one of the users will get rejected. Unfortunately now it seems that the database queries are cached and committed at a later time which as you can think, is disastrous. – Blixem Nov 08 '19 at 08:35
  • @Blixem Have you checked the Windows Policies? If there is one thing that can set the value and keep it set across updates, it is it. | I would personally run the Programm without caches then. It is better to fail safely, then succeed with a unseen danger. Indeed with write caching if two people use the same function, there is actually the danger of a Update Race Condition. – Christopher Nov 08 '19 at 08:54
  • @Blixem: The WPF way of dealing with thing like this is: "If you can not change it, wrap access to it in something you can change." And as they need properties with ChangeNotification the run into "can not change it" a lot. It does sound a lot like the Programm is some sort of server. Maybe you could abstract the old code behind a WebService of your own making, that could then do such nice things as "wait 15 seconds to get the lock, before you just reject a function call". – Christopher Nov 08 '19 at 08:56
1

Okay, So I found a solution for this issue.

As OlivierRogier also mentioned. This setting seems to be stored in the Registry under:

HKLM\SYSTEM\CurrentControlSet\Enum\(IDE OR SCSI)\Diskxxxxxxxxxxxx\DeviceParameters\Disk Key : UserWriteCacheSetting where xxxxxxx is manufacturer information.

Link HERE

I set up some code that checks this setting on a daily basis => changes it => restarts the computer. Will share the code if requested.

Thank you everyone for your input. Blixem

Blixem
  • 59
  • 6