]>
Commit | Line | Data |
---|---|---|
50e1e10f TT |
1 | /* |
2 | * swapfs.c --- swap ext2 filesystem data structures | |
efc6f628 | 3 | * |
8132d840 | 4 | * Copyright (C) 1995, 1996, 2002 Theodore Ts'o. |
19c78dc0 TT |
5 | * |
6 | * %Begin-Header% | |
543547a5 TT |
7 | * This file may be redistributed under the terms of the GNU Library |
8 | * General Public License, version 2. | |
19c78dc0 | 9 | * %End-Header% |
50e1e10f TT |
10 | */ |
11 | ||
d1154eb4 | 12 | #include "config.h" |
50e1e10f | 13 | #include <stdio.h> |
4cbe8af4 | 14 | #if HAVE_UNISTD_H |
50e1e10f | 15 | #include <unistd.h> |
4cbe8af4 | 16 | #endif |
7331196a | 17 | #include <string.h> |
50e1e10f TT |
18 | #include <time.h> |
19 | ||
b5abe6fa | 20 | #include "ext2_fs.h" |
50e1e10f | 21 | #include "ext2fs.h" |
7331196a | 22 | #include <ext2fs/ext2_ext_attr.h> |
50e1e10f | 23 | |
a5dda054 | 24 | #ifdef WORDS_BIGENDIAN |
e5b38a5f | 25 | void ext2fs_swap_super(struct ext2_super_block * sb) |
50e1e10f | 26 | { |
8132d840 | 27 | int i; |
e5b38a5f TT |
28 | sb->s_inodes_count = ext2fs_swab32(sb->s_inodes_count); |
29 | sb->s_blocks_count = ext2fs_swab32(sb->s_blocks_count); | |
30 | sb->s_r_blocks_count = ext2fs_swab32(sb->s_r_blocks_count); | |
31 | sb->s_free_blocks_count = ext2fs_swab32(sb->s_free_blocks_count); | |
32 | sb->s_free_inodes_count = ext2fs_swab32(sb->s_free_inodes_count); | |
33 | sb->s_first_data_block = ext2fs_swab32(sb->s_first_data_block); | |
34 | sb->s_log_block_size = ext2fs_swab32(sb->s_log_block_size); | |
412376ef | 35 | sb->s_log_cluster_size = ext2fs_swab32(sb->s_log_cluster_size); |
e5b38a5f | 36 | sb->s_blocks_per_group = ext2fs_swab32(sb->s_blocks_per_group); |
412376ef | 37 | sb->s_clusters_per_group = ext2fs_swab32(sb->s_clusters_per_group); |
e5b38a5f TT |
38 | sb->s_inodes_per_group = ext2fs_swab32(sb->s_inodes_per_group); |
39 | sb->s_mtime = ext2fs_swab32(sb->s_mtime); | |
40 | sb->s_wtime = ext2fs_swab32(sb->s_wtime); | |
41 | sb->s_mnt_count = ext2fs_swab16(sb->s_mnt_count); | |
42 | sb->s_max_mnt_count = ext2fs_swab16(sb->s_max_mnt_count); | |
43 | sb->s_magic = ext2fs_swab16(sb->s_magic); | |
44 | sb->s_state = ext2fs_swab16(sb->s_state); | |
45 | sb->s_errors = ext2fs_swab16(sb->s_errors); | |
46 | sb->s_minor_rev_level = ext2fs_swab16(sb->s_minor_rev_level); | |
47 | sb->s_lastcheck = ext2fs_swab32(sb->s_lastcheck); | |
48 | sb->s_checkinterval = ext2fs_swab32(sb->s_checkinterval); | |
49 | sb->s_creator_os = ext2fs_swab32(sb->s_creator_os); | |
50 | sb->s_rev_level = ext2fs_swab32(sb->s_rev_level); | |
51 | sb->s_def_resuid = ext2fs_swab16(sb->s_def_resuid); | |
52 | sb->s_def_resgid = ext2fs_swab16(sb->s_def_resgid); | |
53 | sb->s_first_ino = ext2fs_swab32(sb->s_first_ino); | |
54 | sb->s_inode_size = ext2fs_swab16(sb->s_inode_size); | |
55 | sb->s_block_group_nr = ext2fs_swab16(sb->s_block_group_nr); | |
56 | sb->s_feature_compat = ext2fs_swab32(sb->s_feature_compat); | |
57 | sb->s_feature_incompat = ext2fs_swab32(sb->s_feature_incompat); | |
58 | sb->s_feature_ro_compat = ext2fs_swab32(sb->s_feature_ro_compat); | |
59 | sb->s_algorithm_usage_bitmap = ext2fs_swab32(sb->s_algorithm_usage_bitmap); | |
5d28e3be | 60 | sb->s_reserved_gdt_blocks = ext2fs_swab16(sb->s_reserved_gdt_blocks); |
e5b38a5f TT |
61 | sb->s_journal_inum = ext2fs_swab32(sb->s_journal_inum); |
62 | sb->s_journal_dev = ext2fs_swab32(sb->s_journal_dev); | |
63 | sb->s_last_orphan = ext2fs_swab32(sb->s_last_orphan); | |
8061d2c1 | 64 | sb->s_desc_size = ext2fs_swab16(sb->s_desc_size); |
1ba7a2f2 | 65 | sb->s_default_mount_opts = ext2fs_swab32(sb->s_default_mount_opts); |
c046ac7f | 66 | sb->s_first_meta_bg = ext2fs_swab32(sb->s_first_meta_bg); |
1ba7a2f2 | 67 | sb->s_mkfs_time = ext2fs_swab32(sb->s_mkfs_time); |
6b3ce987 TT |
68 | sb->s_blocks_count_hi = ext2fs_swab32(sb->s_blocks_count_hi); |
69 | sb->s_r_blocks_count_hi = ext2fs_swab32(sb->s_r_blocks_count_hi); | |
70 | sb->s_free_blocks_hi = ext2fs_swab32(sb->s_free_blocks_hi); | |
71 | sb->s_min_extra_isize = ext2fs_swab16(sb->s_min_extra_isize); | |
72 | sb->s_want_extra_isize = ext2fs_swab16(sb->s_want_extra_isize); | |
f77704e4 | 73 | sb->s_flags = ext2fs_swab32(sb->s_flags); |
0f5eba75 AD |
74 | sb->s_mmp_update_interval = ext2fs_swab16(sb->s_mmp_update_interval); |
75 | sb->s_mmp_block = ext2fs_swab64(sb->s_mmp_block); | |
b7c5b403 | 76 | sb->s_kbytes_written = ext2fs_swab64(sb->s_kbytes_written); |
f5448c19 | 77 | sb->s_snapshot_inum = ext2fs_swab32(sb->s_snapshot_inum); |
ccc7cf03 | 78 | sb->s_snapshot_id = ext2fs_swab32(sb->s_snapshot_id); |
f5448c19 TT |
79 | sb->s_snapshot_r_blocks_count = |
80 | ext2fs_swab64(sb->s_snapshot_r_blocks_count); | |
81 | sb->s_snapshot_list = ext2fs_swab32(sb->s_snapshot_list); | |
0edcc270 AK |
82 | sb->s_usr_quota_inum = ext2fs_swab32(sb->s_usr_quota_inum); |
83 | sb->s_grp_quota_inum = ext2fs_swab32(sb->s_grp_quota_inum); | |
89efc88e TT |
84 | sb->s_overhead_blocks = ext2fs_swab32(sb->s_overhead_blocks); |
85 | sb->s_checksum = ext2fs_swab32(sb->s_checksum); | |
f5448c19 | 86 | |
8132d840 TT |
87 | for (i=0; i < 4; i++) |
88 | sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]); | |
6eb229dc ES |
89 | |
90 | /* if journal backup is for a valid extent-based journal... */ | |
931b58e1 AD |
91 | if (ext2fs_extent_header_verify(sb->s_jnl_blocks, |
92 | sizeof(sb->s_jnl_blocks)) == 0) { | |
93 | /* ... swap only the journal i_size and i_size_high, | |
94 | * and the extent data is not swapped on read */ | |
95 | i = 15; | |
96 | } else { | |
97 | /* direct/indirect journal: swap it all */ | |
98 | i = 0; | |
6eb229dc | 99 | } |
931b58e1 | 100 | for (; i < 17; i++) |
1ba7a2f2 | 101 | sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]); |
65c6c3e0 TT |
102 | sb->s_backup_bgs[0] = ext2fs_swab32(sb->s_backup_bgs[0]); |
103 | sb->s_backup_bgs[1] = ext2fs_swab32(sb->s_backup_bgs[1]); | |
2ed0adbc | 104 | sb->s_checksum_seed = ext2fs_swab32(sb->s_checksum_seed); |
50e1e10f TT |
105 | } |
106 | ||
cf828f1a | 107 | void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp) |
50e1e10f | 108 | { |
2bc30417 AD |
109 | struct ext4_group_desc *gdp4 = (struct ext4_group_desc *)gdp; |
110 | ||
cf828f1a | 111 | /* Do the 32-bit parts first */ |
50e1e10f TT |
112 | gdp->bg_block_bitmap = ext2fs_swab32(gdp->bg_block_bitmap); |
113 | gdp->bg_inode_bitmap = ext2fs_swab32(gdp->bg_inode_bitmap); | |
114 | gdp->bg_inode_table = ext2fs_swab32(gdp->bg_inode_table); | |
115 | gdp->bg_free_blocks_count = ext2fs_swab16(gdp->bg_free_blocks_count); | |
116 | gdp->bg_free_inodes_count = ext2fs_swab16(gdp->bg_free_inodes_count); | |
117 | gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count); | |
f5fa2007 | 118 | gdp->bg_flags = ext2fs_swab16(gdp->bg_flags); |
89efc88e TT |
119 | gdp->bg_exclude_bitmap_lo = ext2fs_swab32(gdp->bg_exclude_bitmap_lo); |
120 | gdp->bg_block_bitmap_csum_lo = | |
121 | ext2fs_swab16(gdp->bg_block_bitmap_csum_lo); | |
122 | gdp->bg_inode_bitmap_csum_lo = | |
123 | ext2fs_swab16(gdp->bg_inode_bitmap_csum_lo); | |
8815fb8a TT |
124 | gdp->bg_itable_unused = ext2fs_swab16(gdp->bg_itable_unused); |
125 | gdp->bg_checksum = ext2fs_swab16(gdp->bg_checksum); | |
cf828f1a | 126 | /* If we're 32-bit, we're done */ |
2bc30417 | 127 | if (fs == NULL || EXT2_DESC_SIZE(fs->super) < EXT2_MIN_DESC_SIZE_64BIT) |
cf828f1a TT |
128 | return; |
129 | ||
130 | /* Swap the 64-bit parts */ | |
cf828f1a TT |
131 | gdp4->bg_block_bitmap_hi = ext2fs_swab32(gdp4->bg_block_bitmap_hi); |
132 | gdp4->bg_inode_bitmap_hi = ext2fs_swab32(gdp4->bg_inode_bitmap_hi); | |
133 | gdp4->bg_inode_table_hi = ext2fs_swab32(gdp4->bg_inode_table_hi); | |
134 | gdp4->bg_free_blocks_count_hi = | |
135 | ext2fs_swab16(gdp4->bg_free_blocks_count_hi); | |
136 | gdp4->bg_free_inodes_count_hi = | |
137 | ext2fs_swab16(gdp4->bg_free_inodes_count_hi); | |
138 | gdp4->bg_used_dirs_count_hi = | |
139 | ext2fs_swab16(gdp4->bg_used_dirs_count_hi); | |
140 | gdp4->bg_itable_unused_hi = ext2fs_swab16(gdp4->bg_itable_unused_hi); | |
ae96c678 TT |
141 | gdp4->bg_exclude_bitmap_hi = ext2fs_swab16(gdp4->bg_exclude_bitmap_hi); |
142 | gdp4->bg_block_bitmap_csum_hi = | |
143 | ext2fs_swab16(gdp4->bg_block_bitmap_csum_hi); | |
144 | gdp4->bg_inode_bitmap_csum_hi = | |
145 | ext2fs_swab16(gdp4->bg_inode_bitmap_csum_hi); | |
50e1e10f TT |
146 | } |
147 | ||
cf828f1a TT |
148 | void ext2fs_swap_group_desc(struct ext2_group_desc *gdp) |
149 | { | |
ae96c678 | 150 | ext2fs_swap_group_desc2(0, gdp); |
cf828f1a TT |
151 | } |
152 | ||
153 | ||
fefaef39 AD |
154 | void ext2fs_swap_ext_attr_header(struct ext2_ext_attr_header *to_header, |
155 | struct ext2_ext_attr_header *from_header) | |
156 | { | |
157 | int n; | |
158 | ||
159 | to_header->h_magic = ext2fs_swab32(from_header->h_magic); | |
160 | to_header->h_blocks = ext2fs_swab32(from_header->h_blocks); | |
161 | to_header->h_refcount = ext2fs_swab32(from_header->h_refcount); | |
162 | to_header->h_hash = ext2fs_swab32(from_header->h_hash); | |
39f5659a DW |
163 | to_header->h_checksum = ext2fs_swab32(from_header->h_checksum); |
164 | for (n = 0; n < 3; n++) | |
fefaef39 AD |
165 | to_header->h_reserved[n] = |
166 | ext2fs_swab32(from_header->h_reserved[n]); | |
167 | } | |
168 | ||
169 | void ext2fs_swap_ext_attr_entry(struct ext2_ext_attr_entry *to_entry, | |
170 | struct ext2_ext_attr_entry *from_entry) | |
171 | { | |
172 | to_entry->e_value_offs = ext2fs_swab16(from_entry->e_value_offs); | |
173 | to_entry->e_value_block = ext2fs_swab32(from_entry->e_value_block); | |
174 | to_entry->e_value_size = ext2fs_swab32(from_entry->e_value_size); | |
175 | to_entry->e_hash = ext2fs_swab32(from_entry->e_hash); | |
176 | } | |
177 | ||
7331196a TT |
178 | void ext2fs_swap_ext_attr(char *to, char *from, int bufsize, int has_header) |
179 | { | |
180 | struct ext2_ext_attr_header *from_header = | |
181 | (struct ext2_ext_attr_header *)from; | |
182 | struct ext2_ext_attr_header *to_header = | |
183 | (struct ext2_ext_attr_header *)to; | |
184 | struct ext2_ext_attr_entry *from_entry, *to_entry; | |
185 | char *from_end = (char *)from_header + bufsize; | |
7331196a TT |
186 | |
187 | if (to_header != from_header) | |
188 | memcpy(to_header, from_header, bufsize); | |
189 | ||
7331196a | 190 | if (has_header) { |
fefaef39 AD |
191 | ext2fs_swap_ext_attr_header(to_header, from_header); |
192 | ||
7331196a TT |
193 | from_entry = (struct ext2_ext_attr_entry *)(from_header+1); |
194 | to_entry = (struct ext2_ext_attr_entry *)(to_header+1); | |
fefaef39 AD |
195 | } else { |
196 | from_entry = (struct ext2_ext_attr_entry *)from_header; | |
197 | to_entry = (struct ext2_ext_attr_entry *)to_header; | |
7331196a TT |
198 | } |
199 | ||
88334ce0 DW |
200 | while ((char *)from_entry < from_end && |
201 | (char *)EXT2_EXT_ATTR_NEXT(from_entry) <= from_end && | |
202 | *(__u32 *)from_entry) { | |
fefaef39 | 203 | ext2fs_swap_ext_attr_entry(to_entry, from_entry); |
7331196a TT |
204 | from_entry = EXT2_EXT_ATTR_NEXT(from_entry); |
205 | to_entry = EXT2_EXT_ATTR_NEXT(to_entry); | |
206 | } | |
207 | } | |
208 | ||
209 | void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t, | |
210 | struct ext2_inode_large *f, int hostorder, | |
211 | int bufsize) | |
1e3472c5 | 212 | { |
82e54188 | 213 | unsigned i, has_data_blocks, extra_isize, attr_magic; |
fb6627a3 | 214 | int has_extents = 0; |
416c1de9 | 215 | int has_inline_data = 0; |
1e3472c5 | 216 | int islnk = 0; |
17ea174a | 217 | int inode_size; |
7331196a TT |
218 | __u32 *eaf, *eat; |
219 | ||
1e3472c5 TT |
220 | if (hostorder && LINUX_S_ISLNK(f->i_mode)) |
221 | islnk = 1; | |
222 | t->i_mode = ext2fs_swab16(f->i_mode); | |
223 | if (!hostorder && LINUX_S_ISLNK(t->i_mode)) | |
224 | islnk = 1; | |
225 | t->i_uid = ext2fs_swab16(f->i_uid); | |
226 | t->i_size = ext2fs_swab32(f->i_size); | |
227 | t->i_atime = ext2fs_swab32(f->i_atime); | |
228 | t->i_ctime = ext2fs_swab32(f->i_ctime); | |
229 | t->i_mtime = ext2fs_swab32(f->i_mtime); | |
230 | t->i_dtime = ext2fs_swab32(f->i_dtime); | |
231 | t->i_gid = ext2fs_swab16(f->i_gid); | |
232 | t->i_links_count = ext2fs_swab16(f->i_links_count); | |
db9097ca | 233 | t->i_file_acl = ext2fs_swab32(f->i_file_acl); |
3f4c46e3 | 234 | if (hostorder) |
efc6f628 | 235 | has_data_blocks = ext2fs_inode_data_blocks(fs, |
3f4c46e3 | 236 | (struct ext2_inode *) f); |
1e3472c5 | 237 | t->i_blocks = ext2fs_swab32(f->i_blocks); |
3f4c46e3 | 238 | if (!hostorder) |
efc6f628 | 239 | has_data_blocks = ext2fs_inode_data_blocks(fs, |
3f4c46e3 | 240 | (struct ext2_inode *) t); |
4ce3b774 | 241 | if (hostorder && (f->i_flags & EXT4_EXTENTS_FL)) |
fb6627a3 | 242 | has_extents = 1; |
416c1de9 ZL |
243 | if (hostorder && (f->i_flags & EXT4_INLINE_DATA_FL)) |
244 | has_inline_data = 1; | |
1e3472c5 | 245 | t->i_flags = ext2fs_swab32(f->i_flags); |
fb6627a3 ES |
246 | if (!hostorder && (t->i_flags & EXT4_EXTENTS_FL)) |
247 | has_extents = 1; | |
2432a41a | 248 | if (!hostorder && (t->i_flags & EXT4_INLINE_DATA_FL)) |
416c1de9 | 249 | has_inline_data = 1; |
578fcbfd | 250 | t->i_size_high = ext2fs_swab32(f->i_size_high); |
416c1de9 ZL |
251 | /* |
252 | * Extent data and inline data are swapped on access, not here | |
253 | */ | |
254 | if (!has_extents && !has_inline_data && (!islnk || has_data_blocks)) { | |
1e3472c5 TT |
255 | for (i = 0; i < EXT2_N_BLOCKS; i++) |
256 | t->i_block[i] = ext2fs_swab32(f->i_block[i]); | |
257 | } else if (t != f) { | |
258 | for (i = 0; i < EXT2_N_BLOCKS; i++) | |
259 | t->i_block[i] = f->i_block[i]; | |
260 | } | |
e72a9ba3 | 261 | t->i_generation = ext2fs_swab32(f->i_generation); |
1e3472c5 | 262 | t->i_faddr = ext2fs_swab32(f->i_faddr); |
50e1e10f | 263 | |
1e3472c5 TT |
264 | switch (fs->super->s_creator_os) { |
265 | case EXT2_OS_LINUX: | |
d362a3fb TT |
266 | t->osd1.linux1.l_i_version = |
267 | ext2fs_swab32(f->osd1.linux1.l_i_version); | |
efc6f628 | 268 | t->osd2.linux2.l_i_blocks_hi = |
5d17119d | 269 | ext2fs_swab16(f->osd2.linux2.l_i_blocks_hi); |
2ea504bd AK |
270 | t->osd2.linux2.l_i_file_acl_high = |
271 | ext2fs_swab16(f->osd2.linux2.l_i_file_acl_high); | |
80e808fc TT |
272 | t->osd2.linux2.l_i_uid_high = |
273 | ext2fs_swab16 (f->osd2.linux2.l_i_uid_high); | |
274 | t->osd2.linux2.l_i_gid_high = | |
275 | ext2fs_swab16 (f->osd2.linux2.l_i_gid_high); | |
ae96c678 | 276 | t->osd2.linux2.l_i_checksum_lo = |
a7a63675 | 277 | ext2fs_swab16(f->osd2.linux2.l_i_checksum_lo); |
1e3472c5 TT |
278 | break; |
279 | case EXT2_OS_HURD: | |
280 | t->osd1.hurd1.h_i_translator = | |
281 | ext2fs_swab32 (f->osd1.hurd1.h_i_translator); | |
282 | t->osd2.hurd2.h_i_frag = f->osd2.hurd2.h_i_frag; | |
283 | t->osd2.hurd2.h_i_fsize = f->osd2.hurd2.h_i_fsize; | |
284 | t->osd2.hurd2.h_i_mode_high = | |
285 | ext2fs_swab16 (f->osd2.hurd2.h_i_mode_high); | |
286 | t->osd2.hurd2.h_i_uid_high = | |
287 | ext2fs_swab16 (f->osd2.hurd2.h_i_uid_high); | |
288 | t->osd2.hurd2.h_i_gid_high = | |
289 | ext2fs_swab16 (f->osd2.hurd2.h_i_gid_high); | |
290 | t->osd2.hurd2.h_i_author = | |
291 | ext2fs_swab32 (f->osd2.hurd2.h_i_author); | |
292 | break; | |
c9548bc3 | 293 | default: |
1e3472c5 TT |
294 | break; |
295 | } | |
7331196a TT |
296 | |
297 | if (bufsize < (int) (sizeof(struct ext2_inode) + sizeof(__u16))) | |
298 | return; /* no i_extra_isize field */ | |
299 | ||
c844010c TT |
300 | if (hostorder) |
301 | extra_isize = f->i_extra_isize; | |
7331196a | 302 | t->i_extra_isize = ext2fs_swab16(f->i_extra_isize); |
c844010c TT |
303 | if (!hostorder) |
304 | extra_isize = t->i_extra_isize; | |
305 | if (extra_isize > EXT2_INODE_SIZE(fs->super) - | |
7331196a TT |
306 | sizeof(struct ext2_inode)) { |
307 | /* this is error case: i_extra_size is too large */ | |
308 | return; | |
309 | } | |
8d7a6392 TT |
310 | if (extra_isize & 3) |
311 | return; /* Illegal inode extra_isize */ | |
7331196a | 312 | |
080e09b4 LX |
313 | inode_size = EXT2_GOOD_OLD_INODE_SIZE + extra_isize; |
314 | if (inode_includes(inode_size, i_checksum_hi)) | |
ae96c678 | 315 | t->i_checksum_hi = ext2fs_swab16(f->i_checksum_hi); |
080e09b4 | 316 | if (inode_includes(inode_size, i_ctime_extra)) |
ae96c678 | 317 | t->i_ctime_extra = ext2fs_swab32(f->i_ctime_extra); |
080e09b4 | 318 | if (inode_includes(inode_size, i_mtime_extra)) |
ae96c678 | 319 | t->i_mtime_extra = ext2fs_swab32(f->i_mtime_extra); |
080e09b4 | 320 | if (inode_includes(inode_size, i_atime_extra)) |
ae96c678 | 321 | t->i_atime_extra = ext2fs_swab32(f->i_atime_extra); |
080e09b4 | 322 | if (inode_includes(inode_size, i_crtime)) |
ae96c678 | 323 | t->i_crtime = ext2fs_swab32(f->i_crtime); |
080e09b4 | 324 | if (inode_includes(inode_size, i_crtime_extra)) |
ae96c678 | 325 | t->i_crtime_extra = ext2fs_swab32(f->i_crtime_extra); |
080e09b4 | 326 | if (inode_includes(inode_size, i_version_hi)) |
ae96c678 | 327 | t->i_version_hi = ext2fs_swab32(f->i_version_hi); |
080e09b4 LX |
328 | if (inode_includes(inode_size, i_projid)) |
329 | t->i_projid = ext2fs_swab16(f->i_projid); | |
ae96c678 | 330 | |
c844010c | 331 | i = sizeof(struct ext2_inode) + extra_isize + sizeof(__u32); |
7331196a TT |
332 | if (bufsize < (int) i) |
333 | return; /* no space for EA magic */ | |
334 | ||
335 | eaf = (__u32 *) (((char *) f) + sizeof(struct ext2_inode) + | |
c844010c | 336 | extra_isize); |
7331196a | 337 | |
82e54188 ES |
338 | attr_magic = *eaf; |
339 | if (!hostorder) | |
340 | attr_magic = ext2fs_swab32(attr_magic); | |
341 | ||
342 | if (attr_magic != EXT2_EXT_ATTR_MAGIC) | |
7331196a TT |
343 | return; /* it seems no magic here */ |
344 | ||
345 | eat = (__u32 *) (((char *) t) + sizeof(struct ext2_inode) + | |
c844010c | 346 | extra_isize); |
7331196a TT |
347 | *eat = ext2fs_swab32(*eaf); |
348 | ||
349 | /* convert EA(s) */ | |
350 | ext2fs_swap_ext_attr((char *) (eat + 1), (char *) (eaf + 1), | |
351 | bufsize - sizeof(struct ext2_inode) - | |
c844010c | 352 | extra_isize - sizeof(__u32), 0); |
7331196a | 353 | |
1e3472c5 | 354 | } |
7331196a TT |
355 | |
356 | void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t, | |
357 | struct ext2_inode *f, int hostorder) | |
358 | { | |
359 | ext2fs_swap_inode_full(fs, (struct ext2_inode_large *) t, | |
360 | (struct ext2_inode_large *) f, hostorder, | |
361 | sizeof(struct ext2_inode)); | |
362 | } | |
363 | ||
0f5eba75 AD |
364 | void ext2fs_swap_mmp(struct mmp_struct *mmp) |
365 | { | |
366 | mmp->mmp_magic = ext2fs_swab32(mmp->mmp_magic); | |
367 | mmp->mmp_seq = ext2fs_swab32(mmp->mmp_seq); | |
368 | mmp->mmp_time = ext2fs_swab64(mmp->mmp_time); | |
369 | mmp->mmp_check_interval = ext2fs_swab16(mmp->mmp_check_interval); | |
a9620d8b | 370 | mmp->mmp_checksum = ext2fs_swab32(mmp->mmp_checksum); |
0f5eba75 AD |
371 | } |
372 | ||
81683c6a | 373 | errcode_t ext2fs_dirent_swab_in(ext2_filsys fs, char *buf, int flags) |
11f93746 | 374 | { |
f9574ad0 | 375 | return ext2fs_dirent_swab_in2(fs, buf, fs->blocksize, flags); |
11f93746 ZL |
376 | } |
377 | ||
378 | errcode_t ext2fs_dirent_swab_in2(ext2_filsys fs, char *buf, | |
379 | size_t size, int flags) | |
81683c6a DW |
380 | { |
381 | errcode_t retval; | |
382 | char *p, *end; | |
383 | struct ext2_dir_entry *dirent; | |
384 | unsigned int name_len, rec_len; | |
385 | ||
386 | p = (char *) buf; | |
11f93746 | 387 | end = (char *) buf + size; |
81683c6a DW |
388 | while (p < end-8) { |
389 | dirent = (struct ext2_dir_entry *) p; | |
390 | dirent->inode = ext2fs_swab32(dirent->inode); | |
391 | dirent->rec_len = ext2fs_swab16(dirent->rec_len); | |
392 | dirent->name_len = ext2fs_swab16(dirent->name_len); | |
393 | name_len = dirent->name_len; | |
394 | if (flags & EXT2_DIRBLOCK_V2_STRUCT) | |
395 | dirent->name_len = ext2fs_swab16(dirent->name_len); | |
396 | retval = ext2fs_get_rec_len(fs, dirent, &rec_len); | |
397 | if (retval) | |
398 | return retval; | |
399 | if ((rec_len < 8) || (rec_len % 4)) { | |
400 | rec_len = 8; | |
401 | retval = EXT2_ET_DIR_CORRUPTED; | |
402 | } else if (((name_len & 0xFF) + 8) > rec_len) | |
403 | retval = EXT2_ET_DIR_CORRUPTED; | |
404 | p += rec_len; | |
405 | } | |
406 | ||
407 | return 0; | |
408 | } | |
409 | ||
410 | errcode_t ext2fs_dirent_swab_out(ext2_filsys fs, char *buf, int flags) | |
11f93746 ZL |
411 | { |
412 | return ext2fs_dirent_swab_out2(fs, buf, fs->blocksize, flags); | |
413 | } | |
414 | ||
415 | errcode_t ext2fs_dirent_swab_out2(ext2_filsys fs, char *buf, | |
416 | size_t size, int flags) | |
81683c6a DW |
417 | { |
418 | errcode_t retval; | |
419 | char *p, *end; | |
420 | unsigned int rec_len; | |
421 | struct ext2_dir_entry *dirent; | |
422 | ||
423 | p = buf; | |
11f93746 | 424 | end = buf + size; |
81683c6a DW |
425 | while (p < end) { |
426 | dirent = (struct ext2_dir_entry *) p; | |
427 | retval = ext2fs_get_rec_len(fs, dirent, &rec_len); | |
428 | if (retval) | |
429 | return retval; | |
430 | if ((rec_len < 8) || | |
431 | (rec_len % 4)) { | |
432 | ext2fs_free_mem(&buf); | |
433 | return EXT2_ET_DIR_CORRUPTED; | |
434 | } | |
435 | p += rec_len; | |
436 | dirent->inode = ext2fs_swab32(dirent->inode); | |
437 | dirent->rec_len = ext2fs_swab16(dirent->rec_len); | |
438 | dirent->name_len = ext2fs_swab16(dirent->name_len); | |
439 | ||
440 | if (flags & EXT2_DIRBLOCK_V2_STRUCT) | |
441 | dirent->name_len = ext2fs_swab16(dirent->name_len); | |
442 | } | |
443 | ||
444 | return 0; | |
445 | } | |
446 | ||
5df55d7f | 447 | #endif |