/* lftruncate.c - lftruncate */
#include
/*------------------------------------------------------------------------
* lftruncate - Truncate a file by freeing its index and data blocks
* (assumes directory mutex held)
*------------------------------------------------------------------------
*/
status lftruncate (
struct lflcblk *lfptr /* Ptr to file's cntl blk entry */
)
{
struct ldentry *ldptr; /* Pointer to file's dir. entry */
struct lfiblk iblock; /* Buffer for one index block */
ibid32 ifree; /* Start of index blk free list */
ibid32 firstib; /* First index blk of the file */
ibid32 nextib; /* Walks down list of the */
/* file's index blocks */
dbid32 nextdb; /* Next data block to free */
int32 i; /* Moves through data blocks in */
/* a given index block */
ldptr = lfptr->lfdirptr; /* Get pointer to dir. entry */
if (ldptr->ld_size == 0) { /* File is already empty */
return OK;
}
/* Clean up the open local file first */
if ( (lfptr->lfibdirty) || (lfptr->lfdbdirty) ) {
lfflush(lfptr);
}
lfptr->lfpos = 0;
lfptr->lfinum = LF_INULL;
lfptr->lfdnum = LF_DNULL;
lfptr->lfbyte = &lfptr->lfdblock[LF_BLKSIZ];
/* Obtain ID of first index block on free list */
ifree = Lf_data.lf_dir.lfd_ifree;
/* Record file's first i-block and clear directory entry */
firstib = ldptr->ld_ilist;
ldptr->ld_ilist = LF_INULL;
ldptr->ld_size = 0;
Lf_data.lf_dirdirty = TRUE;
/* Walk along index block list, disposing of each data block */
/* and clearing the corresponding pointer. A note on loop */
/* termination: last pointer is set to ifree below. */
for (nextib=firstib; nextib!=ifree; nextib=iblock.ib_next) {
/* Obtain a copy of current index block from disk */
lfibget(Lf_data.lf_dskdev, nextib, &iblock);
/* Free each data block in the index block */
for (i=0; i