/*
* linux/fs/truncate.c
*
* (C) 1991 Linus Torvalds
*/

#include <linux/sched.h>	// ȳͷļṹtask_structʼ0 ݣ
// һЩйúͻȡǶʽຯ䡣

#include <sys/stat.h>		// ļ״̬ͷļļļϵͳ״̬ṹstat{}ͳ

//// ͷһμӿ顣
static void
free_ind (int dev, int block)
{
  struct buffer_head *bh;
  unsigned short *p;
  int i;

// ߼Ϊ0򷵻ء
  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);		// ͷŻ
    }
//ֶ
//i_zone[0]
//i_zone[1]
//i_zone[2]
//i_zone[3]
//i_zone[4]
//i_zone[5]
//i_zone[6]
//i ڵ
//ֱӿ
//һμӿ
//μӿ
//һ
//μӿ
//Ķ
//һμӿ
//μӿ
//i_zone[7]
//i_zone[8]
// ͷ豸ϵһμӿ顣
  free_block (dev, block);
}

//// ͷŶμӿ顣
static void
free_dind (int dev, int block)
{
  struct buffer_head *bh;
  unsigned short *p;
  int i;

// ߼Ϊ0򷵻ء
  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 ߼ȫ㡣
  for (i = 0; i < 7; i++)
    if (inode->i_zone[i])
      {				// ŲΪ0ͷ֮
	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;	// ߼78 㡣
  inode->i_size = 0;		// ļС㡣
  inode->i_dirt = 1;		// ýڵ޸ı־
  inode->i_mtime = inode->i_ctime = CURRENT_TIME;	// ļͽڵ޸ʱΪǰʱ䡣
}
