This source file includes following definitions.
- ext2_put_inode
- block_bmap
- ext2_discard_prealloc
- ext2_alloc_block
- ext2_bmap
- inode_getblk
- block_getblk
- block_getcluster
- ext2_getblk
- ext2_getcluster
- 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
16
17 #include <asm/segment.h>
18 #include <asm/system.h>
19
20 #include <linux/errno.h>
21 #include <linux/fs.h>
22 #include <linux/ext2_fs.h>
23 #include <linux/sched.h>
24 #include <linux/stat.h>
25 #include <linux/string.h>
26 #include <linux/locks.h>
27 #include <linux/mm.h>
28
29 void ext2_put_inode (struct inode * inode)
30 {
31 ext2_discard_prealloc (inode);
32 if (inode->i_nlink || inode->i_ino == EXT2_ACL_IDX_INO ||
33 inode->i_ino == EXT2_ACL_DATA_INO)
34 return;
35 inode->i_size = 0;
36 if (inode->i_blocks)
37 ext2_truncate (inode);
38 ext2_free_inode (inode);
39 }
40
41 #define inode_bmap(inode, nr) ((inode)->u.ext2_i.i_data[(nr)])
42
43 static int block_bmap (struct buffer_head * bh, int nr)
44 {
45 int tmp;
46
47 if (!bh)
48 return 0;
49 tmp = ((unsigned long *) bh->b_data)[nr];
50 brelse (bh);
51 return tmp;
52 }
53
54
55
56
57
58
59
60
61 void ext2_discard_prealloc (struct inode * inode)
62 {
63 #ifdef EXT2_PREALLOCATE
64 if (inode->u.ext2_i.i_prealloc_count) {
65 int i = inode->u.ext2_i.i_prealloc_count;
66 inode->u.ext2_i.i_prealloc_count = 0;
67 ext2_free_blocks (inode->i_sb,
68 inode->u.ext2_i.i_prealloc_block,
69 i);
70 }
71 #endif
72 }
73
74 static int ext2_alloc_block (struct inode * inode, unsigned long goal)
75 {
76 #ifdef EXT2FS_DEBUG
77 static unsigned long alloc_hits = 0, alloc_attempts = 0;
78 #endif
79 unsigned long result;
80 struct buffer_head * bh;
81
82 wait_on_super (inode->i_sb);
83
84 #ifdef EXT2_PREALLOCATE
85 if (inode->u.ext2_i.i_prealloc_count &&
86 (goal == inode->u.ext2_i.i_prealloc_block ||
87 goal + 1 == inode->u.ext2_i.i_prealloc_block))
88 {
89 result = inode->u.ext2_i.i_prealloc_block++;
90 inode->u.ext2_i.i_prealloc_count--;
91 ext2_debug ("preallocation hit (%lu/%lu).\n",
92 ++alloc_hits, ++alloc_attempts);
93
94
95
96
97 if (!(bh = getblk (inode->i_sb->s_dev, result,
98 inode->i_sb->s_blocksize))) {
99 ext2_error (inode->i_sb, "ext2_alloc_block",
100 "cannot get block %lu", result);
101 return 0;
102 }
103 memset(bh->b_data, 0, inode->i_sb->s_blocksize);
104 bh->b_uptodate = 1;
105 mark_buffer_dirty(bh, 1);
106 brelse (bh);
107 } else {
108 ext2_discard_prealloc (inode);
109 ext2_debug ("preallocation miss (%lu/%lu).\n",
110 alloc_hits, ++alloc_attempts);
111 if (S_ISREG(inode->i_mode))
112 result = ext2_new_block
113 (inode->i_sb, goal,
114 &inode->u.ext2_i.i_prealloc_count,
115 &inode->u.ext2_i.i_prealloc_block);
116 else
117 result = ext2_new_block (inode->i_sb, goal, 0, 0);
118 }
119 #else
120 result = ext2_new_block (inode->i_sb, goal, 0, 0);
121 #endif
122
123 return result;
124 }
125
126
127 int ext2_bmap (struct inode * inode, int block)
128 {
129 int i;
130 int addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
131
132 if (block < 0) {
133 ext2_warning (inode->i_sb, "ext2_bmap", "block < 0");
134 return 0;
135 }
136 if (block >= EXT2_NDIR_BLOCKS + addr_per_block +
137 addr_per_block * addr_per_block +
138 addr_per_block * addr_per_block * addr_per_block) {
139 ext2_warning (inode->i_sb, "ext2_bmap", "block > big");
140 return 0;
141 }
142 if (block < EXT2_NDIR_BLOCKS)
143 return inode_bmap (inode, block);
144 block -= EXT2_NDIR_BLOCKS;
145 if (block < addr_per_block) {
146 i = inode_bmap (inode, EXT2_IND_BLOCK);
147 if (!i)
148 return 0;
149 return block_bmap (bread (inode->i_dev, i,
150 inode->i_sb->s_blocksize), block);
151 }
152 block -= addr_per_block;
153 if (block < addr_per_block * addr_per_block) {
154 i = inode_bmap (inode, EXT2_DIND_BLOCK);
155 if (!i)
156 return 0;
157 i = block_bmap (bread (inode->i_dev, i,
158 inode->i_sb->s_blocksize),
159 block / addr_per_block);
160 if (!i)
161 return 0;
162 return block_bmap (bread (inode->i_dev, i,
163 inode->i_sb->s_blocksize),
164 block & (addr_per_block - 1));
165 }
166 block -= addr_per_block * addr_per_block;
167 i = inode_bmap (inode, EXT2_TIND_BLOCK);
168 if (!i)
169 return 0;
170 i = block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
171 block / (addr_per_block * addr_per_block));
172 if (!i)
173 return 0;
174 i = block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
175 (block / addr_per_block) & (addr_per_block - 1));
176 if (!i)
177 return 0;
178 return block_bmap (bread (inode->i_dev, i, inode->i_sb->s_blocksize),
179 block & (addr_per_block - 1));
180 }
181
182 static struct buffer_head * inode_getblk (struct inode * inode, int nr,
183 int create, int new_block, int * err)
184 {
185 int tmp, goal = 0;
186 unsigned long * p;
187 struct buffer_head * result;
188 int blocks = inode->i_sb->s_blocksize / 512;
189
190 p = inode->u.ext2_i.i_data + nr;
191 repeat:
192 tmp = *p;
193 if (tmp) {
194 result = getblk (inode->i_dev, tmp, inode->i_sb->s_blocksize);
195 if (tmp == *p)
196 return result;
197 brelse (result);
198 goto repeat;
199 }
200 if (!create || new_block >=
201 (current->rlim[RLIMIT_FSIZE].rlim_cur >>
202 EXT2_BLOCK_SIZE_BITS(inode->i_sb))) {
203 *err = -EFBIG;
204 return NULL;
205 }
206 if (inode->u.ext2_i.i_next_alloc_block == new_block)
207 goal = inode->u.ext2_i.i_next_alloc_goal;
208
209 ext2_debug ("hint = %d,", goal);
210
211 if (!goal) {
212 for (tmp = nr - 1; tmp >= 0; tmp--) {
213 if (inode->u.ext2_i.i_data[tmp]) {
214 goal = inode->u.ext2_i.i_data[tmp];
215 break;
216 }
217 }
218 if (!goal)
219 goal = (inode->u.ext2_i.i_block_group *
220 EXT2_BLOCKS_PER_GROUP(inode->i_sb)) +
221 inode->i_sb->u.ext2_sb.s_es->s_first_data_block;
222 }
223
224 ext2_debug ("goal = %d.\n", goal);
225
226 tmp = ext2_alloc_block (inode, goal);
227 if (!tmp)
228 return NULL;
229 result = getblk (inode->i_dev, tmp, inode->i_sb->s_blocksize);
230 if (*p) {
231 ext2_free_blocks (inode->i_sb, tmp, 1);
232 brelse (result);
233 goto repeat;
234 }
235 *p = tmp;
236 inode->u.ext2_i.i_next_alloc_block = new_block;
237 inode->u.ext2_i.i_next_alloc_goal = tmp;
238 inode->i_ctime = CURRENT_TIME;
239 inode->i_blocks += blocks;
240 if (IS_SYNC(inode) || inode->u.ext2_i.i_osync)
241 ext2_sync_inode (inode);
242 else
243 inode->i_dirt = 1;
244 return result;
245 }
246
247 static struct buffer_head * block_getblk (struct inode * inode,
248 struct buffer_head * bh, int nr,
249 int create, int blocksize,
250 int new_block, int * err)
251 {
252 int tmp, goal = 0;
253 unsigned long * p;
254 struct buffer_head * result;
255 int blocks = inode->i_sb->s_blocksize / 512;
256
257 if (!bh)
258 return NULL;
259 if (!bh->b_uptodate) {
260 ll_rw_block (READ, 1, &bh);
261 wait_on_buffer (bh);
262 if (!bh->b_uptodate) {
263 brelse (bh);
264 return NULL;
265 }
266 }
267 p = (unsigned long *) bh->b_data + nr;
268 repeat:
269 tmp = *p;
270 if (tmp) {
271 result = getblk (bh->b_dev, tmp, blocksize);
272 if (tmp == *p) {
273 brelse (bh);
274 return result;
275 }
276 brelse (result);
277 goto repeat;
278 }
279 if (!create || new_block >=
280 (current->rlim[RLIMIT_FSIZE].rlim_cur >>
281 EXT2_BLOCK_SIZE_BITS(inode->i_sb))) {
282 brelse (bh);
283 *err = -EFBIG;
284 return NULL;
285 }
286 if (inode->u.ext2_i.i_next_alloc_block == new_block)
287 goal = inode->u.ext2_i.i_next_alloc_goal;
288 if (!goal) {
289 for (tmp = nr - 1; tmp >= 0; tmp--) {
290 if (((unsigned long *) bh->b_data)[tmp]) {
291 goal = ((unsigned long *)bh->b_data)[tmp];
292 break;
293 }
294 }
295 if (!goal)
296 goal = bh->b_blocknr;
297 }
298 tmp = ext2_alloc_block (inode, goal);
299 if (!tmp) {
300 brelse (bh);
301 return NULL;
302 }
303 result = getblk (bh->b_dev, tmp, blocksize);
304 if (*p) {
305 ext2_free_blocks (inode->i_sb, tmp, 1);
306 brelse (result);
307 goto repeat;
308 }
309 *p = tmp;
310 mark_buffer_dirty(bh, 1);
311 if (IS_SYNC(inode) || inode->u.ext2_i.i_osync) {
312 ll_rw_block (WRITE, 1, &bh);
313 wait_on_buffer (bh);
314 }
315 inode->i_ctime = CURRENT_TIME;
316 inode->i_blocks += blocks;
317 inode->i_dirt = 1;
318 inode->u.ext2_i.i_next_alloc_block = new_block;
319 inode->u.ext2_i.i_next_alloc_goal = tmp;
320 brelse (bh);
321 return result;
322 }
323
324 static int block_getcluster (struct inode * inode, struct buffer_head * bh,
325 int nr,
326 int blocksize)
327 {
328 unsigned long * p;
329 int firstblock = 0;
330 int result = 0;
331 int i;
332
333
334
335 if(!bh) return 0;
336
337 if(nr % (PAGE_SIZE / inode->i_sb->s_blocksize) != 0) goto out;
338 if(nr + 3 > EXT2_ADDR_PER_BLOCK(inode->i_sb)) goto out;
339
340 for(i=0; i< (PAGE_SIZE / inode->i_sb->s_blocksize); i++) {
341 p = (unsigned long *) bh->b_data + nr + i;
342
343
344 if(*p == 0) goto out;
345
346
347 if(i==0) firstblock = *p;
348 else if(*p != firstblock + i) goto out;
349 };
350
351 p = (unsigned long *) bh->b_data + nr;
352 result = generate_cluster(bh->b_dev, (int *) p, blocksize);
353
354 out:
355 brelse(bh);
356 return result;
357 }
358
359 struct buffer_head * ext2_getblk (struct inode * inode, long block,
360 int create, int * err)
361 {
362 struct buffer_head * bh;
363 unsigned long b;
364 unsigned long addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
365
366 *err = -EIO;
367 if (block < 0) {
368 ext2_warning (inode->i_sb, "ext2_getblk", "block < 0");
369 return NULL;
370 }
371 if (block > EXT2_NDIR_BLOCKS + addr_per_block +
372 addr_per_block * addr_per_block +
373 addr_per_block * addr_per_block * addr_per_block) {
374 ext2_warning (inode->i_sb, "ext2_getblk", "block > big");
375 return NULL;
376 }
377
378
379
380
381
382
383 ext2_debug ("block %lu, next %lu, goal %lu.\n", block,
384 inode->u.ext2_i.i_next_alloc_block,
385 inode->u.ext2_i.i_next_alloc_goal);
386
387 if (block == inode->u.ext2_i.i_next_alloc_block + 1) {
388 inode->u.ext2_i.i_next_alloc_block++;
389 inode->u.ext2_i.i_next_alloc_goal++;
390 }
391
392 *err = -ENOSPC;
393 b = block;
394 if (block < EXT2_NDIR_BLOCKS)
395 return inode_getblk (inode, block, create, b, err);
396 block -= EXT2_NDIR_BLOCKS;
397 if (block < addr_per_block) {
398 bh = inode_getblk (inode, EXT2_IND_BLOCK, create, b, err);
399 return block_getblk (inode, bh, block, create,
400 inode->i_sb->s_blocksize, b, err);
401 }
402 block -= addr_per_block;
403 if (block < addr_per_block * addr_per_block) {
404 bh = inode_getblk (inode, EXT2_DIND_BLOCK, create, b, err);
405 bh = block_getblk (inode, bh, block / addr_per_block, create,
406 inode->i_sb->s_blocksize, b, err);
407 return block_getblk (inode, bh, block & (addr_per_block - 1),
408 create, inode->i_sb->s_blocksize, b, err);
409 }
410 block -= addr_per_block * addr_per_block;
411 bh = inode_getblk (inode, EXT2_TIND_BLOCK, create, b, err);
412 bh = block_getblk (inode, bh, block/(addr_per_block * addr_per_block),
413 create, inode->i_sb->s_blocksize, b, err);
414 bh = block_getblk (inode, bh, (block/addr_per_block) & (addr_per_block - 1),
415 create, inode->i_sb->s_blocksize, b, err);
416 return block_getblk (inode, bh, block & (addr_per_block - 1), create,
417 inode->i_sb->s_blocksize, b, err);
418 }
419
420 int ext2_getcluster (struct inode * inode, long block)
421 {
422 struct buffer_head * bh;
423 int err, create;
424 unsigned long b;
425 unsigned long addr_per_block = EXT2_ADDR_PER_BLOCK(inode->i_sb);
426
427 create = 0;
428 err = -EIO;
429 if (block < 0) {
430 ext2_warning (inode->i_sb, "ext2_getblk", "block < 0");
431 return 0;
432 }
433 if (block > EXT2_NDIR_BLOCKS + addr_per_block +
434 addr_per_block * addr_per_block +
435 addr_per_block * addr_per_block * addr_per_block) {
436 ext2_warning (inode->i_sb, "ext2_getblk", "block > big");
437 return 0;
438 }
439
440 err = -ENOSPC;
441 b = block;
442 if (block < EXT2_NDIR_BLOCKS) return 0;
443
444 block -= EXT2_NDIR_BLOCKS;
445
446 if (block < addr_per_block) {
447 bh = inode_getblk (inode, EXT2_IND_BLOCK, create, b, &err);
448 return block_getcluster (inode, bh, block,
449 inode->i_sb->s_blocksize);
450 }
451 block -= addr_per_block;
452 if (block < addr_per_block * addr_per_block) {
453 bh = inode_getblk (inode, EXT2_DIND_BLOCK, create, b, &err);
454 bh = block_getblk (inode, bh, block / addr_per_block, create,
455 inode->i_sb->s_blocksize, b, &err);
456 return block_getcluster (inode, bh, block & (addr_per_block - 1),
457 inode->i_sb->s_blocksize);
458 }
459 block -= addr_per_block * addr_per_block;
460 bh = inode_getblk (inode, EXT2_TIND_BLOCK, create, b, &err);
461 bh = block_getblk (inode, bh, block/(addr_per_block * addr_per_block),
462 create, inode->i_sb->s_blocksize, b, &err);
463 bh = block_getblk (inode, bh, (block/addr_per_block) & (addr_per_block - 1),
464 create, inode->i_sb->s_blocksize, b, &err);
465 return block_getcluster (inode, bh, block & (addr_per_block - 1),
466 inode->i_sb->s_blocksize);
467 }
468
469 struct buffer_head * ext2_bread (struct inode * inode, int block,
470 int create, int *err)
471 {
472 struct buffer_head * bh;
473
474 bh = ext2_getblk (inode, block, create, err);
475 if (!bh || bh->b_uptodate)
476 return bh;
477 ll_rw_block (READ, 1, &bh);
478 wait_on_buffer (bh);
479 if (bh->b_uptodate)
480 return bh;
481 brelse (bh);
482 *err = -EIO;
483 return NULL;
484 }
485
486 void ext2_read_inode (struct inode * inode)
487 {
488 struct buffer_head * bh;
489 struct ext2_inode * raw_inode;
490 unsigned long block_group;
491 unsigned long group_desc;
492 unsigned long desc;
493 unsigned long block;
494 struct ext2_group_desc * gdp;
495
496 if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino != EXT2_ACL_IDX_INO &&
497 inode->i_ino != EXT2_ACL_DATA_INO && inode->i_ino < EXT2_FIRST_INO) ||
498 inode->i_ino > inode->i_sb->u.ext2_sb.s_es->s_inodes_count) {
499 ext2_error (inode->i_sb, "ext2_read_inode",
500 "bad inode number: %lu", inode->i_ino);
501 return;
502 }
503 block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
504 if (block_group >= inode->i_sb->u.ext2_sb.s_groups_count)
505 ext2_panic (inode->i_sb, "ext2_read_inode",
506 "group >= groups count");
507 group_desc = block_group / EXT2_DESC_PER_BLOCK(inode->i_sb);
508 desc = block_group % EXT2_DESC_PER_BLOCK(inode->i_sb);
509 bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];
510 if (!bh)
511 ext2_panic (inode->i_sb, "ext2_read_inode",
512 "Descriptor not loaded");
513 gdp = (struct ext2_group_desc *) bh->b_data;
514 block = gdp[desc].bg_inode_table +
515 (((inode->i_ino - 1) % EXT2_INODES_PER_GROUP(inode->i_sb))
516 / EXT2_INODES_PER_BLOCK(inode->i_sb));
517 if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize)))
518 ext2_panic (inode->i_sb, "ext2_read_inode",
519 "unable to read i-node block - "
520 "inode=%lu, block=%lu", inode->i_ino, block);
521 raw_inode = ((struct ext2_inode *) bh->b_data) +
522 (inode->i_ino - 1) % EXT2_INODES_PER_BLOCK(inode->i_sb);
523 inode->i_mode = raw_inode->i_mode;
524 inode->i_uid = raw_inode->i_uid;
525 inode->i_gid = raw_inode->i_gid;
526 inode->i_nlink = raw_inode->i_links_count;
527 inode->i_size = raw_inode->i_size;
528 inode->i_atime = raw_inode->i_atime;
529 inode->i_ctime = raw_inode->i_ctime;
530 inode->i_mtime = raw_inode->i_mtime;
531 inode->u.ext2_i.i_dtime = raw_inode->i_dtime;
532 inode->i_blksize = inode->i_sb->s_blocksize;
533 inode->i_blocks = raw_inode->i_blocks;
534 inode->i_version = ++event;
535 inode->u.ext2_i.i_flags = raw_inode->i_flags;
536 inode->u.ext2_i.i_faddr = raw_inode->i_faddr;
537 inode->u.ext2_i.i_frag_no = raw_inode->i_frag;
538 inode->u.ext2_i.i_frag_size = raw_inode->i_fsize;
539 inode->u.ext2_i.i_osync = 0;
540 inode->u.ext2_i.i_file_acl = raw_inode->i_file_acl;
541 inode->u.ext2_i.i_dir_acl = raw_inode->i_dir_acl;
542 inode->u.ext2_i.i_version = raw_inode->i_version;
543 inode->u.ext2_i.i_block_group = block_group;
544 inode->u.ext2_i.i_next_alloc_block = 0;
545 inode->u.ext2_i.i_next_alloc_goal = 0;
546 if (inode->u.ext2_i.i_prealloc_count)
547 ext2_error (inode->i_sb, "ext2_read_inode",
548 "New inode has non-zero prealloc count!");
549 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
550 inode->i_rdev = raw_inode->i_block[0];
551 else for (block = 0; block < EXT2_N_BLOCKS; block++)
552 inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];
553 brelse (bh);
554 inode->i_op = NULL;
555 if (inode->i_ino == EXT2_ACL_IDX_INO ||
556 inode->i_ino == EXT2_ACL_DATA_INO)
557 ;
558 else if (S_ISREG(inode->i_mode))
559 inode->i_op = &ext2_file_inode_operations;
560 else if (S_ISDIR(inode->i_mode))
561 inode->i_op = &ext2_dir_inode_operations;
562 else if (S_ISLNK(inode->i_mode))
563 inode->i_op = &ext2_symlink_inode_operations;
564 else if (S_ISCHR(inode->i_mode))
565 inode->i_op = &chrdev_inode_operations;
566 else if (S_ISBLK(inode->i_mode))
567 inode->i_op = &blkdev_inode_operations;
568 else if (S_ISFIFO(inode->i_mode))
569 init_fifo(inode);
570 if (inode->u.ext2_i.i_flags & EXT2_SYNC_FL)
571 inode->i_flags |= MS_SYNCHRONOUS;
572 if (inode->u.ext2_i.i_flags & EXT2_APPEND_FL)
573 inode->i_flags |= S_APPEND;
574 if (inode->u.ext2_i.i_flags & EXT2_IMMUTABLE_FL)
575 inode->i_flags |= S_IMMUTABLE;
576 }
577
578 static struct buffer_head * ext2_update_inode (struct inode * inode)
579 {
580 struct buffer_head * bh;
581 struct ext2_inode * raw_inode;
582 unsigned long block_group;
583 unsigned long group_desc;
584 unsigned long desc;
585 unsigned long block;
586 struct ext2_group_desc * gdp;
587
588 if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino < EXT2_FIRST_INO) ||
589 inode->i_ino > inode->i_sb->u.ext2_sb.s_es->s_inodes_count) {
590 ext2_error (inode->i_sb, "ext2_write_inode",
591 "bad inode number: %lu", inode->i_ino);
592 return 0;
593 }
594 block_group = (inode->i_ino - 1) / EXT2_INODES_PER_GROUP(inode->i_sb);
595 if (block_group >= inode->i_sb->u.ext2_sb.s_groups_count)
596 ext2_panic (inode->i_sb, "ext2_write_inode",
597 "group >= groups count");
598 group_desc = block_group / EXT2_DESC_PER_BLOCK(inode->i_sb);
599 desc = block_group % EXT2_DESC_PER_BLOCK(inode->i_sb);
600 bh = inode->i_sb->u.ext2_sb.s_group_desc[group_desc];
601 if (!bh)
602 ext2_panic (inode->i_sb, "ext2_write_inode",
603 "Descriptor not loaded");
604 gdp = (struct ext2_group_desc *) bh->b_data;
605 block = gdp[desc].bg_inode_table +
606 (((inode->i_ino - 1) % EXT2_INODES_PER_GROUP(inode->i_sb))
607 / EXT2_INODES_PER_BLOCK(inode->i_sb));
608 if (!(bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize)))
609 ext2_panic (inode->i_sb, "ext2_write_inode",
610 "unable to read i-node block - "
611 "inode=%lu, block=%lu", inode->i_ino, block);
612 raw_inode = ((struct ext2_inode *)bh->b_data) +
613 (inode->i_ino - 1) % EXT2_INODES_PER_BLOCK(inode->i_sb);
614 raw_inode->i_mode = inode->i_mode;
615 raw_inode->i_uid = inode->i_uid;
616 raw_inode->i_gid = inode->i_gid;
617 raw_inode->i_links_count = inode->i_nlink;
618 raw_inode->i_size = inode->i_size;
619 raw_inode->i_atime = inode->i_atime;
620 raw_inode->i_ctime = inode->i_ctime;
621 raw_inode->i_mtime = inode->i_mtime;
622 raw_inode->i_blocks = inode->i_blocks;
623 raw_inode->i_dtime = inode->u.ext2_i.i_dtime;
624 raw_inode->i_flags = inode->u.ext2_i.i_flags;
625 raw_inode->i_faddr = inode->u.ext2_i.i_faddr;
626 raw_inode->i_frag = inode->u.ext2_i.i_frag_no;
627 raw_inode->i_fsize = inode->u.ext2_i.i_frag_size;
628 raw_inode->i_file_acl = inode->u.ext2_i.i_file_acl;
629 raw_inode->i_dir_acl = inode->u.ext2_i.i_dir_acl;
630 raw_inode->i_version = inode->u.ext2_i.i_version;
631 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
632 raw_inode->i_block[0] = inode->i_rdev;
633 else for (block = 0; block < EXT2_N_BLOCKS; block++)
634 raw_inode->i_block[block] = inode->u.ext2_i.i_data[block];
635 mark_buffer_dirty(bh, 1);
636 inode->i_dirt = 0;
637 return bh;
638 }
639
640 void ext2_write_inode (struct inode * inode)
641 {
642 struct buffer_head * bh;
643 bh = ext2_update_inode (inode);
644 brelse (bh);
645 }
646
647 int ext2_sync_inode (struct inode *inode)
648 {
649 int err = 0;
650 struct buffer_head *bh;
651
652 bh = ext2_update_inode (inode);
653 if (bh && bh->b_dirt)
654 {
655 ll_rw_block (WRITE, 1, &bh);
656 wait_on_buffer (bh);
657 if (bh->b_req && !bh->b_uptodate)
658 {
659 printk ("IO error syncing ext2 inode [%04x:%08lx]\n",
660 inode->i_dev, inode->i_ino);
661 err = -1;
662 }
663 }
664 else if (!bh)
665 err = -1;
666 brelse (bh);
667 return err;
668 }