2 * rw_bitmaps.c --- routines to read and write the inode and block bitmaps.
4 * Copyright (C) 1993, 1994, 1994, 1996 Theodore Ts'o.
7 * This file may be redistributed under the terms of the GNU Public
19 #ifdef HAVE_SYS_STAT_H
22 #ifdef HAVE_SYS_TYPES_H
23 #include <sys/types.h>
26 #if EXT2_FLAT_INCLUDES
29 #include <linux/ext2_fs.h>
36 * On the PowerPC, the big-endian variant of the ext2 filesystem
37 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
38 * of each word. Thus a bitmap with only bit 0 set would be, as
39 * a string of bytes, 00 00 00 01 00 ...
40 * To cope with this, we byte-reverse each word of a bitmap if
41 * we have a big-endian filesystem, that is, if we are *not*
42 * byte-swapping other word-sized numbers.
44 #define EXT2_BIG_ENDIAN_BITMAPS
47 #ifdef EXT2_BIG_ENDIAN_BITMAPS
48 void ext2fs_swap_bitmap(ext2_filsys fs, char *bitmap, int nbytes)
50 __u32 *p = (__u32 *) bitmap;
53 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
54 *p = ext2fs_swab32(*p);
58 errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs)
63 char * inode_bitmap = fs->inode_map->bitmap;
64 char * bitmap_block = NULL;
67 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
69 if (!(fs->flags & EXT2_FLAG_RW))
70 return EXT2_ET_RO_FILSYS;
73 nbytes = (size_t) ((EXT2_INODES_PER_GROUP(fs->super)+7) / 8);
75 retval = ext2fs_get_mem(fs->blocksize, (void **) &bitmap_block);
78 memset(bitmap_block, 0xff, fs->blocksize);
79 for (i = 0; i < fs->group_desc_count; i++) {
80 memcpy(bitmap_block, inode_bitmap, nbytes);
81 blk = fs->group_desc[i].bg_inode_bitmap;
83 #ifdef EXT2_BIG_ENDIAN_BITMAPS
84 if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
85 (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)))
86 ext2fs_swap_bitmap(fs, bitmap_block, nbytes);
88 retval = io_channel_write_blk(fs->io, blk, 1,
91 return EXT2_ET_INODE_BITMAP_WRITE;
93 inode_bitmap += nbytes;
95 fs->flags |= EXT2_FLAG_CHANGED;
96 fs->flags &= ~EXT2_FLAG_IB_DIRTY;
97 ext2fs_free_mem((void **) &bitmap_block);
101 errcode_t ext2fs_write_block_bitmap (ext2_filsys fs)
108 char * block_bitmap = fs->block_map->bitmap;
109 char * bitmap_block = NULL;
112 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
114 if (!(fs->flags & EXT2_FLAG_RW))
115 return EXT2_ET_RO_FILSYS;
118 nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
119 retval = ext2fs_get_mem(fs->blocksize, (void **) &bitmap_block);
122 memset(bitmap_block, 0xff, fs->blocksize);
123 for (i = 0; i < fs->group_desc_count; i++) {
124 memcpy(bitmap_block, block_bitmap, nbytes);
125 if (i == fs->group_desc_count - 1) {
126 /* Force bitmap padding for the last group */
127 nbits = (int) ((fs->super->s_blocks_count
128 - fs->super->s_first_data_block)
129 % EXT2_BLOCKS_PER_GROUP(fs->super));
131 for (j = nbits; j < fs->blocksize * 8; j++)
132 ext2fs_set_bit(j, bitmap_block);
134 blk = fs->group_desc[i].bg_block_bitmap;
136 #ifdef EXT2_BIG_ENDIAN_BITMAPS
137 if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
138 (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)))
139 ext2fs_swap_bitmap(fs, bitmap_block, nbytes);
141 retval = io_channel_write_blk(fs->io, blk, 1,
144 return EXT2_ET_BLOCK_BITMAP_WRITE;
146 block_bitmap += nbytes;
148 fs->flags |= EXT2_FLAG_CHANGED;
149 fs->flags &= ~EXT2_FLAG_BB_DIRTY;
150 ext2fs_free_mem((void **) &bitmap_block);
154 static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
157 char *block_bitmap = 0, *inode_bitmap = 0;
160 int block_nbytes = (int) EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
161 int inode_nbytes = (int) EXT2_INODES_PER_GROUP(fs->super) / 8;
164 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
166 fs->write_bitmaps = ext2fs_write_bitmaps;
168 retval = ext2fs_get_mem(strlen(fs->device_name) + 80, (void **) &buf);
173 ext2fs_free_block_bitmap(fs->block_map);
174 sprintf(buf, "block bitmap for %s", fs->device_name);
175 retval = ext2fs_allocate_block_bitmap(fs, buf, &fs->block_map);
178 block_bitmap = fs->block_map->bitmap;
182 ext2fs_free_inode_bitmap(fs->inode_map);
183 sprintf(buf, "inode bitmap for %s", fs->device_name);
184 retval = ext2fs_allocate_inode_bitmap(fs, buf, &fs->inode_map);
187 inode_bitmap = fs->inode_map->bitmap;
189 ext2fs_free_mem((void **) &buf);
191 for (i = 0; i < fs->group_desc_count; i++) {
193 blk = fs->group_desc[i].bg_block_bitmap;
195 retval = io_channel_read_blk(fs->io, blk,
196 -block_nbytes, block_bitmap);
198 retval = EXT2_ET_BLOCK_BITMAP_READ;
201 #ifdef EXT2_BIG_ENDIAN_BITMAPS
202 if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
203 (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)))
204 ext2fs_swap_bitmap(fs, block_bitmap, block_nbytes);
207 memset(block_bitmap, 0, block_nbytes);
208 block_bitmap += block_nbytes;
211 blk = fs->group_desc[i].bg_inode_bitmap;
213 retval = io_channel_read_blk(fs->io, blk,
214 -inode_nbytes, inode_bitmap);
216 retval = EXT2_ET_INODE_BITMAP_READ;
219 #ifdef EXT2_BIG_ENDIAN_BITMAPS
220 if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
221 (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)))
222 ext2fs_swap_bitmap(fs, inode_bitmap, inode_nbytes);
225 memset(inode_bitmap, 0, inode_nbytes);
226 inode_bitmap += inode_nbytes;
233 ext2fs_free_mem((void **) &fs->block_map);
237 ext2fs_free_mem((void **) &fs->inode_map);
241 ext2fs_free_mem((void **) &buf);
245 errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs)
247 return read_bitmaps(fs, 1, 0);
250 errcode_t ext2fs_read_block_bitmap(ext2_filsys fs)
252 return read_bitmaps(fs, 0, 1);
255 errcode_t ext2fs_read_bitmaps(ext2_filsys fs)
258 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
260 if (fs->inode_map && fs->block_map)
263 return read_bitmaps(fs, !fs->inode_map, !fs->block_map);
266 errcode_t ext2fs_write_bitmaps(ext2_filsys fs)
270 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
272 if (fs->block_map && ext2fs_test_bb_dirty(fs)) {
273 retval = ext2fs_write_block_bitmap(fs);
277 if (fs->inode_map && ext2fs_test_ib_dirty(fs)) {
278 retval = ext2fs_write_inode_bitmap(fs);