swapfs.c revision 89efc88e65136ece22708cc28ec4124a33feeecd
150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o/*
250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o * swapfs.c --- swap ext2 filesystem data structures
3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
48132d840c8f6b0d90ab5048d6f8529f74e1aa0b3Theodore Ts'o * Copyright (C) 1995, 1996, 2002 Theodore Ts'o.
519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o *
619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %Begin-Header%
7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library
8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2.
919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %End-Header%
1050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o */
1150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
1250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <stdio.h>
134cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#if HAVE_UNISTD_H
1450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <unistd.h>
154cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif
167331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o#include <string.h>
1750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <time.h>
1850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
19b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h"
2050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include "ext2fs.h"
217331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o#include <ext2fs/ext2_ext_attr.h>
2250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
23a5dda0542283d0674f42a0d1b04d33888f512eabTheodore Ts'o#ifdef WORDS_BIGENDIAN
24e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'ovoid ext2fs_swap_super(struct ext2_super_block * sb)
2550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{
268132d840c8f6b0d90ab5048d6f8529f74e1aa0b3Theodore Ts'o  	int i;
27e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_inodes_count = ext2fs_swab32(sb->s_inodes_count);
28e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_blocks_count = ext2fs_swab32(sb->s_blocks_count);
29e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_r_blocks_count = ext2fs_swab32(sb->s_r_blocks_count);
30e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_free_blocks_count = ext2fs_swab32(sb->s_free_blocks_count);
31e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_free_inodes_count = ext2fs_swab32(sb->s_free_inodes_count);
32e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_first_data_block = ext2fs_swab32(sb->s_first_data_block);
33e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_log_block_size = ext2fs_swab32(sb->s_log_block_size);
34412376efff3c0e0c2fea00666c2457e6f2ae1878Theodore Ts'o	sb->s_log_cluster_size = ext2fs_swab32(sb->s_log_cluster_size);
35e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_blocks_per_group = ext2fs_swab32(sb->s_blocks_per_group);
36412376efff3c0e0c2fea00666c2457e6f2ae1878Theodore Ts'o	sb->s_clusters_per_group = ext2fs_swab32(sb->s_clusters_per_group);
37e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_inodes_per_group = ext2fs_swab32(sb->s_inodes_per_group);
38e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_mtime = ext2fs_swab32(sb->s_mtime);
39e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_wtime = ext2fs_swab32(sb->s_wtime);
40e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_mnt_count = ext2fs_swab16(sb->s_mnt_count);
41e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_max_mnt_count = ext2fs_swab16(sb->s_max_mnt_count);
42e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_magic = ext2fs_swab16(sb->s_magic);
43e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_state = ext2fs_swab16(sb->s_state);
44e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_errors = ext2fs_swab16(sb->s_errors);
45e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_minor_rev_level = ext2fs_swab16(sb->s_minor_rev_level);
46e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_lastcheck = ext2fs_swab32(sb->s_lastcheck);
47e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_checkinterval = ext2fs_swab32(sb->s_checkinterval);
48e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_creator_os = ext2fs_swab32(sb->s_creator_os);
49e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_rev_level = ext2fs_swab32(sb->s_rev_level);
50e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_def_resuid = ext2fs_swab16(sb->s_def_resuid);
51e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_def_resgid = ext2fs_swab16(sb->s_def_resgid);
52e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_first_ino = ext2fs_swab32(sb->s_first_ino);
53e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_inode_size = ext2fs_swab16(sb->s_inode_size);
54e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_block_group_nr = ext2fs_swab16(sb->s_block_group_nr);
55e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_feature_compat = ext2fs_swab32(sb->s_feature_compat);
56e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_feature_incompat = ext2fs_swab32(sb->s_feature_incompat);
57e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_feature_ro_compat = ext2fs_swab32(sb->s_feature_ro_compat);
58e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_algorithm_usage_bitmap = ext2fs_swab32(sb->s_algorithm_usage_bitmap);
595d28e3be679b515fb4a2e9ce1716f2452381b308Theodore Ts'o	sb->s_reserved_gdt_blocks = ext2fs_swab16(sb->s_reserved_gdt_blocks);
60e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_journal_inum = ext2fs_swab32(sb->s_journal_inum);
61e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_journal_dev = ext2fs_swab32(sb->s_journal_dev);
62e5b38a5fafe4807b54d90a2e70bddf4b41b1695bTheodore Ts'o	sb->s_last_orphan = ext2fs_swab32(sb->s_last_orphan);
638061d2c144bf22ce3e170e40a194932da4baf8fbTheodore Ts'o	sb->s_desc_size = ext2fs_swab16(sb->s_desc_size);
641ba7a2f2b6a9b152828a06443955a7fb1d139930Theodore Ts'o	sb->s_default_mount_opts = ext2fs_swab32(sb->s_default_mount_opts);
65c046ac7f2e4c53e20cf1e909bbe511f91074b396Theodore Ts'o	sb->s_first_meta_bg = ext2fs_swab32(sb->s_first_meta_bg);
661ba7a2f2b6a9b152828a06443955a7fb1d139930Theodore Ts'o	sb->s_mkfs_time = ext2fs_swab32(sb->s_mkfs_time);
676b3ce9871c3424d0b41e0c7227ddc116d2e0de1aTheodore Ts'o	sb->s_blocks_count_hi = ext2fs_swab32(sb->s_blocks_count_hi);
686b3ce9871c3424d0b41e0c7227ddc116d2e0de1aTheodore Ts'o	sb->s_r_blocks_count_hi = ext2fs_swab32(sb->s_r_blocks_count_hi);
696b3ce9871c3424d0b41e0c7227ddc116d2e0de1aTheodore Ts'o	sb->s_free_blocks_hi = ext2fs_swab32(sb->s_free_blocks_hi);
706b3ce9871c3424d0b41e0c7227ddc116d2e0de1aTheodore Ts'o	sb->s_min_extra_isize = ext2fs_swab16(sb->s_min_extra_isize);
716b3ce9871c3424d0b41e0c7227ddc116d2e0de1aTheodore Ts'o	sb->s_want_extra_isize = ext2fs_swab16(sb->s_want_extra_isize);
72f77704e416fca7dbe4cc91abba674d2ae3c14f6fTheodore Ts'o	sb->s_flags = ext2fs_swab32(sb->s_flags);
73b7c5b4030870b31d73019d9d9ec55d550772590bTheodore Ts'o	sb->s_kbytes_written = ext2fs_swab64(sb->s_kbytes_written);
74f5448c19acda0bae0673d17e97b8a0590c99c944Theodore Ts'o	sb->s_snapshot_inum = ext2fs_swab32(sb->s_snapshot_inum);
75ccc7cf032852dd5c84b227bafb481b1d158e2b5eTheodore Ts'o	sb->s_snapshot_id = ext2fs_swab32(sb->s_snapshot_id);
76f5448c19acda0bae0673d17e97b8a0590c99c944Theodore Ts'o	sb->s_snapshot_r_blocks_count =
77f5448c19acda0bae0673d17e97b8a0590c99c944Theodore Ts'o		ext2fs_swab64(sb->s_snapshot_r_blocks_count);
78f5448c19acda0bae0673d17e97b8a0590c99c944Theodore Ts'o	sb->s_snapshot_list = ext2fs_swab32(sb->s_snapshot_list);
790edcc2702106ef8ea0d4ab60ef06c0c38b0b87eeAditya Kali	sb->s_usr_quota_inum = ext2fs_swab32(sb->s_usr_quota_inum);
800edcc2702106ef8ea0d4ab60ef06c0c38b0b87eeAditya Kali	sb->s_grp_quota_inum = ext2fs_swab32(sb->s_grp_quota_inum);
8189efc88e65136ece22708cc28ec4124a33feeecdTheodore Ts'o	sb->s_overhead_blocks = ext2fs_swab32(sb->s_overhead_blocks);
8289efc88e65136ece22708cc28ec4124a33feeecdTheodore Ts'o	sb->s_checksum = ext2fs_swab32(sb->s_checksum);
83f5448c19acda0bae0673d17e97b8a0590c99c944Theodore Ts'o
848132d840c8f6b0d90ab5048d6f8529f74e1aa0b3Theodore Ts'o	for (i=0; i < 4; i++)
858132d840c8f6b0d90ab5048d6f8529f74e1aa0b3Theodore Ts'o		sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]);
866eb229dc5d212ac5897ff626b839318f4e0c57caEric Sandeen
876eb229dc5d212ac5897ff626b839318f4e0c57caEric Sandeen	/* if journal backup is for a valid extent-based journal... */
88931b58e1cb2158c1f5218059cce92e94917ef485Andreas Dilger	if (ext2fs_extent_header_verify(sb->s_jnl_blocks,
89931b58e1cb2158c1f5218059cce92e94917ef485Andreas Dilger					sizeof(sb->s_jnl_blocks)) == 0) {
90931b58e1cb2158c1f5218059cce92e94917ef485Andreas Dilger		/* ... swap only the journal i_size and i_size_high,
91931b58e1cb2158c1f5218059cce92e94917ef485Andreas Dilger		 * and the extent data is not swapped on read */
92931b58e1cb2158c1f5218059cce92e94917ef485Andreas Dilger		i = 15;
93931b58e1cb2158c1f5218059cce92e94917ef485Andreas Dilger	} else {
94931b58e1cb2158c1f5218059cce92e94917ef485Andreas Dilger		/* direct/indirect journal: swap it all */
95931b58e1cb2158c1f5218059cce92e94917ef485Andreas Dilger		i = 0;
966eb229dc5d212ac5897ff626b839318f4e0c57caEric Sandeen	}
97931b58e1cb2158c1f5218059cce92e94917ef485Andreas Dilger	for (; i < 17; i++)
981ba7a2f2b6a9b152828a06443955a7fb1d139930Theodore Ts'o		sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]);
9950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o}
10050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
101cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'ovoid ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp)
10250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{
103cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o	/* Do the 32-bit parts first */
10450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	gdp->bg_block_bitmap = ext2fs_swab32(gdp->bg_block_bitmap);
10550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	gdp->bg_inode_bitmap = ext2fs_swab32(gdp->bg_inode_bitmap);
10650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	gdp->bg_inode_table = ext2fs_swab32(gdp->bg_inode_table);
10750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	gdp->bg_free_blocks_count = ext2fs_swab16(gdp->bg_free_blocks_count);
10850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	gdp->bg_free_inodes_count = ext2fs_swab16(gdp->bg_free_inodes_count);
10950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count);
110f5fa20078bfc05b554294fe9c5505375d7913e8cTheodore Ts'o	gdp->bg_flags = ext2fs_swab16(gdp->bg_flags);
11189efc88e65136ece22708cc28ec4124a33feeecdTheodore Ts'o	gdp->bg_exclude_bitmap_lo = ext2fs_swab32(gdp->bg_exclude_bitmap_lo);
11289efc88e65136ece22708cc28ec4124a33feeecdTheodore Ts'o	gdp->bg_block_bitmap_csum_lo =
11389efc88e65136ece22708cc28ec4124a33feeecdTheodore Ts'o		ext2fs_swab16(gdp->bg_block_bitmap_csum_lo);
11489efc88e65136ece22708cc28ec4124a33feeecdTheodore Ts'o	gdp->bg_inode_bitmap_csum_lo =
11589efc88e65136ece22708cc28ec4124a33feeecdTheodore Ts'o		ext2fs_swab16(gdp->bg_inode_bitmap_csum_lo);
1168815fb8a00f5a441eb62f035353db9e0cca90b38Theodore Ts'o	gdp->bg_itable_unused = ext2fs_swab16(gdp->bg_itable_unused);
1178815fb8a00f5a441eb62f035353db9e0cca90b38Theodore Ts'o	gdp->bg_checksum = ext2fs_swab16(gdp->bg_checksum);
118cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o	/* If we're 32-bit, we're done */
119ccc7cf032852dd5c84b227bafb481b1d158e2b5eTheodore Ts'o	if (fs && (!fs->super->s_desc_size ||
120ccc7cf032852dd5c84b227bafb481b1d158e2b5eTheodore Ts'o		   (fs->super->s_desc_size < EXT2_MIN_DESC_SIZE_64BIT)))
121cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o		return;
122cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o
123cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o	/* Swap the 64-bit parts */
124cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o	struct ext4_group_desc *gdp4 = (struct ext4_group_desc *) gdp;
125cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o	gdp4->bg_block_bitmap_hi = ext2fs_swab32(gdp4->bg_block_bitmap_hi);
126cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o	gdp4->bg_inode_bitmap_hi = ext2fs_swab32(gdp4->bg_inode_bitmap_hi);
127cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o	gdp4->bg_inode_table_hi = ext2fs_swab32(gdp4->bg_inode_table_hi);
128cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o	gdp4->bg_free_blocks_count_hi =
129cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o		ext2fs_swab16(gdp4->bg_free_blocks_count_hi);
130cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o	gdp4->bg_free_inodes_count_hi =
131cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o		ext2fs_swab16(gdp4->bg_free_inodes_count_hi);
132cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o	gdp4->bg_used_dirs_count_hi =
133cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o		ext2fs_swab16(gdp4->bg_used_dirs_count_hi);
134cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o	gdp4->bg_itable_unused_hi = ext2fs_swab16(gdp4->bg_itable_unused_hi);
13589efc88e65136ece22708cc28ec4124a33feeecdTheodore Ts'o	gdp->bg_exclude_bitmap_hi = ext2fs_swab16(gdp->bg_exclude_bitmap_hi);
13689efc88e65136ece22708cc28ec4124a33feeecdTheodore Ts'o	gdp->bg_block_bitmap_csum_hi =
13789efc88e65136ece22708cc28ec4124a33feeecdTheodore Ts'o		ext2fs_swab16(gdp->bg_block_bitmap_csum_hi);
13889efc88e65136ece22708cc28ec4124a33feeecdTheodore Ts'o	gdp->bg_inode_bitmap_csum_hi =
13989efc88e65136ece22708cc28ec4124a33feeecdTheodore Ts'o		ext2fs_swab16(gdp->bg_inode_bitmap_csum_hi);
14050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o}
14150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
142cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'ovoid ext2fs_swap_group_desc(struct ext2_group_desc *gdp)
143cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o{
144cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o	return ext2fs_swap_group_desc2(0, gdp);
145cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o}
146cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o
147cf828f1a72ec1eb0c1e819307137879447c909b7Theodore Ts'o
148fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilgervoid ext2fs_swap_ext_attr_header(struct ext2_ext_attr_header *to_header,
149fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger				 struct ext2_ext_attr_header *from_header)
150fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger{
151fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger	int n;
152fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger
153fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger	to_header->h_magic    = ext2fs_swab32(from_header->h_magic);
154fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger	to_header->h_blocks   = ext2fs_swab32(from_header->h_blocks);
155fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger	to_header->h_refcount = ext2fs_swab32(from_header->h_refcount);
156fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger	to_header->h_hash     = ext2fs_swab32(from_header->h_hash);
157fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger	for (n = 0; n < 4; n++)
158fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger		to_header->h_reserved[n] =
159fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger			ext2fs_swab32(from_header->h_reserved[n]);
160fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger}
161fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger
162fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilgervoid ext2fs_swap_ext_attr_entry(struct ext2_ext_attr_entry *to_entry,
163fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger				struct ext2_ext_attr_entry *from_entry)
164fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger{
165fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger	to_entry->e_value_offs  = ext2fs_swab16(from_entry->e_value_offs);
166fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger	to_entry->e_value_block = ext2fs_swab32(from_entry->e_value_block);
167fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger	to_entry->e_value_size  = ext2fs_swab32(from_entry->e_value_size);
168fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger	to_entry->e_hash	= ext2fs_swab32(from_entry->e_hash);
169fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger}
170fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger
1717331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'ovoid ext2fs_swap_ext_attr(char *to, char *from, int bufsize, int has_header)
1727331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o{
1737331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	struct ext2_ext_attr_header *from_header =
1747331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o		(struct ext2_ext_attr_header *)from;
1757331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	struct ext2_ext_attr_header *to_header =
1767331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o		(struct ext2_ext_attr_header *)to;
1777331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	struct ext2_ext_attr_entry *from_entry, *to_entry;
1787331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	char *from_end = (char *)from_header + bufsize;
1797331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o
1807331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	if (to_header != from_header)
1817331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o		memcpy(to_header, from_header, bufsize);
1827331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o
1837331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	if (has_header) {
184fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger		ext2fs_swap_ext_attr_header(to_header, from_header);
185fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger
1867331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o		from_entry = (struct ext2_ext_attr_entry *)(from_header+1);
1877331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o		to_entry   = (struct ext2_ext_attr_entry *)(to_header+1);
188fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger	} else {
189fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger		from_entry = (struct ext2_ext_attr_entry *)from_header;
190fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger		to_entry   = (struct ext2_ext_attr_entry *)to_header;
1917331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	}
1927331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o
1937331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	while ((char *)from_entry < from_end && *(__u32 *)from_entry) {
194fefaef39e046781ddc75d15a8f12369f17dbd17dAndreas Dilger		ext2fs_swap_ext_attr_entry(to_entry, from_entry);
1957331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o		from_entry = EXT2_EXT_ATTR_NEXT(from_entry);
1967331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o		to_entry   = EXT2_EXT_ATTR_NEXT(to_entry);
1977331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	}
1987331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o}
1997331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o
2007331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'ovoid ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
2017331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o			    struct ext2_inode_large *f, int hostorder,
2027331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o			    int bufsize)
2031e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o{
20482e541885ea912bc6764b97e2545f851cf7e3ff3Eric Sandeen	unsigned i, has_data_blocks, extra_isize, attr_magic;
205fb6627a3fb4fbcb6904716c7a59e5ef9eb5dfafbEric Sandeen	int has_extents = 0;
2061e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	int islnk = 0;
2077331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	__u32 *eaf, *eat;
2087331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o
2091e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if (hostorder && LINUX_S_ISLNK(f->i_mode))
2101e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		islnk = 1;
2111e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	t->i_mode = ext2fs_swab16(f->i_mode);
2121e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if (!hostorder && LINUX_S_ISLNK(t->i_mode))
2131e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		islnk = 1;
2141e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	t->i_uid = ext2fs_swab16(f->i_uid);
2151e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	t->i_size = ext2fs_swab32(f->i_size);
2161e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	t->i_atime = ext2fs_swab32(f->i_atime);
2171e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	t->i_ctime = ext2fs_swab32(f->i_ctime);
2181e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	t->i_mtime = ext2fs_swab32(f->i_mtime);
2191e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	t->i_dtime = ext2fs_swab32(f->i_dtime);
2201e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	t->i_gid = ext2fs_swab16(f->i_gid);
2211e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	t->i_links_count = ext2fs_swab16(f->i_links_count);
222db9097caca17401313c0dc840b4ae683e5b5c1dfEric Sandeen	t->i_file_acl = ext2fs_swab32(f->i_file_acl);
2233f4c46e3f9871011a3d4dffbf7a0beb35bd27d08Bryn M. Reeves	if (hostorder)
224efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		has_data_blocks = ext2fs_inode_data_blocks(fs,
2253f4c46e3f9871011a3d4dffbf7a0beb35bd27d08Bryn M. Reeves					   (struct ext2_inode *) f);
2261e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	t->i_blocks = ext2fs_swab32(f->i_blocks);
2273f4c46e3f9871011a3d4dffbf7a0beb35bd27d08Bryn M. Reeves	if (!hostorder)
228efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		has_data_blocks = ext2fs_inode_data_blocks(fs,
2293f4c46e3f9871011a3d4dffbf7a0beb35bd27d08Bryn M. Reeves					   (struct ext2_inode *) t);
2304ce3b77480496a20cf380bd18a8ae4a414b7d4a0Theodore Ts'o	if (hostorder && (f->i_flags & EXT4_EXTENTS_FL))
231fb6627a3fb4fbcb6904716c7a59e5ef9eb5dfafbEric Sandeen		has_extents = 1;
2321e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	t->i_flags = ext2fs_swab32(f->i_flags);
233fb6627a3fb4fbcb6904716c7a59e5ef9eb5dfafbEric Sandeen	if (!hostorder && (t->i_flags & EXT4_EXTENTS_FL))
234fb6627a3fb4fbcb6904716c7a59e5ef9eb5dfafbEric Sandeen		has_extents = 1;
2351ba7a2f2b6a9b152828a06443955a7fb1d139930Theodore Ts'o	t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
236fb6627a3fb4fbcb6904716c7a59e5ef9eb5dfafbEric Sandeen	/* extent data are swapped on access, not here */
237fb6627a3fb4fbcb6904716c7a59e5ef9eb5dfafbEric Sandeen	if (!has_extents && (!islnk || has_data_blocks)) {
2381e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		for (i = 0; i < EXT2_N_BLOCKS; i++)
2391e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o			t->i_block[i] = ext2fs_swab32(f->i_block[i]);
2401e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	} else if (t != f) {
2411e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		for (i = 0; i < EXT2_N_BLOCKS; i++)
2421e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o			t->i_block[i] = f->i_block[i];
2431e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	}
244e72a9ba39471364ad2f9397f645ca547090e3485Theodore Ts'o	t->i_generation = ext2fs_swab32(f->i_generation);
2451e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	t->i_faddr = ext2fs_swab32(f->i_faddr);
24650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
2471e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	switch (fs->super->s_creator_os) {
2481e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	case EXT2_OS_LINUX:
249d362a3fb7ec1a2b46601f55f4dbae83563c27717Theodore Ts'o		t->osd1.linux1.l_i_version =
250d362a3fb7ec1a2b46601f55f4dbae83563c27717Theodore Ts'o			ext2fs_swab32(f->osd1.linux1.l_i_version);
251efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o		t->osd2.linux2.l_i_blocks_hi =
2525d17119d14fe1276936c85d7986695a4543b1aa1Theodore Ts'o			ext2fs_swab16(f->osd2.linux2.l_i_blocks_hi);
2532ea504bd64dc391530c0eb33904afa27f4156c0eAneesh Kumar K.V		t->osd2.linux2.l_i_file_acl_high =
2542ea504bd64dc391530c0eb33904afa27f4156c0eAneesh Kumar K.V			ext2fs_swab16(f->osd2.linux2.l_i_file_acl_high);
25580e808fceb61c2061b32593c610893bf07a863eeTheodore Ts'o		t->osd2.linux2.l_i_uid_high =
25680e808fceb61c2061b32593c610893bf07a863eeTheodore Ts'o		  ext2fs_swab16 (f->osd2.linux2.l_i_uid_high);
25780e808fceb61c2061b32593c610893bf07a863eeTheodore Ts'o		t->osd2.linux2.l_i_gid_high =
25880e808fceb61c2061b32593c610893bf07a863eeTheodore Ts'o		  ext2fs_swab16 (f->osd2.linux2.l_i_gid_high);
25989efc88e65136ece22708cc28ec4124a33feeecdTheodore Ts'o		t->osd2.linux2.l_i_checksum =
26089efc88e65136ece22708cc28ec4124a33feeecdTheodore Ts'o			ext2fs_swab32(f->osd2.linux2.checksum);
2611e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		break;
2621e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	case EXT2_OS_HURD:
2631e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		t->osd1.hurd1.h_i_translator =
2641e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		  ext2fs_swab32 (f->osd1.hurd1.h_i_translator);
2651e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		t->osd2.hurd2.h_i_frag = f->osd2.hurd2.h_i_frag;
2661e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		t->osd2.hurd2.h_i_fsize = f->osd2.hurd2.h_i_fsize;
2671e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		t->osd2.hurd2.h_i_mode_high =
2681e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		  ext2fs_swab16 (f->osd2.hurd2.h_i_mode_high);
2691e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		t->osd2.hurd2.h_i_uid_high =
2701e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		  ext2fs_swab16 (f->osd2.hurd2.h_i_uid_high);
2711e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		t->osd2.hurd2.h_i_gid_high =
2721e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		  ext2fs_swab16 (f->osd2.hurd2.h_i_gid_high);
2731e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		t->osd2.hurd2.h_i_author =
2741e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		  ext2fs_swab32 (f->osd2.hurd2.h_i_author);
2751e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		break;
276c9548bc37e5d0f55308ebbb74b1e19ce7f88ada1Coly Li	default:
2771e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		break;
2781e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	}
2797331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o
2807331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	if (bufsize < (int) (sizeof(struct ext2_inode) + sizeof(__u16)))
2817331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o		return; /* no i_extra_isize field */
2827331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o
283c844010cc41e4c293b652d252145df12448e22c6Theodore Ts'o	if (hostorder)
284c844010cc41e4c293b652d252145df12448e22c6Theodore Ts'o		extra_isize = f->i_extra_isize;
2857331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	t->i_extra_isize = ext2fs_swab16(f->i_extra_isize);
286c844010cc41e4c293b652d252145df12448e22c6Theodore Ts'o	if (!hostorder)
287c844010cc41e4c293b652d252145df12448e22c6Theodore Ts'o		extra_isize = t->i_extra_isize;
288c844010cc41e4c293b652d252145df12448e22c6Theodore Ts'o	if (extra_isize > EXT2_INODE_SIZE(fs->super) -
2897331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o				sizeof(struct ext2_inode)) {
2907331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o		/* this is error case: i_extra_size is too large */
2917331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o		return;
2927331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	}
2937331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o
294c844010cc41e4c293b652d252145df12448e22c6Theodore Ts'o	i = sizeof(struct ext2_inode) + extra_isize + sizeof(__u32);
2957331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	if (bufsize < (int) i)
2967331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o		return; /* no space for EA magic */
2977331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o
2987331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	eaf = (__u32 *) (((char *) f) + sizeof(struct ext2_inode) +
299c844010cc41e4c293b652d252145df12448e22c6Theodore Ts'o					extra_isize);
3007331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o
30182e541885ea912bc6764b97e2545f851cf7e3ff3Eric Sandeen	attr_magic = *eaf;
30282e541885ea912bc6764b97e2545f851cf7e3ff3Eric Sandeen	if (!hostorder)
30382e541885ea912bc6764b97e2545f851cf7e3ff3Eric Sandeen		attr_magic = ext2fs_swab32(attr_magic);
30482e541885ea912bc6764b97e2545f851cf7e3ff3Eric Sandeen
30582e541885ea912bc6764b97e2545f851cf7e3ff3Eric Sandeen	if (attr_magic != EXT2_EXT_ATTR_MAGIC)
3067331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o		return; /* it seems no magic here */
3077331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o
3087331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	eat = (__u32 *) (((char *) t) + sizeof(struct ext2_inode) +
309c844010cc41e4c293b652d252145df12448e22c6Theodore Ts'o					extra_isize);
3107331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	*eat = ext2fs_swab32(*eaf);
3117331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o
3127331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	/* convert EA(s) */
3137331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	ext2fs_swap_ext_attr((char *) (eat + 1), (char *) (eaf + 1),
3147331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o			     bufsize - sizeof(struct ext2_inode) -
315c844010cc41e4c293b652d252145df12448e22c6Theodore Ts'o			     extra_isize - sizeof(__u32), 0);
3167331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o
3171e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o}
3187331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o
3197331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'ovoid ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t,
3207331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o		       struct ext2_inode *f, int hostorder)
3217331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o{
3227331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o	ext2fs_swap_inode_full(fs, (struct ext2_inode_large *) t,
3237331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o				(struct ext2_inode_large *) f, hostorder,
3247331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o				sizeof(struct ext2_inode));
3257331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o}
3267331196a16e57ef80dd6ae40eeeab14747ce2f5dTheodore Ts'o
3275df55d7f847e29d23227592a0bb23daad1a61500Theodore Ts'o#endif
328