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 struct ext2_struct_inode_scan
{
36 ext2_ino_t current_inode
;
37 blk64_t current_block
;
39 ext2_ino_t inodes_left
;
42 blk_t inode_buffer_blocks
;
48 errcode_t (*done_group
)(ext2_filsys fs
,
52 void * done_group_data
;
59 * This routine flushes the icache, if it exists.
61 errcode_t
ext2fs_flush_icache(ext2_filsys fs
)
68 for (i
=0; i
< fs
->icache
->cache_size
; i
++)
69 fs
->icache
->cache
[i
].ino
= 0;
71 fs
->icache
->buffer_blk
= 0;
76 * Free the inode cache structure
78 void ext2fs_free_inode_cache(struct ext2_inode_cache
*icache
)
82 if (--icache
->refcount
)
85 ext2fs_free_mem(&icache
->buffer
);
86 for (i
= 0; i
< icache
->cache_size
; i
++)
87 ext2fs_free_mem(&icache
->cache
[i
].inode
);
89 ext2fs_free_mem(&icache
->cache
);
90 icache
->buffer_blk
= 0;
91 ext2fs_free_mem(&icache
);
94 static errcode_t
create_icache(ext2_filsys fs
)
101 retval
= ext2fs_get_mem(sizeof(struct ext2_inode_cache
), &fs
->icache
);
105 memset(fs
->icache
, 0, sizeof(struct ext2_inode_cache
));
106 retval
= ext2fs_get_mem(fs
->blocksize
, &fs
->icache
->buffer
);
110 fs
->icache
->buffer_blk
= 0;
111 fs
->icache
->cache_last
= -1;
112 fs
->icache
->cache_size
= 4;
113 fs
->icache
->refcount
= 1;
114 retval
= ext2fs_get_array(fs
->icache
->cache_size
,
115 sizeof(struct ext2_inode_cache_ent
),
120 for (i
= 0; i
< fs
->icache
->cache_size
; i
++) {
121 retval
= ext2fs_get_mem(EXT2_INODE_SIZE(fs
->super
),
122 &fs
->icache
->cache
[i
].inode
);
127 ext2fs_flush_icache(fs
);
130 ext2fs_free_inode_cache(fs
->icache
);
135 errcode_t
ext2fs_open_inode_scan(ext2_filsys fs
, int buffer_blocks
,
136 ext2_inode_scan
*ret_scan
)
138 ext2_inode_scan scan
;
140 errcode_t (*save_get_blocks
)(ext2_filsys f
, ext2_ino_t ino
, blk_t
*blocks
);
142 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
145 * If fs->badblocks isn't set, then set it --- since the inode
146 * scanning functions require it.
148 if (fs
->badblocks
== 0) {
150 * Temporarly save fs->get_blocks and set it to zero,
151 * for compatibility with old e2fsck's.
153 save_get_blocks
= fs
->get_blocks
;
155 retval
= ext2fs_read_bb_inode(fs
, &fs
->badblocks
);
156 if (retval
&& fs
->badblocks
) {
157 ext2fs_badblocks_list_free(fs
->badblocks
);
160 fs
->get_blocks
= save_get_blocks
;
163 retval
= ext2fs_get_mem(sizeof(struct ext2_struct_inode_scan
), &scan
);
166 memset(scan
, 0, sizeof(struct ext2_struct_inode_scan
));
168 scan
->magic
= EXT2_ET_MAGIC_INODE_SCAN
;
170 scan
->inode_size
= EXT2_INODE_SIZE(fs
->super
);
171 scan
->bytes_left
= 0;
172 scan
->current_group
= 0;
173 scan
->groups_left
= fs
->group_desc_count
- 1;
174 scan
->inode_buffer_blocks
= buffer_blocks
? buffer_blocks
: 8;
175 scan
->current_block
= ext2fs_inode_table_loc(scan
->fs
,
176 scan
->current_group
);
177 scan
->inodes_left
= EXT2_INODES_PER_GROUP(scan
->fs
->super
);
178 scan
->blocks_left
= scan
->fs
->inode_blocks_per_group
;
179 if (ext2fs_has_group_desc_csum(fs
)) {
181 ext2fs_bg_itable_unused(fs
, scan
->current_group
);
184 (fs
->blocksize
/ scan
->inode_size
- 1)) *
185 scan
->inode_size
/ fs
->blocksize
;
187 retval
= io_channel_alloc_buf(fs
->io
, scan
->inode_buffer_blocks
,
188 &scan
->inode_buffer
);
189 scan
->done_group
= 0;
190 scan
->done_group_data
= 0;
191 scan
->bad_block_ptr
= 0;
193 ext2fs_free_mem(&scan
);
196 retval
= ext2fs_get_mem(scan
->inode_size
, &scan
->temp_buffer
);
198 ext2fs_free_mem(&scan
->inode_buffer
);
199 ext2fs_free_mem(&scan
);
202 if (scan
->fs
->badblocks
&& scan
->fs
->badblocks
->num
)
203 scan
->scan_flags
|= EXT2_SF_CHK_BADBLOCKS
;
204 if (ext2fs_has_group_desc_csum(fs
))
205 scan
->scan_flags
|= EXT2_SF_DO_LAZY
;
210 void ext2fs_close_inode_scan(ext2_inode_scan scan
)
212 if (!scan
|| (scan
->magic
!= EXT2_ET_MAGIC_INODE_SCAN
))
215 ext2fs_free_mem(&scan
->inode_buffer
);
216 scan
->inode_buffer
= NULL
;
217 ext2fs_free_mem(&scan
->temp_buffer
);
218 scan
->temp_buffer
= NULL
;
219 ext2fs_free_mem(&scan
);
223 void ext2fs_set_inode_callback(ext2_inode_scan scan
,
224 errcode_t (*done_group
)(ext2_filsys fs
,
225 ext2_inode_scan scan
,
228 void *done_group_data
)
230 if (!scan
|| (scan
->magic
!= EXT2_ET_MAGIC_INODE_SCAN
))
233 scan
->done_group
= done_group
;
234 scan
->done_group_data
= done_group_data
;
237 int ext2fs_inode_scan_flags(ext2_inode_scan scan
, int set_flags
,
242 if (!scan
|| (scan
->magic
!= EXT2_ET_MAGIC_INODE_SCAN
))
245 old_flags
= scan
->scan_flags
;
246 scan
->scan_flags
&= ~clear_flags
;
247 scan
->scan_flags
|= set_flags
;
252 * This function is called by ext2fs_get_next_inode when it needs to
253 * get ready to read in a new blockgroup.
255 static errcode_t
get_next_blockgroup(ext2_inode_scan scan
)
257 ext2_filsys fs
= scan
->fs
;
259 scan
->current_group
++;
262 scan
->current_block
= ext2fs_inode_table_loc(scan
->fs
,
263 scan
->current_group
);
264 scan
->current_inode
= scan
->current_group
*
265 EXT2_INODES_PER_GROUP(fs
->super
);
267 scan
->bytes_left
= 0;
268 scan
->inodes_left
= EXT2_INODES_PER_GROUP(fs
->super
);
269 scan
->blocks_left
= fs
->inode_blocks_per_group
;
270 if (ext2fs_has_group_desc_csum(fs
)) {
272 ext2fs_bg_itable_unused(fs
, scan
->current_group
);
275 (fs
->blocksize
/ scan
->inode_size
- 1)) *
276 scan
->inode_size
/ fs
->blocksize
;
282 errcode_t
ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan
,
285 scan
->current_group
= group
- 1;
286 scan
->groups_left
= scan
->fs
->group_desc_count
- group
;
287 return get_next_blockgroup(scan
);
291 * This function is called by get_next_blocks() to check for bad
292 * blocks in the inode table.
294 * This function assumes that badblocks_list->list is sorted in
297 static errcode_t
check_for_inode_bad_blocks(ext2_inode_scan scan
,
300 blk64_t blk
= scan
->current_block
;
301 badblocks_list bb
= scan
->fs
->badblocks
;
304 * If the inode table is missing, then obviously there are no
311 * If the current block is greater than the bad block listed
312 * in the bad block list, then advance the pointer until this
313 * is no longer the case. If we run out of bad blocks, then
314 * we don't need to do any more checking!
316 while (blk
> bb
->list
[scan
->bad_block_ptr
]) {
317 if (++scan
->bad_block_ptr
>= bb
->num
) {
318 scan
->scan_flags
&= ~EXT2_SF_CHK_BADBLOCKS
;
324 * If the current block is equal to the bad block listed in
325 * the bad block list, then handle that one block specially.
326 * (We could try to handle runs of bad blocks, but that
327 * only increases CPU efficiency by a small amount, at the
328 * expense of a huge expense of code complexity, and for an
329 * uncommon case at that.)
331 if (blk
== bb
->list
[scan
->bad_block_ptr
]) {
332 scan
->scan_flags
|= EXT2_SF_BAD_INODE_BLK
;
334 if (++scan
->bad_block_ptr
>= bb
->num
)
335 scan
->scan_flags
&= ~EXT2_SF_CHK_BADBLOCKS
;
340 * If there is a bad block in the range that we're about to
341 * read in, adjust the number of blocks to read so that we we
342 * don't read in the bad block. (Then the next block to read
343 * will be the bad block, which is handled in the above case.)
345 if ((blk
+ *num_blocks
) > bb
->list
[scan
->bad_block_ptr
])
346 *num_blocks
= (int) (bb
->list
[scan
->bad_block_ptr
] - blk
);
352 * This function is called by ext2fs_get_next_inode when it needs to
353 * read in more blocks from the current blockgroup's inode table.
355 static errcode_t
get_next_blocks(ext2_inode_scan scan
)
361 * Figure out how many blocks to read; we read at most
362 * inode_buffer_blocks, and perhaps less if there aren't that
363 * many blocks left to read.
365 num_blocks
= scan
->inode_buffer_blocks
;
366 if (num_blocks
> scan
->blocks_left
)
367 num_blocks
= scan
->blocks_left
;
370 * If the past block "read" was a bad block, then mark the
371 * left-over extra bytes as also being bad.
373 if (scan
->scan_flags
& EXT2_SF_BAD_INODE_BLK
) {
374 if (scan
->bytes_left
)
375 scan
->scan_flags
|= EXT2_SF_BAD_EXTRA_BYTES
;
376 scan
->scan_flags
&= ~EXT2_SF_BAD_INODE_BLK
;
380 * Do inode bad block processing, if necessary.
382 if (scan
->scan_flags
& EXT2_SF_CHK_BADBLOCKS
) {
383 retval
= check_for_inode_bad_blocks(scan
, &num_blocks
);
388 if ((scan
->scan_flags
& EXT2_SF_BAD_INODE_BLK
) ||
389 (scan
->current_block
== 0)) {
390 memset(scan
->inode_buffer
, 0,
391 (size_t) num_blocks
* scan
->fs
->blocksize
);
393 retval
= io_channel_read_blk64(scan
->fs
->io
,
398 return EXT2_ET_NEXT_INODE_READ
;
400 scan
->ptr
= scan
->inode_buffer
;
401 scan
->bytes_left
= num_blocks
* scan
->fs
->blocksize
;
403 scan
->blocks_left
-= num_blocks
;
404 if (scan
->current_block
)
405 scan
->current_block
+= num_blocks
;
411 * Returns 1 if the entire inode_buffer has a non-zero size and
412 * contains all zeros. (Not just deleted inodes, since that means
413 * that part of the inode table was used at one point; we want all
414 * zeros, which means that the inode table is pristine.)
416 static inline int is_empty_scan(ext2_inode_scan scan
)
420 if (scan
->bytes_left
== 0)
423 for (i
=0; i
< scan
->bytes_left
; i
++)
430 errcode_t
ext2fs_get_next_inode_full(ext2_inode_scan scan
, ext2_ino_t
*ino
,
431 struct ext2_inode
*inode
, int bufsize
)
435 const int length
= EXT2_INODE_SIZE(scan
->fs
->super
);
436 struct ext2_inode_large
*iptr
= (struct ext2_inode_large
*)inode
;
438 EXT2_CHECK_MAGIC(scan
, EXT2_ET_MAGIC_INODE_SCAN
);
441 * Do we need to start reading a new block group?
443 if (scan
->inodes_left
<= 0) {
445 if (scan
->done_group
) {
446 retval
= (scan
->done_group
)
447 (scan
->fs
, scan
, scan
->current_group
,
448 scan
->done_group_data
);
452 if (scan
->groups_left
<= 0) {
456 retval
= get_next_blockgroup(scan
);
461 * These checks are done outside the above if statement so
462 * they can be done for block group #0.
464 if ((scan
->scan_flags
& EXT2_SF_DO_LAZY
) &&
465 (ext2fs_bg_flags_test(scan
->fs
, scan
->current_group
, EXT2_BG_INODE_UNINIT
)
467 goto force_new_group
;
468 if (scan
->inodes_left
== 0)
469 goto force_new_group
;
470 if (scan
->current_block
== 0) {
471 if (scan
->scan_flags
& EXT2_SF_SKIP_MISSING_ITABLE
) {
472 goto force_new_group
;
474 return EXT2_ET_MISSING_INODE_TABLE
;
479 * Have we run out of space in the inode buffer? If so, we
480 * need to read in more blocks.
482 if (scan
->bytes_left
< scan
->inode_size
) {
483 memcpy(scan
->temp_buffer
, scan
->ptr
, scan
->bytes_left
);
484 extra_bytes
= scan
->bytes_left
;
486 retval
= get_next_blocks(scan
);
491 * XXX test Need check for used inode somehow.
492 * (Note: this is hard.)
494 if (is_empty_scan(scan
))
495 goto force_new_group
;
499 if (bufsize
< length
) {
500 retval
= ext2fs_get_mem(length
, &iptr
);
507 memcpy(scan
->temp_buffer
+extra_bytes
, scan
->ptr
,
508 scan
->inode_size
- extra_bytes
);
509 scan
->ptr
+= scan
->inode_size
- extra_bytes
;
510 scan
->bytes_left
-= scan
->inode_size
- extra_bytes
;
512 /* Verify the inode checksum. */
513 if (!(scan
->fs
->flags
& EXT2_FLAG_IGNORE_CSUM_ERRORS
) &&
514 !ext2fs_inode_csum_verify(scan
->fs
, scan
->current_inode
+ 1,
515 (struct ext2_inode_large
*)scan
->temp_buffer
))
516 retval
= EXT2_ET_INODE_CSUM_INVALID
;
518 #ifdef WORDS_BIGENDIAN
519 memset(iptr
, 0, length
);
520 ext2fs_swap_inode_full(scan
->fs
,
521 (struct ext2_inode_large
*) iptr
,
522 (struct ext2_inode_large
*) scan
->temp_buffer
,
525 memcpy(iptr
, scan
->temp_buffer
, length
);
527 if (scan
->scan_flags
& EXT2_SF_BAD_EXTRA_BYTES
)
528 retval
= EXT2_ET_BAD_BLOCK_IN_INODE_TABLE
;
529 scan
->scan_flags
&= ~EXT2_SF_BAD_EXTRA_BYTES
;
531 /* Verify the inode checksum. */
532 if (!(scan
->fs
->flags
& EXT2_FLAG_IGNORE_CSUM_ERRORS
) &&
533 !ext2fs_inode_csum_verify(scan
->fs
, scan
->current_inode
+ 1,
534 (struct ext2_inode_large
*)scan
->ptr
))
535 retval
= EXT2_ET_INODE_CSUM_INVALID
;
537 #ifdef WORDS_BIGENDIAN
538 memset(iptr
, 0, length
);
539 ext2fs_swap_inode_full(scan
->fs
,
540 (struct ext2_inode_large
*) iptr
,
541 (struct ext2_inode_large
*) scan
->ptr
,
544 memcpy(iptr
, scan
->ptr
, length
);
546 scan
->ptr
+= scan
->inode_size
;
547 scan
->bytes_left
-= scan
->inode_size
;
548 if (scan
->scan_flags
& EXT2_SF_BAD_INODE_BLK
)
549 retval
= EXT2_ET_BAD_BLOCK_IN_INODE_TABLE
;
553 scan
->current_inode
++;
554 *ino
= scan
->current_inode
;
555 if (iptr
!= (struct ext2_inode_large
*)inode
) {
556 memcpy(inode
, iptr
, bufsize
);
557 ext2fs_free_mem(&iptr
);
562 errcode_t
ext2fs_get_next_inode(ext2_inode_scan scan
, ext2_ino_t
*ino
,
563 struct ext2_inode
*inode
)
565 return ext2fs_get_next_inode_full(scan
, ino
, inode
,
566 sizeof(struct ext2_inode
));
570 * Functions to read and write a single inode.
572 errcode_t
ext2fs_read_inode_full(ext2_filsys fs
, ext2_ino_t ino
,
573 struct ext2_inode
* inode
, int bufsize
)
576 unsigned long group
, block
, offset
;
579 int clen
, i
, inodes_per_block
;
581 int length
= EXT2_INODE_SIZE(fs
->super
);
582 struct ext2_inode_large
*iptr
;
585 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
587 /* Check to see if user has an override function */
588 if (fs
->read_inode
&&
589 ((bufsize
== sizeof(struct ext2_inode
)) ||
590 (EXT2_INODE_SIZE(fs
->super
) == sizeof(struct ext2_inode
)))) {
591 retval
= (fs
->read_inode
)(fs
, ino
, inode
);
592 if (retval
!= EXT2_ET_CALLBACK_NOTHANDLED
)
595 if ((ino
== 0) || (ino
> fs
->super
->s_inodes_count
))
596 return EXT2_ET_BAD_INODE_NUM
;
597 /* Create inode cache if not present */
599 retval
= create_icache(fs
);
603 /* Check to see if it's in the inode cache */
604 for (i
= 0; i
< fs
->icache
->cache_size
; i
++) {
605 if (fs
->icache
->cache
[i
].ino
== ino
) {
606 memcpy(inode
, fs
->icache
->cache
[i
].inode
,
607 (bufsize
> length
) ? length
: bufsize
);
611 if (fs
->flags
& EXT2_FLAG_IMAGE_FILE
) {
612 inodes_per_block
= fs
->blocksize
/ EXT2_INODE_SIZE(fs
->super
);
613 block_nr
= fs
->image_header
->offset_inode
/ fs
->blocksize
;
614 block_nr
+= (ino
- 1) / inodes_per_block
;
615 offset
= ((ino
- 1) % inodes_per_block
) *
616 EXT2_INODE_SIZE(fs
->super
);
619 group
= (ino
- 1) / EXT2_INODES_PER_GROUP(fs
->super
);
620 if (group
> fs
->group_desc_count
)
621 return EXT2_ET_BAD_INODE_NUM
;
622 offset
= ((ino
- 1) % EXT2_INODES_PER_GROUP(fs
->super
)) *
623 EXT2_INODE_SIZE(fs
->super
);
624 block
= offset
>> EXT2_BLOCK_SIZE_BITS(fs
->super
);
625 if (!ext2fs_inode_table_loc(fs
, (unsigned) group
))
626 return EXT2_ET_MISSING_INODE_TABLE
;
627 block_nr
= ext2fs_inode_table_loc(fs
, group
) +
631 offset
&= (EXT2_BLOCK_SIZE(fs
->super
) - 1);
633 cache_slot
= (fs
->icache
->cache_last
+ 1) % fs
->icache
->cache_size
;
634 iptr
= (struct ext2_inode_large
*)fs
->icache
->cache
[cache_slot
].inode
;
639 if ((offset
+ length
) > fs
->blocksize
)
640 clen
= fs
->blocksize
- offset
;
642 if (block_nr
!= fs
->icache
->buffer_blk
) {
643 retval
= io_channel_read_blk64(io
, block_nr
, 1,
647 fs
->icache
->buffer_blk
= block_nr
;
650 memcpy(ptr
, ((char *) fs
->icache
->buffer
) + (unsigned) offset
,
658 length
= EXT2_INODE_SIZE(fs
->super
);
660 /* Verify the inode checksum. */
661 if (!(fs
->flags
& EXT2_FLAG_IGNORE_CSUM_ERRORS
) &&
662 !ext2fs_inode_csum_verify(fs
, ino
, iptr
))
663 return EXT2_ET_INODE_CSUM_INVALID
;
665 #ifdef WORDS_BIGENDIAN
666 ext2fs_swap_inode_full(fs
, (struct ext2_inode_large
*) iptr
,
667 (struct ext2_inode_large
*) iptr
,
671 /* Update the inode cache bookkeeping */
672 fs
->icache
->cache_last
= cache_slot
;
673 fs
->icache
->cache
[cache_slot
].ino
= ino
;
674 memcpy(inode
, iptr
, (bufsize
> length
) ? length
: bufsize
);
679 errcode_t
ext2fs_read_inode(ext2_filsys fs
, ext2_ino_t ino
,
680 struct ext2_inode
* inode
)
682 return ext2fs_read_inode_full(fs
, ino
, inode
,
683 sizeof(struct ext2_inode
));
686 errcode_t
ext2fs_write_inode_full(ext2_filsys fs
, ext2_ino_t ino
,
687 struct ext2_inode
* inode
, int bufsize
)
690 unsigned long group
, block
, offset
;
691 errcode_t retval
= 0;
692 struct ext2_inode_large
*w_inode
;
695 int length
= EXT2_INODE_SIZE(fs
->super
);
697 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
699 /* Check to see if user provided an override function */
700 if (fs
->write_inode
) {
701 retval
= (fs
->write_inode
)(fs
, ino
, inode
);
702 if (retval
!= EXT2_ET_CALLBACK_NOTHANDLED
)
706 if ((ino
== 0) || (ino
> fs
->super
->s_inodes_count
))
707 return EXT2_ET_BAD_INODE_NUM
;
709 /* Prepare our shadow buffer for read/modify/byteswap/write */
710 retval
= ext2fs_get_mem(length
, &w_inode
);
714 if (bufsize
< length
) {
715 int old_flags
= fs
->flags
;
716 fs
->flags
|= EXT2_FLAG_IGNORE_CSUM_ERRORS
;
717 retval
= ext2fs_read_inode_full(fs
, ino
,
718 (struct ext2_inode
*)w_inode
,
720 fs
->flags
= old_flags
;
725 /* Check to see if the inode cache needs to be updated */
727 for (i
=0; i
< fs
->icache
->cache_size
; i
++) {
728 if (fs
->icache
->cache
[i
].ino
== ino
) {
729 memcpy(fs
->icache
->cache
[i
].inode
, inode
,
730 (bufsize
> length
) ? length
: bufsize
);
735 retval
= create_icache(fs
);
739 memcpy(w_inode
, inode
, (bufsize
> length
) ? length
: bufsize
);
741 if (!(fs
->flags
& EXT2_FLAG_RW
)) {
742 retval
= EXT2_ET_RO_FILSYS
;
746 #ifdef WORDS_BIGENDIAN
747 ext2fs_swap_inode_full(fs
, w_inode
, w_inode
, 1, length
);
750 retval
= ext2fs_inode_csum_set(fs
, ino
, w_inode
);
754 group
= (ino
- 1) / EXT2_INODES_PER_GROUP(fs
->super
);
755 offset
= ((ino
- 1) % EXT2_INODES_PER_GROUP(fs
->super
)) *
756 EXT2_INODE_SIZE(fs
->super
);
757 block
= offset
>> EXT2_BLOCK_SIZE_BITS(fs
->super
);
758 if (!ext2fs_inode_table_loc(fs
, (unsigned) group
)) {
759 retval
= EXT2_ET_MISSING_INODE_TABLE
;
762 block_nr
= ext2fs_inode_table_loc(fs
, (unsigned) group
) + block
;
764 offset
&= (EXT2_BLOCK_SIZE(fs
->super
) - 1);
766 ptr
= (char *) w_inode
;
770 if ((offset
+ length
) > fs
->blocksize
)
771 clen
= fs
->blocksize
- offset
;
773 if (fs
->icache
->buffer_blk
!= block_nr
) {
774 retval
= io_channel_read_blk64(fs
->io
, block_nr
, 1,
778 fs
->icache
->buffer_blk
= block_nr
;
782 memcpy((char *) fs
->icache
->buffer
+ (unsigned) offset
,
785 retval
= io_channel_write_blk64(fs
->io
, block_nr
, 1,
796 fs
->flags
|= EXT2_FLAG_CHANGED
;
798 ext2fs_free_mem(&w_inode
);
802 errcode_t
ext2fs_write_inode(ext2_filsys fs
, ext2_ino_t ino
,
803 struct ext2_inode
*inode
)
805 return ext2fs_write_inode_full(fs
, ino
, inode
,
806 sizeof(struct ext2_inode
));
810 * This function should be called when writing a new inode. It makes
811 * sure that extra part of large inodes is initialized properly.
813 errcode_t
ext2fs_write_new_inode(ext2_filsys fs
, ext2_ino_t ino
,
814 struct ext2_inode
*inode
)
816 struct ext2_inode
*buf
;
817 int size
= EXT2_INODE_SIZE(fs
->super
);
818 struct ext2_inode_large
*large_inode
;
820 __u32 t
= fs
->now
? fs
->now
: time(NULL
);
829 if (size
== sizeof(struct ext2_inode
))
830 return ext2fs_write_inode_full(fs
, ino
, inode
,
831 sizeof(struct ext2_inode
));
837 memset(buf
, 0, size
);
840 large_inode
= (struct ext2_inode_large
*) buf
;
841 large_inode
->i_extra_isize
= sizeof(struct ext2_inode_large
) -
842 EXT2_GOOD_OLD_INODE_SIZE
;
843 if (!large_inode
->i_crtime
)
844 large_inode
->i_crtime
= t
;
846 retval
= ext2fs_write_inode_full(fs
, ino
, buf
, size
);
852 errcode_t
ext2fs_get_blocks(ext2_filsys fs
, ext2_ino_t ino
, blk_t
*blocks
)
854 struct ext2_inode inode
;
858 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
860 if (ino
> fs
->super
->s_inodes_count
)
861 return EXT2_ET_BAD_INODE_NUM
;
863 if (fs
->get_blocks
) {
864 if (!(*fs
->get_blocks
)(fs
, ino
, blocks
))
867 retval
= ext2fs_read_inode(fs
, ino
, &inode
);
870 for (i
=0; i
< EXT2_N_BLOCKS
; i
++)
871 blocks
[i
] = inode
.i_block
[i
];
875 errcode_t
ext2fs_check_directory(ext2_filsys fs
, ext2_ino_t ino
)
877 struct ext2_inode inode
;
880 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
882 if (ino
> fs
->super
->s_inodes_count
)
883 return EXT2_ET_BAD_INODE_NUM
;
885 if (fs
->check_directory
) {
886 retval
= (fs
->check_directory
)(fs
, ino
);
887 if (retval
!= EXT2_ET_CALLBACK_NOTHANDLED
)
890 retval
= ext2fs_read_inode(fs
, ino
, &inode
);
893 if (!LINUX_S_ISDIR(inode
.i_mode
))
894 return EXT2_ET_NO_DIRECTORY
;