The Storage Team at Microsoft - File Cabinet Blog : New File Systems and Storage white papers, by Dilip Naik - MVP
ここの、Best Practices To Avoid Fragmentation While Writing To A Fileというペーパーが興味深い。
Sysinternals Contig
ソースコードが示されていないが、大方はこんな感じだろう。
BOOL SetPrivilege(
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
LUID luid ;
// lookup privilege on local
if ( !LookupPrivilegeValue( NULL, lpszPrivilege, &luid ) )
{
return FALSE;
}
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;
// Get Current Process Token
HANDLE hToken ;
OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) ;
// Enable the privilege or disable all privileges.
if ( !AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL) )
{
return FALSE;
}
CloseHandle( hToken ) ;
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
return FALSE;
}
return TRUE;
}
int main()
{
// CreateFile
HANDLE file = CreateFile( L"test.dat", GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL ) ;
if ( file == INVALID_HANDLE_VALUE )
{
return 1 ;
}
// SetFilePointer to desired file size
LARGE_INTEGER pointer ;
pointer.QuadPart = 400 * 1024 ;
SetFilePointerEx( file, pointer, NULL, FILE_BEGIN ) ;
// SetEndOfFile
SetEndOfFile( file ) ;
// SetFileValidData
SetPrivilege( SE_MANAGE_VOLUME_NAME, TRUE ) ;
SetFileValidData( file, 400 * 1024 ) ;
// SetFilePointer to beginning of file
pointer.QuadPart = 0 ;
SetFilePointerEx( file, pointer, NULL, FILE_BEGIN ) ;
// WriteFile in a loop to fill the file with desired data
// – the loop is executed 400 times and each pass through the loop issues a single 1024 byte WriteFile request.
char buf[1024] ;
memset( buf, 0, sizeof(buf) ) ;
for ( int i = 0 ; i < 400 ; ++i )
{
DWORD unused ;
WriteFile( file, buf, sizeof(buf), &unused, NULL ) ;
}
// CloseFile
CloseHandle( file ) ;
return 0;
}
なぜか管理者権限で実行しても、SetFileValidDataを呼び出した後のGetLastErrorに1314が帰ってきてしまう。しかし、SetFileValidData自体はエラーを返していないので、処理が失敗しているわけでもないのだろうか。ローカルポリシーで確認したが、たしかに、「ボリュームの保守タスクを実行」の権限に、Administratorsが入っている。それにしてもOSの説明が日本語になっているのは面倒だ。こういう部分は敢えて訳さなくてもいいと思うのだが。あるいは、Vistaの言語パックをいれて、英語にしてしまうべきか。
しかし不思議なことに、私の環境では、SetFileValidDataを呼び出さずとも、SetFilePointerとSetEndOfFileだけで、フラグメントは起こらなかった。
http://replay.web.archive.org/20080921022116/http://msftmvp.com/Documents/NTFSFrag.pdf
ReplyDelete