1 /* vi: set sw=4 ts=4: */
3 * inode.c --- utility routines to read and write inodes
5 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
8 * This file may be redistributed under the terms of the GNU Public
25 #include <sys/types.h>
32 struct ext2_struct_inode_scan
{
35 ext2_ino_t current_inode
;
38 ext2_ino_t inodes_left
;
41 blk_t inode_buffer_blocks
;
47 errcode_t (*done_group
)(ext2_filsys fs
,
50 void * done_group_data
;
57 * This routine flushes the icache, if it exists.
59 errcode_t
ext2fs_flush_icache(ext2_filsys fs
)
66 for (i
=0; i
< fs
->icache
->cache_size
; i
++)
67 fs
->icache
->cache
[i
].ino
= 0;
69 fs
->icache
->buffer_blk
= 0;
73 static errcode_t
create_icache(ext2_filsys fs
)
79 retval
= ext2fs_get_mem(sizeof(struct ext2_inode_cache
), &fs
->icache
);
83 memset(fs
->icache
, 0, sizeof(struct ext2_inode_cache
));
84 retval
= ext2fs_get_mem(fs
->blocksize
, &fs
->icache
->buffer
);
86 ext2fs_free_mem(&fs
->icache
);
89 fs
->icache
->buffer_blk
= 0;
90 fs
->icache
->cache_last
= -1;
91 fs
->icache
->cache_size
= 4;
92 fs
->icache
->refcount
= 1;
93 retval
= ext2fs_get_mem(sizeof(struct ext2_inode_cache_ent
)
94 * fs
->icache
->cache_size
,
97 ext2fs_free_mem(&fs
->icache
->buffer
);
98 ext2fs_free_mem(&fs
->icache
);
101 ext2fs_flush_icache(fs
);
105 errcode_t
ext2fs_open_inode_scan(ext2_filsys fs
, int buffer_blocks
,
106 ext2_inode_scan
*ret_scan
)
108 ext2_inode_scan scan
;
110 errcode_t (*save_get_blocks
)(ext2_filsys f
, ext2_ino_t ino
, blk_t
*blocks
);
112 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
115 * If fs->badblocks isn't set, then set it --- since the inode
116 * scanning functions require it.
118 if (fs
->badblocks
== 0) {
120 * Temporarly save fs->get_blocks and set it to zero,
121 * for compatibility with old e2fsck's.
123 save_get_blocks
= fs
->get_blocks
;
125 retval
= ext2fs_read_bb_inode(fs
, &fs
->badblocks
);
127 ext2fs_badblocks_list_free(fs
->badblocks
);
130 fs
->get_blocks
= save_get_blocks
;
133 retval
= ext2fs_get_mem(sizeof(struct ext2_struct_inode_scan
), &scan
);
136 memset(scan
, 0, sizeof(struct ext2_struct_inode_scan
));
138 scan
->magic
= EXT2_ET_MAGIC_INODE_SCAN
;
140 scan
->inode_size
= EXT2_INODE_SIZE(fs
->super
);
141 scan
->bytes_left
= 0;
142 scan
->current_group
= 0;
143 scan
->groups_left
= fs
->group_desc_count
- 1;
144 scan
->inode_buffer_blocks
= buffer_blocks
? buffer_blocks
: 8;
145 scan
->current_block
= scan
->fs
->
146 group_desc
[scan
->current_group
].bg_inode_table
;
147 scan
->inodes_left
= EXT2_INODES_PER_GROUP(scan
->fs
->super
);
148 scan
->blocks_left
= scan
->fs
->inode_blocks_per_group
;
149 retval
= ext2fs_get_mem((size_t) (scan
->inode_buffer_blocks
*
151 &scan
->inode_buffer
);
152 scan
->done_group
= 0;
153 scan
->done_group_data
= 0;
154 scan
->bad_block_ptr
= 0;
156 ext2fs_free_mem(&scan
);
159 retval
= ext2fs_get_mem(scan
->inode_size
, &scan
->temp_buffer
);
161 ext2fs_free_mem(&scan
->inode_buffer
);
162 ext2fs_free_mem(&scan
);
165 if (scan
->fs
->badblocks
&& scan
->fs
->badblocks
->num
)
166 scan
->scan_flags
|= EXT2_SF_CHK_BADBLOCKS
;
171 void ext2fs_close_inode_scan(ext2_inode_scan scan
)
173 if (!scan
|| (scan
->magic
!= EXT2_ET_MAGIC_INODE_SCAN
))
176 ext2fs_free_mem(&scan
->inode_buffer
);
177 scan
->inode_buffer
= NULL
;
178 ext2fs_free_mem(&scan
->temp_buffer
);
179 scan
->temp_buffer
= NULL
;
180 ext2fs_free_mem(&scan
);
183 void ext2fs_set_inode_callback(ext2_inode_scan scan
,
184 errcode_t (*done_group
)(ext2_filsys fs
,
187 void *done_group_data
)
189 if (!scan
|| (scan
->magic
!= EXT2_ET_MAGIC_INODE_SCAN
))
192 scan
->done_group
= done_group
;
193 scan
->done_group_data
= done_group_data
;
196 int ext2fs_inode_scan_flags(ext2_inode_scan scan
, int set_flags
,
201 if (!scan
|| (scan
->magic
!= EXT2_ET_MAGIC_INODE_SCAN
))
204 old_flags
= scan
->scan_flags
;
205 scan
->scan_flags
&= ~clear_flags
;
206 scan
->scan_flags
|= set_flags
;
211 * This function is called by ext2fs_get_next_inode when it needs to
212 * get ready to read in a new blockgroup.
214 static errcode_t
get_next_blockgroup(ext2_inode_scan scan
)
216 scan
->current_group
++;
219 scan
->current_block
= scan
->fs
->
220 group_desc
[scan
->current_group
].bg_inode_table
;
222 scan
->current_inode
= scan
->current_group
*
223 EXT2_INODES_PER_GROUP(scan
->fs
->super
);
225 scan
->bytes_left
= 0;
226 scan
->inodes_left
= EXT2_INODES_PER_GROUP(scan
->fs
->super
);
227 scan
->blocks_left
= scan
->fs
->inode_blocks_per_group
;
231 errcode_t
ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan
,
234 scan
->current_group
= group
- 1;
235 scan
->groups_left
= scan
->fs
->group_desc_count
- group
;
236 return get_next_blockgroup(scan
);
240 * This function is called by get_next_blocks() to check for bad
241 * blocks in the inode table.
243 * This function assumes that badblocks_list->list is sorted in
246 static errcode_t
check_for_inode_bad_blocks(ext2_inode_scan scan
,
249 blk_t blk
= scan
->current_block
;
250 badblocks_list bb
= scan
->fs
->badblocks
;
253 * If the inode table is missing, then obviously there are no
260 * If the current block is greater than the bad block listed
261 * in the bad block list, then advance the pointer until this
262 * is no longer the case. If we run out of bad blocks, then
263 * we don't need to do any more checking!
265 while (blk
> bb
->list
[scan
->bad_block_ptr
]) {
266 if (++scan
->bad_block_ptr
>= bb
->num
) {
267 scan
->scan_flags
&= ~EXT2_SF_CHK_BADBLOCKS
;
273 * If the current block is equal to the bad block listed in
274 * the bad block list, then handle that one block specially.
275 * (We could try to handle runs of bad blocks, but that
276 * only increases CPU efficiency by a small amount, at the
277 * expense of a huge expense of code complexity, and for an
278 * uncommon case at that.)
280 if (blk
== bb
->list
[scan
->bad_block_ptr
]) {
281 scan
->scan_flags
|= EXT2_SF_BAD_INODE_BLK
;
283 if (++scan
->bad_block_ptr
>= bb
->num
)
284 scan
->scan_flags
&= ~EXT2_SF_CHK_BADBLOCKS
;
289 * If there is a bad block in the range that we're about to
290 * read in, adjust the number of blocks to read so that we we
291 * don't read in the bad block. (Then the next block to read
292 * will be the bad block, which is handled in the above case.)
294 if ((blk
+ *num_blocks
) > bb
->list
[scan
->bad_block_ptr
])
295 *num_blocks
= (int) (bb
->list
[scan
->bad_block_ptr
] - blk
);
301 * This function is called by ext2fs_get_next_inode when it needs to
302 * read in more blocks from the current blockgroup's inode table.
304 static errcode_t
get_next_blocks(ext2_inode_scan scan
)
310 * Figure out how many blocks to read; we read at most
311 * inode_buffer_blocks, and perhaps less if there aren't that
312 * many blocks left to read.
314 num_blocks
= scan
->inode_buffer_blocks
;
315 if (num_blocks
> scan
->blocks_left
)
316 num_blocks
= scan
->blocks_left
;
319 * If the past block "read" was a bad block, then mark the
320 * left-over extra bytes as also being bad.
322 if (scan
->scan_flags
& EXT2_SF_BAD_INODE_BLK
) {
323 if (scan
->bytes_left
)
324 scan
->scan_flags
|= EXT2_SF_BAD_EXTRA_BYTES
;
325 scan
->scan_flags
&= ~EXT2_SF_BAD_INODE_BLK
;
329 * Do inode bad block processing, if necessary.
331 if (scan
->scan_flags
& EXT2_SF_CHK_BADBLOCKS
) {
332 retval
= check_for_inode_bad_blocks(scan
, &num_blocks
);
337 if ((scan
->scan_flags
& EXT2_SF_BAD_INODE_BLK
) ||
338 (scan
->current_block
== 0)) {
339 memset(scan
->inode_buffer
, 0,
340 (size_t) num_blocks
* scan
->fs
->blocksize
);
342 retval
= io_channel_read_blk(scan
->fs
->io
,
347 return EXT2_ET_NEXT_INODE_READ
;
349 scan
->ptr
= scan
->inode_buffer
;
350 scan
->bytes_left
= num_blocks
* scan
->fs
->blocksize
;
352 scan
->blocks_left
-= num_blocks
;
353 if (scan
->current_block
)
354 scan
->current_block
+= num_blocks
;
358 errcode_t
ext2fs_get_next_inode_full(ext2_inode_scan scan
, ext2_ino_t
*ino
,
359 struct ext2_inode
*inode
, int bufsize
)
364 EXT2_CHECK_MAGIC(scan
, EXT2_ET_MAGIC_INODE_SCAN
);
367 * Do we need to start reading a new block group?
369 if (scan
->inodes_left
<= 0) {
371 if (scan
->done_group
) {
372 retval
= (scan
->done_group
)
373 (scan
->fs
, scan
->current_group
,
374 scan
->done_group_data
);
378 if (scan
->groups_left
<= 0) {
382 retval
= get_next_blockgroup(scan
);
387 * This is done outside the above if statement so that the
388 * check can be done for block group #0.
390 if (scan
->current_block
== 0) {
391 if (scan
->scan_flags
& EXT2_SF_SKIP_MISSING_ITABLE
) {
392 goto force_new_group
;
394 return EXT2_ET_MISSING_INODE_TABLE
;
399 * Have we run out of space in the inode buffer? If so, we
400 * need to read in more blocks.
402 if (scan
->bytes_left
< scan
->inode_size
) {
403 memcpy(scan
->temp_buffer
, scan
->ptr
, scan
->bytes_left
);
404 extra_bytes
= scan
->bytes_left
;
406 retval
= get_next_blocks(scan
);
411 * XXX test Need check for used inode somehow.
412 * (Note: this is hard.)
414 if (is_empty_scan(scan
))
415 goto force_new_group
;
421 memcpy(scan
->temp_buffer
+extra_bytes
, scan
->ptr
,
422 scan
->inode_size
- extra_bytes
);
423 scan
->ptr
+= scan
->inode_size
- extra_bytes
;
424 scan
->bytes_left
-= scan
->inode_size
- extra_bytes
;
427 if ((scan
->fs
->flags
& EXT2_FLAG_SWAP_BYTES
) ||
428 (scan
->fs
->flags
& EXT2_FLAG_SWAP_BYTES_READ
))
429 ext2fs_swap_inode_full(scan
->fs
,
430 (struct ext2_inode_large
*) inode
,
431 (struct ext2_inode_large
*) scan
->temp_buffer
,
435 *inode
= *((struct ext2_inode
*) scan
->temp_buffer
);
436 if (scan
->scan_flags
& EXT2_SF_BAD_EXTRA_BYTES
)
437 retval
= EXT2_ET_BAD_BLOCK_IN_INODE_TABLE
;
438 scan
->scan_flags
&= ~EXT2_SF_BAD_EXTRA_BYTES
;
441 if ((scan
->fs
->flags
& EXT2_FLAG_SWAP_BYTES
) ||
442 (scan
->fs
->flags
& EXT2_FLAG_SWAP_BYTES_READ
))
443 ext2fs_swap_inode_full(scan
->fs
,
444 (struct ext2_inode_large
*) inode
,
445 (struct ext2_inode_large
*) scan
->ptr
,
449 memcpy(inode
, scan
->ptr
, bufsize
);
450 scan
->ptr
+= scan
->inode_size
;
451 scan
->bytes_left
-= scan
->inode_size
;
452 if (scan
->scan_flags
& EXT2_SF_BAD_INODE_BLK
)
453 retval
= EXT2_ET_BAD_BLOCK_IN_INODE_TABLE
;
457 scan
->current_inode
++;
458 *ino
= scan
->current_inode
;
462 errcode_t
ext2fs_get_next_inode(ext2_inode_scan scan
, ext2_ino_t
*ino
,
463 struct ext2_inode
*inode
)
465 return ext2fs_get_next_inode_full(scan
, ino
, inode
,
466 sizeof(struct ext2_inode
));
470 * Functions to read and write a single inode.
472 errcode_t
ext2fs_read_inode_full(ext2_filsys fs
, ext2_ino_t ino
,
473 struct ext2_inode
* inode
, int bufsize
)
475 unsigned long group
, block
, block_nr
, offset
;
478 int clen
, i
, inodes_per_block
, length
;
481 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
483 /* Check to see if user has an override function */
484 if (fs
->read_inode
) {
485 retval
= (fs
->read_inode
)(fs
, ino
, inode
);
486 if (retval
!= EXT2_ET_CALLBACK_NOTHANDLED
)
489 /* Create inode cache if not present */
491 retval
= create_icache(fs
);
495 /* Check to see if it's in the inode cache */
496 if (bufsize
== sizeof(struct ext2_inode
)) {
497 /* only old good inode can be retrieve from the cache */
498 for (i
=0; i
< fs
->icache
->cache_size
; i
++) {
499 if (fs
->icache
->cache
[i
].ino
== ino
) {
500 *inode
= fs
->icache
->cache
[i
].inode
;
505 if ((ino
== 0) || (ino
> fs
->super
->s_inodes_count
))
506 return EXT2_ET_BAD_INODE_NUM
;
507 if (fs
->flags
& EXT2_FLAG_IMAGE_FILE
) {
508 inodes_per_block
= fs
->blocksize
/ EXT2_INODE_SIZE(fs
->super
);
509 block_nr
= fs
->image_header
->offset_inode
/ fs
->blocksize
;
510 block_nr
+= (ino
- 1) / inodes_per_block
;
511 offset
= ((ino
- 1) % inodes_per_block
) *
512 EXT2_INODE_SIZE(fs
->super
);
515 group
= (ino
- 1) / EXT2_INODES_PER_GROUP(fs
->super
);
516 offset
= ((ino
- 1) % EXT2_INODES_PER_GROUP(fs
->super
)) *
517 EXT2_INODE_SIZE(fs
->super
);
518 block
= offset
>> EXT2_BLOCK_SIZE_BITS(fs
->super
);
519 if (!fs
->group_desc
[(unsigned)group
].bg_inode_table
)
520 return EXT2_ET_MISSING_INODE_TABLE
;
521 block_nr
= fs
->group_desc
[(unsigned)group
].bg_inode_table
+
525 offset
&= (EXT2_BLOCK_SIZE(fs
->super
) - 1);
527 length
= EXT2_INODE_SIZE(fs
->super
);
528 if (bufsize
< length
)
531 ptr
= (char *) inode
;
534 if ((offset
+ length
) > fs
->blocksize
)
535 clen
= fs
->blocksize
- offset
;
537 if (block_nr
!= fs
->icache
->buffer_blk
) {
538 retval
= io_channel_read_blk(io
, block_nr
, 1,
542 fs
->icache
->buffer_blk
= block_nr
;
545 memcpy(ptr
, ((char *) fs
->icache
->buffer
) + (unsigned) offset
,
555 if ((fs
->flags
& EXT2_FLAG_SWAP_BYTES
) ||
556 (fs
->flags
& EXT2_FLAG_SWAP_BYTES_READ
))
557 ext2fs_swap_inode_full(fs
, (struct ext2_inode_large
*) inode
,
558 (struct ext2_inode_large
*) inode
,
562 /* Update the inode cache */
563 fs
->icache
->cache_last
= (fs
->icache
->cache_last
+ 1) %
564 fs
->icache
->cache_size
;
565 fs
->icache
->cache
[fs
->icache
->cache_last
].ino
= ino
;
566 fs
->icache
->cache
[fs
->icache
->cache_last
].inode
= *inode
;
571 errcode_t
ext2fs_read_inode(ext2_filsys fs
, ext2_ino_t ino
,
572 struct ext2_inode
* inode
)
574 return ext2fs_read_inode_full(fs
, ino
, inode
,
575 sizeof(struct ext2_inode
));
578 errcode_t
ext2fs_write_inode_full(ext2_filsys fs
, ext2_ino_t ino
,
579 struct ext2_inode
* inode
, int bufsize
)
581 unsigned long group
, block
, block_nr
, offset
;
582 errcode_t retval
= 0;
583 struct ext2_inode_large temp_inode
, *w_inode
;
587 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
589 /* Check to see if user provided an override function */
590 if (fs
->write_inode
) {
591 retval
= (fs
->write_inode
)(fs
, ino
, inode
);
592 if (retval
!= EXT2_ET_CALLBACK_NOTHANDLED
)
596 /* Check to see if the inode cache needs to be updated */
598 for (i
=0; i
< fs
->icache
->cache_size
; i
++) {
599 if (fs
->icache
->cache
[i
].ino
== ino
) {
600 fs
->icache
->cache
[i
].inode
= *inode
;
605 retval
= create_icache(fs
);
610 if (!(fs
->flags
& EXT2_FLAG_RW
))
611 return EXT2_ET_RO_FILSYS
;
613 if ((ino
== 0) || (ino
> fs
->super
->s_inodes_count
))
614 return EXT2_ET_BAD_INODE_NUM
;
617 if (length
< EXT2_INODE_SIZE(fs
->super
))
618 length
= EXT2_INODE_SIZE(fs
->super
);
620 if (length
> (int) sizeof(struct ext2_inode_large
)) {
621 w_inode
= xmalloc(length
);
623 w_inode
= &temp_inode
;
624 memset(w_inode
, 0, length
);
627 if ((fs
->flags
& EXT2_FLAG_SWAP_BYTES
) ||
628 (fs
->flags
& EXT2_FLAG_SWAP_BYTES_WRITE
))
629 ext2fs_swap_inode_full(fs
, w_inode
,
630 (struct ext2_inode_large
*) inode
,
634 memcpy(w_inode
, inode
, bufsize
);
636 group
= (ino
- 1) / EXT2_INODES_PER_GROUP(fs
->super
);
637 offset
= ((ino
- 1) % EXT2_INODES_PER_GROUP(fs
->super
)) *
638 EXT2_INODE_SIZE(fs
->super
);
639 block
= offset
>> EXT2_BLOCK_SIZE_BITS(fs
->super
);
640 if (!fs
->group_desc
[(unsigned) group
].bg_inode_table
)
641 return EXT2_ET_MISSING_INODE_TABLE
;
642 block_nr
= fs
->group_desc
[(unsigned) group
].bg_inode_table
+ block
;
644 offset
&= (EXT2_BLOCK_SIZE(fs
->super
) - 1);
646 length
= EXT2_INODE_SIZE(fs
->super
);
647 if (length
> bufsize
)
650 ptr
= (char *) w_inode
;
654 if ((offset
+ length
) > fs
->blocksize
)
655 clen
= fs
->blocksize
- offset
;
657 if (fs
->icache
->buffer_blk
!= block_nr
) {
658 retval
= io_channel_read_blk(fs
->io
, block_nr
, 1,
662 fs
->icache
->buffer_blk
= block_nr
;
666 memcpy((char *) fs
->icache
->buffer
+ (unsigned) offset
,
669 retval
= io_channel_write_blk(fs
->io
, block_nr
, 1,
680 fs
->flags
|= EXT2_FLAG_CHANGED
;
682 if (w_inode
&& w_inode
!= &temp_inode
)
687 errcode_t
ext2fs_write_inode(ext2_filsys fs
, ext2_ino_t ino
,
688 struct ext2_inode
*inode
)
690 return ext2fs_write_inode_full(fs
, ino
, inode
,
691 sizeof(struct ext2_inode
));
695 * This function should be called when writing a new inode. It makes
696 * sure that extra part of large inodes is initialized properly.
698 errcode_t
ext2fs_write_new_inode(ext2_filsys fs
, ext2_ino_t ino
,
699 struct ext2_inode
*inode
)
701 struct ext2_inode
*buf
;
702 int size
= EXT2_INODE_SIZE(fs
->super
);
703 struct ext2_inode_large
*large_inode
;
705 if (size
== sizeof(struct ext2_inode
))
706 return ext2fs_write_inode_full(fs
, ino
, inode
,
707 sizeof(struct ext2_inode
));
711 memset(buf
, 0, size
);
714 large_inode
= (struct ext2_inode_large
*) buf
;
715 large_inode
->i_extra_isize
= sizeof(struct ext2_inode_large
) -
716 EXT2_GOOD_OLD_INODE_SIZE
;
718 return ext2fs_write_inode_full(fs
, ino
, buf
, size
);
722 errcode_t
ext2fs_get_blocks(ext2_filsys fs
, ext2_ino_t ino
, blk_t
*blocks
)
724 struct ext2_inode inode
;
728 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
730 if (ino
> fs
->super
->s_inodes_count
)
731 return EXT2_ET_BAD_INODE_NUM
;
733 if (fs
->get_blocks
) {
734 if (!(*fs
->get_blocks
)(fs
, ino
, blocks
))
737 retval
= ext2fs_read_inode(fs
, ino
, &inode
);
740 for (i
=0; i
< EXT2_N_BLOCKS
; i
++)
741 blocks
[i
] = inode
.i_block
[i
];
745 errcode_t
ext2fs_check_directory(ext2_filsys fs
, ext2_ino_t ino
)
747 struct ext2_inode inode
;
750 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
752 if (ino
> fs
->super
->s_inodes_count
)
753 return EXT2_ET_BAD_INODE_NUM
;
755 if (fs
->check_directory
) {
756 retval
= (fs
->check_directory
)(fs
, ino
);
757 if (retval
!= EXT2_ET_CALLBACK_NOTHANDLED
)
760 retval
= ext2fs_read_inode(fs
, ino
, &inode
);
763 if (!LINUX_S_ISDIR(inode
.i_mode
))
764 return EXT2_ET_NO_DIRECTORY
;