This source file includes following definitions.
- V1_trunc_direct
- V1_trunc_indirect
- V1_trunc_dindirect
- V1_minix_truncate
- V2_trunc_direct
- V2_trunc_indirect
- V2_trunc_dindirect
- V2_trunc_tindirect
- V2_minix_truncate
- minix_truncate
1
2
3
4
5
6
7
8
9
10 #include <linux/errno.h>
11 #include <linux/sched.h>
12 #include <linux/minix_fs.h>
13 #include <linux/stat.h>
14 #include <linux/fcntl.h>
15
16 #define DIRECT_BLOCK ((inode->i_size + 1023) >> 10)
17 #define INDIRECT_BLOCK(offset) (DIRECT_BLOCK-offset)
18 #define DINDIRECT_BLOCK(offset) ((DIRECT_BLOCK-offset)>>9)
19 #define TINDIRECT_BLOCK(offset) ((DIRECT_BLOCK-(offset))>>9)
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 static int V1_trunc_direct(struct inode * inode)
38 {
39 unsigned short * p;
40 struct buffer_head * bh;
41 int i, tmp;
42 int retry = 0;
43
44 repeat:
45 for (i = DIRECT_BLOCK ; i < 7 ; i++) {
46 p = i + inode->u.minix_i.u.i1_data;
47 if (!(tmp = *p))
48 continue;
49 bh = get_hash_table(inode->i_dev,tmp,BLOCK_SIZE);
50 if (i < DIRECT_BLOCK) {
51 brelse(bh);
52 goto repeat;
53 }
54 if ((bh && bh->b_count != 1) || tmp != *p) {
55 retry = 1;
56 brelse(bh);
57 continue;
58 }
59 *p = 0;
60 inode->i_dirt = 1;
61 if (bh) {
62 mark_buffer_clean(bh);
63 brelse(bh);
64 }
65 minix_free_block(inode->i_sb,tmp);
66 }
67 return retry;
68 }
69
70 static int V1_trunc_indirect(struct inode * inode, int offset, unsigned short * p)
71 {
72 struct buffer_head * bh;
73 int i, tmp;
74 struct buffer_head * ind_bh;
75 unsigned short * ind;
76 int retry = 0;
77
78 tmp = *p;
79 if (!tmp)
80 return 0;
81 ind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
82 if (tmp != *p) {
83 brelse(ind_bh);
84 return 1;
85 }
86 if (!ind_bh) {
87 *p = 0;
88 return 0;
89 }
90 repeat:
91 for (i = INDIRECT_BLOCK(offset) ; i < 512 ; i++) {
92 if (i < 0)
93 i = 0;
94 if (i < INDIRECT_BLOCK(offset))
95 goto repeat;
96 ind = i+(unsigned short *) ind_bh->b_data;
97 tmp = *ind;
98 if (!tmp)
99 continue;
100 bh = get_hash_table(inode->i_dev,tmp,BLOCK_SIZE);
101 if (i < INDIRECT_BLOCK(offset)) {
102 brelse(bh);
103 goto repeat;
104 }
105 if ((bh && bh->b_count != 1) || tmp != *ind) {
106 retry = 1;
107 brelse(bh);
108 continue;
109 }
110 *ind = 0;
111 mark_buffer_dirty(ind_bh, 1);
112 brelse(bh);
113 minix_free_block(inode->i_sb,tmp);
114 }
115 ind = (unsigned short *) ind_bh->b_data;
116 for (i = 0; i < 512; i++)
117 if (*(ind++))
118 break;
119 if (i >= 512)
120 if (ind_bh->b_count != 1)
121 retry = 1;
122 else {
123 tmp = *p;
124 *p = 0;
125 minix_free_block(inode->i_sb,tmp);
126 }
127 brelse(ind_bh);
128 return retry;
129 }
130
131 static int V1_trunc_dindirect(struct inode * inode, int offset, unsigned short *p)
132 {
133 int i, tmp;
134 struct buffer_head * dind_bh;
135 unsigned short * dind;
136 int retry = 0;
137
138 if (!(tmp = *p))
139 return 0;
140 dind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
141 if (tmp != *p) {
142 brelse(dind_bh);
143 return 1;
144 }
145 if (!dind_bh) {
146 *p = 0;
147 return 0;
148 }
149 repeat:
150 for (i = DINDIRECT_BLOCK(offset) ; i < 512 ; i ++) {
151 if (i < 0)
152 i = 0;
153 if (i < DINDIRECT_BLOCK(offset))
154 goto repeat;
155 dind = i+(unsigned short *) dind_bh->b_data;
156 retry |= V1_trunc_indirect(inode,offset+(i<<9),dind);
157 mark_buffer_dirty(dind_bh, 1);
158 }
159 dind = (unsigned short *) dind_bh->b_data;
160 for (i = 0; i < 512; i++)
161 if (*(dind++))
162 break;
163 if (i >= 512)
164 if (dind_bh->b_count != 1)
165 retry = 1;
166 else {
167 tmp = *p;
168 *p = 0;
169 inode->i_dirt = 1;
170 minix_free_block(inode->i_sb,tmp);
171 }
172 brelse(dind_bh);
173 return retry;
174 }
175
176 void V1_minix_truncate(struct inode * inode)
177 {
178 int retry;
179
180 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
181 S_ISLNK(inode->i_mode)))
182 return;
183 while (1) {
184 retry = V1_trunc_direct(inode);
185 retry |= V1_trunc_indirect(inode, 7, inode->u.minix_i.u.i1_data + 7);
186 retry |= V1_trunc_dindirect(inode, 7+512, inode->u.minix_i.u.i1_data + 8);
187 if (!retry)
188 break;
189 current->counter = 0;
190 schedule();
191 }
192 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
193 inode->i_dirt = 1;
194 }
195
196
197
198
199 static int V2_trunc_direct(struct inode * inode)
200 {
201 unsigned long * p;
202 struct buffer_head * bh;
203 int i, tmp;
204 int retry = 0;
205
206 repeat:
207 for (i = DIRECT_BLOCK ; i < 7 ; i++) {
208 p = (unsigned long *) inode->u.minix_i.u.i2_data + i;
209 if (!(tmp = *p))
210 continue;
211 bh = get_hash_table(inode->i_dev,tmp,BLOCK_SIZE);
212 if (i < DIRECT_BLOCK) {
213 brelse(bh);
214 goto repeat;
215 }
216 if ((bh && bh->b_count != 1) || tmp != *p) {
217 retry = 1;
218 brelse(bh);
219 continue;
220 }
221 *p = 0;
222 inode->i_dirt = 1;
223 if (bh) {
224 mark_buffer_clean(bh);
225 brelse(bh);
226 }
227 minix_free_block(inode->i_sb,tmp);
228 }
229 return retry;
230 }
231
232 static int V2_trunc_indirect(struct inode * inode, int offset, unsigned long * p)
233 {
234 struct buffer_head * bh;
235 int i, tmp;
236 struct buffer_head * ind_bh;
237 unsigned long * ind;
238 int retry = 0;
239
240 tmp = *p;
241 if (!tmp)
242 return 0;
243 ind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
244 if (tmp != *p) {
245 brelse(ind_bh);
246 return 1;
247 }
248 if (!ind_bh) {
249 *p = 0;
250 return 0;
251 }
252 repeat:
253 for (i = INDIRECT_BLOCK(offset) ; i < 256 ; i++) {
254 if (i < 0)
255 i = 0;
256 if (i < INDIRECT_BLOCK(offset))
257 goto repeat;
258 ind = i+(unsigned long *) ind_bh->b_data;
259 tmp = *ind;
260 if (!tmp)
261 continue;
262 bh = get_hash_table(inode->i_dev,tmp,BLOCK_SIZE);
263 if (i < INDIRECT_BLOCK(offset)) {
264 brelse(bh);
265 goto repeat;
266 }
267 if ((bh && bh->b_count != 1) || tmp != *ind) {
268 retry = 1;
269 brelse(bh);
270 continue;
271 }
272 *ind = 0;
273 mark_buffer_dirty(ind_bh, 1);
274 brelse(bh);
275 minix_free_block(inode->i_sb,tmp);
276 }
277 ind = (unsigned long *) ind_bh->b_data;
278 for (i = 0; i < 256; i++)
279 if (*(ind++))
280 break;
281 if (i >= 256)
282 if (ind_bh->b_count != 1)
283 retry = 1;
284 else {
285 tmp = *p;
286 *p = 0;
287 minix_free_block(inode->i_sb,tmp);
288 }
289 brelse(ind_bh);
290 return retry;
291 }
292
293 static int V2_trunc_dindirect(struct inode * inode, int offset, unsigned long *p)
294 {
295 int i, tmp;
296 struct buffer_head * dind_bh;
297 unsigned long * dind;
298 int retry = 0;
299
300 if (!(tmp = *p))
301 return 0;
302 dind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
303 if (tmp != *p) {
304 brelse(dind_bh);
305 return 1;
306 }
307 if (!dind_bh) {
308 *p = 0;
309 return 0;
310 }
311 repeat:
312 for (i = DINDIRECT_BLOCK(offset) ; i < 256 ; i ++) {
313 if (i < 0)
314 i = 0;
315 if (i < DINDIRECT_BLOCK(offset))
316 goto repeat;
317 dind = i+(unsigned long *) dind_bh->b_data;
318 retry |= V2_trunc_indirect(inode,offset+(i<<9),dind);
319 mark_buffer_dirty(dind_bh, 1);
320 }
321 dind = (unsigned long *) dind_bh->b_data;
322 for (i = 0; i < 256; i++)
323 if (*(dind++))
324 break;
325 if (i >= 256)
326 if (dind_bh->b_count != 1)
327 retry = 1;
328 else {
329 tmp = *p;
330 *p = 0;
331 inode->i_dirt = 1;
332 minix_free_block(inode->i_sb,tmp);
333 }
334 brelse(dind_bh);
335 return retry;
336 }
337
338 static int V2_trunc_tindirect(struct inode * inode, int offset, unsigned long * p)
339 {
340 int i, tmp;
341 struct buffer_head * tind_bh;
342 unsigned long * tind;
343 int retry = 0;
344
345 if (!(tmp = *p))
346 return 0;
347 tind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
348 if (tmp != *p) {
349 brelse(tind_bh);
350 return 1;
351 }
352 if (!tind_bh) {
353 *p = 0;
354 return 0;
355 }
356 repeat:
357 for (i = TINDIRECT_BLOCK(offset) ; i < 256 ; i ++) {
358 if (i < 0)
359 i = 0;
360 if (i < TINDIRECT_BLOCK(offset))
361 goto repeat;
362 tind = i+(unsigned long *) tind_bh->b_data;
363 retry |= V2_trunc_dindirect(inode,offset+(i<<9),tind);
364 mark_buffer_dirty(tind_bh, 1);
365 }
366 tind = (unsigned long *) tind_bh->b_data;
367 for (i = 0; i < 256; i++)
368 if (*(tind++))
369 break;
370 if (i >= 256)
371 if (tind_bh->b_count != 1)
372 retry = 1;
373 else {
374 tmp = *p;
375 *p = 0;
376 inode->i_dirt = 1;
377 minix_free_block(inode->i_sb,tmp);
378 }
379 brelse(tind_bh);
380 return retry;
381 }
382
383 static void V2_minix_truncate(struct inode * inode)
384 {
385 int retry;
386
387 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
388 S_ISLNK(inode->i_mode)))
389 return;
390 while (1) {
391 retry = V2_trunc_direct(inode);
392 retry |= V2_trunc_indirect(inode,7,
393 (unsigned long *) inode->u.minix_i.u.i2_data + 7);
394 retry |= V2_trunc_dindirect(inode, 7+256,
395 (unsigned long *) inode->u.minix_i.u.i2_data + 8);
396 retry |= V2_trunc_tindirect(inode, 7+256+256*256,
397 (unsigned long *) inode->u.minix_i.u.i2_data + 9);
398 if (!retry)
399 break;
400 current->counter = 0;
401 schedule();
402 }
403 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
404 inode->i_dirt = 1;
405 }
406
407
408
409
410 void minix_truncate(struct inode * inode)
411 {
412 if (INODE_VERSION(inode) == MINIX_V1)
413 V1_minix_truncate(inode);
414 else
415 V2_minix_truncate(inode);
416 }