1*6a54128fSAndroid Build Coastguard Worker /*
2*6a54128fSAndroid Build Coastguard Worker * swapfs.c --- swap ext2 filesystem data structures
3*6a54128fSAndroid Build Coastguard Worker *
4*6a54128fSAndroid Build Coastguard Worker * Copyright (C) 1995, 1996, 2002 Theodore Ts'o.
5*6a54128fSAndroid Build Coastguard Worker *
6*6a54128fSAndroid Build Coastguard Worker * %Begin-Header%
7*6a54128fSAndroid Build Coastguard Worker * This file may be redistributed under the terms of the GNU Library
8*6a54128fSAndroid Build Coastguard Worker * General Public License, version 2.
9*6a54128fSAndroid Build Coastguard Worker * %End-Header%
10*6a54128fSAndroid Build Coastguard Worker */
11*6a54128fSAndroid Build Coastguard Worker
12*6a54128fSAndroid Build Coastguard Worker #include "config.h"
13*6a54128fSAndroid Build Coastguard Worker #include <stdio.h>
14*6a54128fSAndroid Build Coastguard Worker #if HAVE_UNISTD_H
15*6a54128fSAndroid Build Coastguard Worker #include <unistd.h>
16*6a54128fSAndroid Build Coastguard Worker #endif
17*6a54128fSAndroid Build Coastguard Worker #include <string.h>
18*6a54128fSAndroid Build Coastguard Worker #include <time.h>
19*6a54128fSAndroid Build Coastguard Worker
20*6a54128fSAndroid Build Coastguard Worker #include "ext2_fs.h"
21*6a54128fSAndroid Build Coastguard Worker #include "ext2fs.h"
22*6a54128fSAndroid Build Coastguard Worker #include "ext2fsP.h"
23*6a54128fSAndroid Build Coastguard Worker #include <ext2fs/ext2_ext_attr.h>
24*6a54128fSAndroid Build Coastguard Worker
ext2fs_swap_super(struct ext2_super_block * sb)25*6a54128fSAndroid Build Coastguard Worker void ext2fs_swap_super(struct ext2_super_block * sb)
26*6a54128fSAndroid Build Coastguard Worker {
27*6a54128fSAndroid Build Coastguard Worker int i;
28*6a54128fSAndroid Build Coastguard Worker
29*6a54128fSAndroid Build Coastguard Worker sb->s_inodes_count = ext2fs_swab32(sb->s_inodes_count);
30*6a54128fSAndroid Build Coastguard Worker sb->s_blocks_count = ext2fs_swab32(sb->s_blocks_count);
31*6a54128fSAndroid Build Coastguard Worker sb->s_r_blocks_count = ext2fs_swab32(sb->s_r_blocks_count);
32*6a54128fSAndroid Build Coastguard Worker sb->s_free_blocks_count = ext2fs_swab32(sb->s_free_blocks_count);
33*6a54128fSAndroid Build Coastguard Worker sb->s_free_inodes_count = ext2fs_swab32(sb->s_free_inodes_count);
34*6a54128fSAndroid Build Coastguard Worker sb->s_first_data_block = ext2fs_swab32(sb->s_first_data_block);
35*6a54128fSAndroid Build Coastguard Worker sb->s_log_block_size = ext2fs_swab32(sb->s_log_block_size);
36*6a54128fSAndroid Build Coastguard Worker sb->s_log_cluster_size = ext2fs_swab32(sb->s_log_cluster_size);
37*6a54128fSAndroid Build Coastguard Worker sb->s_blocks_per_group = ext2fs_swab32(sb->s_blocks_per_group);
38*6a54128fSAndroid Build Coastguard Worker sb->s_clusters_per_group = ext2fs_swab32(sb->s_clusters_per_group);
39*6a54128fSAndroid Build Coastguard Worker sb->s_inodes_per_group = ext2fs_swab32(sb->s_inodes_per_group);
40*6a54128fSAndroid Build Coastguard Worker sb->s_mtime = ext2fs_swab32(sb->s_mtime);
41*6a54128fSAndroid Build Coastguard Worker sb->s_wtime = ext2fs_swab32(sb->s_wtime);
42*6a54128fSAndroid Build Coastguard Worker sb->s_mnt_count = ext2fs_swab16(sb->s_mnt_count);
43*6a54128fSAndroid Build Coastguard Worker sb->s_max_mnt_count = ext2fs_swab16(sb->s_max_mnt_count);
44*6a54128fSAndroid Build Coastguard Worker sb->s_magic = ext2fs_swab16(sb->s_magic);
45*6a54128fSAndroid Build Coastguard Worker sb->s_state = ext2fs_swab16(sb->s_state);
46*6a54128fSAndroid Build Coastguard Worker sb->s_errors = ext2fs_swab16(sb->s_errors);
47*6a54128fSAndroid Build Coastguard Worker sb->s_minor_rev_level = ext2fs_swab16(sb->s_minor_rev_level);
48*6a54128fSAndroid Build Coastguard Worker sb->s_lastcheck = ext2fs_swab32(sb->s_lastcheck);
49*6a54128fSAndroid Build Coastguard Worker sb->s_checkinterval = ext2fs_swab32(sb->s_checkinterval);
50*6a54128fSAndroid Build Coastguard Worker sb->s_creator_os = ext2fs_swab32(sb->s_creator_os);
51*6a54128fSAndroid Build Coastguard Worker sb->s_rev_level = ext2fs_swab32(sb->s_rev_level);
52*6a54128fSAndroid Build Coastguard Worker sb->s_def_resuid = ext2fs_swab16(sb->s_def_resuid);
53*6a54128fSAndroid Build Coastguard Worker sb->s_def_resgid = ext2fs_swab16(sb->s_def_resgid);
54*6a54128fSAndroid Build Coastguard Worker sb->s_first_ino = ext2fs_swab32(sb->s_first_ino);
55*6a54128fSAndroid Build Coastguard Worker sb->s_inode_size = ext2fs_swab16(sb->s_inode_size);
56*6a54128fSAndroid Build Coastguard Worker sb->s_block_group_nr = ext2fs_swab16(sb->s_block_group_nr);
57*6a54128fSAndroid Build Coastguard Worker sb->s_feature_compat = ext2fs_swab32(sb->s_feature_compat);
58*6a54128fSAndroid Build Coastguard Worker sb->s_feature_incompat = ext2fs_swab32(sb->s_feature_incompat);
59*6a54128fSAndroid Build Coastguard Worker sb->s_feature_ro_compat = ext2fs_swab32(sb->s_feature_ro_compat);
60*6a54128fSAndroid Build Coastguard Worker /* sb->s_uuid is __u8 and does not need swabbing */
61*6a54128fSAndroid Build Coastguard Worker /* sb->s_volume_name is char and does not need swabbing */
62*6a54128fSAndroid Build Coastguard Worker /* sb->s_last_mounted is char and does not need swabbing */
63*6a54128fSAndroid Build Coastguard Worker sb->s_algorithm_usage_bitmap = ext2fs_swab32(sb->s_algorithm_usage_bitmap);
64*6a54128fSAndroid Build Coastguard Worker /* sb->s_prealloc_blocks is __u8 and does not need swabbing */
65*6a54128fSAndroid Build Coastguard Worker /* sb->s_prealloc_dir_blocks is __u8 and does not need swabbing */
66*6a54128fSAndroid Build Coastguard Worker sb->s_reserved_gdt_blocks = ext2fs_swab16(sb->s_reserved_gdt_blocks);
67*6a54128fSAndroid Build Coastguard Worker /* sb->s_journal_uuid is __u8 and does not need swabbing */
68*6a54128fSAndroid Build Coastguard Worker sb->s_journal_inum = ext2fs_swab32(sb->s_journal_inum);
69*6a54128fSAndroid Build Coastguard Worker sb->s_journal_dev = ext2fs_swab32(sb->s_journal_dev);
70*6a54128fSAndroid Build Coastguard Worker sb->s_last_orphan = ext2fs_swab32(sb->s_last_orphan);
71*6a54128fSAndroid Build Coastguard Worker for (i = 0; i < 4; i++)
72*6a54128fSAndroid Build Coastguard Worker sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]);
73*6a54128fSAndroid Build Coastguard Worker /* sb->s_def_hash_version is __u8 and does not need swabbing */
74*6a54128fSAndroid Build Coastguard Worker /* sb->s_jnl_backup_type is __u8 and does not need swabbing */
75*6a54128fSAndroid Build Coastguard Worker sb->s_desc_size = ext2fs_swab16(sb->s_desc_size);
76*6a54128fSAndroid Build Coastguard Worker sb->s_default_mount_opts = ext2fs_swab32(sb->s_default_mount_opts);
77*6a54128fSAndroid Build Coastguard Worker sb->s_first_meta_bg = ext2fs_swab32(sb->s_first_meta_bg);
78*6a54128fSAndroid Build Coastguard Worker sb->s_mkfs_time = ext2fs_swab32(sb->s_mkfs_time);
79*6a54128fSAndroid Build Coastguard Worker /* if journal backup is for a valid extent-based journal... */
80*6a54128fSAndroid Build Coastguard Worker if (ext2fs_extent_header_verify(sb->s_jnl_blocks,
81*6a54128fSAndroid Build Coastguard Worker sizeof(sb->s_jnl_blocks)) == 0) {
82*6a54128fSAndroid Build Coastguard Worker /* ... swap only the journal i_size and i_size_high,
83*6a54128fSAndroid Build Coastguard Worker * and the extent data is not swapped on read */
84*6a54128fSAndroid Build Coastguard Worker i = 15;
85*6a54128fSAndroid Build Coastguard Worker } else {
86*6a54128fSAndroid Build Coastguard Worker /* direct/indirect journal: swap it all */
87*6a54128fSAndroid Build Coastguard Worker i = 0;
88*6a54128fSAndroid Build Coastguard Worker }
89*6a54128fSAndroid Build Coastguard Worker for (; i < 17; i++)
90*6a54128fSAndroid Build Coastguard Worker sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]);
91*6a54128fSAndroid Build Coastguard Worker sb->s_blocks_count_hi = ext2fs_swab32(sb->s_blocks_count_hi);
92*6a54128fSAndroid Build Coastguard Worker sb->s_r_blocks_count_hi = ext2fs_swab32(sb->s_r_blocks_count_hi);
93*6a54128fSAndroid Build Coastguard Worker sb->s_free_blocks_hi = ext2fs_swab32(sb->s_free_blocks_hi);
94*6a54128fSAndroid Build Coastguard Worker sb->s_min_extra_isize = ext2fs_swab16(sb->s_min_extra_isize);
95*6a54128fSAndroid Build Coastguard Worker sb->s_want_extra_isize = ext2fs_swab16(sb->s_want_extra_isize);
96*6a54128fSAndroid Build Coastguard Worker sb->s_flags = ext2fs_swab32(sb->s_flags);
97*6a54128fSAndroid Build Coastguard Worker sb->s_raid_stride = ext2fs_swab16(sb->s_raid_stride);
98*6a54128fSAndroid Build Coastguard Worker sb->s_mmp_update_interval = ext2fs_swab16(sb->s_mmp_update_interval);
99*6a54128fSAndroid Build Coastguard Worker sb->s_mmp_block = ext2fs_swab64(sb->s_mmp_block);
100*6a54128fSAndroid Build Coastguard Worker sb->s_raid_stripe_width = ext2fs_swab32(sb->s_raid_stripe_width);
101*6a54128fSAndroid Build Coastguard Worker /* sb->s_log_groups_per_flex is __u8 and does not need swabbing */
102*6a54128fSAndroid Build Coastguard Worker /* sb->s_checksum_type is __u8 and does not need swabbing */
103*6a54128fSAndroid Build Coastguard Worker /* sb->s_encryption_level is __u8 and does not need swabbing */
104*6a54128fSAndroid Build Coastguard Worker /* sb->s_reserved_pad is __u8 and does not need swabbing */
105*6a54128fSAndroid Build Coastguard Worker sb->s_kbytes_written = ext2fs_swab64(sb->s_kbytes_written);
106*6a54128fSAndroid Build Coastguard Worker sb->s_snapshot_inum = ext2fs_swab32(sb->s_snapshot_inum);
107*6a54128fSAndroid Build Coastguard Worker sb->s_snapshot_id = ext2fs_swab32(sb->s_snapshot_id);
108*6a54128fSAndroid Build Coastguard Worker sb->s_snapshot_r_blocks_count =
109*6a54128fSAndroid Build Coastguard Worker ext2fs_swab64(sb->s_snapshot_r_blocks_count);
110*6a54128fSAndroid Build Coastguard Worker sb->s_snapshot_list = ext2fs_swab32(sb->s_snapshot_list);
111*6a54128fSAndroid Build Coastguard Worker sb->s_error_count = ext2fs_swab32(sb->s_error_count);
112*6a54128fSAndroid Build Coastguard Worker sb->s_first_error_time = ext2fs_swab32(sb->s_first_error_time);
113*6a54128fSAndroid Build Coastguard Worker sb->s_first_error_ino = ext2fs_swab32(sb->s_first_error_ino);
114*6a54128fSAndroid Build Coastguard Worker sb->s_first_error_block = ext2fs_swab64(sb->s_first_error_block);
115*6a54128fSAndroid Build Coastguard Worker /* sb->s_first_error_func is __u8 and does not need swabbing */
116*6a54128fSAndroid Build Coastguard Worker sb->s_last_error_time = ext2fs_swab32(sb->s_last_error_time);
117*6a54128fSAndroid Build Coastguard Worker sb->s_last_error_ino = ext2fs_swab32(sb->s_last_error_ino);
118*6a54128fSAndroid Build Coastguard Worker sb->s_last_error_block = ext2fs_swab64(sb->s_last_error_block);
119*6a54128fSAndroid Build Coastguard Worker /* sb->s_last_error_func is __u8 and does not need swabbing */
120*6a54128fSAndroid Build Coastguard Worker /* sb->s_mount_opts is __u8 and does not need swabbing */
121*6a54128fSAndroid Build Coastguard Worker sb->s_usr_quota_inum = ext2fs_swab32(sb->s_usr_quota_inum);
122*6a54128fSAndroid Build Coastguard Worker sb->s_grp_quota_inum = ext2fs_swab32(sb->s_grp_quota_inum);
123*6a54128fSAndroid Build Coastguard Worker sb->s_overhead_clusters = ext2fs_swab32(sb->s_overhead_clusters);
124*6a54128fSAndroid Build Coastguard Worker sb->s_backup_bgs[0] = ext2fs_swab32(sb->s_backup_bgs[0]);
125*6a54128fSAndroid Build Coastguard Worker sb->s_backup_bgs[1] = ext2fs_swab32(sb->s_backup_bgs[1]);
126*6a54128fSAndroid Build Coastguard Worker /* sb->s_encrypt_algos is __u8 and does not need swabbing */
127*6a54128fSAndroid Build Coastguard Worker /* sb->s_encrypt_pw_salt is __u8 and does not need swabbing */
128*6a54128fSAndroid Build Coastguard Worker sb->s_lpf_ino = ext2fs_swab32(sb->s_lpf_ino);
129*6a54128fSAndroid Build Coastguard Worker sb->s_prj_quota_inum = ext2fs_swab32(sb->s_prj_quota_inum);
130*6a54128fSAndroid Build Coastguard Worker sb->s_checksum_seed = ext2fs_swab32(sb->s_checksum_seed);
131*6a54128fSAndroid Build Coastguard Worker /* s_*_time_hi are __u8 and does not need swabbing */
132*6a54128fSAndroid Build Coastguard Worker sb->s_encoding = ext2fs_swab16(sb->s_encoding);
133*6a54128fSAndroid Build Coastguard Worker sb->s_encoding_flags = ext2fs_swab16(sb->s_encoding_flags);
134*6a54128fSAndroid Build Coastguard Worker /* catch when new fields are used from s_reserved */
135*6a54128fSAndroid Build Coastguard Worker EXT2FS_BUILD_BUG_ON(sizeof(sb->s_reserved) != 95 * sizeof(__le32));
136*6a54128fSAndroid Build Coastguard Worker sb->s_checksum = ext2fs_swab32(sb->s_checksum);
137*6a54128fSAndroid Build Coastguard Worker }
138*6a54128fSAndroid Build Coastguard Worker
ext2fs_swap_group_desc2(ext2_filsys fs,struct ext2_group_desc * gdp)139*6a54128fSAndroid Build Coastguard Worker void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp)
140*6a54128fSAndroid Build Coastguard Worker {
141*6a54128fSAndroid Build Coastguard Worker struct ext4_group_desc *gdp4 = (struct ext4_group_desc *)gdp;
142*6a54128fSAndroid Build Coastguard Worker
143*6a54128fSAndroid Build Coastguard Worker /* Do the 32-bit parts first */
144*6a54128fSAndroid Build Coastguard Worker gdp->bg_block_bitmap = ext2fs_swab32(gdp->bg_block_bitmap);
145*6a54128fSAndroid Build Coastguard Worker gdp->bg_inode_bitmap = ext2fs_swab32(gdp->bg_inode_bitmap);
146*6a54128fSAndroid Build Coastguard Worker gdp->bg_inode_table = ext2fs_swab32(gdp->bg_inode_table);
147*6a54128fSAndroid Build Coastguard Worker gdp->bg_free_blocks_count = ext2fs_swab16(gdp->bg_free_blocks_count);
148*6a54128fSAndroid Build Coastguard Worker gdp->bg_free_inodes_count = ext2fs_swab16(gdp->bg_free_inodes_count);
149*6a54128fSAndroid Build Coastguard Worker gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count);
150*6a54128fSAndroid Build Coastguard Worker gdp->bg_flags = ext2fs_swab16(gdp->bg_flags);
151*6a54128fSAndroid Build Coastguard Worker gdp->bg_exclude_bitmap_lo = ext2fs_swab32(gdp->bg_exclude_bitmap_lo);
152*6a54128fSAndroid Build Coastguard Worker gdp->bg_block_bitmap_csum_lo =
153*6a54128fSAndroid Build Coastguard Worker ext2fs_swab16(gdp->bg_block_bitmap_csum_lo);
154*6a54128fSAndroid Build Coastguard Worker gdp->bg_inode_bitmap_csum_lo =
155*6a54128fSAndroid Build Coastguard Worker ext2fs_swab16(gdp->bg_inode_bitmap_csum_lo);
156*6a54128fSAndroid Build Coastguard Worker gdp->bg_itable_unused = ext2fs_swab16(gdp->bg_itable_unused);
157*6a54128fSAndroid Build Coastguard Worker gdp->bg_checksum = ext2fs_swab16(gdp->bg_checksum);
158*6a54128fSAndroid Build Coastguard Worker /* If we're 32-bit, we're done */
159*6a54128fSAndroid Build Coastguard Worker if (fs == NULL || EXT2_DESC_SIZE(fs->super) < EXT2_MIN_DESC_SIZE_64BIT)
160*6a54128fSAndroid Build Coastguard Worker return;
161*6a54128fSAndroid Build Coastguard Worker
162*6a54128fSAndroid Build Coastguard Worker /* Swap the 64-bit parts */
163*6a54128fSAndroid Build Coastguard Worker gdp4->bg_block_bitmap_hi = ext2fs_swab32(gdp4->bg_block_bitmap_hi);
164*6a54128fSAndroid Build Coastguard Worker gdp4->bg_inode_bitmap_hi = ext2fs_swab32(gdp4->bg_inode_bitmap_hi);
165*6a54128fSAndroid Build Coastguard Worker gdp4->bg_inode_table_hi = ext2fs_swab32(gdp4->bg_inode_table_hi);
166*6a54128fSAndroid Build Coastguard Worker gdp4->bg_free_blocks_count_hi =
167*6a54128fSAndroid Build Coastguard Worker ext2fs_swab16(gdp4->bg_free_blocks_count_hi);
168*6a54128fSAndroid Build Coastguard Worker gdp4->bg_free_inodes_count_hi =
169*6a54128fSAndroid Build Coastguard Worker ext2fs_swab16(gdp4->bg_free_inodes_count_hi);
170*6a54128fSAndroid Build Coastguard Worker gdp4->bg_used_dirs_count_hi =
171*6a54128fSAndroid Build Coastguard Worker ext2fs_swab16(gdp4->bg_used_dirs_count_hi);
172*6a54128fSAndroid Build Coastguard Worker gdp4->bg_itable_unused_hi = ext2fs_swab16(gdp4->bg_itable_unused_hi);
173*6a54128fSAndroid Build Coastguard Worker gdp4->bg_exclude_bitmap_hi = ext2fs_swab16(gdp4->bg_exclude_bitmap_hi);
174*6a54128fSAndroid Build Coastguard Worker gdp4->bg_block_bitmap_csum_hi =
175*6a54128fSAndroid Build Coastguard Worker ext2fs_swab16(gdp4->bg_block_bitmap_csum_hi);
176*6a54128fSAndroid Build Coastguard Worker gdp4->bg_inode_bitmap_csum_hi =
177*6a54128fSAndroid Build Coastguard Worker ext2fs_swab16(gdp4->bg_inode_bitmap_csum_hi);
178*6a54128fSAndroid Build Coastguard Worker EXT2FS_BUILD_BUG_ON(sizeof(gdp4->bg_reserved) != sizeof(__u32));
179*6a54128fSAndroid Build Coastguard Worker }
180*6a54128fSAndroid Build Coastguard Worker
ext2fs_swap_group_desc(struct ext2_group_desc * gdp)181*6a54128fSAndroid Build Coastguard Worker void ext2fs_swap_group_desc(struct ext2_group_desc *gdp)
182*6a54128fSAndroid Build Coastguard Worker {
183*6a54128fSAndroid Build Coastguard Worker ext2fs_swap_group_desc2(0, gdp);
184*6a54128fSAndroid Build Coastguard Worker }
185*6a54128fSAndroid Build Coastguard Worker
186*6a54128fSAndroid Build Coastguard Worker
ext2fs_swap_ext_attr_header(struct ext2_ext_attr_header * to_header,struct ext2_ext_attr_header * from_header)187*6a54128fSAndroid Build Coastguard Worker void ext2fs_swap_ext_attr_header(struct ext2_ext_attr_header *to_header,
188*6a54128fSAndroid Build Coastguard Worker struct ext2_ext_attr_header *from_header)
189*6a54128fSAndroid Build Coastguard Worker {
190*6a54128fSAndroid Build Coastguard Worker int n;
191*6a54128fSAndroid Build Coastguard Worker
192*6a54128fSAndroid Build Coastguard Worker to_header->h_magic = ext2fs_swab32(from_header->h_magic);
193*6a54128fSAndroid Build Coastguard Worker to_header->h_blocks = ext2fs_swab32(from_header->h_blocks);
194*6a54128fSAndroid Build Coastguard Worker to_header->h_refcount = ext2fs_swab32(from_header->h_refcount);
195*6a54128fSAndroid Build Coastguard Worker to_header->h_hash = ext2fs_swab32(from_header->h_hash);
196*6a54128fSAndroid Build Coastguard Worker to_header->h_checksum = ext2fs_swab32(from_header->h_checksum);
197*6a54128fSAndroid Build Coastguard Worker for (n = 0; n < 3; n++)
198*6a54128fSAndroid Build Coastguard Worker to_header->h_reserved[n] =
199*6a54128fSAndroid Build Coastguard Worker ext2fs_swab32(from_header->h_reserved[n]);
200*6a54128fSAndroid Build Coastguard Worker }
201*6a54128fSAndroid Build Coastguard Worker
ext2fs_swap_ext_attr_entry(struct ext2_ext_attr_entry * to_entry,struct ext2_ext_attr_entry * from_entry)202*6a54128fSAndroid Build Coastguard Worker void ext2fs_swap_ext_attr_entry(struct ext2_ext_attr_entry *to_entry,
203*6a54128fSAndroid Build Coastguard Worker struct ext2_ext_attr_entry *from_entry)
204*6a54128fSAndroid Build Coastguard Worker {
205*6a54128fSAndroid Build Coastguard Worker to_entry->e_value_offs = ext2fs_swab16(from_entry->e_value_offs);
206*6a54128fSAndroid Build Coastguard Worker to_entry->e_value_inum = ext2fs_swab32(from_entry->e_value_inum);
207*6a54128fSAndroid Build Coastguard Worker to_entry->e_value_size = ext2fs_swab32(from_entry->e_value_size);
208*6a54128fSAndroid Build Coastguard Worker to_entry->e_hash = ext2fs_swab32(from_entry->e_hash);
209*6a54128fSAndroid Build Coastguard Worker }
210*6a54128fSAndroid Build Coastguard Worker
ext2fs_swap_ext_attr(char * to,char * from,int bufsize,int has_header)211*6a54128fSAndroid Build Coastguard Worker void ext2fs_swap_ext_attr(char *to, char *from, int bufsize, int has_header)
212*6a54128fSAndroid Build Coastguard Worker {
213*6a54128fSAndroid Build Coastguard Worker struct ext2_ext_attr_header *from_header =
214*6a54128fSAndroid Build Coastguard Worker (struct ext2_ext_attr_header *)from;
215*6a54128fSAndroid Build Coastguard Worker struct ext2_ext_attr_header *to_header =
216*6a54128fSAndroid Build Coastguard Worker (struct ext2_ext_attr_header *)to;
217*6a54128fSAndroid Build Coastguard Worker struct ext2_ext_attr_entry *from_entry, *to_entry;
218*6a54128fSAndroid Build Coastguard Worker char *from_end = (char *)from_header + bufsize;
219*6a54128fSAndroid Build Coastguard Worker
220*6a54128fSAndroid Build Coastguard Worker if (to_header != from_header)
221*6a54128fSAndroid Build Coastguard Worker memcpy(to_header, from_header, bufsize);
222*6a54128fSAndroid Build Coastguard Worker
223*6a54128fSAndroid Build Coastguard Worker if (has_header) {
224*6a54128fSAndroid Build Coastguard Worker ext2fs_swap_ext_attr_header(to_header, from_header);
225*6a54128fSAndroid Build Coastguard Worker
226*6a54128fSAndroid Build Coastguard Worker from_entry = (struct ext2_ext_attr_entry *)(from_header+1);
227*6a54128fSAndroid Build Coastguard Worker to_entry = (struct ext2_ext_attr_entry *)(to_header+1);
228*6a54128fSAndroid Build Coastguard Worker } else {
229*6a54128fSAndroid Build Coastguard Worker from_entry = (struct ext2_ext_attr_entry *)from_header;
230*6a54128fSAndroid Build Coastguard Worker to_entry = (struct ext2_ext_attr_entry *)to_header;
231*6a54128fSAndroid Build Coastguard Worker }
232*6a54128fSAndroid Build Coastguard Worker
233*6a54128fSAndroid Build Coastguard Worker while ((char *)from_entry < from_end &&
234*6a54128fSAndroid Build Coastguard Worker (char *)EXT2_EXT_ATTR_NEXT(from_entry) <= from_end &&
235*6a54128fSAndroid Build Coastguard Worker *(__u32 *)from_entry) {
236*6a54128fSAndroid Build Coastguard Worker ext2fs_swap_ext_attr_entry(to_entry, from_entry);
237*6a54128fSAndroid Build Coastguard Worker from_entry = EXT2_EXT_ATTR_NEXT(from_entry);
238*6a54128fSAndroid Build Coastguard Worker to_entry = EXT2_EXT_ATTR_NEXT(to_entry);
239*6a54128fSAndroid Build Coastguard Worker }
240*6a54128fSAndroid Build Coastguard Worker }
241*6a54128fSAndroid Build Coastguard Worker
ext2fs_swap_inode_full(ext2_filsys fs,struct ext2_inode_large * t,struct ext2_inode_large * f,int hostorder,int bufsize)242*6a54128fSAndroid Build Coastguard Worker void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
243*6a54128fSAndroid Build Coastguard Worker struct ext2_inode_large *f, int hostorder,
244*6a54128fSAndroid Build Coastguard Worker int bufsize)
245*6a54128fSAndroid Build Coastguard Worker {
246*6a54128fSAndroid Build Coastguard Worker unsigned i, extra_isize, attr_magic;
247*6a54128fSAndroid Build Coastguard Worker int has_extents = 0, has_inline_data = 0, islnk = 0, fast_symlink = 0;
248*6a54128fSAndroid Build Coastguard Worker unsigned int inode_size;
249*6a54128fSAndroid Build Coastguard Worker __u32 *eaf, *eat;
250*6a54128fSAndroid Build Coastguard Worker
251*6a54128fSAndroid Build Coastguard Worker /*
252*6a54128fSAndroid Build Coastguard Worker * Note that t and f may point to the same address. That's why
253*6a54128fSAndroid Build Coastguard Worker * if (hostorder) condition is executed before swab calls and
254*6a54128fSAndroid Build Coastguard Worker * if (!hostorder) afterwards.
255*6a54128fSAndroid Build Coastguard Worker */
256*6a54128fSAndroid Build Coastguard Worker if (hostorder) {
257*6a54128fSAndroid Build Coastguard Worker islnk = LINUX_S_ISLNK(f->i_mode);
258*6a54128fSAndroid Build Coastguard Worker fast_symlink = ext2fs_is_fast_symlink(EXT2_INODE(f));
259*6a54128fSAndroid Build Coastguard Worker has_extents = (f->i_flags & EXT4_EXTENTS_FL) != 0;
260*6a54128fSAndroid Build Coastguard Worker has_inline_data = (f->i_flags & EXT4_INLINE_DATA_FL) != 0;
261*6a54128fSAndroid Build Coastguard Worker }
262*6a54128fSAndroid Build Coastguard Worker
263*6a54128fSAndroid Build Coastguard Worker t->i_mode = ext2fs_swab16(f->i_mode);
264*6a54128fSAndroid Build Coastguard Worker t->i_uid = ext2fs_swab16(f->i_uid);
265*6a54128fSAndroid Build Coastguard Worker t->i_size = ext2fs_swab32(f->i_size);
266*6a54128fSAndroid Build Coastguard Worker t->i_atime = ext2fs_swab32(f->i_atime);
267*6a54128fSAndroid Build Coastguard Worker t->i_ctime = ext2fs_swab32(f->i_ctime);
268*6a54128fSAndroid Build Coastguard Worker t->i_mtime = ext2fs_swab32(f->i_mtime);
269*6a54128fSAndroid Build Coastguard Worker t->i_dtime = ext2fs_swab32(f->i_dtime);
270*6a54128fSAndroid Build Coastguard Worker t->i_gid = ext2fs_swab16(f->i_gid);
271*6a54128fSAndroid Build Coastguard Worker t->i_links_count = ext2fs_swab16(f->i_links_count);
272*6a54128fSAndroid Build Coastguard Worker t->i_file_acl = ext2fs_swab32(f->i_file_acl);
273*6a54128fSAndroid Build Coastguard Worker t->i_blocks = ext2fs_swab32(f->i_blocks);
274*6a54128fSAndroid Build Coastguard Worker t->i_flags = ext2fs_swab32(f->i_flags);
275*6a54128fSAndroid Build Coastguard Worker t->i_size_high = ext2fs_swab32(f->i_size_high);
276*6a54128fSAndroid Build Coastguard Worker
277*6a54128fSAndroid Build Coastguard Worker if (!hostorder) {
278*6a54128fSAndroid Build Coastguard Worker islnk = LINUX_S_ISLNK(t->i_mode);
279*6a54128fSAndroid Build Coastguard Worker fast_symlink = ext2fs_is_fast_symlink(EXT2_INODE(t));
280*6a54128fSAndroid Build Coastguard Worker has_extents = (t->i_flags & EXT4_EXTENTS_FL) != 0;
281*6a54128fSAndroid Build Coastguard Worker has_inline_data = (t->i_flags & EXT4_INLINE_DATA_FL) != 0;
282*6a54128fSAndroid Build Coastguard Worker }
283*6a54128fSAndroid Build Coastguard Worker
284*6a54128fSAndroid Build Coastguard Worker /*
285*6a54128fSAndroid Build Coastguard Worker * Extent data and inline data are swapped on access, not here
286*6a54128fSAndroid Build Coastguard Worker */
287*6a54128fSAndroid Build Coastguard Worker if (!has_extents && !has_inline_data && (!islnk || !fast_symlink)) {
288*6a54128fSAndroid Build Coastguard Worker for (i = 0; i < EXT2_N_BLOCKS; i++)
289*6a54128fSAndroid Build Coastguard Worker t->i_block[i] = ext2fs_swab32(f->i_block[i]);
290*6a54128fSAndroid Build Coastguard Worker } else if (t != f) {
291*6a54128fSAndroid Build Coastguard Worker for (i = 0; i < EXT2_N_BLOCKS; i++)
292*6a54128fSAndroid Build Coastguard Worker t->i_block[i] = f->i_block[i];
293*6a54128fSAndroid Build Coastguard Worker }
294*6a54128fSAndroid Build Coastguard Worker t->i_generation = ext2fs_swab32(f->i_generation);
295*6a54128fSAndroid Build Coastguard Worker t->i_faddr = ext2fs_swab32(f->i_faddr);
296*6a54128fSAndroid Build Coastguard Worker
297*6a54128fSAndroid Build Coastguard Worker switch (fs->super->s_creator_os) {
298*6a54128fSAndroid Build Coastguard Worker case EXT2_OS_LINUX:
299*6a54128fSAndroid Build Coastguard Worker t->osd1.linux1.l_i_version =
300*6a54128fSAndroid Build Coastguard Worker ext2fs_swab32(f->osd1.linux1.l_i_version);
301*6a54128fSAndroid Build Coastguard Worker t->osd2.linux2.l_i_blocks_hi =
302*6a54128fSAndroid Build Coastguard Worker ext2fs_swab16(f->osd2.linux2.l_i_blocks_hi);
303*6a54128fSAndroid Build Coastguard Worker t->osd2.linux2.l_i_file_acl_high =
304*6a54128fSAndroid Build Coastguard Worker ext2fs_swab16(f->osd2.linux2.l_i_file_acl_high);
305*6a54128fSAndroid Build Coastguard Worker t->osd2.linux2.l_i_uid_high =
306*6a54128fSAndroid Build Coastguard Worker ext2fs_swab16 (f->osd2.linux2.l_i_uid_high);
307*6a54128fSAndroid Build Coastguard Worker t->osd2.linux2.l_i_gid_high =
308*6a54128fSAndroid Build Coastguard Worker ext2fs_swab16 (f->osd2.linux2.l_i_gid_high);
309*6a54128fSAndroid Build Coastguard Worker t->osd2.linux2.l_i_checksum_lo =
310*6a54128fSAndroid Build Coastguard Worker ext2fs_swab16(f->osd2.linux2.l_i_checksum_lo);
311*6a54128fSAndroid Build Coastguard Worker break;
312*6a54128fSAndroid Build Coastguard Worker case EXT2_OS_HURD:
313*6a54128fSAndroid Build Coastguard Worker t->osd1.hurd1.h_i_translator =
314*6a54128fSAndroid Build Coastguard Worker ext2fs_swab32 (f->osd1.hurd1.h_i_translator);
315*6a54128fSAndroid Build Coastguard Worker t->osd2.hurd2.h_i_frag = f->osd2.hurd2.h_i_frag;
316*6a54128fSAndroid Build Coastguard Worker t->osd2.hurd2.h_i_fsize = f->osd2.hurd2.h_i_fsize;
317*6a54128fSAndroid Build Coastguard Worker t->osd2.hurd2.h_i_mode_high =
318*6a54128fSAndroid Build Coastguard Worker ext2fs_swab16 (f->osd2.hurd2.h_i_mode_high);
319*6a54128fSAndroid Build Coastguard Worker t->osd2.hurd2.h_i_uid_high =
320*6a54128fSAndroid Build Coastguard Worker ext2fs_swab16 (f->osd2.hurd2.h_i_uid_high);
321*6a54128fSAndroid Build Coastguard Worker t->osd2.hurd2.h_i_gid_high =
322*6a54128fSAndroid Build Coastguard Worker ext2fs_swab16 (f->osd2.hurd2.h_i_gid_high);
323*6a54128fSAndroid Build Coastguard Worker t->osd2.hurd2.h_i_author =
324*6a54128fSAndroid Build Coastguard Worker ext2fs_swab32 (f->osd2.hurd2.h_i_author);
325*6a54128fSAndroid Build Coastguard Worker break;
326*6a54128fSAndroid Build Coastguard Worker default:
327*6a54128fSAndroid Build Coastguard Worker break;
328*6a54128fSAndroid Build Coastguard Worker }
329*6a54128fSAndroid Build Coastguard Worker
330*6a54128fSAndroid Build Coastguard Worker if (bufsize < (int) (sizeof(struct ext2_inode) + sizeof(__u16)))
331*6a54128fSAndroid Build Coastguard Worker return; /* no i_extra_isize field */
332*6a54128fSAndroid Build Coastguard Worker
333*6a54128fSAndroid Build Coastguard Worker if (hostorder)
334*6a54128fSAndroid Build Coastguard Worker extra_isize = f->i_extra_isize;
335*6a54128fSAndroid Build Coastguard Worker t->i_extra_isize = ext2fs_swab16(f->i_extra_isize);
336*6a54128fSAndroid Build Coastguard Worker if (!hostorder)
337*6a54128fSAndroid Build Coastguard Worker extra_isize = t->i_extra_isize;
338*6a54128fSAndroid Build Coastguard Worker if (extra_isize > EXT2_INODE_SIZE(fs->super) -
339*6a54128fSAndroid Build Coastguard Worker sizeof(struct ext2_inode)) {
340*6a54128fSAndroid Build Coastguard Worker /* this is error case: i_extra_size is too large */
341*6a54128fSAndroid Build Coastguard Worker return;
342*6a54128fSAndroid Build Coastguard Worker }
343*6a54128fSAndroid Build Coastguard Worker if (extra_isize & 3)
344*6a54128fSAndroid Build Coastguard Worker return; /* Illegal inode extra_isize */
345*6a54128fSAndroid Build Coastguard Worker
346*6a54128fSAndroid Build Coastguard Worker inode_size = EXT2_GOOD_OLD_INODE_SIZE + extra_isize;
347*6a54128fSAndroid Build Coastguard Worker if (inode_includes(inode_size, i_checksum_hi))
348*6a54128fSAndroid Build Coastguard Worker t->i_checksum_hi = ext2fs_swab16(f->i_checksum_hi);
349*6a54128fSAndroid Build Coastguard Worker if (inode_includes(inode_size, i_ctime_extra))
350*6a54128fSAndroid Build Coastguard Worker t->i_ctime_extra = ext2fs_swab32(f->i_ctime_extra);
351*6a54128fSAndroid Build Coastguard Worker if (inode_includes(inode_size, i_mtime_extra))
352*6a54128fSAndroid Build Coastguard Worker t->i_mtime_extra = ext2fs_swab32(f->i_mtime_extra);
353*6a54128fSAndroid Build Coastguard Worker if (inode_includes(inode_size, i_atime_extra))
354*6a54128fSAndroid Build Coastguard Worker t->i_atime_extra = ext2fs_swab32(f->i_atime_extra);
355*6a54128fSAndroid Build Coastguard Worker if (inode_includes(inode_size, i_crtime))
356*6a54128fSAndroid Build Coastguard Worker t->i_crtime = ext2fs_swab32(f->i_crtime);
357*6a54128fSAndroid Build Coastguard Worker if (inode_includes(inode_size, i_crtime_extra))
358*6a54128fSAndroid Build Coastguard Worker t->i_crtime_extra = ext2fs_swab32(f->i_crtime_extra);
359*6a54128fSAndroid Build Coastguard Worker if (inode_includes(inode_size, i_version_hi))
360*6a54128fSAndroid Build Coastguard Worker t->i_version_hi = ext2fs_swab32(f->i_version_hi);
361*6a54128fSAndroid Build Coastguard Worker if (inode_includes(inode_size, i_projid))
362*6a54128fSAndroid Build Coastguard Worker t->i_projid = ext2fs_swab32(f->i_projid);
363*6a54128fSAndroid Build Coastguard Worker /* catch new static fields added after i_projid */
364*6a54128fSAndroid Build Coastguard Worker EXT2FS_BUILD_BUG_ON(sizeof(struct ext2_inode_large) != 160);
365*6a54128fSAndroid Build Coastguard Worker
366*6a54128fSAndroid Build Coastguard Worker i = sizeof(struct ext2_inode) + extra_isize + sizeof(__u32);
367*6a54128fSAndroid Build Coastguard Worker if (bufsize < (int) i)
368*6a54128fSAndroid Build Coastguard Worker return; /* no space for EA magic */
369*6a54128fSAndroid Build Coastguard Worker
370*6a54128fSAndroid Build Coastguard Worker eaf = (__u32 *) (((char *) f) + sizeof(struct ext2_inode) +
371*6a54128fSAndroid Build Coastguard Worker extra_isize);
372*6a54128fSAndroid Build Coastguard Worker
373*6a54128fSAndroid Build Coastguard Worker attr_magic = *eaf;
374*6a54128fSAndroid Build Coastguard Worker if (!hostorder)
375*6a54128fSAndroid Build Coastguard Worker attr_magic = ext2fs_swab32(attr_magic);
376*6a54128fSAndroid Build Coastguard Worker
377*6a54128fSAndroid Build Coastguard Worker if (attr_magic != EXT2_EXT_ATTR_MAGIC)
378*6a54128fSAndroid Build Coastguard Worker return; /* it seems no magic here */
379*6a54128fSAndroid Build Coastguard Worker
380*6a54128fSAndroid Build Coastguard Worker eat = (__u32 *) (((char *) t) + sizeof(struct ext2_inode) +
381*6a54128fSAndroid Build Coastguard Worker extra_isize);
382*6a54128fSAndroid Build Coastguard Worker *eat = ext2fs_swab32(*eaf);
383*6a54128fSAndroid Build Coastguard Worker
384*6a54128fSAndroid Build Coastguard Worker /* convert EA(s) */
385*6a54128fSAndroid Build Coastguard Worker ext2fs_swap_ext_attr((char *) (eat + 1), (char *) (eaf + 1),
386*6a54128fSAndroid Build Coastguard Worker bufsize - sizeof(struct ext2_inode) -
387*6a54128fSAndroid Build Coastguard Worker extra_isize - sizeof(__u32), 0);
388*6a54128fSAndroid Build Coastguard Worker
389*6a54128fSAndroid Build Coastguard Worker }
390*6a54128fSAndroid Build Coastguard Worker
ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode * t,struct ext2_inode * f,int hostorder)391*6a54128fSAndroid Build Coastguard Worker void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t,
392*6a54128fSAndroid Build Coastguard Worker struct ext2_inode *f, int hostorder)
393*6a54128fSAndroid Build Coastguard Worker {
394*6a54128fSAndroid Build Coastguard Worker ext2fs_swap_inode_full(fs, (struct ext2_inode_large *) t,
395*6a54128fSAndroid Build Coastguard Worker (struct ext2_inode_large *) f, hostorder,
396*6a54128fSAndroid Build Coastguard Worker sizeof(struct ext2_inode));
397*6a54128fSAndroid Build Coastguard Worker }
398*6a54128fSAndroid Build Coastguard Worker
ext2fs_swap_mmp(struct mmp_struct * mmp)399*6a54128fSAndroid Build Coastguard Worker void ext2fs_swap_mmp(struct mmp_struct *mmp)
400*6a54128fSAndroid Build Coastguard Worker {
401*6a54128fSAndroid Build Coastguard Worker mmp->mmp_magic = ext2fs_swab32(mmp->mmp_magic);
402*6a54128fSAndroid Build Coastguard Worker mmp->mmp_seq = ext2fs_swab32(mmp->mmp_seq);
403*6a54128fSAndroid Build Coastguard Worker mmp->mmp_time = ext2fs_swab64(mmp->mmp_time);
404*6a54128fSAndroid Build Coastguard Worker mmp->mmp_check_interval = ext2fs_swab16(mmp->mmp_check_interval);
405*6a54128fSAndroid Build Coastguard Worker mmp->mmp_checksum = ext2fs_swab32(mmp->mmp_checksum);
406*6a54128fSAndroid Build Coastguard Worker }
407*6a54128fSAndroid Build Coastguard Worker
ext2fs_dirent_swab_in(ext2_filsys fs,char * buf,int flags)408*6a54128fSAndroid Build Coastguard Worker errcode_t ext2fs_dirent_swab_in(ext2_filsys fs, char *buf, int flags)
409*6a54128fSAndroid Build Coastguard Worker {
410*6a54128fSAndroid Build Coastguard Worker return ext2fs_dirent_swab_in2(fs, buf, fs->blocksize, flags);
411*6a54128fSAndroid Build Coastguard Worker }
412*6a54128fSAndroid Build Coastguard Worker
ext2fs_dirent_swab_in2(ext2_filsys fs,char * buf,size_t size,int flags)413*6a54128fSAndroid Build Coastguard Worker errcode_t ext2fs_dirent_swab_in2(ext2_filsys fs, char *buf,
414*6a54128fSAndroid Build Coastguard Worker size_t size, int flags)
415*6a54128fSAndroid Build Coastguard Worker {
416*6a54128fSAndroid Build Coastguard Worker errcode_t retval;
417*6a54128fSAndroid Build Coastguard Worker char *p, *end;
418*6a54128fSAndroid Build Coastguard Worker struct ext2_dir_entry *dirent;
419*6a54128fSAndroid Build Coastguard Worker unsigned int name_len, rec_len, left;
420*6a54128fSAndroid Build Coastguard Worker
421*6a54128fSAndroid Build Coastguard Worker p = (char *) buf;
422*6a54128fSAndroid Build Coastguard Worker end = (char *) buf + size;
423*6a54128fSAndroid Build Coastguard Worker left = size;
424*6a54128fSAndroid Build Coastguard Worker while (p < end-8) {
425*6a54128fSAndroid Build Coastguard Worker dirent = (struct ext2_dir_entry *) p;
426*6a54128fSAndroid Build Coastguard Worker dirent->inode = ext2fs_swab32(dirent->inode);
427*6a54128fSAndroid Build Coastguard Worker dirent->rec_len = ext2fs_swab16(dirent->rec_len);
428*6a54128fSAndroid Build Coastguard Worker dirent->name_len = ext2fs_swab16(dirent->name_len);
429*6a54128fSAndroid Build Coastguard Worker name_len = dirent->name_len;
430*6a54128fSAndroid Build Coastguard Worker if (flags & EXT2_DIRBLOCK_V2_STRUCT)
431*6a54128fSAndroid Build Coastguard Worker dirent->name_len = ext2fs_swab16(dirent->name_len);
432*6a54128fSAndroid Build Coastguard Worker retval = ext2fs_get_rec_len(fs, dirent, &rec_len);
433*6a54128fSAndroid Build Coastguard Worker if (retval)
434*6a54128fSAndroid Build Coastguard Worker return retval;
435*6a54128fSAndroid Build Coastguard Worker if ((rec_len < 8) || (rec_len % 4)) {
436*6a54128fSAndroid Build Coastguard Worker rec_len = 8;
437*6a54128fSAndroid Build Coastguard Worker if (!(fs->flags & EXT2_FLAG_IGNORE_SWAP_DIRENT))
438*6a54128fSAndroid Build Coastguard Worker return EXT2_ET_DIR_CORRUPTED;
439*6a54128fSAndroid Build Coastguard Worker } else if (((name_len & 0xFF) + 8) > rec_len)
440*6a54128fSAndroid Build Coastguard Worker if (!(fs->flags & EXT2_FLAG_IGNORE_SWAP_DIRENT))
441*6a54128fSAndroid Build Coastguard Worker return EXT2_ET_DIR_CORRUPTED;
442*6a54128fSAndroid Build Coastguard Worker if (rec_len > left)
443*6a54128fSAndroid Build Coastguard Worker if (!(fs->flags & EXT2_FLAG_IGNORE_SWAP_DIRENT))
444*6a54128fSAndroid Build Coastguard Worker return EXT2_ET_DIR_CORRUPTED;
445*6a54128fSAndroid Build Coastguard Worker left -= rec_len;
446*6a54128fSAndroid Build Coastguard Worker p += rec_len;
447*6a54128fSAndroid Build Coastguard Worker }
448*6a54128fSAndroid Build Coastguard Worker
449*6a54128fSAndroid Build Coastguard Worker return 0;
450*6a54128fSAndroid Build Coastguard Worker }
451*6a54128fSAndroid Build Coastguard Worker
ext2fs_dirent_swab_out(ext2_filsys fs,char * buf,int flags)452*6a54128fSAndroid Build Coastguard Worker errcode_t ext2fs_dirent_swab_out(ext2_filsys fs, char *buf, int flags)
453*6a54128fSAndroid Build Coastguard Worker {
454*6a54128fSAndroid Build Coastguard Worker return ext2fs_dirent_swab_out2(fs, buf, fs->blocksize, flags);
455*6a54128fSAndroid Build Coastguard Worker }
456*6a54128fSAndroid Build Coastguard Worker
ext2fs_dirent_swab_out2(ext2_filsys fs,char * buf,size_t size,int flags)457*6a54128fSAndroid Build Coastguard Worker errcode_t ext2fs_dirent_swab_out2(ext2_filsys fs, char *buf,
458*6a54128fSAndroid Build Coastguard Worker size_t size, int flags)
459*6a54128fSAndroid Build Coastguard Worker {
460*6a54128fSAndroid Build Coastguard Worker errcode_t retval;
461*6a54128fSAndroid Build Coastguard Worker char *p, *end;
462*6a54128fSAndroid Build Coastguard Worker unsigned int rec_len;
463*6a54128fSAndroid Build Coastguard Worker struct ext2_dir_entry *dirent;
464*6a54128fSAndroid Build Coastguard Worker
465*6a54128fSAndroid Build Coastguard Worker p = buf;
466*6a54128fSAndroid Build Coastguard Worker end = buf + size;
467*6a54128fSAndroid Build Coastguard Worker while (p < end) {
468*6a54128fSAndroid Build Coastguard Worker dirent = (struct ext2_dir_entry *) p;
469*6a54128fSAndroid Build Coastguard Worker retval = ext2fs_get_rec_len(fs, dirent, &rec_len);
470*6a54128fSAndroid Build Coastguard Worker if (retval)
471*6a54128fSAndroid Build Coastguard Worker return retval;
472*6a54128fSAndroid Build Coastguard Worker if ((rec_len < 8) ||
473*6a54128fSAndroid Build Coastguard Worker (rec_len % 4)) {
474*6a54128fSAndroid Build Coastguard Worker ext2fs_free_mem(&buf);
475*6a54128fSAndroid Build Coastguard Worker return EXT2_ET_DIR_CORRUPTED;
476*6a54128fSAndroid Build Coastguard Worker }
477*6a54128fSAndroid Build Coastguard Worker p += rec_len;
478*6a54128fSAndroid Build Coastguard Worker dirent->inode = ext2fs_swab32(dirent->inode);
479*6a54128fSAndroid Build Coastguard Worker dirent->rec_len = ext2fs_swab16(dirent->rec_len);
480*6a54128fSAndroid Build Coastguard Worker dirent->name_len = ext2fs_swab16(dirent->name_len);
481*6a54128fSAndroid Build Coastguard Worker if (rec_len > size)
482*6a54128fSAndroid Build Coastguard Worker return EXT2_ET_DIR_CORRUPTED;
483*6a54128fSAndroid Build Coastguard Worker size -= rec_len;
484*6a54128fSAndroid Build Coastguard Worker
485*6a54128fSAndroid Build Coastguard Worker if (flags & EXT2_DIRBLOCK_V2_STRUCT)
486*6a54128fSAndroid Build Coastguard Worker dirent->name_len = ext2fs_swab16(dirent->name_len);
487*6a54128fSAndroid Build Coastguard Worker }
488*6a54128fSAndroid Build Coastguard Worker
489*6a54128fSAndroid Build Coastguard Worker return 0;
490*6a54128fSAndroid Build Coastguard Worker }
491