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, tmp;
36 unsigned long * p;
37 struct buffer_head * bh;
38 int retry = 0;
39 #define DIRECT_BLOCK ((inode->i_size + 1023) >> 10)
40
41 repeat:
42 for (i = DIRECT_BLOCK ; i < 9 ; i++) {
43 p = inode->u.ext_i.i_data+i;
44 if (!(tmp = *p))
45 continue;
46 bh = getblk(inode->i_dev,tmp,BLOCK_SIZE);
47 if (i < DIRECT_BLOCK) {
48 brelse(bh);
49 goto repeat;
50 }
51 if ((bh && bh->b_count != 1) || tmp != *p) {
52 retry = 1;
53 brelse(bh);
54 continue;
55 }
56 *p = 0;
57 inode->i_dirt = 1;
58 brelse(bh);
59 ext_free_block(inode->i_sb,tmp);
60 }
61 return retry;
62 }
63
64 static int trunc_indirect(struct inode * inode, int offset, unsigned long * p)
65 {
66 int i, tmp;
67 struct buffer_head * bh;
68 struct buffer_head * ind_bh;
69 unsigned long * ind;
70 int retry = 0;
71 #define INDIRECT_BLOCK (DIRECT_BLOCK-offset)
72
73 tmp = *p;
74 if (!tmp)
75 return 0;
76 ind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
77 if (tmp != *p) {
78 brelse(ind_bh);
79 return 1;
80 }
81 if (!ind_bh) {
82 *p = 0;
83 return 0;
84 }
85 repeat:
86 for (i = INDIRECT_BLOCK ; i < 256 ; i++) {
87 if (i < 0)
88 i = 0;
89 if (i < INDIRECT_BLOCK)
90 goto repeat;
91 ind = i+(unsigned long *) ind_bh->b_data;
92 tmp = *ind;
93 if (!tmp)
94 continue;
95 bh = getblk(inode->i_dev,tmp,BLOCK_SIZE);
96 if (i < INDIRECT_BLOCK) {
97 brelse(bh);
98 goto repeat;
99 }
100 if ((bh && bh->b_count != 1) || tmp != *ind) {
101 retry = 1;
102 brelse(bh);
103 continue;
104 }
105 *ind = 0;
106 ind_bh->b_dirt = 1;
107 brelse(bh);
108 ext_free_block(inode->i_sb,tmp);
109 }
110 ind = (unsigned long *) ind_bh->b_data;
111 for (i = 0; i < 256; i++)
112 if (*(ind++))
113 break;
114 if (i >= 256)
115 if (ind_bh->b_count != 1)
116 retry = 1;
117 else {
118 tmp = *p;
119 *p = 0;
120 inode->i_dirt = 1;
121 ext_free_block(inode->i_sb,tmp);
122 }
123 brelse(ind_bh);
124 return retry;
125 }
126
127 static int trunc_dindirect(struct inode * inode, int offset, unsigned long * p)
128 {
129 int i,tmp;
130 struct buffer_head * dind_bh;
131 unsigned long * dind;
132 int retry = 0;
133 #define DINDIRECT_BLOCK ((DIRECT_BLOCK-offset)>>8)
134
135 tmp = *p;
136 if (!tmp)
137 return 0;
138 dind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
139 if (tmp != *p) {
140 brelse(dind_bh);
141 return 1;
142 }
143 if (!dind_bh) {
144 *p = 0;
145 return 0;
146 }
147 repeat:
148 for (i = DINDIRECT_BLOCK ; i < 256 ; i ++) {
149 if (i < 0)
150 i = 0;
151 if (i < DINDIRECT_BLOCK)
152 goto repeat;
153 dind = i+(unsigned long *) dind_bh->b_data;
154 tmp = *dind;
155 if (!tmp)
156 continue;
157 retry |= trunc_indirect(inode,offset+(i<<8),dind);
158 dind_bh->b_dirt = 1;
159 }
160 dind = (unsigned long *) dind_bh->b_data;
161 for (i = 0; i < 256; i++)
162 if (*(dind++))
163 break;
164 if (i >= 256)
165 if (dind_bh->b_count != 1)
166 retry = 1;
167 else {
168 tmp = *p;
169 *p = 0;
170 inode->i_dirt = 1;
171 ext_free_block(inode->i_sb,tmp);
172 }
173 brelse(dind_bh);
174 return retry;
175 }
176
177 static int trunc_tindirect(struct inode * inode)
178 {
179 int i,tmp;
180 struct buffer_head * tind_bh;
181 unsigned long * tind, * p;
182 int retry = 0;
183 #define TINDIRECT_BLOCK ((DIRECT_BLOCK-(256*256+256+9))>>16)
184
185 p = inode->u.ext_i.i_data+11;
186 if (!(tmp = *p))
187 return 0;
188 tind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
189 if (tmp != *p) {
190 brelse(tind_bh);
191 return 1;
192 }
193 if (!tind_bh) {
194 *p = 0;
195 return 0;
196 }
197 repeat:
198 for (i = TINDIRECT_BLOCK ; i < 256 ; i ++) {
199 if (i < 0)
200 i = 0;
201 if (i < TINDIRECT_BLOCK)
202 goto repeat;
203 tind = i+(unsigned long *) tind_bh->b_data;
204 retry |= trunc_dindirect(inode,9+256+256*256+(i<<16),tind);
205 tind_bh->b_dirt = 1;
206 }
207 tind = (unsigned long *) tind_bh->b_data;
208 for (i = 0; i < 256; i++)
209 if (*(tind++))
210 break;
211 if (i >= 256)
212 if (tind_bh->b_count != 1)
213 retry = 1;
214 else {
215 tmp = *p;
216 *p = 0;
217 inode->i_dirt = 1;
218 ext_free_block(inode->i_sb,tmp);
219 }
220 brelse(tind_bh);
221 return retry;
222 }
223
224 void ext_truncate(struct inode * inode)
225 {
226 int retry;
227
228 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
229 S_ISLNK(inode->i_mode)))
230 return;
231 while (1) {
232 retry = trunc_direct(inode);
233 retry |= trunc_indirect(inode,9,inode->u.ext_i.i_data+9);
234 retry |= trunc_dindirect(inode,9+256,inode->u.ext_i.i_data+10);
235 retry |= trunc_tindirect(inode);
236 if (!retry)
237 break;
238 current->counter = 0;
239 schedule();
240 }
241 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
242 inode->i_dirt = 1;
243 }
244
245
246
247
248
249
250 void ext_release(struct inode * inode, struct file * filp)
251 {
252 printk("ext_release not implemented\n");
253 }