1cfe60390STomohiro Kusumi /*-
2cfe60390STomohiro Kusumi * SPDX-License-Identifier: MIT-CMU
3cfe60390STomohiro Kusumi *
4cfe60390STomohiro Kusumi * Copyright (c) 1995 The University of Utah and
5cfe60390STomohiro Kusumi * the Computer Systems Laboratory at the University of Utah (CSL).
6cfe60390STomohiro Kusumi * All rights reserved.
7cfe60390STomohiro Kusumi *
8cfe60390STomohiro Kusumi * Permission to use, copy, modify and distribute this software is hereby
9cfe60390STomohiro Kusumi * granted provided that (1) source code retains these copyright, permission,
10cfe60390STomohiro Kusumi * and disclaimer notices, and (2) redistributions including binaries
11cfe60390STomohiro Kusumi * reproduce the notices in supporting documentation, and (3) all advertising
12cfe60390STomohiro Kusumi * materials mentioning features or use of this software display the following
13cfe60390STomohiro Kusumi * acknowledgement: ``This product includes software developed by the
14cfe60390STomohiro Kusumi * Computer Systems Laboratory at the University of Utah.''
15cfe60390STomohiro Kusumi *
16cfe60390STomohiro Kusumi * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
17cfe60390STomohiro Kusumi * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
18cfe60390STomohiro Kusumi * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19cfe60390STomohiro Kusumi *
20cfe60390STomohiro Kusumi * CSL requests users of this software to return to csl-dist@cs.utah.edu any
21cfe60390STomohiro Kusumi * improvements that they make and grant CSL redistribution rights.
22cfe60390STomohiro Kusumi *
23cfe60390STomohiro Kusumi * Utah $Hdr$
24cfe60390STomohiro Kusumi * $FreeBSD$
25cfe60390STomohiro Kusumi */
26cfe60390STomohiro Kusumi
27cfe60390STomohiro Kusumi /*
28cfe60390STomohiro Kusumi * routines to convert on disk ext2 inodes into inodes and back
29cfe60390STomohiro Kusumi */
30cfe60390STomohiro Kusumi #include <sys/param.h>
31cfe60390STomohiro Kusumi #include <sys/systm.h>
32cfe60390STomohiro Kusumi #include <sys/endian.h>
33cfe60390STomohiro Kusumi #include <sys/lock.h>
34cfe60390STomohiro Kusumi #include <sys/stat.h>
35cfe60390STomohiro Kusumi #include <sys/vnode.h>
36cfe60390STomohiro Kusumi
37cfe60390STomohiro Kusumi #include <vfs/ext2fs/fs.h>
38cfe60390STomohiro Kusumi #include <vfs/ext2fs/inode.h>
39cfe60390STomohiro Kusumi #include <vfs/ext2fs/ext2fs.h>
40cfe60390STomohiro Kusumi #include <vfs/ext2fs/ext2_dinode.h>
41cfe60390STomohiro Kusumi #include <vfs/ext2fs/ext2_extern.h>
42cfe60390STomohiro Kusumi
43cfe60390STomohiro Kusumi SDT_PROVIDER_DECLARE(ext2fs);
44cfe60390STomohiro Kusumi /*
45cfe60390STomohiro Kusumi * ext2fs trace probe:
46cfe60390STomohiro Kusumi * arg0: verbosity. Higher numbers give more verbose messages
47cfe60390STomohiro Kusumi * arg1: Textual message
48cfe60390STomohiro Kusumi */
49cfe60390STomohiro Kusumi SDT_PROBE_DEFINE2(ext2fs, , trace, inode_cnv, "int", "char*");
50cfe60390STomohiro Kusumi
51cfe60390STomohiro Kusumi #ifdef EXT2FS_PRINT_EXTENTS
52cfe60390STomohiro Kusumi void
ext2_print_inode(struct inode * in)53cfe60390STomohiro Kusumi ext2_print_inode(struct inode *in)
54cfe60390STomohiro Kusumi {
55cfe60390STomohiro Kusumi int i;
56cfe60390STomohiro Kusumi struct ext4_extent_header *ehp;
57cfe60390STomohiro Kusumi struct ext4_extent *ep;
58cfe60390STomohiro Kusumi
59cfe60390STomohiro Kusumi printf("Inode: %5ju", (uintmax_t)in->i_number);
60cfe60390STomohiro Kusumi printf( /* "Inode: %5d" */
61cfe60390STomohiro Kusumi " Type: %10s Mode: 0x%o Flags: 0x%x Version: %d acl: 0x%jx\n",
62cfe60390STomohiro Kusumi "n/a", in->i_mode, in->i_flags, in->i_gen, in->i_facl);
63cfe60390STomohiro Kusumi printf("User: %5u Group: %5u Size: %ju\n",
64cfe60390STomohiro Kusumi in->i_uid, in->i_gid, (uintmax_t)in->i_size);
65cfe60390STomohiro Kusumi printf("Links: %3d Blockcount: %ju\n",
66cfe60390STomohiro Kusumi in->i_nlink, (uintmax_t)in->i_blocks);
67*d4fdf3e6STomohiro Kusumi printf("ctime: 0x%llx ", (unsigned long long)in->i_ctime);
68*d4fdf3e6STomohiro Kusumi printf("atime: 0x%llx ", (unsigned long long)in->i_atime);
69*d4fdf3e6STomohiro Kusumi printf("mtime: 0x%llx ", (unsigned long long)in->i_mtime);
70cfe60390STomohiro Kusumi if (E2DI_HAS_XTIME(in))
71*d4fdf3e6STomohiro Kusumi printf("crtime %llx\n", (unsigned long long)in->i_birthtime);
72cfe60390STomohiro Kusumi else
73cfe60390STomohiro Kusumi printf("\n");
74cfe60390STomohiro Kusumi if (in->i_flag & IN_E4EXTENTS) {
75cfe60390STomohiro Kusumi printf("Extents:\n");
76cfe60390STomohiro Kusumi ehp = (struct ext4_extent_header *)in->i_db;
77cfe60390STomohiro Kusumi printf("Header (magic 0x%x entries %d max %d depth %d gen %d)\n",
78cfe60390STomohiro Kusumi le16toh(ehp->eh_magic), le16toh(ehp->eh_ecount),
79cfe60390STomohiro Kusumi le16toh(ehp->eh_max), le16toh(ehp->eh_depth),
80cfe60390STomohiro Kusumi le32toh(ehp->eh_gen));
81cfe60390STomohiro Kusumi ep = (struct ext4_extent *)(char *)(ehp + 1);
82cfe60390STomohiro Kusumi printf("Index (blk %d len %d start_lo %d start_hi %d)\n",
83cfe60390STomohiro Kusumi le32toh(ep->e_blk),
84cfe60390STomohiro Kusumi le16toh(ep->e_len), le32toh(ep->e_start_lo),
85cfe60390STomohiro Kusumi le16toh(ep->e_start_hi));
86cfe60390STomohiro Kusumi printf("\n");
87cfe60390STomohiro Kusumi } else {
88cfe60390STomohiro Kusumi printf("BLOCKS:");
89cfe60390STomohiro Kusumi for (i = 0; i < (in->i_blocks <= 24 ? (in->i_blocks + 1) / 2 : 12); i++)
90cfe60390STomohiro Kusumi printf(" %d", in->i_db[i]);
91cfe60390STomohiro Kusumi printf("\n");
92cfe60390STomohiro Kusumi }
93cfe60390STomohiro Kusumi }
94cfe60390STomohiro Kusumi #endif /* EXT2FS_PRINT_EXTENTS */
95cfe60390STomohiro Kusumi
96ff7e9f49STomohiro Kusumi static inline void
ext2_decode_extra_time(ext_time_t * sec,int32_t * nsec,uint32_t extra)97ff7e9f49STomohiro Kusumi ext2_decode_extra_time(ext_time_t *sec, int32_t *nsec, uint32_t extra)
98ff7e9f49STomohiro Kusumi {
99ff7e9f49STomohiro Kusumi if (extra & htole32(EXT3_EPOCH_MASK))
100ff7e9f49STomohiro Kusumi *sec += (uint64_t)(le32toh(extra) & EXT3_EPOCH_MASK) << 32;
101ff7e9f49STomohiro Kusumi
102ff7e9f49STomohiro Kusumi *nsec = (le32toh(extra) & EXT3_NSEC_MASK) >> EXT3_EPOCH_BITS;
103ff7e9f49STomohiro Kusumi }
104cfe60390STomohiro Kusumi
105cfe60390STomohiro Kusumi /*
106cfe60390STomohiro Kusumi * raw ext2 inode LE to host inode conversion
107cfe60390STomohiro Kusumi */
108cfe60390STomohiro Kusumi int
ext2_ei2i(struct ext2fs_dinode * ei,struct inode * ip)109cfe60390STomohiro Kusumi ext2_ei2i(struct ext2fs_dinode *ei, struct inode *ip)
110cfe60390STomohiro Kusumi {
111cfe60390STomohiro Kusumi struct m_ext2fs *fs = ip->i_e2fs;
112cfe60390STomohiro Kusumi uint32_t ei_flags_host;
113cfe60390STomohiro Kusumi uint16_t ei_extra_isize_le;
114cfe60390STomohiro Kusumi int i;
115cfe60390STomohiro Kusumi
116cfe60390STomohiro Kusumi if ((ip->i_number < EXT2_FIRST_INO(fs) && ip->i_number != EXT2_ROOTINO) ||
117cfe60390STomohiro Kusumi (ip->i_number < EXT2_ROOTINO) ||
118cfe60390STomohiro Kusumi (ip->i_number > le32toh(fs->e2fs->e2fs_icount))) {
119cfe60390STomohiro Kusumi SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, "bad inode number");
120cfe60390STomohiro Kusumi return (EINVAL);
121cfe60390STomohiro Kusumi }
122cfe60390STomohiro Kusumi
1237d478d3dSTomohiro Kusumi /*
1247d478d3dSTomohiro Kusumi * Godmar thinks - if the link count is zero, then the inode is
1257d478d3dSTomohiro Kusumi * unused - according to ext2 standards. Ufs marks this fact by
1267d478d3dSTomohiro Kusumi * setting i_mode to zero - why ? I can see that this might lead to
1277d478d3dSTomohiro Kusumi * problems in an undelete.
1287d478d3dSTomohiro Kusumi */
129cfe60390STomohiro Kusumi ip->i_nlink = le16toh(ei->e2di_nlink);
1307d478d3dSTomohiro Kusumi ip->i_mode = ip->i_nlink ? le16toh(ei->e2di_mode) : 0;
1317d478d3dSTomohiro Kusumi if (ip->i_number == EXT2_ROOTINO &&
1327d478d3dSTomohiro Kusumi (ip->i_nlink < 2 || !S_ISDIR(ip->i_mode))) {
1337d478d3dSTomohiro Kusumi SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, "root inode invalid");
134cfe60390STomohiro Kusumi return (EINVAL);
135cfe60390STomohiro Kusumi }
136cfe60390STomohiro Kusumi
137cfe60390STomohiro Kusumi /* Check extra inode size */
138cfe60390STomohiro Kusumi ei_extra_isize_le = le16toh(ei->e2di_extra_isize);
139cfe60390STomohiro Kusumi if (EXT2_INODE_SIZE(fs) > E2FS_REV0_INODE_SIZE) {
140cfe60390STomohiro Kusumi if (E2FS_REV0_INODE_SIZE + ei_extra_isize_le >
141cfe60390STomohiro Kusumi EXT2_INODE_SIZE(fs) || (ei_extra_isize_le & 3)) {
142cfe60390STomohiro Kusumi SDT_PROBE2(ext2fs, , trace, inode_cnv, 1,
143cfe60390STomohiro Kusumi "bad extra inode size");
144cfe60390STomohiro Kusumi return (EINVAL);
145cfe60390STomohiro Kusumi }
146cfe60390STomohiro Kusumi }
147cfe60390STomohiro Kusumi
148cfe60390STomohiro Kusumi ip->i_size = le32toh(ei->e2di_size);
149cfe60390STomohiro Kusumi if (S_ISREG(ip->i_mode))
150cfe60390STomohiro Kusumi ip->i_size |= (uint64_t)le32toh(ei->e2di_size_high) << 32;
151ff7e9f49STomohiro Kusumi ip->i_atime = (signed)le32toh(ei->e2di_atime);
152ff7e9f49STomohiro Kusumi ip->i_mtime = (signed)le32toh(ei->e2di_mtime);
153ff7e9f49STomohiro Kusumi ip->i_ctime = (signed)le32toh(ei->e2di_ctime);
154cfe60390STomohiro Kusumi if (E2DI_HAS_XTIME(ip)) {
155ff7e9f49STomohiro Kusumi ext2_decode_extra_time(&ip->i_atime, &ip->i_atimensec,
156ff7e9f49STomohiro Kusumi ei->e2di_atime_extra);
157ff7e9f49STomohiro Kusumi ext2_decode_extra_time(&ip->i_mtime, &ip->i_mtimensec,
158ff7e9f49STomohiro Kusumi ei->e2di_mtime_extra);
159ff7e9f49STomohiro Kusumi ext2_decode_extra_time(&ip->i_ctime, &ip->i_ctimensec,
160ff7e9f49STomohiro Kusumi ei->e2di_ctime_extra);
161ff7e9f49STomohiro Kusumi ip->i_birthtime = (signed)le32toh(ei->e2di_crtime);
162ff7e9f49STomohiro Kusumi ext2_decode_extra_time(&ip->i_birthtime, &ip->i_birthnsec,
163ff7e9f49STomohiro Kusumi ei->e2di_crtime_extra);
164cfe60390STomohiro Kusumi }
165cfe60390STomohiro Kusumi ip->i_flags = 0;
166cfe60390STomohiro Kusumi ei_flags_host = le32toh(ei->e2di_flags);
167cfe60390STomohiro Kusumi ip->i_flags |= (ei_flags_host & EXT2_APPEND) ? SF_APPEND : 0;
168cfe60390STomohiro Kusumi ip->i_flags |= (ei_flags_host & EXT2_IMMUTABLE) ? SF_IMMUTABLE : 0;
169cfe60390STomohiro Kusumi ip->i_flags |= (ei_flags_host & EXT2_NODUMP) ? UF_NODUMP : 0;
170cfe60390STomohiro Kusumi ip->i_flag |= (ei_flags_host & EXT3_INDEX) ? IN_E3INDEX : 0;
171cfe60390STomohiro Kusumi ip->i_flag |= (ei_flags_host & EXT4_EXTENTS) ? IN_E4EXTENTS : 0;
172cfe60390STomohiro Kusumi ip->i_blocks = le32toh(ei->e2di_nblock);
173cfe60390STomohiro Kusumi ip->i_facl = le32toh(ei->e2di_facl);
174cfe60390STomohiro Kusumi if (E2DI_HAS_HUGE_FILE(ip)) {
175cfe60390STomohiro Kusumi ip->i_blocks |= (uint64_t)le16toh(ei->e2di_nblock_high) << 32;
176cfe60390STomohiro Kusumi ip->i_facl |= (uint64_t)le16toh(ei->e2di_facl_high) << 32;
177cfe60390STomohiro Kusumi if (ei_flags_host & EXT4_HUGE_FILE)
178cfe60390STomohiro Kusumi ip->i_blocks = fsbtodb(ip->i_e2fs, ip->i_blocks);
179cfe60390STomohiro Kusumi }
180cfe60390STomohiro Kusumi ip->i_gen = le32toh(ei->e2di_gen);
181cfe60390STomohiro Kusumi ip->i_uid = le16toh(ei->e2di_uid);
182cfe60390STomohiro Kusumi ip->i_gid = le16toh(ei->e2di_gid);
183cfe60390STomohiro Kusumi ip->i_uid |= (uint32_t)le16toh(ei->e2di_uid_high) << 16;
184cfe60390STomohiro Kusumi ip->i_gid |= (uint32_t)le16toh(ei->e2di_gid_high) << 16;
185cfe60390STomohiro Kusumi
186cfe60390STomohiro Kusumi if ((ip->i_flag & IN_E4EXTENTS)) {
187cfe60390STomohiro Kusumi memcpy(ip->i_data, ei->e2di_blocks, sizeof(ei->e2di_blocks));
188cfe60390STomohiro Kusumi } else {
189cfe60390STomohiro Kusumi for (i = 0; i < EXT2_NDADDR; i++)
190cfe60390STomohiro Kusumi ip->i_db[i] = le32toh(ei->e2di_blocks[i]);
191cfe60390STomohiro Kusumi for (i = 0; i < EXT2_NIADDR; i++)
192cfe60390STomohiro Kusumi ip->i_ib[i] = le32toh(ei->e2di_blocks[EXT2_NDIR_BLOCKS + i]);
193cfe60390STomohiro Kusumi }
194cfe60390STomohiro Kusumi
195cfe60390STomohiro Kusumi /* Verify inode csum. */
196cfe60390STomohiro Kusumi return (ext2_ei_csum_verify(ip, ei));
197cfe60390STomohiro Kusumi }
198cfe60390STomohiro Kusumi
199ff7e9f49STomohiro Kusumi static inline uint32_t
ext2_encode_extra_time(int64_t sec,int32_t nsec)200ff7e9f49STomohiro Kusumi ext2_encode_extra_time(int64_t sec, int32_t nsec)
201ff7e9f49STomohiro Kusumi {
202ff7e9f49STomohiro Kusumi uint32_t extra;
203ff7e9f49STomohiro Kusumi
204ff7e9f49STomohiro Kusumi extra = ((sec - (int32_t)sec) >> 32) & EXT3_EPOCH_MASK;
205ff7e9f49STomohiro Kusumi
206ff7e9f49STomohiro Kusumi return (htole32(extra | (nsec << EXT3_EPOCH_BITS)));
207ff7e9f49STomohiro Kusumi }
208cfe60390STomohiro Kusumi
209cfe60390STomohiro Kusumi /*
210cfe60390STomohiro Kusumi * inode to raw ext2 LE inode conversion
211cfe60390STomohiro Kusumi */
212cfe60390STomohiro Kusumi int
ext2_i2ei(struct inode * ip,struct ext2fs_dinode * ei)213cfe60390STomohiro Kusumi ext2_i2ei(struct inode *ip, struct ext2fs_dinode *ei)
214cfe60390STomohiro Kusumi {
215cfe60390STomohiro Kusumi struct m_ext2fs *fs;
216cfe60390STomohiro Kusumi int i;
217cfe60390STomohiro Kusumi
218cfe60390STomohiro Kusumi fs = ip->i_e2fs;
219cfe60390STomohiro Kusumi ei->e2di_mode = htole16(ip->i_mode);
220cfe60390STomohiro Kusumi ei->e2di_nlink = htole16(ip->i_nlink);
221cfe60390STomohiro Kusumi ei->e2di_size = htole32(ip->i_size);
222cfe60390STomohiro Kusumi if (S_ISREG(ip->i_mode))
223cfe60390STomohiro Kusumi ei->e2di_size_high = htole32(ip->i_size >> 32);
224cfe60390STomohiro Kusumi ei->e2di_atime = htole32(ip->i_atime);
225cfe60390STomohiro Kusumi ei->e2di_mtime = htole32(ip->i_mtime);
226cfe60390STomohiro Kusumi ei->e2di_ctime = htole32(ip->i_ctime);
227cfe60390STomohiro Kusumi /*
228cfe60390STomohiro Kusumi * Godmar thinks: if dtime is nonzero, ext2 says this inode has been
229cfe60390STomohiro Kusumi * deleted, this would correspond to a zero link count
230cfe60390STomohiro Kusumi */
231cfe60390STomohiro Kusumi ei->e2di_dtime = htole32(le16toh(ei->e2di_nlink) ? 0 :
232cfe60390STomohiro Kusumi le32toh(ei->e2di_mtime));
233cfe60390STomohiro Kusumi if (E2DI_HAS_XTIME(ip)) {
234ff7e9f49STomohiro Kusumi ei->e2di_ctime_extra = ext2_encode_extra_time(ip->i_ctime,
235ff7e9f49STomohiro Kusumi ip->i_ctimensec);
236ff7e9f49STomohiro Kusumi ei->e2di_mtime_extra = ext2_encode_extra_time(ip->i_mtime,
237ff7e9f49STomohiro Kusumi ip->i_mtimensec);
238ff7e9f49STomohiro Kusumi ei->e2di_atime_extra = ext2_encode_extra_time(ip->i_atime,
239ff7e9f49STomohiro Kusumi ip->i_atimensec);
240cfe60390STomohiro Kusumi ei->e2di_crtime = htole32(ip->i_birthtime);
241ff7e9f49STomohiro Kusumi ei->e2di_crtime_extra = ext2_encode_extra_time(ip->i_birthtime,
242ff7e9f49STomohiro Kusumi ip->i_birthnsec);
243cfe60390STomohiro Kusumi }
244cfe60390STomohiro Kusumi /* Keep these in host endian for a while since they change a lot */
245cfe60390STomohiro Kusumi ei->e2di_flags = 0;
246cfe60390STomohiro Kusumi ei->e2di_flags |= htole32((ip->i_flags & SF_APPEND) ? EXT2_APPEND : 0);
247cfe60390STomohiro Kusumi ei->e2di_flags |= htole32((ip->i_flags & SF_IMMUTABLE) ? EXT2_IMMUTABLE : 0);
248cfe60390STomohiro Kusumi ei->e2di_flags |= htole32((ip->i_flags & UF_NODUMP) ? EXT2_NODUMP : 0);
249cfe60390STomohiro Kusumi ei->e2di_flags |= htole32((ip->i_flag & IN_E3INDEX) ? EXT3_INDEX : 0);
250cfe60390STomohiro Kusumi ei->e2di_flags |= htole32((ip->i_flag & IN_E4EXTENTS) ? EXT4_EXTENTS : 0);
251cfe60390STomohiro Kusumi if (ip->i_blocks > ~0U &&
252cfe60390STomohiro Kusumi !EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_HUGE_FILE)) {
253cfe60390STomohiro Kusumi SDT_PROBE2(ext2fs, , trace, inode_cnv, 1, "i_blocks value is out of range");
254cfe60390STomohiro Kusumi return (EIO);
255cfe60390STomohiro Kusumi }
256cfe60390STomohiro Kusumi if (ip->i_blocks <= 0xffffffffffffULL) {
257cfe60390STomohiro Kusumi ei->e2di_nblock = htole32(ip->i_blocks & 0xffffffff);
258cfe60390STomohiro Kusumi ei->e2di_nblock_high = htole16(ip->i_blocks >> 32 & 0xffff);
259cfe60390STomohiro Kusumi } else {
260cfe60390STomohiro Kusumi ei->e2di_flags |= htole32(EXT4_HUGE_FILE);
261cfe60390STomohiro Kusumi ei->e2di_nblock = htole32(dbtofsb(fs, ip->i_blocks));
262cfe60390STomohiro Kusumi ei->e2di_nblock_high = htole16(dbtofsb(fs, ip->i_blocks) >> 32 & 0xffff);
263cfe60390STomohiro Kusumi }
264cfe60390STomohiro Kusumi
265cfe60390STomohiro Kusumi ei->e2di_facl = htole32(ip->i_facl & 0xffffffff);
266cfe60390STomohiro Kusumi ei->e2di_facl_high = htole16(ip->i_facl >> 32 & 0xffff);
267cfe60390STomohiro Kusumi ei->e2di_gen = htole32(ip->i_gen);
268cfe60390STomohiro Kusumi ei->e2di_uid = htole16(ip->i_uid & 0xffff);
269cfe60390STomohiro Kusumi ei->e2di_uid_high = htole16(ip->i_uid >> 16 & 0xffff);
270cfe60390STomohiro Kusumi ei->e2di_gid = htole16(ip->i_gid & 0xffff);
271cfe60390STomohiro Kusumi ei->e2di_gid_high = htole16(ip->i_gid >> 16 & 0xffff);
272cfe60390STomohiro Kusumi
273cfe60390STomohiro Kusumi if ((ip->i_flag & IN_E4EXTENTS)) {
274cfe60390STomohiro Kusumi memcpy(ei->e2di_blocks, ip->i_data, sizeof(ei->e2di_blocks));
275cfe60390STomohiro Kusumi } else {
276cfe60390STomohiro Kusumi for (i = 0; i < EXT2_NDADDR; i++)
277cfe60390STomohiro Kusumi ei->e2di_blocks[i] = htole32(ip->i_db[i]);
278cfe60390STomohiro Kusumi for (i = 0; i < EXT2_NIADDR; i++)
279cfe60390STomohiro Kusumi ei->e2di_blocks[EXT2_NDIR_BLOCKS + i] = htole32(ip->i_ib[i]);
280cfe60390STomohiro Kusumi }
281cfe60390STomohiro Kusumi
282cfe60390STomohiro Kusumi /* Set inode csum. */
283cfe60390STomohiro Kusumi ext2_ei_csum_set(ip, ei);
284cfe60390STomohiro Kusumi
285cfe60390STomohiro Kusumi return (0);
286cfe60390STomohiro Kusumi }
287