summaryrefslogtreecommitdiffstats
path: root/src/fs/truncate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fs/truncate.c')
-rw-r--r--src/fs/truncate.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/fs/truncate.c b/src/fs/truncate.c
new file mode 100644
index 0000000..cb22d5f
--- /dev/null
+++ b/src/fs/truncate.c
@@ -0,0 +1,65 @@
1/*
2 * linux/fs/truncate.c
3 *
4 * (C) 1991 Linus Torvalds
5 */
6
7#include <linux/sched.h>
8
9#include <sys/stat.h>
10
11static void free_ind(int dev,int block)
12{
13 struct buffer_head * bh;
14 unsigned short * p;
15 int i;
16
17 if (!block)
18 return;
19 if ((bh=bread(dev,block))) {
20 p = (unsigned short *) bh->b_data;
21 for (i=0;i<512;i++,p++)
22 if (*p)
23 free_block(dev,*p);
24 brelse(bh);
25 }
26 free_block(dev,block);
27}
28
29static void free_dind(int dev,int block)
30{
31 struct buffer_head * bh;
32 unsigned short * p;
33 int i;
34
35 if (!block)
36 return;
37 if ((bh=bread(dev,block))) {
38 p = (unsigned short *) bh->b_data;
39 for (i=0;i<512;i++,p++)
40 if (*p)
41 free_ind(dev,*p);
42 brelse(bh);
43 }
44 free_block(dev,block);
45}
46
47void truncate(struct m_inode * inode)
48{
49 int i;
50
51 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
52 return;
53 for (i=0;i<7;i++)
54 if (inode->i_zone[i]) {
55 free_block(inode->i_dev,inode->i_zone[i]);
56 inode->i_zone[i]=0;
57 }
58 free_ind(inode->i_dev,inode->i_zone[7]);
59 free_dind(inode->i_dev,inode->i_zone[8]);
60 inode->i_zone[7] = inode->i_zone[8] = 0;
61 inode->i_size = 0;
62 inode->i_dirt = 1;
63 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
64}
65