2 * Super/root block reading routines
5 #define _FILE_OFFSET_BITS 64
14 static void _omfs_swap_buffer(void *buf
, int count
)
17 // only valid for Replay 4xxx and 5xxx: unconditionally force change
20 u32
*ibuf
= (u32
*) buf
;
23 for (i
=0; i
<count
; i
++)
24 ibuf
[i
] = __swap32(ibuf
[i
]);
29 * Write the superblock to disk
31 int omfs_write_super(FILE *dev
, struct omfs_super_block
*super
)
35 fseeko(dev
, 0LL, SEEK_SET
);
36 _omfs_swap_buffer(super
, sizeof(struct omfs_super_block
));
37 count
= fwrite(super
, 1, sizeof(struct omfs_super_block
), dev
);
39 if (count
< sizeof(struct omfs_super_block
))
46 * Read the superblock and store the result in ret
48 int omfs_read_super(FILE *dev
, struct omfs_super_block
*ret
)
52 fseeko(dev
, 0LL, SEEK_SET
);
53 count
= fread(ret
, 1, sizeof(struct omfs_super_block
), dev
);
55 if (count
< sizeof(struct omfs_super_block
))
58 _omfs_swap_buffer(ret
, count
);
62 static int _omfs_write_block(FILE *dev
, struct omfs_super_block
*sb
,
63 u64 block
, u8
* buf
, size_t len
)
66 _omfs_swap_buffer(buf
, len
);
67 for (i
=0; i
<swap_be32(sb
->mirrors
); i
++)
69 fseeko(dev
, (block
+ i
) * swap_be32(sb
->blocksize
), SEEK_SET
);
70 count
= fwrite(buf
, 1, len
, dev
);
79 * Read the numbered block into a raw array.
80 * buf must be at least blocksize bytes.
82 static int _omfs_read_block(FILE *dev
, struct omfs_super_block
*sb
,
86 fseeko(dev
, block
* swap_be32(sb
->blocksize
), SEEK_SET
);
87 count
= fread(buf
, 1, swap_be32(sb
->blocksize
), dev
);
89 if (count
< swap_be32(sb
->blocksize
))
92 _omfs_swap_buffer(buf
, count
);
96 static void _update_header_checksums(u8
*buf
, int block_size
)
99 omfs_header_t
*header
= (omfs_header_t
*) buf
;
100 u8
*body
= buf
+ sizeof(omfs_header_t
);
101 int body_size
= block_size
- sizeof(omfs_header_t
);
103 header
->crc
= swap_be16(crc_ccitt_msb(0, body
, body_size
));
106 for (i
=1; i
<OMFS_XOR_COUNT
; i
++)
108 header
->check_xor
= xor;
112 int omfs_write_root_block(FILE *dev
, struct omfs_super_block
*sb
,
113 struct omfs_root_block
*root
)
115 u64 block
= swap_be64(root
->head
.self
);
116 return _omfs_write_block(dev
, sb
, block
, (u8
*) root
,
117 sizeof(struct omfs_root_block
));
121 int omfs_read_root_block(FILE *dev
, struct omfs_super_block
*sb
,
122 struct omfs_root_block
*root
)
126 buf
= omfs_get_block(dev
, sb
, swap_be64(sb
->root_block
));
130 memcpy(root
, buf
, sizeof(struct omfs_root_block
));
135 u8
*omfs_get_block(FILE *dev
, struct omfs_super_block
*sb
, u64 block
)
138 if (!(buf
= malloc(swap_be32(sb
->blocksize
))))
141 if (_omfs_read_block(dev
, sb
, block
, buf
))
151 * Write an inode to the device.
153 int omfs_write_inode(omfs_info_t
*info
, omfs_inode_t
*inode
)
155 int size
= swap_be32(inode
->head
.body_size
) + sizeof(omfs_header_t
);
157 _update_header_checksums((u8
*)inode
, size
);
159 return _omfs_write_block(info
->dev
, info
->super
,
160 swap_be64(inode
->head
.self
), (u8
*) inode
, size
);
163 omfs_inode_t
*omfs_get_inode(omfs_info_t
*info
, u64 block
)
166 buf
= omfs_get_block(info
->dev
, info
->super
, block
);
170 return (omfs_inode_t
*) buf
;
173 void omfs_release_inode(omfs_inode_t
*oi
)
178 int omfs_write_bitmap(omfs_info_t
*info
, u8
* bitmap
)
181 u64 bitmap_blk
= swap_be64(info
->root
->bitmap
);
183 size
= (swap_be64(info
->super
->num_blocks
) + 7) / 8;
184 fseeko(info
->dev
, bitmap_blk
* swap_be32(info
->super
->blocksize
),
186 count
= fwrite(bitmap
, 1, size
, info
->dev
);
192 u8
*omfs_get_bitmap(omfs_info_t
*info
)
196 u64 bitmap_blk
= swap_be64(info
->root
->bitmap
);
197 if (bitmap_blk
== ~0)
200 size
= (swap_be64(info
->super
->num_blocks
) + 7) / 8;
202 if (!(buf
= malloc(size
)))
205 fseeko(info
->dev
, bitmap_blk
* swap_be32(info
->super
->blocksize
), SEEK_SET
);
206 fread(buf
, 1, size
, info
->dev
);
210 int omfs_compute_hash(omfs_info_t
*info
, char *filename
)
213 int m
= (swap_be32(info
->super
->sys_blocksize
) - OMFS_DIR_START
) / 8;
215 for (i
=0; i
<strlen(filename
); i
++)
216 hash
^= tolower(filename
[i
]) << (i
% 24);
221 void omfs_sync(omfs_info_t
*info
)