2 * swapfs.c --- swap ext2 filesystem data structures
4 * Copyright (C) 1995, 1996, 2002 Theodore Ts'o.
7 * This file may be redistributed under the terms of the GNU Library
8 * General Public License, version 2.
22 #include <ext2fs/ext2_ext_attr.h>
24 #ifdef WORDS_BIGENDIAN
25 void ext2fs_swap_super(struct ext2_super_block
* sb
)
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
);
35 sb
->s_log_cluster_size
= ext2fs_swab32(sb
->s_log_cluster_size
);
36 sb
->s_blocks_per_group
= ext2fs_swab32(sb
->s_blocks_per_group
);
37 sb
->s_clusters_per_group
= ext2fs_swab32(sb
->s_clusters_per_group
);
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
);
60 sb
->s_reserved_gdt_blocks
= ext2fs_swab16(sb
->s_reserved_gdt_blocks
);
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
);
64 sb
->s_desc_size
= ext2fs_swab16(sb
->s_desc_size
);
65 sb
->s_default_mount_opts
= ext2fs_swab32(sb
->s_default_mount_opts
);
66 sb
->s_first_meta_bg
= ext2fs_swab32(sb
->s_first_meta_bg
);
67 sb
->s_mkfs_time
= ext2fs_swab32(sb
->s_mkfs_time
);
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
);
73 sb
->s_flags
= ext2fs_swab32(sb
->s_flags
);
74 sb
->s_mmp_update_interval
= ext2fs_swab16(sb
->s_mmp_update_interval
);
75 sb
->s_mmp_block
= ext2fs_swab64(sb
->s_mmp_block
);
76 sb
->s_kbytes_written
= ext2fs_swab64(sb
->s_kbytes_written
);
77 sb
->s_snapshot_inum
= ext2fs_swab32(sb
->s_snapshot_inum
);
78 sb
->s_snapshot_id
= ext2fs_swab32(sb
->s_snapshot_id
);
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
);
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
);
84 sb
->s_overhead_blocks
= ext2fs_swab32(sb
->s_overhead_blocks
);
85 sb
->s_checksum
= ext2fs_swab32(sb
->s_checksum
);
88 sb
->s_hash_seed
[i
] = ext2fs_swab32(sb
->s_hash_seed
[i
]);
90 /* if journal backup is for a valid extent-based journal... */
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 */
97 /* direct/indirect journal: swap it all */
101 sb
->s_jnl_blocks
[i
] = ext2fs_swab32(sb
->s_jnl_blocks
[i
]);
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]);
106 void ext2fs_swap_group_desc2(ext2_filsys fs
, struct ext2_group_desc
*gdp
)
108 struct ext4_group_desc
*gdp4
= (struct ext4_group_desc
*)gdp
;
110 /* Do the 32-bit parts first */
111 gdp
->bg_block_bitmap
= ext2fs_swab32(gdp
->bg_block_bitmap
);
112 gdp
->bg_inode_bitmap
= ext2fs_swab32(gdp
->bg_inode_bitmap
);
113 gdp
->bg_inode_table
= ext2fs_swab32(gdp
->bg_inode_table
);
114 gdp
->bg_free_blocks_count
= ext2fs_swab16(gdp
->bg_free_blocks_count
);
115 gdp
->bg_free_inodes_count
= ext2fs_swab16(gdp
->bg_free_inodes_count
);
116 gdp
->bg_used_dirs_count
= ext2fs_swab16(gdp
->bg_used_dirs_count
);
117 gdp
->bg_flags
= ext2fs_swab16(gdp
->bg_flags
);
118 gdp
->bg_exclude_bitmap_lo
= ext2fs_swab32(gdp
->bg_exclude_bitmap_lo
);
119 gdp
->bg_block_bitmap_csum_lo
=
120 ext2fs_swab16(gdp
->bg_block_bitmap_csum_lo
);
121 gdp
->bg_inode_bitmap_csum_lo
=
122 ext2fs_swab16(gdp
->bg_inode_bitmap_csum_lo
);
123 gdp
->bg_itable_unused
= ext2fs_swab16(gdp
->bg_itable_unused
);
124 gdp
->bg_checksum
= ext2fs_swab16(gdp
->bg_checksum
);
125 /* If we're 32-bit, we're done */
126 if (fs
== NULL
|| EXT2_DESC_SIZE(fs
->super
) < EXT2_MIN_DESC_SIZE_64BIT
)
129 /* Swap the 64-bit parts */
130 gdp4
->bg_block_bitmap_hi
= ext2fs_swab32(gdp4
->bg_block_bitmap_hi
);
131 gdp4
->bg_inode_bitmap_hi
= ext2fs_swab32(gdp4
->bg_inode_bitmap_hi
);
132 gdp4
->bg_inode_table_hi
= ext2fs_swab32(gdp4
->bg_inode_table_hi
);
133 gdp4
->bg_free_blocks_count_hi
=
134 ext2fs_swab16(gdp4
->bg_free_blocks_count_hi
);
135 gdp4
->bg_free_inodes_count_hi
=
136 ext2fs_swab16(gdp4
->bg_free_inodes_count_hi
);
137 gdp4
->bg_used_dirs_count_hi
=
138 ext2fs_swab16(gdp4
->bg_used_dirs_count_hi
);
139 gdp4
->bg_itable_unused_hi
= ext2fs_swab16(gdp4
->bg_itable_unused_hi
);
140 gdp4
->bg_exclude_bitmap_hi
= ext2fs_swab16(gdp4
->bg_exclude_bitmap_hi
);
141 gdp4
->bg_block_bitmap_csum_hi
=
142 ext2fs_swab16(gdp4
->bg_block_bitmap_csum_hi
);
143 gdp4
->bg_inode_bitmap_csum_hi
=
144 ext2fs_swab16(gdp4
->bg_inode_bitmap_csum_hi
);
147 void ext2fs_swap_group_desc(struct ext2_group_desc
*gdp
)
149 ext2fs_swap_group_desc2(0, gdp
);
153 void ext2fs_swap_ext_attr_header(struct ext2_ext_attr_header
*to_header
,
154 struct ext2_ext_attr_header
*from_header
)
158 to_header
->h_magic
= ext2fs_swab32(from_header
->h_magic
);
159 to_header
->h_blocks
= ext2fs_swab32(from_header
->h_blocks
);
160 to_header
->h_refcount
= ext2fs_swab32(from_header
->h_refcount
);
161 to_header
->h_hash
= ext2fs_swab32(from_header
->h_hash
);
162 for (n
= 0; n
< 4; n
++)
163 to_header
->h_reserved
[n
] =
164 ext2fs_swab32(from_header
->h_reserved
[n
]);
167 void ext2fs_swap_ext_attr_entry(struct ext2_ext_attr_entry
*to_entry
,
168 struct ext2_ext_attr_entry
*from_entry
)
170 to_entry
->e_value_offs
= ext2fs_swab16(from_entry
->e_value_offs
);
171 to_entry
->e_value_block
= ext2fs_swab32(from_entry
->e_value_block
);
172 to_entry
->e_value_size
= ext2fs_swab32(from_entry
->e_value_size
);
173 to_entry
->e_hash
= ext2fs_swab32(from_entry
->e_hash
);
176 void ext2fs_swap_ext_attr(char *to
, char *from
, int bufsize
, int has_header
)
178 struct ext2_ext_attr_header
*from_header
=
179 (struct ext2_ext_attr_header
*)from
;
180 struct ext2_ext_attr_header
*to_header
=
181 (struct ext2_ext_attr_header
*)to
;
182 struct ext2_ext_attr_entry
*from_entry
, *to_entry
;
183 char *from_end
= (char *)from_header
+ bufsize
;
185 if (to_header
!= from_header
)
186 memcpy(to_header
, from_header
, bufsize
);
189 ext2fs_swap_ext_attr_header(to_header
, from_header
);
191 from_entry
= (struct ext2_ext_attr_entry
*)(from_header
+1);
192 to_entry
= (struct ext2_ext_attr_entry
*)(to_header
+1);
194 from_entry
= (struct ext2_ext_attr_entry
*)from_header
;
195 to_entry
= (struct ext2_ext_attr_entry
*)to_header
;
198 while ((char *)from_entry
< from_end
&& *(__u32
*)from_entry
) {
199 ext2fs_swap_ext_attr_entry(to_entry
, from_entry
);
200 from_entry
= EXT2_EXT_ATTR_NEXT(from_entry
);
201 to_entry
= EXT2_EXT_ATTR_NEXT(to_entry
);
205 void ext2fs_swap_inode_full(ext2_filsys fs
, struct ext2_inode_large
*t
,
206 struct ext2_inode_large
*f
, int hostorder
,
209 unsigned i
, has_data_blocks
, extra_isize
, attr_magic
;
214 if (hostorder
&& LINUX_S_ISLNK(f
->i_mode
))
216 t
->i_mode
= ext2fs_swab16(f
->i_mode
);
217 if (!hostorder
&& LINUX_S_ISLNK(t
->i_mode
))
219 t
->i_uid
= ext2fs_swab16(f
->i_uid
);
220 t
->i_size
= ext2fs_swab32(f
->i_size
);
221 t
->i_atime
= ext2fs_swab32(f
->i_atime
);
222 t
->i_ctime
= ext2fs_swab32(f
->i_ctime
);
223 t
->i_mtime
= ext2fs_swab32(f
->i_mtime
);
224 t
->i_dtime
= ext2fs_swab32(f
->i_dtime
);
225 t
->i_gid
= ext2fs_swab16(f
->i_gid
);
226 t
->i_links_count
= ext2fs_swab16(f
->i_links_count
);
227 t
->i_file_acl
= ext2fs_swab32(f
->i_file_acl
);
229 has_data_blocks
= ext2fs_inode_data_blocks(fs
,
230 (struct ext2_inode
*) f
);
231 t
->i_blocks
= ext2fs_swab32(f
->i_blocks
);
233 has_data_blocks
= ext2fs_inode_data_blocks(fs
,
234 (struct ext2_inode
*) t
);
235 if (hostorder
&& (f
->i_flags
& EXT4_EXTENTS_FL
))
237 t
->i_flags
= ext2fs_swab32(f
->i_flags
);
238 if (!hostorder
&& (t
->i_flags
& EXT4_EXTENTS_FL
))
240 t
->i_dir_acl
= ext2fs_swab32(f
->i_dir_acl
);
241 /* extent data are swapped on access, not here */
242 if (!has_extents
&& (!islnk
|| has_data_blocks
)) {
243 for (i
= 0; i
< EXT2_N_BLOCKS
; i
++)
244 t
->i_block
[i
] = ext2fs_swab32(f
->i_block
[i
]);
246 for (i
= 0; i
< EXT2_N_BLOCKS
; i
++)
247 t
->i_block
[i
] = f
->i_block
[i
];
249 t
->i_generation
= ext2fs_swab32(f
->i_generation
);
250 t
->i_faddr
= ext2fs_swab32(f
->i_faddr
);
252 switch (fs
->super
->s_creator_os
) {
254 t
->osd1
.linux1
.l_i_version
=
255 ext2fs_swab32(f
->osd1
.linux1
.l_i_version
);
256 t
->osd2
.linux2
.l_i_blocks_hi
=
257 ext2fs_swab16(f
->osd2
.linux2
.l_i_blocks_hi
);
258 t
->osd2
.linux2
.l_i_file_acl_high
=
259 ext2fs_swab16(f
->osd2
.linux2
.l_i_file_acl_high
);
260 t
->osd2
.linux2
.l_i_uid_high
=
261 ext2fs_swab16 (f
->osd2
.linux2
.l_i_uid_high
);
262 t
->osd2
.linux2
.l_i_gid_high
=
263 ext2fs_swab16 (f
->osd2
.linux2
.l_i_gid_high
);
264 t
->osd2
.linux2
.l_i_checksum_lo
=
265 ext2fs_swab16(f
->osd2
.linux2
.l_i_checksum_lo
);
268 t
->osd1
.hurd1
.h_i_translator
=
269 ext2fs_swab32 (f
->osd1
.hurd1
.h_i_translator
);
270 t
->osd2
.hurd2
.h_i_frag
= f
->osd2
.hurd2
.h_i_frag
;
271 t
->osd2
.hurd2
.h_i_fsize
= f
->osd2
.hurd2
.h_i_fsize
;
272 t
->osd2
.hurd2
.h_i_mode_high
=
273 ext2fs_swab16 (f
->osd2
.hurd2
.h_i_mode_high
);
274 t
->osd2
.hurd2
.h_i_uid_high
=
275 ext2fs_swab16 (f
->osd2
.hurd2
.h_i_uid_high
);
276 t
->osd2
.hurd2
.h_i_gid_high
=
277 ext2fs_swab16 (f
->osd2
.hurd2
.h_i_gid_high
);
278 t
->osd2
.hurd2
.h_i_author
=
279 ext2fs_swab32 (f
->osd2
.hurd2
.h_i_author
);
285 if (bufsize
< (int) (sizeof(struct ext2_inode
) + sizeof(__u16
)))
286 return; /* no i_extra_isize field */
289 extra_isize
= f
->i_extra_isize
;
290 t
->i_extra_isize
= ext2fs_swab16(f
->i_extra_isize
);
292 extra_isize
= t
->i_extra_isize
;
293 if (extra_isize
> EXT2_INODE_SIZE(fs
->super
) -
294 sizeof(struct ext2_inode
)) {
295 /* this is error case: i_extra_size is too large */
299 if (extra_isize
>= 4)
300 t
->i_checksum_hi
= ext2fs_swab16(f
->i_checksum_hi
);
301 if (extra_isize
>= 8)
302 t
->i_ctime_extra
= ext2fs_swab32(f
->i_ctime_extra
);
303 if (extra_isize
>= 12)
304 t
->i_mtime_extra
= ext2fs_swab32(f
->i_mtime_extra
);
305 if (extra_isize
>= 16)
306 t
->i_atime_extra
= ext2fs_swab32(f
->i_atime_extra
);
307 if (extra_isize
>= 20)
308 t
->i_crtime
= ext2fs_swab32(f
->i_crtime
);
309 if (extra_isize
>= 24)
310 t
->i_crtime_extra
= ext2fs_swab32(f
->i_crtime_extra
);
311 if (extra_isize
>= 28)
312 t
->i_version_hi
= ext2fs_swab32(f
->i_version_hi
);
314 i
= sizeof(struct ext2_inode
) + extra_isize
+ sizeof(__u32
);
315 if (bufsize
< (int) i
)
316 return; /* no space for EA magic */
318 eaf
= (__u32
*) (((char *) f
) + sizeof(struct ext2_inode
) +
323 attr_magic
= ext2fs_swab32(attr_magic
);
325 if (attr_magic
!= EXT2_EXT_ATTR_MAGIC
)
326 return; /* it seems no magic here */
328 eat
= (__u32
*) (((char *) t
) + sizeof(struct ext2_inode
) +
330 *eat
= ext2fs_swab32(*eaf
);
333 ext2fs_swap_ext_attr((char *) (eat
+ 1), (char *) (eaf
+ 1),
334 bufsize
- sizeof(struct ext2_inode
) -
335 extra_isize
- sizeof(__u32
), 0);
339 void ext2fs_swap_inode(ext2_filsys fs
, struct ext2_inode
*t
,
340 struct ext2_inode
*f
, int hostorder
)
342 ext2fs_swap_inode_full(fs
, (struct ext2_inode_large
*) t
,
343 (struct ext2_inode_large
*) f
, hostorder
,
344 sizeof(struct ext2_inode
));
347 void ext2fs_swap_mmp(struct mmp_struct
*mmp
)
349 mmp
->mmp_magic
= ext2fs_swab32(mmp
->mmp_magic
);
350 mmp
->mmp_seq
= ext2fs_swab32(mmp
->mmp_seq
);
351 mmp
->mmp_time
= ext2fs_swab64(mmp
->mmp_time
);
352 mmp
->mmp_check_interval
= ext2fs_swab16(mmp
->mmp_check_interval
);