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 brelse(bh);
56 minix_free_block(inode->i_sb,tmp);
57 }
58 return retry;
59 }
60
61 static int trunc_indirect(struct inode * inode, int offset, unsigned short * p)
62 {
63 struct buffer_head * bh;
64 int i, tmp;
65 struct buffer_head * ind_bh;
66 unsigned short * ind;
67 int retry = 0;
68 #define INDIRECT_BLOCK (DIRECT_BLOCK-offset)
69
70 tmp = *p;
71 if (!tmp)
72 return 0;
73 ind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
74 if (tmp != *p) {
75 brelse(ind_bh);
76 return 1;
77 }
78 if (!ind_bh) {
79 *p = 0;
80 return 0;
81 }
82 repeat:
83 for (i = INDIRECT_BLOCK ; i < 512 ; i++) {
84 if (i < 0)
85 i = 0;
86 if (i < INDIRECT_BLOCK)
87 goto repeat;
88 ind = i+(unsigned short *) ind_bh->b_data;
89 tmp = *ind;
90 if (!tmp)
91 continue;
92 bh = get_hash_table(inode->i_dev,tmp,BLOCK_SIZE);
93 if (i < INDIRECT_BLOCK) {
94 brelse(bh);
95 goto repeat;
96 }
97 if ((bh && bh->b_count != 1) || tmp != *ind) {
98 retry = 1;
99 brelse(bh);
100 continue;
101 }
102 *ind = 0;
103 mark_buffer_dirty(ind_bh, 1);
104 brelse(bh);
105 minix_free_block(inode->i_sb,tmp);
106 }
107 ind = (unsigned short *) ind_bh->b_data;
108 for (i = 0; i < 512; i++)
109 if (*(ind++))
110 break;
111 if (i >= 512)
112 if (ind_bh->b_count != 1)
113 retry = 1;
114 else {
115 tmp = *p;
116 *p = 0;
117 minix_free_block(inode->i_sb,tmp);
118 }
119 brelse(ind_bh);
120 return retry;
121 }
122
123 static int trunc_dindirect(struct inode * inode)
124 {
125 int i, tmp;
126 struct buffer_head * dind_bh;
127 unsigned short * dind, * p;
128 int retry = 0;
129 #define DINDIRECT_BLOCK ((DIRECT_BLOCK-(512+7))>>9)
130
131 p = 8 + inode->u.minix_i.i_data;
132 if (!(tmp = *p))
133 return 0;
134 dind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
135 if (tmp != *p) {
136 brelse(dind_bh);
137 return 1;
138 }
139 if (!dind_bh) {
140 *p = 0;
141 return 0;
142 }
143 repeat:
144 for (i = DINDIRECT_BLOCK ; i < 512 ; i ++) {
145 if (i < 0)
146 i = 0;
147 if (i < DINDIRECT_BLOCK)
148 goto repeat;
149 dind = i+(unsigned short *) dind_bh->b_data;
150 retry |= trunc_indirect(inode,7+512+(i<<9),dind);
151 mark_buffer_dirty(dind_bh, 1);
152 }
153 dind = (unsigned short *) dind_bh->b_data;
154 for (i = 0; i < 512; i++)
155 if (*(dind++))
156 break;
157 if (i >= 512)
158 if (dind_bh->b_count != 1)
159 retry = 1;
160 else {
161 tmp = *p;
162 *p = 0;
163 inode->i_dirt = 1;
164 minix_free_block(inode->i_sb,tmp);
165 }
166 brelse(dind_bh);
167 return retry;
168 }
169
170 void minix_truncate(struct inode * inode)
171 {
172 int retry;
173
174 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
175 S_ISLNK(inode->i_mode)))
176 return;
177 while (1) {
178 retry = trunc_direct(inode);
179 retry |= trunc_indirect(inode,7,inode->u.minix_i.i_data+7);
180 retry |= trunc_dindirect(inode);
181 if (!retry)
182 break;
183 current->counter = 0;
184 schedule();
185 }
186 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
187 inode->i_dirt = 1;
188 }