2 * inode.c --- utility routines to read and write inodes
4 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
7 * This file may be redistributed under the terms of the GNU Library
8 * General Public License, version 2.
26 #include <sys/types.h>
33 #define IBLOCK_STATUS_CSUMS_OK 1
34 #define IBLOCK_STATUS_INSANE 2
35 #define SCAN_BLOCK_STATUS(scan) ((scan)->temp_buffer + (scan)->inode_size)
37 struct ext2_struct_inode_scan
{
40 ext2_ino_t current_inode
;
41 blk64_t current_block
;
43 ext2_ino_t inodes_left
;
46 blk_t inode_buffer_blocks
;
52 errcode_t (*done_group
)(ext2_filsys fs
,
56 void * done_group_data
;
63 * This routine flushes the icache, if it exists.
65 errcode_t
ext2fs_flush_icache(ext2_filsys fs
)
72 for (i
=0; i
< fs
->icache
->cache_size
; i
++)
73 fs
->icache
->cache
[i
].ino
= 0;
75 fs
->icache
->buffer_blk
= 0;
80 * Free the inode cache structure
82 void ext2fs_free_inode_cache(struct ext2_inode_cache
*icache
)
86 if (--icache
->refcount
)
89 ext2fs_free_mem(&icache
->buffer
);
90 for (i
= 0; i
< icache
->cache_size
; i
++)
91 ext2fs_free_mem(&icache
->cache
[i
].inode
);
93 ext2fs_free_mem(&icache
->cache
);
94 icache
->buffer_blk
= 0;
95 ext2fs_free_mem(&icache
);
98 errcode_t
ext2fs_create_inode_cache(ext2_filsys fs
, unsigned int cache_size
)
105 retval
= ext2fs_get_mem(sizeof(struct ext2_inode_cache
), &fs
->icache
);
109 memset(fs
->icache
, 0, sizeof(struct ext2_inode_cache
));
110 retval
= ext2fs_get_mem(fs
->blocksize
, &fs
->icache
->buffer
);
114 fs
->icache
->buffer_blk
= 0;
115 fs
->icache
->cache_last
= -1;
116 fs
->icache
->cache_size
= cache_size
;
117 fs
->icache
->refcount
= 1;
118 retval
= ext2fs_get_array(fs
->icache
->cache_size
,
119 sizeof(struct ext2_inode_cache_ent
),
124 for (i
= 0; i
< fs
->icache
->cache_size
; i
++) {
125 retval
= ext2fs_get_mem(EXT2_INODE_SIZE(fs
->super
),
126 &fs
->icache
->cache
[i
].inode
);
131 ext2fs_flush_icache(fs
);
134 ext2fs_free_inode_cache(fs
->icache
);
139 errcode_t
ext2fs_open_inode_scan(ext2_filsys fs
, int buffer_blocks
,
140 ext2_inode_scan
*ret_scan
)
142 ext2_inode_scan scan
;
144 errcode_t (*save_get_blocks
)(ext2_filsys f
, ext2_ino_t ino
, blk_t
*blocks
);
146 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
149 * If fs->badblocks isn't set, then set it --- since the inode
150 * scanning functions require it.
152 if (fs
->badblocks
== 0) {
154 * Temporarily save fs->get_blocks and set it to zero,
155 * for compatibility with old e2fsck's.
157 save_get_blocks
= fs
->get_blocks
;
159 retval
= ext2fs_read_bb_inode(fs
, &fs
->badblocks
);
160 if (retval
&& fs
->badblocks
) {
161 ext2fs_badblocks_list_free(fs
->badblocks
);
164 fs
->get_blocks
= save_get_blocks
;
167 retval
= ext2fs_get_mem(sizeof(struct ext2_struct_inode_scan
), &scan
);
170 memset(scan
, 0, sizeof(struct ext2_struct_inode_scan
));
172 scan
->magic
= EXT2_ET_MAGIC_INODE_SCAN
;
174 scan
->inode_size
= EXT2_INODE_SIZE(fs
->super
);
175 scan
->bytes_left
= 0;
176 scan
->current_group
= 0;
177 scan
->groups_left
= fs
->group_desc_count
- 1;
178 scan
->inode_buffer_blocks
= buffer_blocks
? buffer_blocks
:
179 EXT2_INODE_SCAN_DEFAULT_BUFFER_BLOCKS
;
180 scan
->current_block
= ext2fs_inode_table_loc(scan
->fs
,
181 scan
->current_group
);
182 if (scan
->current_block
&&
183 ((scan
->current_block
< fs
->super
->s_first_data_block
) ||
184 (scan
->current_block
+ fs
->inode_blocks_per_group
- 1 >=
185 ext2fs_blocks_count(fs
->super
)))) {
186 ext2fs_free_mem(&scan
);
187 return EXT2_ET_GDESC_BAD_INODE_TABLE
;
190 scan
->inodes_left
= EXT2_INODES_PER_GROUP(scan
->fs
->super
);
191 scan
->blocks_left
= scan
->fs
->inode_blocks_per_group
;
192 if (ext2fs_has_group_desc_csum(fs
)) {
193 __u32 unused
= ext2fs_bg_itable_unused(fs
, scan
->current_group
);
194 if (scan
->inodes_left
> unused
)
195 scan
->inodes_left
-= unused
;
197 scan
->inodes_left
= 0;
200 (fs
->blocksize
/ scan
->inode_size
- 1)) *
201 scan
->inode_size
/ fs
->blocksize
;
203 retval
= io_channel_alloc_buf(fs
->io
, scan
->inode_buffer_blocks
,
204 &scan
->inode_buffer
);
205 scan
->done_group
= 0;
206 scan
->done_group_data
= 0;
207 scan
->bad_block_ptr
= 0;
209 ext2fs_free_mem(&scan
);
212 retval
= ext2fs_get_mem(scan
->inode_size
+ scan
->inode_buffer_blocks
,
215 ext2fs_free_mem(&scan
->inode_buffer
);
216 ext2fs_free_mem(&scan
);
219 memset(SCAN_BLOCK_STATUS(scan
), 0, scan
->inode_buffer_blocks
);
220 if (scan
->fs
->badblocks
&& scan
->fs
->badblocks
->num
)
221 scan
->scan_flags
|= EXT2_SF_CHK_BADBLOCKS
;
222 if (ext2fs_has_group_desc_csum(fs
))
223 scan
->scan_flags
|= EXT2_SF_DO_LAZY
;
228 void ext2fs_close_inode_scan(ext2_inode_scan scan
)
230 if (!scan
|| (scan
->magic
!= EXT2_ET_MAGIC_INODE_SCAN
))
233 ext2fs_free_mem(&scan
->inode_buffer
);
234 scan
->inode_buffer
= NULL
;
235 ext2fs_free_mem(&scan
->temp_buffer
);
236 scan
->temp_buffer
= NULL
;
237 ext2fs_free_mem(&scan
);
241 void ext2fs_set_inode_callback(ext2_inode_scan scan
,
242 errcode_t (*done_group
)(ext2_filsys fs
,
243 ext2_inode_scan scan
,
246 void *done_group_data
)
248 if (!scan
|| (scan
->magic
!= EXT2_ET_MAGIC_INODE_SCAN
))
251 scan
->done_group
= done_group
;
252 scan
->done_group_data
= done_group_data
;
255 int ext2fs_inode_scan_flags(ext2_inode_scan scan
, int set_flags
,
260 if (!scan
|| (scan
->magic
!= EXT2_ET_MAGIC_INODE_SCAN
))
263 old_flags
= scan
->scan_flags
;
264 scan
->scan_flags
&= ~clear_flags
;
265 scan
->scan_flags
|= set_flags
;
270 * This function is called by ext2fs_get_next_inode when it needs to
271 * get ready to read in a new blockgroup.
273 static errcode_t
get_next_blockgroup(ext2_inode_scan scan
)
275 ext2_filsys fs
= scan
->fs
;
277 scan
->current_group
++;
280 scan
->current_block
= ext2fs_inode_table_loc(scan
->fs
,
281 scan
->current_group
);
282 scan
->current_inode
= scan
->current_group
*
283 EXT2_INODES_PER_GROUP(fs
->super
);
285 scan
->bytes_left
= 0;
286 scan
->inodes_left
= EXT2_INODES_PER_GROUP(fs
->super
);
287 scan
->blocks_left
= fs
->inode_blocks_per_group
;
288 if (ext2fs_has_group_desc_csum(fs
)) {
289 __u32 unused
= ext2fs_bg_itable_unused(fs
, scan
->current_group
);
290 if (scan
->inodes_left
> unused
)
291 scan
->inodes_left
-= unused
;
293 scan
->inodes_left
= 0;
296 (fs
->blocksize
/ scan
->inode_size
- 1)) *
297 scan
->inode_size
/ fs
->blocksize
;
299 if (scan
->current_block
&&
300 ((scan
->current_block
< fs
->super
->s_first_data_block
) ||
301 (scan
->current_block
+ fs
->inode_blocks_per_group
- 1 >=
302 ext2fs_blocks_count(fs
->super
))))
303 return EXT2_ET_GDESC_BAD_INODE_TABLE
;
307 errcode_t
ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan
,
310 scan
->current_group
= group
- 1;
311 scan
->groups_left
= scan
->fs
->group_desc_count
- group
;
312 scan
->bad_block_ptr
= 0;
313 return get_next_blockgroup(scan
);
317 * This function is called by get_next_blocks() to check for bad
318 * blocks in the inode table.
320 * This function assumes that badblocks_list->list is sorted in
323 static errcode_t
check_for_inode_bad_blocks(ext2_inode_scan scan
,
326 blk64_t blk
= scan
->current_block
;
327 badblocks_list bb
= scan
->fs
->badblocks
;
330 * If the inode table is missing, then obviously there are no
336 /* Make sure bad_block_ptr is still valid */
337 if (scan
->bad_block_ptr
>= bb
->num
) {
338 scan
->scan_flags
&= ~EXT2_SF_CHK_BADBLOCKS
;
343 * If the current block is greater than the bad block listed
344 * in the bad block list, then advance the pointer until this
345 * is no longer the case. If we run out of bad blocks, then
346 * we don't need to do any more checking!
348 while (blk
> bb
->list
[scan
->bad_block_ptr
]) {
349 if (++scan
->bad_block_ptr
>= bb
->num
) {
350 scan
->scan_flags
&= ~EXT2_SF_CHK_BADBLOCKS
;
356 * If the current block is equal to the bad block listed in
357 * the bad block list, then handle that one block specially.
358 * (We could try to handle runs of bad blocks, but that
359 * only increases CPU efficiency by a small amount, at the
360 * expense of a huge expense of code complexity, and for an
361 * uncommon case at that.)
363 if (blk
== bb
->list
[scan
->bad_block_ptr
]) {
364 scan
->scan_flags
|= EXT2_SF_BAD_INODE_BLK
;
366 if (++scan
->bad_block_ptr
>= bb
->num
)
367 scan
->scan_flags
&= ~EXT2_SF_CHK_BADBLOCKS
;
372 * If there is a bad block in the range that we're about to
373 * read in, adjust the number of blocks to read so that we we
374 * don't read in the bad block. (Then the next block to read
375 * will be the bad block, which is handled in the above case.)
377 if ((blk
+ *num_blocks
) > bb
->list
[scan
->bad_block_ptr
])
378 *num_blocks
= (int) (bb
->list
[scan
->bad_block_ptr
] - blk
);
383 static int block_map_looks_insane(ext2_filsys fs
,
384 struct ext2_inode_large
*inode
)
388 /* We're only interested in block mapped files, dirs, and symlinks */
389 if ((inode
->i_flags
& EXT4_INLINE_DATA_FL
) ||
390 (inode
->i_flags
& EXT4_EXTENTS_FL
))
392 if (!LINUX_S_ISREG(inode
->i_mode
) &&
393 !LINUX_S_ISLNK(inode
->i_mode
) &&
394 !LINUX_S_ISDIR(inode
->i_mode
))
396 if (LINUX_S_ISLNK(inode
->i_mode
) &&
397 EXT2_I_SIZE(inode
) <= sizeof(inode
->i_block
))
400 /* Unused inodes probably aren't insane */
401 if (inode
->i_links_count
== 0)
404 /* See if more than half the block maps are insane */
405 for (i
= 0, bad
= 0; i
< EXT2_N_BLOCKS
; i
++)
406 if (inode
->i_block
[i
] != 0 &&
407 (inode
->i_block
[i
] < fs
->super
->s_first_data_block
||
408 inode
->i_block
[i
] >= ext2fs_blocks_count(fs
->super
)))
410 return bad
> EXT2_N_BLOCKS
/ 2;
413 static int extent_head_looks_insane(struct ext2_inode_large
*inode
)
415 if (!(inode
->i_flags
& EXT4_EXTENTS_FL
) ||
416 ext2fs_extent_header_verify(inode
->i_block
,
417 sizeof(inode
->i_block
)) == 0)
423 * Check all the inodes that we just read into the buffer. Record what we
424 * find here -- currently, we can observe that all checksums are ok; more
425 * than half the inodes are insane; or no conclusions at all.
427 static void check_inode_block_sanity(ext2_inode_scan scan
, blk64_t num_blocks
)
429 ext2_ino_t ino
, inodes_to_scan
;
430 unsigned int badness
, checksum_failures
;
431 unsigned int inodes_in_buf
, inodes_per_block
;
433 struct ext2_inode_large
*inode
;
435 unsigned int blk
, bad_csum
;
437 if (!(scan
->scan_flags
& EXT2_SF_WARN_GARBAGE_INODES
))
440 inodes_to_scan
= scan
->inodes_left
;
441 inodes_in_buf
= num_blocks
* scan
->fs
->blocksize
/ scan
->inode_size
;
442 if (inodes_to_scan
> inodes_in_buf
)
443 inodes_to_scan
= inodes_in_buf
;
445 p
= (char *) scan
->inode_buffer
;
446 ino
= scan
->current_inode
+ 1;
447 checksum_failures
= badness
= 0;
448 block_status
= SCAN_BLOCK_STATUS(scan
);
449 memset(block_status
, 0, scan
->inode_buffer_blocks
);
450 inodes_per_block
= EXT2_INODES_PER_BLOCK(scan
->fs
->super
);
452 if (inodes_per_block
< 2)
455 #ifdef WORDS_BIGENDIAN
456 if (ext2fs_get_mem(EXT2_INODE_SIZE(scan
->fs
->super
), &inode
))
460 while (inodes_to_scan
> 0) {
461 blk
= (p
- (char *)scan
->inode_buffer
) / scan
->fs
->blocksize
;
462 bad_csum
= ext2fs_inode_csum_verify(scan
->fs
, ino
,
463 (struct ext2_inode_large
*) p
) == 0;
465 #ifdef WORDS_BIGENDIAN
466 ext2fs_swap_inode_full(scan
->fs
,
467 (struct ext2_inode_large
*) inode
,
468 (struct ext2_inode_large
*) p
,
469 0, EXT2_INODE_SIZE(scan
->fs
->super
));
471 inode
= (struct ext2_inode_large
*) p
;
474 /* Is this inode insane? */
478 } else if (extent_head_looks_insane(inode
) ||
479 block_map_looks_insane(scan
->fs
, inode
))
482 /* If more than half are insane, declare the whole block bad */
483 if (badness
> inodes_per_block
/ 2) {
484 unsigned int ino_adj
;
486 block_status
[blk
] |= IBLOCK_STATUS_INSANE
;
487 ino_adj
= inodes_per_block
-
488 ((ino
- 1) % inodes_per_block
);
489 if (ino_adj
> inodes_to_scan
)
490 ino_adj
= inodes_to_scan
;
491 inodes_to_scan
-= ino_adj
;
492 p
+= scan
->inode_size
* ino_adj
;
494 checksum_failures
= badness
= 0;
498 if ((ino
% inodes_per_block
) == 0) {
499 if (checksum_failures
== 0)
500 block_status
[blk
] |= IBLOCK_STATUS_CSUMS_OK
;
501 checksum_failures
= badness
= 0;
504 p
+= scan
->inode_size
;
508 #ifdef WORDS_BIGENDIAN
509 ext2fs_free_mem(&inode
);
514 * This function is called by ext2fs_get_next_inode when it needs to
515 * read in more blocks from the current blockgroup's inode table.
517 static errcode_t
get_next_blocks(ext2_inode_scan scan
)
523 * Figure out how many blocks to read; we read at most
524 * inode_buffer_blocks, and perhaps less if there aren't that
525 * many blocks left to read.
527 num_blocks
= scan
->inode_buffer_blocks
;
528 if (num_blocks
> scan
->blocks_left
)
529 num_blocks
= scan
->blocks_left
;
532 * If the past block "read" was a bad block, then mark the
533 * left-over extra bytes as also being bad.
535 if (scan
->scan_flags
& EXT2_SF_BAD_INODE_BLK
) {
536 if (scan
->bytes_left
)
537 scan
->scan_flags
|= EXT2_SF_BAD_EXTRA_BYTES
;
538 scan
->scan_flags
&= ~EXT2_SF_BAD_INODE_BLK
;
542 * Do inode bad block processing, if necessary.
544 if (scan
->scan_flags
& EXT2_SF_CHK_BADBLOCKS
) {
545 retval
= check_for_inode_bad_blocks(scan
, &num_blocks
);
550 if ((scan
->scan_flags
& EXT2_SF_BAD_INODE_BLK
) ||
551 (scan
->current_block
== 0)) {
552 memset(scan
->inode_buffer
, 0,
553 (size_t) num_blocks
* scan
->fs
->blocksize
);
555 retval
= io_channel_read_blk64(scan
->fs
->io
,
560 return EXT2_ET_NEXT_INODE_READ
;
562 check_inode_block_sanity(scan
, num_blocks
);
564 scan
->ptr
= scan
->inode_buffer
;
565 scan
->bytes_left
= num_blocks
* scan
->fs
->blocksize
;
567 scan
->blocks_left
-= num_blocks
;
568 if (scan
->current_block
)
569 scan
->current_block
+= num_blocks
;
576 * Returns 1 if the entire inode_buffer has a non-zero size and
577 * contains all zeros. (Not just deleted inodes, since that means
578 * that part of the inode table was used at one point; we want all
579 * zeros, which means that the inode table is pristine.)
581 static inline int is_empty_scan(ext2_inode_scan scan
)
585 if (scan
->bytes_left
== 0)
588 for (i
=0; i
< scan
->bytes_left
; i
++)
595 errcode_t
ext2fs_get_next_inode_full(ext2_inode_scan scan
, ext2_ino_t
*ino
,
596 struct ext2_inode
*inode
, int bufsize
)
601 struct ext2_inode_large
*iptr
= (struct ext2_inode_large
*)inode
;
605 EXT2_CHECK_MAGIC(scan
, EXT2_ET_MAGIC_INODE_SCAN
);
606 length
= EXT2_INODE_SIZE(scan
->fs
->super
);
607 iblock_status
= SCAN_BLOCK_STATUS(scan
);
610 * Do we need to start reading a new block group?
612 if (scan
->inodes_left
<= 0) {
614 if (scan
->done_group
) {
615 retval
= (scan
->done_group
)
616 (scan
->fs
, scan
, scan
->current_group
,
617 scan
->done_group_data
);
621 if (scan
->groups_left
<= 0) {
625 retval
= get_next_blockgroup(scan
);
630 * These checks are done outside the above if statement so
631 * they can be done for block group #0.
633 if ((scan
->scan_flags
& EXT2_SF_DO_LAZY
) &&
634 (ext2fs_bg_flags_test(scan
->fs
, scan
->current_group
, EXT2_BG_INODE_UNINIT
)
636 goto force_new_group
;
637 if (scan
->inodes_left
== 0)
638 goto force_new_group
;
639 if (scan
->current_block
== 0) {
640 if (scan
->scan_flags
& EXT2_SF_SKIP_MISSING_ITABLE
) {
641 goto force_new_group
;
643 return EXT2_ET_MISSING_INODE_TABLE
;
648 * Have we run out of space in the inode buffer? If so, we
649 * need to read in more blocks.
651 if (scan
->bytes_left
< scan
->inode_size
) {
652 if (scan
->bytes_left
)
653 memcpy(scan
->temp_buffer
, scan
->ptr
, scan
->bytes_left
);
654 extra_bytes
= scan
->bytes_left
;
656 retval
= get_next_blocks(scan
);
661 * XXX test Need check for used inode somehow.
662 * (Note: this is hard.)
664 if (is_empty_scan(scan
))
665 goto force_new_group
;
669 if (bufsize
< length
) {
670 retval
= ext2fs_get_mem(length
, &iptr
);
676 iblk
= scan
->current_inode
% EXT2_INODES_PER_GROUP(scan
->fs
->super
) /
677 EXT2_INODES_PER_BLOCK(scan
->fs
->super
) %
678 scan
->inode_buffer_blocks
;
680 memcpy(scan
->temp_buffer
+extra_bytes
, scan
->ptr
,
681 scan
->inode_size
- extra_bytes
);
682 scan
->ptr
+= scan
->inode_size
- extra_bytes
;
683 scan
->bytes_left
-= scan
->inode_size
- extra_bytes
;
685 /* Verify the inode checksum. */
686 if (!(iblock_status
[iblk
] & IBLOCK_STATUS_CSUMS_OK
) &&
687 !(scan
->fs
->flags
& EXT2_FLAG_IGNORE_CSUM_ERRORS
) &&
688 !ext2fs_inode_csum_verify(scan
->fs
, scan
->current_inode
+ 1,
689 (struct ext2_inode_large
*)scan
->temp_buffer
))
690 retval
= EXT2_ET_INODE_CSUM_INVALID
;
692 #ifdef WORDS_BIGENDIAN
693 memset(iptr
, 0, length
);
694 ext2fs_swap_inode_full(scan
->fs
,
695 (struct ext2_inode_large
*) iptr
,
696 (struct ext2_inode_large
*) scan
->temp_buffer
,
699 memcpy(iptr
, scan
->temp_buffer
, length
);
701 if (scan
->scan_flags
& EXT2_SF_BAD_EXTRA_BYTES
)
702 retval
= EXT2_ET_BAD_BLOCK_IN_INODE_TABLE
;
703 scan
->scan_flags
&= ~EXT2_SF_BAD_EXTRA_BYTES
;
705 /* Verify the inode checksum. */
706 if (!(iblock_status
[iblk
] & IBLOCK_STATUS_CSUMS_OK
) &&
707 !(scan
->fs
->flags
& EXT2_FLAG_IGNORE_CSUM_ERRORS
) &&
708 !ext2fs_inode_csum_verify(scan
->fs
, scan
->current_inode
+ 1,
709 (struct ext2_inode_large
*)scan
->ptr
))
710 retval
= EXT2_ET_INODE_CSUM_INVALID
;
712 #ifdef WORDS_BIGENDIAN
713 memset(iptr
, 0, length
);
714 ext2fs_swap_inode_full(scan
->fs
,
715 (struct ext2_inode_large
*) iptr
,
716 (struct ext2_inode_large
*) scan
->ptr
,
719 memcpy(iptr
, scan
->ptr
, length
);
721 scan
->ptr
+= scan
->inode_size
;
722 scan
->bytes_left
-= scan
->inode_size
;
723 if (scan
->scan_flags
& EXT2_SF_BAD_INODE_BLK
)
724 retval
= EXT2_ET_BAD_BLOCK_IN_INODE_TABLE
;
726 if ((iblock_status
[iblk
] & IBLOCK_STATUS_INSANE
) &&
727 (retval
== 0 || retval
== EXT2_ET_INODE_CSUM_INVALID
))
728 retval
= EXT2_ET_INODE_IS_GARBAGE
;
731 scan
->current_inode
++;
732 *ino
= scan
->current_inode
;
733 if (iptr
!= (struct ext2_inode_large
*)inode
) {
734 memcpy(inode
, iptr
, bufsize
);
735 ext2fs_free_mem(&iptr
);
740 errcode_t
ext2fs_get_next_inode(ext2_inode_scan scan
, ext2_ino_t
*ino
,
741 struct ext2_inode
*inode
)
743 return ext2fs_get_next_inode_full(scan
, ino
, inode
,
744 sizeof(struct ext2_inode
));
748 * Functions to read and write a single inode.
750 errcode_t
ext2fs_read_inode2(ext2_filsys fs
, ext2_ino_t ino
,
751 struct ext2_inode
* inode
, int bufsize
,
756 unsigned long block
, offset
;
760 int clen
, inodes_per_block
;
762 int length
= EXT2_INODE_SIZE(fs
->super
);
763 struct ext2_inode_large
*iptr
;
764 int cache_slot
, fail_csum
;
766 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
768 /* Check to see if user has an override function */
769 if (fs
->read_inode
&&
770 ((bufsize
== sizeof(struct ext2_inode
)) ||
771 (EXT2_INODE_SIZE(fs
->super
) == sizeof(struct ext2_inode
)))) {
772 retval
= (fs
->read_inode
)(fs
, ino
, inode
);
773 if (retval
!= EXT2_ET_CALLBACK_NOTHANDLED
)
776 if ((ino
== 0) || (ino
> fs
->super
->s_inodes_count
))
777 return EXT2_ET_BAD_INODE_NUM
;
778 /* Create inode cache if not present */
780 retval
= ext2fs_create_inode_cache(fs
, 4);
784 /* Check to see if it's in the inode cache */
785 for (i
= 0; i
< fs
->icache
->cache_size
; i
++) {
786 if (fs
->icache
->cache
[i
].ino
== ino
) {
787 memcpy(inode
, fs
->icache
->cache
[i
].inode
,
788 (bufsize
> length
) ? length
: bufsize
);
792 if (fs
->flags
& EXT2_FLAG_IMAGE_FILE
) {
793 inodes_per_block
= fs
->blocksize
/ EXT2_INODE_SIZE(fs
->super
);
794 block_nr
= ext2fs_le32_to_cpu(fs
->image_header
->offset_inode
) / fs
->blocksize
;
795 block_nr
+= (ino
- 1) / inodes_per_block
;
796 offset
= ((ino
- 1) % inodes_per_block
) *
797 EXT2_INODE_SIZE(fs
->super
);
800 group
= (ino
- 1) / EXT2_INODES_PER_GROUP(fs
->super
);
801 if (group
> fs
->group_desc_count
)
802 return EXT2_ET_BAD_INODE_NUM
;
803 offset
= ((ino
- 1) % EXT2_INODES_PER_GROUP(fs
->super
)) *
804 EXT2_INODE_SIZE(fs
->super
);
805 block
= offset
>> EXT2_BLOCK_SIZE_BITS(fs
->super
);
806 block_nr
= ext2fs_inode_table_loc(fs
, group
);
808 return EXT2_ET_MISSING_INODE_TABLE
;
809 if ((block_nr
< fs
->super
->s_first_data_block
) ||
810 (block_nr
+ fs
->inode_blocks_per_group
- 1 >=
811 ext2fs_blocks_count(fs
->super
)))
812 return EXT2_ET_GDESC_BAD_INODE_TABLE
;
816 offset
&= (EXT2_BLOCK_SIZE(fs
->super
) - 1);
818 cache_slot
= (fs
->icache
->cache_last
+ 1) % fs
->icache
->cache_size
;
819 iptr
= (struct ext2_inode_large
*)fs
->icache
->cache
[cache_slot
].inode
;
824 if ((offset
+ length
) > fs
->blocksize
)
825 clen
= fs
->blocksize
- offset
;
827 if (block_nr
!= fs
->icache
->buffer_blk
) {
828 retval
= io_channel_read_blk64(io
, block_nr
, 1,
832 fs
->icache
->buffer_blk
= block_nr
;
835 memcpy(ptr
, ((char *) fs
->icache
->buffer
) + (unsigned) offset
,
843 length
= EXT2_INODE_SIZE(fs
->super
);
845 /* Verify the inode checksum. */
846 fail_csum
= !ext2fs_inode_csum_verify(fs
, ino
, iptr
);
848 #ifdef WORDS_BIGENDIAN
849 ext2fs_swap_inode_full(fs
, (struct ext2_inode_large
*) iptr
,
850 (struct ext2_inode_large
*) iptr
,
854 /* Update the inode cache bookkeeping */
856 fs
->icache
->cache_last
= cache_slot
;
857 fs
->icache
->cache
[cache_slot
].ino
= ino
;
859 memcpy(inode
, iptr
, (bufsize
> length
) ? length
: bufsize
);
861 if (!(fs
->flags
& EXT2_FLAG_IGNORE_CSUM_ERRORS
) &&
862 !(flags
& READ_INODE_NOCSUM
) && fail_csum
)
863 return EXT2_ET_INODE_CSUM_INVALID
;
868 errcode_t
ext2fs_read_inode_full(ext2_filsys fs
, ext2_ino_t ino
,
869 struct ext2_inode
* inode
, int bufsize
)
871 return ext2fs_read_inode2(fs
, ino
, inode
, bufsize
, 0);
874 errcode_t
ext2fs_read_inode(ext2_filsys fs
, ext2_ino_t ino
,
875 struct ext2_inode
* inode
)
877 return ext2fs_read_inode2(fs
, ino
, inode
,
878 sizeof(struct ext2_inode
), 0);
881 errcode_t
ext2fs_write_inode2(ext2_filsys fs
, ext2_ino_t ino
,
882 struct ext2_inode
* inode
, int bufsize
,
887 unsigned long block
, offset
;
888 errcode_t retval
= 0;
889 struct ext2_inode_large
*w_inode
;
893 int length
= EXT2_INODE_SIZE(fs
->super
);
895 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
897 /* Check to see if user provided an override function */
898 if (fs
->write_inode
) {
899 retval
= (fs
->write_inode
)(fs
, ino
, inode
);
900 if (retval
!= EXT2_ET_CALLBACK_NOTHANDLED
)
904 if ((ino
== 0) || (ino
> fs
->super
->s_inodes_count
))
905 return EXT2_ET_BAD_INODE_NUM
;
907 /* Prepare our shadow buffer for read/modify/byteswap/write */
908 retval
= ext2fs_get_mem(length
, &w_inode
);
912 if (bufsize
< length
) {
913 retval
= ext2fs_read_inode2(fs
, ino
,
914 (struct ext2_inode
*)w_inode
,
915 length
, READ_INODE_NOCSUM
);
920 /* Check to see if the inode cache needs to be updated */
922 for (i
=0; i
< fs
->icache
->cache_size
; i
++) {
923 if (fs
->icache
->cache
[i
].ino
== ino
) {
924 memcpy(fs
->icache
->cache
[i
].inode
, inode
,
925 (bufsize
> length
) ? length
: bufsize
);
930 retval
= ext2fs_create_inode_cache(fs
, 4);
934 memcpy(w_inode
, inode
, (bufsize
> length
) ? length
: bufsize
);
936 if (!(fs
->flags
& EXT2_FLAG_RW
)) {
937 retval
= EXT2_ET_RO_FILSYS
;
941 #ifdef WORDS_BIGENDIAN
942 ext2fs_swap_inode_full(fs
, w_inode
, w_inode
, 1, length
);
945 if ((flags
& WRITE_INODE_NOCSUM
) == 0) {
946 retval
= ext2fs_inode_csum_set(fs
, ino
, w_inode
);
951 group
= (ino
- 1) / EXT2_INODES_PER_GROUP(fs
->super
);
952 offset
= ((ino
- 1) % EXT2_INODES_PER_GROUP(fs
->super
)) *
953 EXT2_INODE_SIZE(fs
->super
);
954 block
= offset
>> EXT2_BLOCK_SIZE_BITS(fs
->super
);
955 block_nr
= ext2fs_inode_table_loc(fs
, (unsigned) group
);
957 retval
= EXT2_ET_MISSING_INODE_TABLE
;
960 if ((block_nr
< fs
->super
->s_first_data_block
) ||
961 (block_nr
+ fs
->inode_blocks_per_group
- 1 >=
962 ext2fs_blocks_count(fs
->super
))) {
963 retval
= EXT2_ET_GDESC_BAD_INODE_TABLE
;
968 offset
&= (EXT2_BLOCK_SIZE(fs
->super
) - 1);
970 ptr
= (char *) w_inode
;
974 if ((offset
+ length
) > fs
->blocksize
)
975 clen
= fs
->blocksize
- offset
;
977 if (fs
->icache
->buffer_blk
!= block_nr
) {
978 retval
= io_channel_read_blk64(fs
->io
, block_nr
, 1,
982 fs
->icache
->buffer_blk
= block_nr
;
986 memcpy((char *) fs
->icache
->buffer
+ (unsigned) offset
,
989 retval
= io_channel_write_blk64(fs
->io
, block_nr
, 1,
1000 fs
->flags
|= EXT2_FLAG_CHANGED
;
1002 ext2fs_free_mem(&w_inode
);
1006 errcode_t
ext2fs_write_inode_full(ext2_filsys fs
, ext2_ino_t ino
,
1007 struct ext2_inode
* inode
, int bufsize
)
1009 return ext2fs_write_inode2(fs
, ino
, inode
, bufsize
, 0);
1012 errcode_t
ext2fs_write_inode(ext2_filsys fs
, ext2_ino_t ino
,
1013 struct ext2_inode
*inode
)
1015 return ext2fs_write_inode2(fs
, ino
, inode
,
1016 sizeof(struct ext2_inode
), 0);
1020 * This function should be called when writing a new inode. It makes
1021 * sure that extra part of large inodes is initialized properly.
1023 errcode_t
ext2fs_write_new_inode(ext2_filsys fs
, ext2_ino_t ino
,
1024 struct ext2_inode
*inode
)
1026 struct ext2_inode
*buf
;
1027 int size
= EXT2_INODE_SIZE(fs
->super
);
1028 struct ext2_inode_large
*large_inode
;
1030 __u32 t
= fs
->now
? fs
->now
: time(NULL
);
1032 if (!inode
->i_ctime
)
1034 if (!inode
->i_mtime
)
1036 if (!inode
->i_atime
)
1039 if (size
== sizeof(struct ext2_inode
))
1040 return ext2fs_write_inode_full(fs
, ino
, inode
,
1041 sizeof(struct ext2_inode
));
1047 memset(buf
, 0, size
);
1050 large_inode
= (struct ext2_inode_large
*) buf
;
1051 large_inode
->i_extra_isize
= sizeof(struct ext2_inode_large
) -
1052 EXT2_GOOD_OLD_INODE_SIZE
;
1053 if (!large_inode
->i_crtime
)
1054 large_inode
->i_crtime
= t
;
1056 retval
= ext2fs_write_inode_full(fs
, ino
, buf
, size
);
1062 errcode_t
ext2fs_get_blocks(ext2_filsys fs
, ext2_ino_t ino
, blk_t
*blocks
)
1064 struct ext2_inode inode
;
1068 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
1070 if (ino
> fs
->super
->s_inodes_count
)
1071 return EXT2_ET_BAD_INODE_NUM
;
1073 if (fs
->get_blocks
) {
1074 if (!(*fs
->get_blocks
)(fs
, ino
, blocks
))
1077 retval
= ext2fs_read_inode(fs
, ino
, &inode
);
1080 for (i
=0; i
< EXT2_N_BLOCKS
; i
++)
1081 blocks
[i
] = inode
.i_block
[i
];
1085 errcode_t
ext2fs_check_directory(ext2_filsys fs
, ext2_ino_t ino
)
1087 struct ext2_inode inode
;
1090 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
1092 if (ino
> fs
->super
->s_inodes_count
)
1093 return EXT2_ET_BAD_INODE_NUM
;
1095 if (fs
->check_directory
) {
1096 retval
= (fs
->check_directory
)(fs
, ino
);
1097 if (retval
!= EXT2_ET_CALLBACK_NOTHANDLED
)
1100 retval
= ext2fs_read_inode(fs
, ino
, &inode
);
1103 if (!LINUX_S_ISDIR(inode
.i_mode
))
1104 return EXT2_ET_NO_DIRECTORY
;