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