Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 Aug 1998 22:27:59 +0000 (GMT)
From:      Terry Lambert <tlambert@primenet.com>
To:        poipoi@famipow.com
Cc:        freebsd-fs@FreeBSD.ORG, linux-fsdevel@vger.rutgers.edu
Subject:   Re: file hole ?
Message-ID:  <199808042228.PAA06764@usr07.primenet.com>
In-Reply-To: <19980804175705.377.qmail@hwi.poi.org> from "poipoi@famipow.com" at Aug 4, 98 07:57:05 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> 	i want to know how to handle file hole. 
> for example, i have a 8k file. i do a seek at 20000 and write a byte. 
> 
> Does the fs alloc every block to store 20001 bytes ?

Depends on the FS.  Most UNIX FS's do not.  MSDOSFS on UNIX would
have to, because there is no concept of a sparse file in the FS's
design.

> yes ? but its a space wasting...

Generally "yes" for Linux or FreeBSD using their native FS's.

> no ? but when the user will fill the hole (writing from 8192 to 20000),
> my fs will perhaps be full and i have to reject the write operation...

You can put 10 pounds of manure in a 5 pound bag.  That would be a blivet.


> what is the standard (good?) behaviour ?

To supprt sparse files (leave holes, unless specifically asked to fill
them in).

> and why (if possible) ?

Because you can explicitly fill the holes in if you want if the default
is to leave holes, but you can't explicitly cause holes if the default
is to fill them in.  8-).

Consider the case of a sparsely filled database that uses a perfect hash
to locate all its records.  The file containing the records is sparsely
used, and the majority of blocks backing the file would be wasted, unless
the underlying filesystem supported sparse files.

If you want to "fill in the file" so that the system will "commit"
to having backing for all of the possible records in the file, you
should use statfs(2) and use f_bsize to determine the block size.
You should them multiply f_bsize by f_bavail (or f_bsize, if you are
root and are willing to overfill the disk, damaging performance), and
if that number is larger than the file you want to allocate, then
there is sufficient space for the allocation.

If you are concerned with the possibility that other users may consume
the space after the seek/write, but before you have filled in the
subsequent blocks, and therefore want the blocks preallocated (thus
wasting the space for an indeterminate amount of time), you should
do the following:

	struct statfs	sfsb;
	char		*zero = "";
	long		i;
	long		count;
	int		fd;

	statfs( PATH_TO_FS, &sfsb);

	count = (SIZE_WANTED_IN_BYTES + sfsb.f_bsize - 1) / sfsb.f_bsize;

	if( count > sfsb.f_bfree || (getuid() != 0 && count > sfsb.f_bavail)) {
		fprintf( stderr, "You maniac!\007\n");
		exit( 1);
	}

... create the file, open it on fd ...

	/*
	 * I work for Quantum; the only good disk is a full disk
	 */.
	lseek( fd, sfsb.f_bsize - 1, SEEK_SET);		/* we fear frags*/
	for( i = 0; i < count; i++) {
		lseek( fd, sfsb.f_bsize, SEEK_CUR);
		write( fd, zero, 1);			/* spam!*/
	}

	printf( "Success: disk spammed, per your instructions\n");
	exit( 0);



					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-fs" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199808042228.PAA06764>