The FSCTL_FILE_LEVEL_TRIM control code provides a method to trim data ranges with in a file. The file trim ranges are translated to the underlying storage device allowing it to optimize its resource organization to improve access performance. An FSCTL_FILE_LEVEL_TRIM request allows a virtual disk file to remain allocated at a fixed size while trimming physical storage to correspond to data ranges freed on the virtual disk.

To perform this operation, call FltFsControlFile or ZwFsControlFile with the following parameters.


Instance [in]

FltFsControlFile only. Opaque instance pointer for the caller. This parameter is required and cannot be NULL.

FileObject [in]

FltFsControlFile only. The file pointer object specifying the file for the trim operation. This parameter is required and cannot be NULL.

FileHandle [in]

ZwFsControlFile only. The file handle of the file to be trimmed. This parameter is required and cannot be NULL.

FsControlCode [in]

Control code for the operation. Use FSCTL_FILE_LEVEL_TRIM for this operation.


A pointer to a FILE_LEVEL_TRIM structure which contains an array of trim ranges for the file.

InputBufferLength [in]

Size, in bytes, of the buffer pointed to by InputBuffer. This value is size of the FILE_LEVEL_TRIM structure plus the size the array of FILE_LEVEL_TRIM_RANGE structures.

OutputBuffer [out]

A pointer to an optional FILE_LEVEL_TRIM_OUTPUT structure which receives the result of the trim operation.

OutputBufferLength [in]

Size, in bytes, of the buffer pointed to by the OutputBuffer parameter. This value must be at least sizeof(FILE_LEVEL_TRIM_OUTPUT) if FILE_LEVEL_TRIM_OUTPUT is included in OutputBuffer. Otherwise, this is set to 0.

Return value

FltFsControlFile or ZwFsControlFile returns STATUS_SUCCESS or possibly one of the following values.

Return codeDescription

The file to trim is either compressed or encrypted, the input or output buffer length is invalid, or, no trim ranges are specified.


An internal resource allocation failed.


A trim range is part of a previously locked byte range.


The volume where the file resides is not mounted.


A cache purge failed for a trim range.


No ranges in the trim range array were processed.



Performing trim on certain storage devices can significantly improve their future write performance. Trim also returns resources to the allocation pool in storage systems that are thinly provisioned. When files are deleted on a virtual disk, the size of the virtual disk file itself is not changed. The data ranges freed on the virtual disk are not trimmed on the physical storage where the virtual disk file resides. A virtual disk device can notify the file system that certain data ranges in a virtual disk file can be trimmed on the physical storage device with an FSCTL_FILE_LEVEL_TRIM request. The file system will then issue a trim request to the physical storage. An FSCTL_FILE_LEVEL_TRIM request could also be issued by service applications managing database or memory swap files.

The FSCTL_FILE_LEVEL_TRIM control code will attempt to trim the selected byte ranges of a file from a storage device. The byte ranges are contained in the Ranges array in the FILE_LEVEL_TRIM structure. Included in the Ranges array are one or more FILE_LEVEL_TRIM_RANGE structures.

Including overlapping ranges in the range array is not necessarily an error condition. This is dependant on how extent processing is handled by the underlying storage.

Trimmed ranges are purged as pages from the file system cache. In order to match the cache page size, a trim range's length is adjusted down to a multiple of PAGE_SIZE. Also, if a trim range offset does not begin at a page boundary, it is aligned to the next page boundary. With these constraints, trim range lengths will reduce when their offsets are not page aligned or lengths are not a page size multiple. A trim range length may reduce to 0 if the original length is less than two pages and the offset is not page aligned.

If a trim range is specified or page adjusted beyond the end-of-file (EOF), the range is ignored. However, a range offset aligned before EOF but having a length extending past EOF will be adjusted to a page size multiple <= EOF.

File level trim is not supported for compressed or encrypted files (files with ATTRIBUTE_FLAG_COMPRESSION_MASK or ATTRIBUTE_FLAG_ENCRYPTED attributes set).

A file trim is performed outside of any transaction. The trim operation cannot be rolled back.

With sparse files (files with the ATTRIBUTE_FLAG_SPARSE attribute set), a trim range in an unallocated portion of the file is ignored.

When included in OutputBuffer, the NumRangesProcessed member of the FILE_LEVEL_TRIM_OUTPUT will indicate the number of trim ranges successfully processed. If an error occurs during the processing of the trim ranges, NumRangesProcessed will specify the starting index of the remaining unprocessed ranges, ending at the NumRanges member of FILE_LEVEL_TRIM - 1.



Available in Windows 8 and later versions of Windows.


Ntifs.h (include Ntifs.h or Fltkernel.h)

See also




Send comments about this topic to Microsoft