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