punching holes in files

Anton Altaparmakov aia21 at cam.ac.uk
Thu Nov 1 23:17:32 GMT 2007

On 1 Nov 2007, at 19:16, Steve French wrote:
> madvise_remove (in Linux) is used to free the backing store associated
> with pages (punching a hole in a file).   This is one of the vfs
> operations that we do not send over the wire to Samba (so this call
> would return -ENOSYS locally).   Any thoughts on whether this could be
> done with an obscure SetFileInfo level or FCNTL or whether it is worth
> adding to the CIFS POSIX Extensions?

Don't know about SMB/CIFS but on Windows locally you would need to  
first set the file sparse, and then to punch the hole.  These two  
things are accomplished like so on Windows (STARTING_OFFSET is the  
first byte of the hole to be punched and END_OFFSET is the first byte  
after the hole to be punched):

	HANDLE f; // This is obtained from a CreateFile() call...
	DWORD bw;

	/* Set file sparse. */
	if (!DeviceIoControl(f, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &bw,  
NULL)) {
		// Failed.
		return 1;


	/* Create a hole. */
	z.FileOffset.QuadPart = STARTING_OFFSET;
	z.BeyondFinalZero.QuadPart = END_OFFSET;
	if (!DeviceIoControl(f, FSCTL_SET_ZERO_DATA, &z, sizeof(z), NULL, 0,  
&bw, NULL)) {
		// Failed.
		return 1;

> A second interesting question is whether to implement fallocate over
> the wire.  sys_fallocate takes a range (and also a flag which
> indicates whether to extend the size beyond end of file).
> SET_FILE_ALLOCATION_INFO takes a size field rather than a range.  For
> the case of the range starting at zero, we could simply call Trans2
> set pathinfo (or file info) with SET_FILE_ALLOCATION_INFO.   Should we
> add a CIFS POSIX Extension operation for this too?
> By the way it looks like OCFS2 (not just ext4) implement these.

Again, I don't know about SMB/CIFS but Windows locally supports this,  
too.  To pre-allocate some space without changing the file size (i.e.  
this only allocates space on disk, assigns it to the file, and changes  
the allocated_size on NTFS appropriately but does not change the  
data_size), one would call (note BYTE_OFFSET_IN_FILE_TO_PREALLOCATE_TO  
is the logical file offset to which to pre-allocate to):

	HANDLE f; // This is obtained from a CreateFile() call...

	if (!SetFileInformationByHandle(f, FileAllocationInfo, &ai,  
sizeof(ai))) {
		// Failed.
		return 1;

Hope this is of some use to use...

Best regards,

Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer, http://www.linux-ntfs.org/

More information about the samba-technical mailing list