This source file includes following definitions.
- trunc_direct
- trunc_indirect
- trunc_dindirect
- trunc_tindirect
- ext_truncate
- ext_release
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/sched.h>
14 #include <linux/ext_fs.h>
15 #include <linux/tty.h>
16 #include <linux/stat.h>
17 #include <linux/fcntl.h>
18 #include <linux/errno.h>
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 static int trunc_direct(struct inode * inode)
34 {
35 int i;
36 int result = 0;
37 #define DIRECT_BLOCK ((inode->i_size + 1023) >> 10)
38
39 repeat:
40 for (i = DIRECT_BLOCK ; i < 9 ; i++) {
41 if (i < DIRECT_BLOCK)
42 goto repeat;
43 if (!inode->i_data[i])
44 continue;
45 result = 1;
46 if (ext_free_block(inode->i_dev,inode->i_data[i]))
47 inode->i_data[i] = 0;
48 }
49 return result;
50 }
51
52 static int trunc_indirect(struct inode * inode, int offset, unsigned long * p)
53 {
54 int i;
55 struct buffer_head * bh = NULL;
56 unsigned long * ind;
57 int result = 0;
58 #define INDIRECT_BLOCK (DIRECT_BLOCK-offset)
59
60 if (*p)
61 bh = bread(inode->i_dev, *p, BLOCK_SIZE);
62 if (!bh)
63 return 0;
64 repeat:
65 for (i = INDIRECT_BLOCK ; i < 256 ; i++) {
66 if (i < 0)
67 i = 0;
68 if (i < INDIRECT_BLOCK)
69 goto repeat;
70 ind = i+(unsigned long *) bh->b_data;
71 if (!*ind)
72 continue;
73 result = 1;
74 if (ext_free_block(inode->i_dev,*ind))
75 *ind = 0;
76 }
77 ind = (unsigned long *) bh->b_data;
78 for (i = 0; i < 256; i++)
79 if (*(ind++))
80 break;
81 brelse(bh);
82 if (i >= 256) {
83 result = 1;
84 if (ext_free_block(inode->i_dev,*p))
85 *p = 0;
86 }
87 return result;
88 }
89
90 static int trunc_dindirect(struct inode * inode, int offset, unsigned long * p)
91 {
92 int i;
93 struct buffer_head * bh = NULL;
94 unsigned long * dind;
95 int result = 0;
96 #define DINDIRECT_BLOCK ((DIRECT_BLOCK-offset)>>8)
97
98 if (*p)
99 bh = bread(inode->i_dev, *p, BLOCK_SIZE);
100 if (!bh)
101 return 0;
102 repeat:
103 for (i = DINDIRECT_BLOCK ; i < 256 ; i ++) {
104 if (i < 0)
105 i = 0;
106 if (i < DINDIRECT_BLOCK)
107 goto repeat;
108 dind = i+(unsigned long *) bh->b_data;
109 if (!*dind)
110 continue;
111 result |= trunc_indirect(inode,offset+(i<<8),dind);
112 }
113 dind = (unsigned long *) bh->b_data;
114 for (i = 0; i < 256; i++)
115 if (*(dind++))
116 break;
117 brelse(bh);
118 if (i >= 256) {
119 result = 1;
120 if (ext_free_block(inode->i_dev,*p))
121 *p = 0;
122 }
123 return result;
124 }
125
126 static int trunc_tindirect(struct inode * inode)
127 {
128 int i;
129 struct buffer_head * bh = NULL;
130 unsigned long * tind;
131 int result = 0;
132 #define TINDIRECT_BLOCK ((DIRECT_BLOCK-(256*256+256+9))>>16)
133
134 if (inode->i_data[11])
135 bh = bread(inode->i_dev, inode->i_data[11], BLOCK_SIZE);
136 if (!bh)
137 return 0;
138 repeat:
139 for (i = TINDIRECT_BLOCK ; i < 256 ; i ++) {
140 if (i < 0)
141 i = 0;
142 if (i < TINDIRECT_BLOCK)
143 goto repeat;
144 tind = i+(unsigned long *) bh->b_data;
145 if (!*tind)
146 continue;
147 result |= trunc_dindirect(inode,9+256+256*256+(i<<16),tind);
148 }
149 tind = (unsigned long *) bh->b_data;
150 for (i = 0; i < 256; i++)
151 if (*(tind++))
152 break;
153 brelse(bh);
154 if (i >= 256) {
155 result = 1;
156 if (ext_free_block(inode->i_dev,inode->i_data[11]))
157 inode->i_data[11] = 0;
158 }
159 return result;
160 }
161
162 void ext_truncate(struct inode * inode)
163 {
164 int flag;
165
166 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
167 S_ISLNK(inode->i_mode)))
168 return;
169
170
171 while (1) {
172 flag = trunc_direct(inode);
173 flag |= trunc_indirect(inode,9,(unsigned long *)&inode->i_data[9]);
174 flag |= trunc_dindirect(inode,9+256,(unsigned long *)&inode->i_data[10]);
175 flag |= trunc_tindirect(inode);
176 if (!flag)
177 break;
178 current->counter = 0;
179 schedule();
180 }
181 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
182 inode->i_dirt = 1;
183 }
184
185
186
187
188
189
190 void ext_release(struct inode * inode, struct file * filp)
191 {
192 printk("ext_release not implemented\n");
193 }