You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
1.1 KiB
66 lines
1.1 KiB
/*
|
|
* linux/fs/truncate.c
|
|
*
|
|
* (C) 1991 Linus Torvalds
|
|
*/
|
|
|
|
#include <linux/sched.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
static void free_ind(int dev,int block)
|
|
{
|
|
struct buffer_head * bh;
|
|
unsigned short * p;
|
|
int i;
|
|
|
|
if (!block)
|
|
return;
|
|
if (bh=bread(dev,block)) {
|
|
p = (unsigned short *) bh->b_data;
|
|
for (i=0;i<512;i++,p++)
|
|
if (*p)
|
|
free_block(dev,*p);
|
|
brelse(bh);
|
|
}
|
|
free_block(dev,block);
|
|
}
|
|
|
|
static void free_dind(int dev,int block)
|
|
{
|
|
struct buffer_head * bh;
|
|
unsigned short * p;
|
|
int i;
|
|
|
|
if (!block)
|
|
return;
|
|
if (bh=bread(dev,block)) {
|
|
p = (unsigned short *) bh->b_data;
|
|
for (i=0;i<512;i++,p++)
|
|
if (*p)
|
|
free_ind(dev,*p);
|
|
brelse(bh);
|
|
}
|
|
free_block(dev,block);
|
|
}
|
|
|
|
void truncate(struct m_inode * inode)
|
|
{
|
|
int i;
|
|
|
|
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
|
|
return;
|
|
for (i=0;i<7;i++)
|
|
if (inode->i_zone[i]) {
|
|
free_block(inode->i_dev,inode->i_zone[i]);
|
|
inode->i_zone[i]=0;
|
|
}
|
|
free_ind(inode->i_dev,inode->i_zone[7]);
|
|
free_dind(inode->i_dev,inode->i_zone[8]);
|
|
inode->i_zone[7] = inode->i_zone[8] = 0;
|
|
inode->i_size = 0;
|
|
inode->i_dirt = 1;
|
|
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
|
}
|
|
|