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),
76
(void **) &fs->icache);
80
memset(fs->icache, 0, sizeof(struct ext2_inode_cache));
81
retval = ext2fs_get_mem(fs->blocksize, (void **) &fs->icache->buffer);
83
ext2fs_free_mem((void **) &fs->icache);
86
fs->icache->buffer_blk = 0;
87
fs->icache->cache_last = -1;
88
fs->icache->cache_size = 4;
89
fs->icache->refcount = 1;
90
retval = ext2fs_get_mem(sizeof(struct ext2_inode_cache_ent)
91
* fs->icache->cache_size,
92
(void **) &fs->icache->cache);
94
ext2fs_free_mem((void **) &fs->icache->buffer);
95
ext2fs_free_mem((void **) &fs->icache);
98
ext2fs_flush_icache(fs);
102
errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
103
ext2_inode_scan *ret_scan)
105
ext2_inode_scan scan;
107
errcode_t (*save_get_blocks)(ext2_filsys f, ext2_ino_t ino, blk_t *blocks);
109
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
112
* If fs->badblocks isn't set, then set it --- since the inode
113
* scanning functions require it.
115
if (fs->badblocks == 0) {
117
* Temporarly save fs->get_blocks and set it to zero,
118
* for compatibility with old e2fsck's.
120
save_get_blocks = fs->get_blocks;
122
retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
123
if (retval && fs->badblocks) {
124
ext2fs_badblocks_list_free(fs->badblocks);
127
fs->get_blocks = save_get_blocks;
130
retval = ext2fs_get_mem(sizeof(struct ext2_struct_inode_scan),
134
memset(scan, 0, sizeof(struct ext2_struct_inode_scan));
136
scan->magic = EXT2_ET_MAGIC_INODE_SCAN;
138
scan->inode_size = EXT2_INODE_SIZE(fs->super);
139
scan->bytes_left = 0;
140
scan->current_group = 0;
141
scan->groups_left = fs->group_desc_count - 1;
142
scan->inode_buffer_blocks = buffer_blocks ? buffer_blocks : 8;
143
scan->current_block = scan->fs->
144
group_desc[scan->current_group].bg_inode_table;
145
scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
146
scan->blocks_left = scan->fs->inode_blocks_per_group;
147
retval = ext2fs_get_mem((size_t) (scan->inode_buffer_blocks *
149
(void **) &scan->inode_buffer);
150
scan->done_group = 0;
151
scan->done_group_data = 0;
152
scan->bad_block_ptr = 0;
154
ext2fs_free_mem((void **) &scan);
157
retval = ext2fs_get_mem(scan->inode_size,
158
(void **) &scan->temp_buffer);
160
ext2fs_free_mem((void **) &scan->inode_buffer);
161
ext2fs_free_mem((void **) &scan);
164
if (scan->fs->badblocks && scan->fs->badblocks->num)
165
scan->scan_flags |= EXT2_SF_CHK_BADBLOCKS;
170
void ext2fs_close_inode_scan(ext2_inode_scan scan)
172
if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
175
ext2fs_free_mem((void **) &scan->inode_buffer);
176
scan->inode_buffer = NULL;
177
ext2fs_free_mem((void **) &scan->temp_buffer);
178
scan->temp_buffer = NULL;
179
ext2fs_free_mem((void **) &scan);
183
void ext2fs_set_inode_callback(ext2_inode_scan scan,
184
errcode_t (*done_group)(ext2_filsys fs,
185
ext2_inode_scan scan,
188
void *done_group_data)
190
if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
193
scan->done_group = done_group;
194
scan->done_group_data = done_group_data;
197
int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
202
if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
205
old_flags = scan->scan_flags;
206
scan->scan_flags &= ~clear_flags;
207
scan->scan_flags |= set_flags;
212
* This function is called by ext2fs_get_next_inode when it needs to
213
* get ready to read in a new blockgroup.
215
static errcode_t get_next_blockgroup(ext2_inode_scan scan)
217
scan->current_group++;
220
scan->current_block = scan->fs->
221
group_desc[scan->current_group].bg_inode_table;
223
scan->current_inode = scan->current_group *
224
EXT2_INODES_PER_GROUP(scan->fs->super);
226
scan->bytes_left = 0;
227
scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
228
scan->blocks_left = scan->fs->inode_blocks_per_group;
232
errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan,
235
scan->current_group = group - 1;
236
scan->groups_left = scan->fs->group_desc_count - group;
237
return get_next_blockgroup(scan);
241
* This function is called by get_next_blocks() to check for bad
242
* blocks in the inode table.
244
* This function assumes that badblocks_list->list is sorted in
247
static errcode_t check_for_inode_bad_blocks(ext2_inode_scan scan,
250
blk_t blk = scan->current_block;
251
badblocks_list bb = scan->fs->badblocks;
254
* If the inode table is missing, then obviously there are no
261
* If the current block is greater than the bad block listed
262
* in the bad block list, then advance the pointer until this
263
* is no longer the case. If we run out of bad blocks, then
264
* we don't need to do any more checking!
266
while (blk > bb->list[scan->bad_block_ptr]) {
267
if (++scan->bad_block_ptr >= bb->num) {
268
scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS;
274
* If the current block is equal to the bad block listed in
275
* the bad block list, then handle that one block specially.
276
* (We could try to handle runs of bad blocks, but that
277
* only increases CPU efficiency by a small amount, at the
278
* expense of a huge expense of code complexity, and for an
279
* uncommon case at that.)
281
if (blk == bb->list[scan->bad_block_ptr]) {
282
scan->scan_flags |= EXT2_SF_BAD_INODE_BLK;
284
if (++scan->bad_block_ptr >= bb->num)
285
scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS;
290
* If there is a bad block in the range that we're about to
291
* read in, adjust the number of blocks to read so that we we
292
* don't read in the bad block. (Then the next block to read
293
* will be the bad block, which is handled in the above case.)
295
if ((blk + *num_blocks) > bb->list[scan->bad_block_ptr])
296
*num_blocks = (int) (bb->list[scan->bad_block_ptr] - blk);
302
* This function is called by ext2fs_get_next_inode when it needs to
303
* read in more blocks from the current blockgroup's inode table.
305
static errcode_t get_next_blocks(ext2_inode_scan scan)
311
* Figure out how many blocks to read; we read at most
312
* inode_buffer_blocks, and perhaps less if there aren't that
313
* many blocks left to read.
315
num_blocks = scan->inode_buffer_blocks;
316
if (num_blocks > scan->blocks_left)
317
num_blocks = scan->blocks_left;
320
* If the past block "read" was a bad block, then mark the
321
* left-over extra bytes as also being bad.
323
if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK) {
324
if (scan->bytes_left)
325
scan->scan_flags |= EXT2_SF_BAD_EXTRA_BYTES;
326
scan->scan_flags &= ~EXT2_SF_BAD_INODE_BLK;
330
* Do inode bad block processing, if necessary.
332
if (scan->scan_flags & EXT2_SF_CHK_BADBLOCKS) {
333
retval = check_for_inode_bad_blocks(scan, &num_blocks);
338
if ((scan->scan_flags & EXT2_SF_BAD_INODE_BLK) ||
339
(scan->current_block == 0)) {
340
memset(scan->inode_buffer, 0,
341
(size_t) num_blocks * scan->fs->blocksize);
343
retval = io_channel_read_blk(scan->fs->io,
348
return EXT2_ET_NEXT_INODE_READ;
350
scan->ptr = scan->inode_buffer;
351
scan->bytes_left = num_blocks * scan->fs->blocksize;
353
scan->blocks_left -= num_blocks;
354
if (scan->current_block)
355
scan->current_block += num_blocks;
361
* Returns 1 if the entire inode_buffer has a non-zero size and
362
* contains all zeros. (Not just deleted inodes, since that means
363
* that part of the inode table was used at one point; we want all
364
* zeros, which means that the inode table is pristine.)
366
static inline int is_empty_scan(ext2_inode_scan scan)
370
if (scan->bytes_left == 0)
373
for (i=0; i < scan->bytes_left; i++)
380
errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,
381
struct ext2_inode *inode)
386
EXT2_CHECK_MAGIC(scan, EXT2_ET_MAGIC_INODE_SCAN);
389
* Do we need to start reading a new block group?
391
if (scan->inodes_left <= 0) {
393
if (scan->done_group) {
394
retval = (scan->done_group)
395
(scan->fs, scan, scan->current_group,
396
scan->done_group_data);
400
if (scan->groups_left <= 0) {
404
retval = get_next_blockgroup(scan);
409
* This is done outside the above if statement so that the
410
* check can be done for block group #0.
412
if (scan->current_block == 0) {
413
if (scan->scan_flags & EXT2_SF_SKIP_MISSING_ITABLE) {
414
goto force_new_group;
416
return EXT2_ET_MISSING_INODE_TABLE;
421
* Have we run out of space in the inode buffer? If so, we
422
* need to read in more blocks.
424
if (scan->bytes_left < scan->inode_size) {
425
memcpy(scan->temp_buffer, scan->ptr, scan->bytes_left);
426
extra_bytes = scan->bytes_left;
428
retval = get_next_blocks(scan);
433
* XXX test Need check for used inode somehow.
434
* (Note: this is hard.)
436
if (is_empty_scan(scan))
437
goto force_new_group;
443
memcpy(scan->temp_buffer+extra_bytes, scan->ptr,
444
scan->inode_size - extra_bytes);
445
scan->ptr += scan->inode_size - extra_bytes;
446
scan->bytes_left -= scan->inode_size - extra_bytes;
448
#ifdef EXT2FS_ENABLE_SWAPFS
449
if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
450
(scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
451
ext2fs_swap_inode(scan->fs, inode,
452
(struct ext2_inode *) scan->temp_buffer, 0);
455
*inode = *((struct ext2_inode *) scan->temp_buffer);
456
if (scan->scan_flags & EXT2_SF_BAD_EXTRA_BYTES)
457
retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE;
458
scan->scan_flags &= ~EXT2_SF_BAD_EXTRA_BYTES;
460
#ifdef EXT2FS_ENABLE_SWAPFS
461
if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
462
(scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
463
ext2fs_swap_inode(scan->fs, inode,
464
(struct ext2_inode *) scan->ptr, 0);
467
*inode = *((struct ext2_inode *) scan->ptr);
468
scan->ptr += scan->inode_size;
469
scan->bytes_left -= scan->inode_size;
470
if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK)
471
retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE;
475
scan->current_inode++;
476
*ino = scan->current_inode;
481
* Functions to read and write a single inode.
483
errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
484
struct ext2_inode * inode)
486
unsigned long group, block, block_nr, offset;
489
int clen, length, i, inodes_per_block;
491
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
493
/* Check to see if user has an override function */
494
if (fs->read_inode) {
495
retval = (fs->read_inode)(fs, ino, inode);
496
if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
499
/* Create inode cache if not present */
501
retval = create_icache(fs);
505
/* Check to see if it's in the inode cache */
506
for (i=0; i < fs->icache->cache_size; i++) {
507
if (fs->icache->cache[i].ino == ino) {
508
*inode = fs->icache->cache[i].inode;
512
if ((ino == 0) || (ino > fs->super->s_inodes_count))
513
return EXT2_ET_BAD_INODE_NUM;
514
if (fs->flags & EXT2_FLAG_IMAGE_FILE) {
515
inodes_per_block = fs->blocksize / EXT2_INODE_SIZE(fs->super);
516
block_nr = fs->image_header->offset_inode / fs->blocksize;
517
block_nr += (ino - 1) / inodes_per_block;
518
offset = ((ino - 1) % inodes_per_block) *
519
EXT2_INODE_SIZE(fs->super);
521
group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
522
offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
523
EXT2_INODE_SIZE(fs->super);
524
block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
525
if (!fs->group_desc[(unsigned)group].bg_inode_table)
526
return EXT2_ET_MISSING_INODE_TABLE;
527
block_nr = fs->group_desc[(unsigned)group].bg_inode_table +
530
if (block_nr != fs->icache->buffer_blk) {
531
retval = io_channel_read_blk(fs->io, block_nr, 1,
535
fs->icache->buffer_blk = block_nr;
537
offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
538
ptr = ((char *) fs->icache->buffer) + (unsigned) offset;
540
memset(inode, 0, sizeof(struct ext2_inode));
541
length = EXT2_INODE_SIZE(fs->super);
542
if (length > sizeof(struct ext2_inode))
543
length = sizeof(struct ext2_inode);
545
if ((offset + length) > EXT2_BLOCK_SIZE(fs->super)) {
546
clen = (int) (EXT2_BLOCK_SIZE(fs->super) - offset);
547
memcpy((char *) inode, ptr, clen);
550
retval = io_channel_read_blk(fs->io, block_nr+1, 1,
553
fs->icache->buffer_blk = 0;
556
fs->icache->buffer_blk = block_nr+1;
558
memcpy(((char *) inode) + clen,
559
fs->icache->buffer, length);
561
memcpy((char *) inode, ptr, length);
563
#ifdef EXT2FS_ENABLE_SWAPFS
564
if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
565
(fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
566
ext2fs_swap_inode(fs, inode, inode, 0);
569
/* Update the inode cache */
570
fs->icache->cache_last = (fs->icache->cache_last + 1) %
571
fs->icache->cache_size;
572
fs->icache->cache[fs->icache->cache_last].ino = ino;
573
fs->icache->cache[fs->icache->cache_last].inode = *inode;
578
errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
579
struct ext2_inode * inode)
581
unsigned long group, block, block_nr, offset;
583
struct ext2_inode temp_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;
616
#ifdef EXT2FS_ENABLE_SWAPFS
617
if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
618
(fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
619
ext2fs_swap_inode(fs, &temp_inode, inode, 1);
622
memcpy(&temp_inode, inode, sizeof(struct ext2_inode));
624
group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
625
offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
626
EXT2_INODE_SIZE(fs->super);
627
block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
628
if (!fs->group_desc[(unsigned) group].bg_inode_table)
629
return EXT2_ET_MISSING_INODE_TABLE;
630
block_nr = fs->group_desc[(unsigned) group].bg_inode_table + block;
631
offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
632
ptr = (char *) fs->icache->buffer + (unsigned) offset;
634
length = EXT2_INODE_SIZE(fs->super);
636
if (length > sizeof(struct ext2_inode))
637
length = sizeof(struct ext2_inode);
639
if (fs->icache->buffer_blk != block_nr) {
640
retval = io_channel_read_blk(fs->io, block_nr, 1,
644
fs->icache->buffer_blk = block_nr;
647
if ((offset + length) > EXT2_BLOCK_SIZE(fs->super)) {
648
clen = (int) (EXT2_BLOCK_SIZE(fs->super) - offset);
653
memcpy(ptr, &temp_inode, clen);
654
retval = io_channel_write_blk(fs->io, block_nr, 1, fs->icache->buffer);
659
retval = io_channel_read_blk(fs->io, ++block_nr, 1,
662
fs->icache->buffer_blk = 0;
665
fs->icache->buffer_blk = block_nr;
666
memcpy(fs->icache->buffer, ((char *) &temp_inode) + clen,
669
retval = io_channel_write_blk(fs->io, block_nr, 1,
675
fs->flags |= EXT2_FLAG_CHANGED;
679
errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks)
681
struct ext2_inode inode;
685
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
687
if (ino > fs->super->s_inodes_count)
688
return EXT2_ET_BAD_INODE_NUM;
690
if (fs->get_blocks) {
691
if (!(*fs->get_blocks)(fs, ino, blocks))
694
retval = ext2fs_read_inode(fs, ino, &inode);
697
for (i=0; i < EXT2_N_BLOCKS; i++)
698
blocks[i] = inode.i_block[i];
702
errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino)
704
struct ext2_inode inode;
707
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
709
if (ino > fs->super->s_inodes_count)
710
return EXT2_ET_BAD_INODE_NUM;
712
if (fs->check_directory) {
713
retval = (fs->check_directory)(fs, ino);
714
if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
717
retval = ext2fs_read_inode(fs, ino, &inode);
720
if (!LINUX_S_ISDIR(inode.i_mode))
721
return EXT2_ET_NO_DIRECTORY;