truncate文件只要实现释放指定i节点在设备上占用的所有逻辑块,包括直接块、一次间接块、二次间接块。从而将文件节点对应的文件长度截为0,并释放占用的设备空间。
索引节点的逻辑块连接方式
释放一次间接块
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++) //每个逻辑块上有512块号
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++) //每个逻辑块可连接512个二级块
if (*p)
free_ind(dev,*p);
brelse(bh);
}
free_block(dev,block);
}
将节点对应的文件长度截0,并释放占用的设备空间
void truncate(struct m_inode * inode)
{
int i;
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
return;
//释放i节点的7个直接逻辑块,并将这7个逻辑块项全置为0
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;
}