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