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