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 Public
21 #include <sys/types.h>
28 struct ext2_struct_inode_scan {
31 ext2_ino_t current_inode;
34 ext2_ino_t inodes_left;
37 blk_t inode_buffer_blocks;
43 errcode_t (*done_group)(ext2_filsys fs,
47 void * done_group_data;
54 * This routine flushes the icache, if it exists.
56 errcode_t ext2fs_flush_icache(ext2_filsys fs)
63 for (i=0; i < fs->icache->cache_size; i++)
64 fs->icache->cache[i].ino = 0;
69 static errcode_t create_icache(ext2_filsys fs)
75 retval = ext2fs_get_mem(sizeof(struct ext2_inode_cache), &fs->icache);
79 memset(fs->icache, 0, sizeof(struct ext2_inode_cache));
80 retval = ext2fs_get_mem(fs->blocksize, &fs->icache->buffer);
82 ext2fs_free_mem(&fs->icache);
85 fs->icache->buffer_blk = 0;
86 fs->icache->cache_last = -1;
87 fs->icache->cache_size = 4;
88 fs->icache->refcount = 1;
89 retval = ext2fs_get_mem(sizeof(struct ext2_inode_cache_ent)
90 * fs->icache->cache_size,
93 ext2fs_free_mem(&fs->icache->buffer);
94 ext2fs_free_mem(&fs->icache);
97 ext2fs_flush_icache(fs);
101 errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
102 ext2_inode_scan *ret_scan)
104 ext2_inode_scan scan;
106 errcode_t (*save_get_blocks)(ext2_filsys f, ext2_ino_t ino, blk_t *blocks);
108 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
111 * If fs->badblocks isn't set, then set it --- since the inode
112 * scanning functions require it.
114 if (fs->badblocks == 0) {
116 * Temporarly save fs->get_blocks and set it to zero,
117 * for compatibility with old e2fsck's.
119 save_get_blocks = fs->get_blocks;
121 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
122 if (retval && fs->badblocks) {
123 ext2fs_badblocks_list_free(fs->badblocks);
126 fs->get_blocks = save_get_blocks;
129 retval = ext2fs_get_mem(sizeof(struct ext2_struct_inode_scan), &scan);
132 memset(scan, 0, sizeof(struct ext2_struct_inode_scan));
134 scan->magic = EXT2_ET_MAGIC_INODE_SCAN;
136 scan->inode_size = EXT2_INODE_SIZE(fs->super);
137 scan->bytes_left = 0;
138 scan->current_group = 0;
139 scan->groups_left = fs->group_desc_count - 1;
140 scan->inode_buffer_blocks = buffer_blocks ? buffer_blocks : 8;
141 scan->current_block = scan->fs->
142 group_desc[scan->current_group].bg_inode_table;
143 scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
144 scan->blocks_left = scan->fs->inode_blocks_per_group;
145 retval = ext2fs_get_mem((size_t) (scan->inode_buffer_blocks *
147 &scan->inode_buffer);
148 scan->done_group = 0;
149 scan->done_group_data = 0;
150 scan->bad_block_ptr = 0;
152 ext2fs_free_mem(&scan);
155 retval = ext2fs_get_mem(scan->inode_size, &scan->temp_buffer);
157 ext2fs_free_mem(&scan->inode_buffer);
158 ext2fs_free_mem(&scan);
161 if (scan->fs->badblocks && scan->fs->badblocks->num)
162 scan->scan_flags |= EXT2_SF_CHK_BADBLOCKS;
167 void ext2fs_close_inode_scan(ext2_inode_scan scan)
169 if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
172 ext2fs_free_mem(&scan->inode_buffer);
173 scan->inode_buffer = NULL;
174 ext2fs_free_mem(&scan->temp_buffer);
175 scan->temp_buffer = NULL;
176 ext2fs_free_mem(&scan);
180 void ext2fs_set_inode_callback(ext2_inode_scan scan,
181 errcode_t (*done_group)(ext2_filsys fs,
182 ext2_inode_scan scan,
185 void *done_group_data)
187 if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
190 scan->done_group = done_group;
191 scan->done_group_data = done_group_data;
194 int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
199 if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
202 old_flags = scan->scan_flags;
203 scan->scan_flags &= ~clear_flags;
204 scan->scan_flags |= set_flags;
209 * This function is called by ext2fs_get_next_inode when it needs to
210 * get ready to read in a new blockgroup.
212 static errcode_t get_next_blockgroup(ext2_inode_scan scan)
214 scan->current_group++;
217 scan->current_block = scan->fs->
218 group_desc[scan->current_group].bg_inode_table;
220 scan->current_inode = scan->current_group *
221 EXT2_INODES_PER_GROUP(scan->fs->super);
223 scan->bytes_left = 0;
224 scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
225 scan->blocks_left = scan->fs->inode_blocks_per_group;
229 errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan,
232 scan->current_group = group - 1;
233 scan->groups_left = scan->fs->group_desc_count - group;
234 return get_next_blockgroup(scan);
238 * This function is called by get_next_blocks() to check for bad
239 * blocks in the inode table.
241 * This function assumes that badblocks_list->list is sorted in
244 static errcode_t check_for_inode_bad_blocks(ext2_inode_scan scan,
247 blk_t blk = scan->current_block;
248 badblocks_list bb = scan->fs->badblocks;
251 * If the inode table is missing, then obviously there are no
258 * If the current block is greater than the bad block listed
259 * in the bad block list, then advance the pointer until this
260 * is no longer the case. If we run out of bad blocks, then
261 * we don't need to do any more checking!
263 while (blk > bb->list[scan->bad_block_ptr]) {
264 if (++scan->bad_block_ptr >= bb->num) {
265 scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS;
271 * If the current block is equal to the bad block listed in
272 * the bad block list, then handle that one block specially.
273 * (We could try to handle runs of bad blocks, but that
274 * only increases CPU efficiency by a small amount, at the
275 * expense of a huge expense of code complexity, and for an
276 * uncommon case at that.)
278 if (blk == bb->list[scan->bad_block_ptr]) {
279 scan->scan_flags |= EXT2_SF_BAD_INODE_BLK;
281 if (++scan->bad_block_ptr >= bb->num)
282 scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS;
287 * If there is a bad block in the range that we're about to
288 * read in, adjust the number of blocks to read so that we we
289 * don't read in the bad block. (Then the next block to read
290 * will be the bad block, which is handled in the above case.)
292 if ((blk + *num_blocks) > bb->list[scan->bad_block_ptr])
293 *num_blocks = (int) (bb->list[scan->bad_block_ptr] - blk);
299 * This function is called by ext2fs_get_next_inode when it needs to
300 * read in more blocks from the current blockgroup's inode table.
302 static errcode_t get_next_blocks(ext2_inode_scan scan)
308 * Figure out how many blocks to read; we read at most
309 * inode_buffer_blocks, and perhaps less if there aren't that
310 * many blocks left to read.
312 num_blocks = scan->inode_buffer_blocks;
313 if (num_blocks > scan->blocks_left)
314 num_blocks = scan->blocks_left;
317 * If the past block "read" was a bad block, then mark the
318 * left-over extra bytes as also being bad.
320 if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK) {
321 if (scan->bytes_left)
322 scan->scan_flags |= EXT2_SF_BAD_EXTRA_BYTES;
323 scan->scan_flags &= ~EXT2_SF_BAD_INODE_BLK;
327 * Do inode bad block processing, if necessary.
329 if (scan->scan_flags & EXT2_SF_CHK_BADBLOCKS) {
330 retval = check_for_inode_bad_blocks(scan, &num_blocks);
335 if ((scan->scan_flags & EXT2_SF_BAD_INODE_BLK) ||
336 (scan->current_block == 0)) {
337 memset(scan->inode_buffer, 0,
338 (size_t) num_blocks * scan->fs->blocksize);
340 retval = io_channel_read_blk(scan->fs->io,
345 return EXT2_ET_NEXT_INODE_READ;
347 scan->ptr = scan->inode_buffer;
348 scan->bytes_left = num_blocks * scan->fs->blocksize;
350 scan->blocks_left -= num_blocks;
351 if (scan->current_block)
352 scan->current_block += num_blocks;
358 * Returns 1 if the entire inode_buffer has a non-zero size and
359 * contains all zeros. (Not just deleted inodes, since that means
360 * that part of the inode table was used at one point; we want all
361 * zeros, which means that the inode table is pristine.)
363 static inline int is_empty_scan(ext2_inode_scan scan)
367 if (scan->bytes_left == 0)
370 for (i=0; i < scan->bytes_left; i++)
377 errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,
378 struct ext2_inode *inode)
383 EXT2_CHECK_MAGIC(scan, EXT2_ET_MAGIC_INODE_SCAN);
386 * Do we need to start reading a new block group?
388 if (scan->inodes_left <= 0) {
390 if (scan->done_group) {
391 retval = (scan->done_group)
392 (scan->fs, scan, scan->current_group,
393 scan->done_group_data);
397 if (scan->groups_left <= 0) {
401 retval = get_next_blockgroup(scan);
406 * This is done outside the above if statement so that the
407 * check can be done for block group #0.
409 if (scan->current_block == 0) {
410 if (scan->scan_flags & EXT2_SF_SKIP_MISSING_ITABLE) {
411 goto force_new_group;
413 return EXT2_ET_MISSING_INODE_TABLE;
418 * Have we run out of space in the inode buffer? If so, we
419 * need to read in more blocks.
421 if (scan->bytes_left < scan->inode_size) {
422 memcpy(scan->temp_buffer, scan->ptr, scan->bytes_left);
423 extra_bytes = scan->bytes_left;
425 retval = get_next_blocks(scan);
430 * XXX test Need check for used inode somehow.
431 * (Note: this is hard.)
433 if (is_empty_scan(scan))
434 goto force_new_group;
440 memcpy(scan->temp_buffer+extra_bytes, scan->ptr,
441 scan->inode_size - extra_bytes);
442 scan->ptr += scan->inode_size - extra_bytes;
443 scan->bytes_left -= scan->inode_size - extra_bytes;
445 #ifdef EXT2FS_ENABLE_SWAPFS
446 if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
447 (scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
448 ext2fs_swap_inode(scan->fs, inode,
449 (struct ext2_inode *) scan->temp_buffer, 0);
452 *inode = *((struct ext2_inode *) scan->temp_buffer);
453 if (scan->scan_flags & EXT2_SF_BAD_EXTRA_BYTES)
454 retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE;
455 scan->scan_flags &= ~EXT2_SF_BAD_EXTRA_BYTES;
457 #ifdef EXT2FS_ENABLE_SWAPFS
458 if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
459 (scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
460 ext2fs_swap_inode(scan->fs, inode,
461 (struct ext2_inode *) scan->ptr, 0);
464 *inode = *((struct ext2_inode *) scan->ptr);
465 scan->ptr += scan->inode_size;
466 scan->bytes_left -= scan->inode_size;
467 if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK)
468 retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE;
472 scan->current_inode++;
473 *ino = scan->current_inode;
478 * Functions to read and write a single inode.
480 errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
481 struct ext2_inode * inode)
483 unsigned long group, block, block_nr, offset;
486 int clen, i, inodes_per_block;
489 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
491 /* Check to see if user has an override function */
492 if (fs->read_inode) {
493 retval = (fs->read_inode)(fs, ino, inode);
494 if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
497 /* Create inode cache if not present */
499 retval = create_icache(fs);
503 /* Check to see if it's in the inode cache */
504 for (i=0; i < fs->icache->cache_size; i++) {
505 if (fs->icache->cache[i].ino == ino) {
506 *inode = fs->icache->cache[i].inode;
510 if ((ino == 0) || (ino > fs->super->s_inodes_count))
511 return EXT2_ET_BAD_INODE_NUM;
512 if (fs->flags & EXT2_FLAG_IMAGE_FILE) {
513 inodes_per_block = fs->blocksize / EXT2_INODE_SIZE(fs->super);
514 block_nr = fs->image_header->offset_inode / fs->blocksize;
515 block_nr += (ino - 1) / inodes_per_block;
516 offset = ((ino - 1) % inodes_per_block) *
517 EXT2_INODE_SIZE(fs->super);
519 group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
520 offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
521 EXT2_INODE_SIZE(fs->super);
522 block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
523 if (!fs->group_desc[(unsigned)group].bg_inode_table)
524 return EXT2_ET_MISSING_INODE_TABLE;
525 block_nr = fs->group_desc[(unsigned)group].bg_inode_table +
528 if (block_nr != fs->icache->buffer_blk) {
529 retval = io_channel_read_blk(fs->io, block_nr, 1,
533 fs->icache->buffer_blk = block_nr;
535 offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
536 ptr = ((char *) fs->icache->buffer) + (unsigned) offset;
538 memset(inode, 0, sizeof(struct ext2_inode));
539 length = EXT2_INODE_SIZE(fs->super);
540 if (length > sizeof(struct ext2_inode))
541 length = sizeof(struct ext2_inode);
543 if ((offset + length) > (unsigned) EXT2_BLOCK_SIZE(fs->super)) {
544 clen = (int) (EXT2_BLOCK_SIZE(fs->super) - offset);
545 memcpy((char *) inode, ptr, clen);
548 retval = io_channel_read_blk(fs->io, block_nr+1, 1,
551 fs->icache->buffer_blk = 0;
554 fs->icache->buffer_blk = block_nr+1;
556 memcpy(((char *) inode) + clen,
557 fs->icache->buffer, length);
559 memcpy((char *) inode, ptr, length);
561 #ifdef EXT2FS_ENABLE_SWAPFS
562 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
563 (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
564 ext2fs_swap_inode(fs, inode, inode, 0);
567 /* Update the inode cache */
568 fs->icache->cache_last = (fs->icache->cache_last + 1) %
569 fs->icache->cache_size;
570 fs->icache->cache[fs->icache->cache_last].ino = ino;
571 fs->icache->cache[fs->icache->cache_last].inode = *inode;
576 errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
577 struct ext2_inode * inode)
579 unsigned long group, block, block_nr, offset;
581 struct ext2_inode temp_inode;
586 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
588 /* Check to see if user provided an override function */
589 if (fs->write_inode) {
590 retval = (fs->write_inode)(fs, ino, inode);
591 if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
595 /* Check to see if the inode cache needs to be updated */
597 for (i=0; i < fs->icache->cache_size; i++) {
598 if (fs->icache->cache[i].ino == ino) {
599 fs->icache->cache[i].inode = *inode;
604 retval = create_icache(fs);
609 if (!(fs->flags & EXT2_FLAG_RW))
610 return EXT2_ET_RO_FILSYS;
612 if ((ino == 0) || (ino > fs->super->s_inodes_count))
613 return EXT2_ET_BAD_INODE_NUM;
615 #ifdef EXT2FS_ENABLE_SWAPFS
616 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
617 (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
618 ext2fs_swap_inode(fs, &temp_inode, inode, 1);
621 memcpy(&temp_inode, inode, sizeof(struct ext2_inode));
623 group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
624 offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
625 EXT2_INODE_SIZE(fs->super);
626 block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
627 if (!fs->group_desc[(unsigned) group].bg_inode_table)
628 return EXT2_ET_MISSING_INODE_TABLE;
629 block_nr = fs->group_desc[(unsigned) group].bg_inode_table + block;
630 offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
631 ptr = (char *) fs->icache->buffer + (unsigned) offset;
633 length = EXT2_INODE_SIZE(fs->super);
635 if (length > sizeof(struct ext2_inode))
636 length = sizeof(struct ext2_inode);
638 if (fs->icache->buffer_blk != block_nr) {
639 retval = io_channel_read_blk(fs->io, block_nr, 1,
643 fs->icache->buffer_blk = block_nr;
646 if ((offset + length) > (unsigned) EXT2_BLOCK_SIZE(fs->super)) {
647 clen = (int) (EXT2_BLOCK_SIZE(fs->super) - offset);
652 memcpy(ptr, &temp_inode, clen);
653 retval = io_channel_write_blk(fs->io, block_nr, 1, fs->icache->buffer);
658 retval = io_channel_read_blk(fs->io, ++block_nr, 1,
661 fs->icache->buffer_blk = 0;
664 fs->icache->buffer_blk = block_nr;
665 memcpy(fs->icache->buffer, ((char *) &temp_inode) + clen,
668 retval = io_channel_write_blk(fs->io, block_nr, 1,
674 fs->flags |= EXT2_FLAG_CHANGED;
678 errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks)
680 struct ext2_inode inode;
684 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
686 if (ino > fs->super->s_inodes_count)
687 return EXT2_ET_BAD_INODE_NUM;
689 if (fs->get_blocks) {
690 if (!(*fs->get_blocks)(fs, ino, blocks))
693 retval = ext2fs_read_inode(fs, ino, &inode);
696 for (i=0; i < EXT2_N_BLOCKS; i++)
697 blocks[i] = inode.i_block[i];
701 errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino)
703 struct ext2_inode inode;
706 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
708 if (ino > fs->super->s_inodes_count)
709 return EXT2_ET_BAD_INODE_NUM;
711 if (fs->check_directory) {
712 retval = (fs->check_directory)(fs, ino);
713 if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
716 retval = ext2fs_read_inode(fs, ino, &inode);
719 if (!LINUX_S_ISDIR(inode.i_mode))
720 return EXT2_ET_NO_DIRECTORY;