This source file includes following definitions.
- ext2_put_inode
- block_bmap
- ext2_bmap
- inode_getblk
- block_getblk
- ext2_getblk
- ext2_bread
- ext2_read_inode
- ext2_update_inode
- ext2_write_inode
- ext2_sync_inode
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #include <asm/segment.h>
16 #include <asm/system.h>
17
18 #include <linux/errno.h>
19 #include <linux/fs.h>
20 #include <linux/ext2_fs.h>
21 #include <linux/kernel.h>
22 #include <linux/sched.h>
23 #include <linux/stat.h>
24 #include <linux/string.h>
25 #include <linux/locks.h>
26
27 void ext2_put_inode (struct inode * inode)
28 {
29 if (inode->i_nlink || inode->i_ino == EXT2_ACL_IDX_INO ||
30 inode->i_ino == EXT2_ACL_DATA_INO)
31 return;
32 inode->i_size = 0;
33 if (inode->i_blocks)
34 ext2_truncate (inode);
35 ext2_free_inode (inode);
36 }
37
38 #define inode_bmap(inode, nr) ((inode)->u.ext2_i.i_data[(nr)])
39
40 static int block_bmap (struct buffer_head * bh, int nr)
41 {
42 int tmp;
43
44 if (!bh)
45 return 0;
46 tmp = ((unsigned long *) bh->b_data)[nr];
47 brelse (bh);
48 return tmp;
49 }
50
51 int ext2_bmap (struct inode * inode, int block)
52 {
53 int i;
54 int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
55
56 if (block < 0) {
57 ext2_warning (inode->i_sb, "ext2_bmap", "block < 0");
58 return 0;
59 }
60 if (block >= EXT2_NDIR_BLOCKS + addr_per_block +
61 addr_per_block * addr_per_block +
62 addr_per_block * addr_per_block * addr_per_block) {
63 ext2_warning (inode->i_sb, "ext2_bmap", "block > big");
64 return 0;
65 }
66 if (block < EXT2_NDIR_BLOCKS)
67 return inode_bmap (inode, block);
68 block -= EXT2_NDIR_BLOCKS;
69 if (block < addr_per_block) {
70 i = inode_bmap (inode, EXT2_IND_BLOCK);
71 if (!i)
72 return 0;
73 return block_bmap (bread (inode->i_dev, i,
74 inode->i_sb->s_blocksize), block);
75 }
76 block -= addr_per_block;
77 if (block < addr_per_block * addr_per_block) {
78 i = inode_bmap (inode, EXT2_DIND_BLOCK);
79 if (!i)
80 return 0;
81 i = block_bmap (bread (inode->i_dev, i,
82 inode->i_sb->s_blocksize),
83 block / addr_per_block);
84 if (!i)
85 return 0;
86 return block_bmap (bread (inode->i_dev, i,
87 inode->i_sb->s_blocksize),
88 block & (addr_per_block - 1));
89 }
90 block -= addr_per_block * addr_per_block;
91 i = inode_bmap (inode, EXT2_TIND_BLOCK);
92 if (!i)
93 return 0;
94 i = block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
95 block / (addr_per_block * addr_per_block));
96 if (!i)
97 return 0;
98 i = block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
99 (block / addr_per_block) & (addr_per_block - 1));
100 if (!i)
101 return 0;
102 return block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
103 block & (addr_per_block - 1));
104 }
105
106 static struct buffer_head * inode_getblk (struct inode * inode, int nr,
107 int create, int new_block, int * err)
108 {
109 int tmp, goal = 0;
110 unsigned long * p;
111 struct buffer_head * result;
112 int blocks = inode->i_sb->s_blocksize / 512;
113
114 p = inode->u.ext2_i.i_data + nr;
115 repeat:
116 tmp = *p;
117 if (tmp) {
118 result = getblk (inode->i_dev, tmp, inode->i_sb->s_blocksize);
119 if (tmp == *p)
120 return result;
121 brelse (result);
122 goto repeat;
123 }
124 if (!create || new_block >=
125 (current->rlim[RLIMIT_FSIZE].rlim_cur >>
126 EXT2_BLOCK_SIZE_BITS(inode->i_sb))) {
127 *err = -EFBIG;
128 return NULL;
129 }
130 if (inode->u.ext2_i.i_next_alloc_block == new_block)
131 goal = inode->u.ext2_i.i_next_alloc_goal;
132
133 ext2_debug ("hint = %d,", goal);
134
135 if (!goal) {
136 for (tmp = nr - 1; tmp >= 0; tmp--) {
137 if (inode->u.ext2_i.i_data[tmp]) {
138 goal = inode->u.ext2_i.i_data[tmp];
139 break;
140 }
141 }
142 if (!goal)
143 goal = (inode->u.ext2_i.i_block_group *
144 EXT2_BLOCKS_PER_GROUP(inode->i_sb)) +
145 inode->i_sb->u.ext2_sb.s_es->s_first_data_block;
146 }
147
148 ext2_debug ("goal = %d.\n", goal);
149
150 tmp = ext2_new_block (inode->i_sb, goal);
151 if (!tmp)
152 return NULL;
153 result = getblk (inode->i_dev, tmp, inode->i_sb->s_blocksize);
154 if (*p) {
155 ext2_free_block (inode->i_sb, tmp);
156 brelse (result);
157 goto repeat;
158 }
159 *p = tmp;
160 inode->u.ext2_i.i_next_alloc_block = new_block;
161 inode->u.ext2_i.i_next_alloc_goal = tmp;
162 inode->i_ctime = CURRENT_TIME;
163 inode->i_blocks += blocks;
164 if (IS_SYNC(inode))
165 ext2_sync_inode (inode);
166 else
167 inode->i_dirt = 1;
168 return result;
169 }
170
171 static struct buffer_head * block_getblk (struct inode * inode,
172 struct buffer_head * bh, int nr,
173 int create, int blocksize,
174 int new_block, int * err)
175 {
176 int tmp, goal = 0;
177 unsigned long * p;
178 struct buffer_head * result;
179 int blocks = inode->i_sb->s_blocksize / 512;
180
181 if (!bh)
182 return NULL;
183 if (!bh->b_uptodate) {
184 ll_rw_block (READ, 1, &bh);
185 wait_on_buffer (bh);
186 if (!bh->b_uptodate) {
187 brelse (bh);
188 return NULL;
189 }
190 }
191 p = (unsigned long *) bh->b_data + nr;
192 repeat:
193 tmp = *p;
194 if (tmp) {
195 result = getblk (bh->b_dev, tmp, blocksize);
196 if (tmp == *p) {
197 brelse (bh);
198 return result;
199 }
200 brelse (result);
201 goto repeat;
202 }
203 if (!create || new_block >=
204 (current->rlim[RLIMIT_FSIZE].rlim_cur >>
205 EXT2_BLOCK_SIZE_BITS(inode->i_sb))) {
206 brelse (bh);
207 *err = -EFBIG;
208 return NULL;
209 }
210 if (inode->u.ext2_i.i_next_alloc_block == new_block)
211 goal = inode->u.ext2_i.i_next_alloc_goal;
212 if (!goal) {
213 for (tmp = nr - 1; tmp >= 0; tmp--) {
214 if (((unsigned long *) bh->b_data)[tmp]) {
215 goal = ((unsigned long *)bh->b_data)[tmp];
216 break;
217 }
218 }
219 if (!goal)
220 goal = bh->b_blocknr + 1;
221 }
222 tmp = ext2_new_block (inode->i_sb, goal);
223 if (!tmp) {
224 brelse (bh);
225 return NULL;
226 }
227 result = getblk (bh->b_dev, tmp, blocksize);
228 if (*p) {
229 ext2_free_block (inode->i_sb, tmp);
230 brelse (result);
231 goto repeat;
232 }
233 *p = tmp;
234 bh->b_dirt = 1;
235 if (IS_SYNC(inode)) {
236 ll_rw_block (WRITE, 1, &bh);
237 wait_on_buffer (bh);
238 }
239 inode->i_ctime = CURRENT_TIME;
240 inode->i_blocks += blocks;
241 inode->i_dirt = 1;
242 inode->u.ext2_i.i_next_alloc_block = new_block;
243 inode->u.ext2_i.i_next_alloc_goal = tmp;
244 brelse (bh);
245 return result;
246 }
247
248 struct buffer_head * ext2_getblk (struct inode * inode, long block,
249 int create, int * err)
250 {
251 struct buffer_head * bh;
252 unsigned long b;
253 unsigned long addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
254
255 *err = -EIO;
256 if (block < 0) {
257 ext2_warning (inode->i_sb, "ext2_getblk", "block < 0");
258 return NULL;
259 }
260 if (block > EXT2_NDIR_BLOCKS + addr_per_block +
261 addr_per_block * addr_per_block +
262 addr_per_block * addr_per_block * addr_per_block) {
263 ext2_warning (inode->i_sb, "ext2_getblk", "block > big");
264 return NULL;
265 }
266
267
268
269
270 ext2_debug ("block %lu, next %lu, goal %lu.\n", block,
271 inode->u.ext2_i.i_next_alloc_block,
272 inode->u.ext2_i.i_next_alloc_goal);
273
274 if (block == inode->u.ext2_i.i_next_alloc_block + 1) {
275 inode->u.ext2_i.i_next_alloc_block++;
276 inode->u.ext2_i.i_next_alloc_goal++;
277 }
278
279 *err = -ENOSPC;
280 b = block;
281 if (block < EXT2_NDIR_BLOCKS)
282 return inode_getblk (inode, block, create, b, err);
283 block -= EXT2_NDIR_BLOCKS;
284 if (block < addr_per_block) {
285 bh = inode_getblk (inode, EXT2_IND_BLOCK, create, b, err);
286 return block_getblk (inode, bh, block, create,
287 inode->i_sb->s_blocksize, b, err);
288 }
289 block -= addr_per_block;
290 if (block < addr_per_block * addr_per_block) {
291 bh = inode_getblk (inode, EXT2_DIND_BLOCK, create, b, err);
292 bh = block_getblk (inode, bh, block / addr_per_block, create,
293 inode->i_sb->s_blocksize, b, err);
294 return block_getblk (inode, bh, block & (addr_per_block - 1),
295 create, inode->i_sb->s_blocksize, b, err);
296 }
297 block -= addr_per_block * addr_per_block;
298 bh = inode_getblk (inode, EXT2_TIND_BLOCK, create, b, err);
299 bh = block_getblk (inode, bh, block/(addr_per_block * addr_per_block),
300 create, inode->i_sb->s_blocksize, b, err);
301 bh = block_getblk (inode, bh, (block/addr_per_block) & (addr_per_block - 1),
302 create, inode->i_sb->s_blocksize, b, err);
303 return block_getblk (inode, bh, block & (addr_per_block - 1), create,
304 inode->i_sb->s_blocksize, b, err);
305 }
306
307 struct buffer_head * ext2_bread (struct inode * inode, int block,
308 int create, int *err)
309 {
310 struct buffer_head * bh;
311
312 bh = ext2_getblk (inode, block, create, err);
313 if (!bh || bh->b_uptodate)
314 return bh;
315 ll_rw_block (READ, 1, &bh);
316 wait_on_buffer (bh);
317 if (bh->b_uptodate)
318 return bh;
319 brelse (bh);
320 *err = -EIO;
321 return NULL;
322 }
323
324 void ext2_read_inode (struct inode * inode)
325 {
326 struct buffer_head * bh;
327 struct ext2_inode * raw_inode;
328 unsigned long block_group;
329 unsigned long group_desc;
330 unsigned long desc;
331 unsigned long block;
332 struct ext2_group_desc * gdp;
333
334 if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino != EXT2_ACL_IDX_INO &&
335 inode->i_ino != EXT2_ACL_DATA_INO && inode->i_ino < EXT2_FIRST_INO) ||
336 inode->i_ino > inode->i_sb->u.ext2_sb.s_es->s_inodes_count) {
337 ext2_error (inode->i_sb, "ext2_read_inode",
338 "bad inode number: %lu", inode->i_ino);
339 return;
340 }
341 block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
342 if (block_group >= inode->i_sb->u.ext2_sb.s_groups_count)
343 ext2_panic (inode->i_sb, "ext2_read_inode",
344 "group >= groups count");
345 group_desc = block_group / EXT2_DESC_PER_BLOCK(inode->i_sb);
346 desc = block_group % EXT2_DESC_PER_BLOCK(inode->i_sb);
347 bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];
348 if (!bh)
349 ext2_panic (inode->i_sb, "ext2_read_inode",
350 "Descriptor not loaded");
351 gdp = (struct ext2_group_desc *) bh->b_data;
352 block = gdp[desc].bg_inode_table +
353 (((inode->i_ino - 1) % EXT2_INODES_PER_GROUP(inode->i_sb))
354 / EXT2_INODES_PER_BLOCK(inode->i_sb));
355 if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize)))
356 ext2_panic (inode->i_sb, "ext2_read_inode",
357 "unable to read i-node block\n"
358 "inode=%lu, block=%lu", inode->i_ino, block);
359 raw_inode = ((struct ext2_inode *) bh->b_data) +
360 (inode->i_ino - 1) % EXT2_INODES_PER_BLOCK(inode->i_sb);
361 inode->i_mode = raw_inode->i_mode;
362 inode->i_uid = raw_inode->i_uid;
363 inode->i_gid = raw_inode->i_gid;
364 inode->i_nlink = raw_inode->i_links_count;
365 inode->i_size = raw_inode->i_size;
366 inode->i_atime = raw_inode->i_atime;
367 inode->i_ctime = raw_inode->i_ctime;
368 inode->i_mtime = raw_inode->i_mtime;
369 inode->u.ext2_i.i_dtime = raw_inode->i_dtime;
370 inode->i_blksize = inode->i_sb->s_blocksize;
371 inode->i_blocks = raw_inode->i_blocks;
372 inode->u.ext2_i.i_flags = raw_inode->i_flags;
373 inode->u.ext2_i.i_faddr = raw_inode->i_faddr;
374 inode->u.ext2_i.i_frag = raw_inode->i_frag;
375 inode->u.ext2_i.i_fsize = raw_inode->i_fsize;
376 inode->u.ext2_i.i_file_acl = raw_inode->i_file_acl;
377 inode->u.ext2_i.i_dir_acl = raw_inode->i_dir_acl;
378 inode->u.ext2_i.i_version = raw_inode->i_version;
379 inode->u.ext2_i.i_block_group = block_group;
380 inode->u.ext2_i.i_next_alloc_block = 0;
381 inode->u.ext2_i.i_next_alloc_goal = 0;
382 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
383 inode->i_rdev = raw_inode->i_block[0];
384 else for (block = 0; block < EXT2_N_BLOCKS; block++)
385 inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
386 brelse (bh);
387 inode->i_op = NULL;
388 if (inode->i_ino == EXT2_ACL_IDX_INO ||
389 inode->i_ino == EXT2_ACL_DATA_INO)
390 ;
391 else if (S_ISREG(inode->i_mode))
392 inode->i_op = &ext2_file_inode_operations;
393 else if (S_ISDIR(inode->i_mode))
394 inode->i_op = &ext2_dir_inode_operations;
395 else if (S_ISLNK(inode->i_mode))
396 inode->i_op = &ext2_symlink_inode_operations;
397 else if (S_ISCHR(inode->i_mode))
398 inode->i_op = &chrdev_inode_operations;
399 else if (S_ISBLK(inode->i_mode))
400 inode->i_op = &blkdev_inode_operations;
401 else if (S_ISFIFO(inode->i_mode))
402 init_fifo(inode);
403 if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL)
404 inode->i_flags |= MS_SYNC;
405 }
406
407 static struct buffer_head * ext2_update_inode (struct inode * inode)
408 {
409 struct buffer_head * bh;
410 struct ext2_inode * raw_inode;
411 unsigned long block_group;
412 unsigned long group_desc;
413 unsigned long desc;
414 unsigned long block;
415 struct ext2_group_desc * gdp;
416
417 if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino < EXT2_FIRST_INO) ||
418 inode->i_ino > inode->i_sb->u.ext2_sb.s_es->s_inodes_count) {
419 ext2_error (inode->i_sb, "ext2_write_inode",
420 "bad inode number: %lu", inode->i_ino);
421 return 0;
422 }
423 block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
424 if (block_group >= inode->i_sb->u.ext2_sb.s_groups_count)
425 ext2_panic (inode->i_sb, "ext2_write_inode",
426 "group >= groups count");
427 group_desc = block_group / EXT2_DESC_PER_BLOCK(inode->i_sb);
428 desc = block_group % EXT2_DESC_PER_BLOCK(inode->i_sb);
429 bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];
430 if (!bh)
431 ext2_panic (inode->i_sb, "ext2_write_inode",
432 "Descriptor not loaded");
433 gdp = (struct ext2_group_desc *) bh->b_data;
434 block = gdp[desc].bg_inode_table +
435 (((inode->i_ino - 1) % EXT2_INODES_PER_GROUP(inode->i_sb))
436 / EXT2_INODES_PER_BLOCK(inode->i_sb));
437 if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize)))
438 ext2_panic (inode->i_sb, "ext2_write_inode",
439 "unable to read i-node block\n"
440 "inode=%lu, block=%lu", inode->i_ino, block);
441 raw_inode = ((struct ext2_inode *)bh->b_data) +
442 (inode->i_ino - 1) % EXT2_INODES_PER_BLOCK(inode->i_sb);
443 raw_inode->i_mode = inode->i_mode;
444 raw_inode->i_uid = inode->i_uid;
445 raw_inode->i_gid = inode->i_gid;
446 raw_inode->i_links_count = inode->i_nlink;
447 raw_inode->i_size = inode->i_size;
448 raw_inode->i_atime = inode->i_atime;
449 raw_inode->i_ctime = inode->i_ctime;
450 raw_inode->i_mtime = inode->i_mtime;
451 raw_inode->i_blocks = inode->i_blocks;
452 raw_inode->i_dtime = inode->u.ext2_i.i_dtime;
453 raw_inode->i_flags = inode->u.ext2_i.i_flags;
454 raw_inode->i_faddr = inode->u.ext2_i.i_faddr;
455 raw_inode->i_frag = inode->u.ext2_i.i_frag;
456 raw_inode->i_fsize = inode->u.ext2_i.i_fsize;
457 raw_inode->i_file_acl = inode->u.ext2_i.i_file_acl;
458 raw_inode->i_dir_acl = inode->u.ext2_i.i_dir_acl;
459 raw_inode->i_version = inode->u.ext2_i.i_version;
460 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
461 raw_inode->i_block[0] = inode->i_rdev;
462 else for (block = 0; block < EXT2_N_BLOCKS; block++)
463 raw_inode->i_block[block] = inode->u.ext2_i.i_data[block];
464 bh->b_dirt = 1;
465 inode->i_dirt = 0;
466 return bh;
467 }
468
469 void ext2_write_inode (struct inode * inode)
470 {
471 struct buffer_head * bh;
472 bh = ext2_update_inode (inode);
473 brelse (bh);
474 }
475
476 int ext2_sync_inode (struct inode *inode)
477 {
478 int err = 0;
479 struct buffer_head *bh;
480
481 bh = ext2_update_inode (inode);
482 if (bh && bh->b_dirt)
483 {
484 ll_rw_block (WRITE, 1, &bh);
485 wait_on_buffer (bh);
486 if (bh->b_req && !bh->b_uptodate)
487 {
488 printk ("IO error syncing ext2 inode [%04x:%08lx]\n",
489 inode->i_dev, inode->i_ino);
490 err = -1;
491 }
492 }
493 else if (!bh)
494 err = -1;
495 brelse (bh);
496 return err;
497 }