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