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