2 * inode.c --- utility routines to read and write inodes
4 * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
5 * under the terms of the GNU Public License.
13 #include <sys/types.h>
16 #include <linux/ext2_fs.h>
20 errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
21 ext2_inode_scan *ret_scan)
25 scan = (ext2_inode_scan) malloc(sizeof(struct ext2_struct_inode_scan));
28 memset(scan, 0, sizeof(struct ext2_struct_inode_scan));
31 scan->current_group = -1;
32 scan->inode_buffer_blocks = buffer_blocks ? buffer_blocks : 8;
33 scan->groups_left = fs->group_desc_count;
34 scan->inode_buffer = malloc(scan->inode_buffer_blocks * fs->blocksize);
35 if (!scan->inode_buffer) {
43 void ext2fs_close_inode_scan(ext2_inode_scan scan)
45 free(scan->inode_buffer);
46 scan->inode_buffer = NULL;
51 errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ino_t *ino,
52 struct ext2_inode *inode)
57 if (!scan->inode_buffer)
60 if (scan->inodes_left <= 0) {
61 if (scan->blocks_left <= 0) {
62 if (scan->groups_left <= 0) {
66 scan->current_group++;
69 scan->current_block = scan->fs->group_desc[scan->current_group].bg_inode_table;
70 scan->blocks_left = (EXT2_INODES_PER_GROUP(scan->fs->super) /
71 EXT2_INODES_PER_BLOCK(scan->fs->super));
73 scan->current_block += scan->inode_buffer_blocks;
75 scan->blocks_left -= scan->inode_buffer_blocks;
76 num_blocks = scan->inode_buffer_blocks;
77 if (scan->blocks_left < 0)
78 num_blocks += scan->blocks_left;
80 scan->inodes_left = EXT2_INODES_PER_BLOCK(scan->fs->super) *
83 retval = io_channel_read_blk(scan->fs->io, scan->current_block,
84 num_blocks, scan->inode_buffer);
86 return EXT2_ET_NEXT_INODE_READ;
87 scan->inode_scan_ptr = (struct ext2_inode *) scan->inode_buffer;
89 *inode = *scan->inode_scan_ptr++;
91 scan->current_inode++;
92 *ino = scan->current_inode;
97 * Functions to read and write a single inode.
99 static char *inode_buffer = 0;
100 static blk_t inode_buffer_block;
101 static int inode_buffer_size = 0;
103 errcode_t ext2fs_read_inode (ext2_filsys fs, unsigned long ino,
104 struct ext2_inode * inode)
108 unsigned long block_nr;
112 if (ino > fs->super->s_inodes_count)
113 return EXT2_ET_BAD_INODE_NUM;
114 if (inode_buffer_size != fs->blocksize) {
117 inode_buffer_size = 0;
118 inode_buffer = malloc(fs->blocksize);
121 inode_buffer_size = fs->blocksize;
122 inode_buffer_block = 0;
125 group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
126 block = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) /
127 EXT2_INODES_PER_BLOCK(fs->super);
128 i = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) %
129 EXT2_INODES_PER_BLOCK(fs->super);
130 block_nr = fs->group_desc[group].bg_inode_table + block;
131 if (block_nr != inode_buffer_block) {
132 retval = io_channel_read_blk(fs->io, block_nr, 1,
136 inode_buffer_block = block_nr;
138 memcpy (inode, (struct ext2_inode *) inode_buffer + i,
139 sizeof (struct ext2_inode));
143 errcode_t ext2fs_write_inode(ext2_filsys fs, unsigned long ino,
144 struct ext2_inode * inode)
148 unsigned long block_nr;
152 if (!(fs->flags & EXT2_FLAG_RW))
153 return EXT2_ET_RO_FILSYS;
155 if (ino > fs->super->s_inodes_count)
156 return EXT2_ET_BAD_INODE_NUM;
158 if (inode_buffer_size != fs->blocksize) {
161 inode_buffer_size = 0;
162 inode_buffer = malloc(fs->blocksize);
165 inode_buffer_size = fs->blocksize;
166 inode_buffer_block = 0;
169 group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
170 block = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) /
171 EXT2_INODES_PER_BLOCK(fs->super);
172 i = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) %
173 EXT2_INODES_PER_BLOCK(fs->super);
174 block_nr = fs->group_desc[group].bg_inode_table + block;
175 if (inode_buffer_block != block_nr) {
176 retval = io_channel_read_blk(fs->io, block_nr, 1,
180 inode_buffer_block = block_nr;
182 memcpy ((struct ext2_inode *) inode_buffer + i, inode,
183 sizeof (struct ext2_inode));
184 retval = io_channel_write_blk(fs->io, block_nr, 1, inode_buffer);
187 fs->flags |= EXT2_FLAG_CHANGED;
191 errcode_t ext2fs_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks)
193 struct ext2_inode inode;
197 if (ino > fs->super->s_inodes_count)
198 return EXT2_ET_BAD_INODE_NUM;
200 if (fs->get_blocks) {
201 if (!(*fs->get_blocks)(fs, ino, blocks))
204 retval = ext2fs_read_inode(fs, ino, &inode);
207 for (i=0; i < EXT2_N_BLOCKS; i++)
208 blocks[i] = inode.i_block[i];
212 errcode_t ext2fs_check_directory(ext2_filsys fs, ino_t ino)
214 struct ext2_inode inode;
217 if (ino > fs->super->s_inodes_count)
218 return EXT2_ET_BAD_INODE_NUM;
220 if (fs->check_directory)
221 return (fs->check_directory)(fs, ino);
222 retval = ext2fs_read_inode(fs, ino, &inode);
225 if (!S_ISDIR(inode.i_mode))