Introduction
Recently I was evaluating the options I had for implementing disk quotas on a backend system running on a major Internet Service Provider in Brazil.
Windows offers quota management up to some degree since NTFS 5 (Windows 2000) with user/volume quotas. Those were not appropriate for our scenario since we needed to set quotas on a per directory basis and this was not supported natively by Windows until the arrival of Windows Server 2003 R2.
R2 brings us a new feature called File Server Resource Manager a.k.a. FSRM. It is exposed for the system administrator as an MMC 3.0 snap-in.
Unfortunately, as of today Microsoft does not officially support any way for programming against FSRM quotas. I said “officially support” because if the snap-in can do it, probably we can too! So after some research I found two DLLs called srm.dll and srmlib.dll that happens to do the stuff we want. Srm.dll exposes FSRM functionality through COM and srmlib.dll is a managed code wrapper around srm.dll.
Let’s take a look at some sample code:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Storage;
using System.IO;
using System.Runtime.InteropServices;
namespace Fsrm {
class Program {
static void Main(string[] args) {
string directoryName = @"c:FsrmTests";
// Creates a directory for testing if necessary
if (!Directory.Exists(directoryName)) {
Directory.CreateDirectory(directoryName);
}
ISrmQuotaManager quotaManager = new SrmQuotaManagerClass();
ISrmQuota quota = null;
try {
// Try to get quota info
quota = quotaManager.GetQuota(directoryName);
quota.QuotaLimit *= 2;
}
catch (COMException ex) {
unchecked {
if (ex.ErrorCode == (int)0x80045301) {
// Quota doesn’t exist for this directory. Create it.
Console.WriteLine("No quota defined for ‘{0}’. Creating quota.", directoryName);
quota = quotaManager.CreateQuota(directoryName);
quota.QuotaLimit = 1024 * 1024;
}
else {
Console.WriteLine(ex);
return;
}
}
}
// Update quota info
quota.Commit();
// Add new file to the diretory to see QuotaUsed getting updated
File.WriteAllText(directoryName + @"" + Path.GetRandomFileName() + ".txt", "Testing FSRM directory quotas");
Console.WriteLine("New file added. Quota doubledrn{0} of {1} used.", quota.QuotaUsed, quota.QuotaLimit);
}
}
}
This sample doubles the size of the directory’s quota and puts a file in it every time it is run.
There are a bunch of other classes and methods available. Have fun!