This source file includes following definitions.
- trunc_direct
- trunc_indirect
- trunc_dindirect
- minix_truncate
1
2
3
4
5
6
7 #ifdef MODULE
8 #include <linux/module.h>
9 #endif
10
11 #include <linux/errno.h>
12 #include <linux/sched.h>
13 #include <linux/minix_fs.h>
14 #include <linux/stat.h>
15 #include <linux/fcntl.h>
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 static int trunc_direct(struct inode * inode)
31 {
32 unsigned short * p;
33 struct buffer_head * bh;
34 int i, tmp;
35 int retry = 0;
36 #define DIRECT_BLOCK ((inode->i_size + 1023) >> 10)
37
38 repeat:
39 for (i = DIRECT_BLOCK ; i < 7 ; i++) {
40 p = i + inode->u.minix_i.i_data;
41 if (!(tmp = *p))
42 continue;
43 bh = get_hash_table(inode->i_dev,tmp,BLOCK_SIZE);
44 if (i < DIRECT_BLOCK) {
45 brelse(bh);
46 goto repeat;
47 }
48 if ((bh && bh->b_count != 1) || tmp != *p) {
49 retry = 1;
50 brelse(bh);
51 continue;
52 }
53 *p = 0;
54 inode->i_dirt = 1;
55 if (bh) {
56 mark_buffer_clean(bh);
57 brelse(bh);
58 }
59 minix_free_block(inode->i_sb,tmp);
60 }
61 return retry;
62 }
63
64 static int trunc_indirect(struct inode * inode, int offset, unsigned short * p)
65 {
66 struct buffer_head * bh;
67 int i, tmp;
68 struct buffer_head * ind_bh;
69 unsigned short * 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 < 512 ; i++) {
87 if (i < 0)
88 i = 0;
89 if (i < INDIRECT_BLOCK)
90 goto repeat;
91 ind = i+(unsigned short *) ind_bh->b_data;
92 tmp = *ind;
93 if (!tmp)
94 continue;
95 bh = get_hash_table(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 mark_buffer_dirty(ind_bh, 1);
107 brelse(bh);
108 minix_free_block(inode->i_sb,tmp);
109 }
110 ind = (unsigned short *) ind_bh->b_data;
111 for (i = 0; i < 512; i++)
112 if (*(ind++))
113 break;
114 if (i >= 512)
115 if (ind_bh->b_count != 1)
116 retry = 1;
117 else {
118 tmp = *p;
119 *p = 0;
120 minix_free_block(inode->i_sb,tmp);
121 }
122 brelse(ind_bh);
123 return retry;
124 }
125
126 static int trunc_dindirect(struct inode * inode)
127 {
128 int i, tmp;
129 struct buffer_head * dind_bh;
130 unsigned short * dind, * p;
131 int retry = 0;
132 #define DINDIRECT_BLOCK ((DIRECT_BLOCK-(512+7))>>9)
133
134 p = 8 + inode->u.minix_i.i_data;
135 if (!(tmp = *p))
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 < 512 ; i ++) {
148 if (i < 0)
149 i = 0;
150 if (i < DINDIRECT_BLOCK)
151 goto repeat;
152 dind = i+(unsigned short *) dind_bh->b_data;
153 retry |= trunc_indirect(inode,7+512+(i<<9),dind);
154 mark_buffer_dirty(dind_bh, 1);
155 }
156 dind = (unsigned short *) dind_bh->b_data;
157 for (i = 0; i < 512; i++)
158 if (*(dind++))
159 break;
160 if (i >= 512)
161 if (dind_bh->b_count != 1)
162 retry = 1;
163 else {
164 tmp = *p;
165 *p = 0;
166 inode->i_dirt = 1;
167 minix_free_block(inode->i_sb,tmp);
168 }
169 brelse(dind_bh);
170 return retry;
171 }
172
173 void minix_truncate(struct inode * inode)
174 {
175 int retry;
176
177 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
178 S_ISLNK(inode->i_mode)))
179 return;
180 while (1) {
181 retry = trunc_direct(inode);
182 retry |= trunc_indirect(inode,7,inode->u.minix_i.i_data+7);
183 retry |= trunc_dindirect(inode);
184 if (!retry)
185 break;
186 current->counter = 0;
187 schedule();
188 }
189 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
190 inode->i_dirt = 1;
191 }