2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
35 xfs_zone_t
*xfs_ifork_zone
;
36 xfs_zone_t
*xfs_inode_zone
;
48 j
= mp
->m_inode_cluster_size
>> mp
->m_sb
.sb_inodelog
;
50 for (i
= 0; i
< j
; i
++) {
51 dip
= (xfs_dinode_t
*)xfs_buf_offset(bp
,
52 i
* mp
->m_sb
.sb_inodesize
);
53 if (INT_ISZERO(dip
->di_next_unlinked
, ARCH_CONVERT
)) {
54 xfs_fs_cmn_err(CE_ALERT
, mp
,
55 "Detected a bogus zero next_unlinked field in incore inode buffer 0x%p. About to pop an ASSERT.",
57 ASSERT(!INT_ISZERO(dip
->di_next_unlinked
, ARCH_CONVERT
));
65 * This routine is called to map an inode to the buffer containing
66 * the on-disk version of the inode. It returns a pointer to the
67 * buffer containing the on-disk inode in the bpp parameter, and in
68 * the dip parameter it returns a pointer to the on-disk inode within
71 * If a non-zero error is returned, then the contents of bpp and
74 * If the inode is new and has not yet been initialized, use xfs_imap()
75 * to determine the size and location of the buffer to read from disk.
76 * If the inode has already been mapped to its buffer and read in once,
77 * then use the mapping information stored in the inode rather than
78 * calling xfs_imap(). This allows us to avoid the overhead of looking
79 * at the inode btree for small block file systems (see xfs_dilocate()).
80 * We can tell whether the inode has been mapped in before by comparing
81 * its disk block address to 0. Only uninitialized inodes will have
82 * 0 for the disk block address.
101 if (ip
->i_blkno
== (xfs_daddr_t
)0) {
103 * Call the space management code to find the location of the
107 error
= xfs_imap(mp
, tp
, ip
->i_ino
, &imap
, XFS_IMAP_LOOKUP
);
113 * If the inode number maps to a block outside the bounds
114 * of the file system then return NULL rather than calling
115 * read_buf and panicing when we get an error from the
118 if ((imap
.im_blkno
+ imap
.im_len
) >
119 XFS_FSB_TO_BB(mp
, mp
->m_sb
.sb_dblocks
)) {
120 return XFS_ERROR(EINVAL
);
124 * Fill in the fields in the inode that will be used to
125 * map the inode to its buffer from now on.
127 ip
->i_blkno
= imap
.im_blkno
;
128 ip
->i_len
= imap
.im_len
;
129 ip
->i_boffset
= imap
.im_boffset
;
132 * We've already mapped the inode once, so just use the
133 * mapping that we saved the first time.
135 imap
.im_blkno
= ip
->i_blkno
;
136 imap
.im_len
= ip
->i_len
;
137 imap
.im_boffset
= ip
->i_boffset
;
139 ASSERT(bno
== 0 || bno
== imap
.im_blkno
);
142 * Read in the buffer. If tp is NULL, xfs_trans_read_buf() will
143 * default to just a read_buf() call.
145 error
= xfs_trans_read_buf(mp
, tp
, mp
->m_ddev_targp
, imap
.im_blkno
,
146 (int)imap
.im_len
, XFS_BUF_LOCK
, &bp
);
153 * Validate the magic number and version of every inode in the buffer
154 * (if DEBUG kernel) or the first inode in the buffer, otherwise.
157 ni
= BBTOB(imap
.im_len
) >> mp
->m_sb
.sb_inodelog
;
161 for (i
= 0; i
< ni
; i
++) {
165 dip
= (xfs_dinode_t
*)xfs_buf_offset(bp
,
166 (i
<< mp
->m_sb
.sb_inodelog
));
167 di_ok
= INT_GET(dip
->di_core
.di_magic
, ARCH_CONVERT
) == XFS_DINODE_MAGIC
&&
168 XFS_DINODE_GOOD_VERSION(INT_GET(dip
->di_core
.di_version
, ARCH_CONVERT
));
169 if (XFS_TEST_ERROR(!di_ok
, mp
, XFS_ERRTAG_ITOBP_INOTOBP
,
170 XFS_RANDOM_ITOBP_INOTOBP
)) {
172 prdev("bad inode magic/vsn daddr 0x%Lx #%d (magic=%x)",
173 mp
->m_dev
, imap
.im_blkno
, i
,
174 INT_GET(dip
->di_core
.di_magic
, ARCH_CONVERT
));
176 xfs_trans_brelse(tp
, bp
);
177 return XFS_ERROR(EFSCORRUPTED
);
180 #endif /* __KERNEL__ */
182 xfs_inobp_check(mp
, bp
);
185 * Mark the buffer as an inode buffer now that it looks good
187 XFS_BUF_SET_VTYPE(bp
, B_FS_INO
);
190 * Set *dipp to point to the on-disk inode in the buffer.
192 *dipp
= (xfs_dinode_t
*)xfs_buf_offset(bp
, imap
.im_boffset
);
198 * Move inode type and inode format specific information from the
199 * on-disk inode to the in-core inode. For fifos, devs, and sockets
200 * this means set if_rdev to the proper value. For files, directories,
201 * and symlinks this means to bring in the in-line data or extent
202 * pointers. For a file in B-tree format, only the root is immediately
203 * brought in-core. The rest will be in-lined in if_extents when it
204 * is first referenced (see xfs_iread_extents()).
211 xfs_attr_shortform_t
*atp
;
215 ip
->i_df
.if_ext_max
=
216 XFS_IFORK_DSIZE(ip
) / (uint
)sizeof(xfs_bmbt_rec_t
);
219 if (INT_GET(dip
->di_core
.di_nextents
, ARCH_CONVERT
) +
220 INT_GET(dip
->di_core
.di_anextents
, ARCH_CONVERT
) >
221 INT_GET(dip
->di_core
.di_nblocks
, ARCH_CONVERT
)) {
222 xfs_fs_cmn_err(CE_WARN
, ip
->i_mount
,
223 "corrupt dinode %Lu, extent total = %d, nblocks = %Ld. Unmount and run xfs_repair.",
225 (int)(INT_GET(dip
->di_core
.di_nextents
, ARCH_CONVERT
) + INT_GET(dip
->di_core
.di_anextents
, ARCH_CONVERT
)),
226 INT_GET(dip
->di_core
.di_nblocks
, ARCH_CONVERT
));
227 return XFS_ERROR(EFSCORRUPTED
);
230 if (INT_GET(dip
->di_core
.di_forkoff
, ARCH_CONVERT
) > ip
->i_mount
->m_sb
.sb_inodesize
) {
231 xfs_fs_cmn_err(CE_WARN
, ip
->i_mount
,
232 "corrupt dinode %Lu, forkoff = 0x%x. Unmount and run xfs_repair.",
233 ip
->i_ino
, (int)(INT_GET(dip
->di_core
.di_forkoff
, ARCH_CONVERT
)));
234 return XFS_ERROR(EFSCORRUPTED
);
237 switch (ip
->i_d
.di_mode
& IFMT
) {
242 if (INT_GET(dip
->di_core
.di_format
, ARCH_CONVERT
) != XFS_DINODE_FMT_DEV
)
243 return XFS_ERROR(EFSCORRUPTED
);
245 ip
->i_df
.if_u2
.if_rdev
= INT_GET(dip
->di_u
.di_dev
, ARCH_CONVERT
);
251 switch (INT_GET(dip
->di_core
.di_format
, ARCH_CONVERT
)) {
252 case XFS_DINODE_FMT_LOCAL
:
254 * no local regular files yet
256 if ((INT_GET(dip
->di_core
.di_mode
, ARCH_CONVERT
) & IFMT
) == IFREG
) {
257 xfs_fs_cmn_err(CE_WARN
, ip
->i_mount
,
258 "corrupt inode (local format for regular file) %Lu. Unmount and run xfs_repair.",
260 return XFS_ERROR(EFSCORRUPTED
);
263 di_size
=INT_GET(dip
->di_core
.di_size
, ARCH_CONVERT
);
265 XFS_DFORK_DSIZE_ARCH(dip
, ip
->i_mount
, ARCH_CONVERT
)) {
266 xfs_fs_cmn_err(CE_WARN
, ip
->i_mount
,
267 "corrupt inode %Lu (bad size %Ld for local inode). Unmount and run xfs_repair.",
269 return XFS_ERROR(EFSCORRUPTED
);
273 error
= xfs_iformat_local(ip
, dip
, XFS_DATA_FORK
, size
);
275 case XFS_DINODE_FMT_EXTENTS
:
276 error
= xfs_iformat_extents(ip
, dip
, XFS_DATA_FORK
);
278 case XFS_DINODE_FMT_BTREE
:
279 error
= xfs_iformat_btree(ip
, dip
, XFS_DATA_FORK
);
282 return XFS_ERROR(EFSCORRUPTED
);
287 return XFS_ERROR(EFSCORRUPTED
);
292 if (!XFS_DFORK_Q_ARCH(dip
, ARCH_CONVERT
))
294 ASSERT(ip
->i_afp
== NULL
);
295 ip
->i_afp
= kmem_zone_zalloc(xfs_ifork_zone
, KM_SLEEP
);
296 ip
->i_afp
->if_ext_max
=
297 XFS_IFORK_ASIZE(ip
) / (uint
)sizeof(xfs_bmbt_rec_t
);
298 switch (INT_GET(dip
->di_core
.di_aformat
, ARCH_CONVERT
)) {
299 case XFS_DINODE_FMT_LOCAL
:
300 atp
= (xfs_attr_shortform_t
*)XFS_DFORK_APTR_ARCH(dip
, ARCH_CONVERT
);
301 size
= (int)INT_GET(atp
->hdr
.totsize
, ARCH_CONVERT
);
302 error
= xfs_iformat_local(ip
, dip
, XFS_ATTR_FORK
, size
);
304 case XFS_DINODE_FMT_EXTENTS
:
305 error
= xfs_iformat_extents(ip
, dip
, XFS_ATTR_FORK
);
307 case XFS_DINODE_FMT_BTREE
:
308 error
= xfs_iformat_btree(ip
, dip
, XFS_ATTR_FORK
);
311 error
= XFS_ERROR(EFSCORRUPTED
);
315 kmem_zone_free(xfs_ifork_zone
, ip
->i_afp
);
317 xfs_idestroy_fork(ip
, XFS_DATA_FORK
);
323 * The file is in-lined in the on-disk inode.
324 * If it fits into if_inline_data, then copy
325 * it there, otherwise allocate a buffer for it
326 * and copy the data there. Either way, set
327 * if_data to point at the data.
328 * If we allocate a buffer for the data, make
329 * sure that its size is a multiple of 4 and
330 * record the real size in i_real_bytes.
343 * If the size is unreasonable, then something
344 * is wrong and we just bail out rather than crash in
345 * kmem_alloc() or bcopy() below.
347 if (size
> XFS_DFORK_SIZE_ARCH(dip
, ip
->i_mount
, whichfork
, ARCH_CONVERT
)) {
348 xfs_fs_cmn_err(CE_WARN
, ip
->i_mount
,
349 "corrupt inode %Lu (bad size %d for local fork, size = %d). Unmount and run xfs_repair.",
351 XFS_DFORK_SIZE_ARCH(dip
, ip
->i_mount
, whichfork
, ARCH_CONVERT
));
352 return XFS_ERROR(EFSCORRUPTED
);
354 ifp
= XFS_IFORK_PTR(ip
, whichfork
);
357 ifp
->if_u1
.if_data
= NULL
;
358 else if (size
<= sizeof(ifp
->if_u2
.if_inline_data
))
359 ifp
->if_u1
.if_data
= ifp
->if_u2
.if_inline_data
;
361 real_size
= roundup(size
, 4);
362 ifp
->if_u1
.if_data
= kmem_alloc(real_size
, KM_SLEEP
);
364 ifp
->if_bytes
= size
;
365 ifp
->if_real_bytes
= real_size
;
367 bcopy(XFS_DFORK_PTR_ARCH(dip
, whichfork
, ARCH_CONVERT
), ifp
->if_u1
.if_data
, size
);
368 ifp
->if_flags
&= ~XFS_IFEXTENTS
;
369 ifp
->if_flags
|= XFS_IFINLINE
;
374 * The file consists of a set of extents all
375 * of which fit into the on-disk inode.
376 * If there are few enough extents to fit into
377 * the if_inline_ext, then copy them there.
378 * Otherwise allocate a buffer for them and copy
379 * them into it. Either way, set if_extents
380 * to point at the extents.
393 ifp
= XFS_IFORK_PTR(ip
, whichfork
);
394 nex
= XFS_DFORK_NEXTENTS_ARCH(dip
, whichfork
, ARCH_CONVERT
);
395 size
= nex
* (uint
)sizeof(xfs_bmbt_rec_t
);
398 * If the number of extents is unreasonable, then something
399 * is wrong and we just bail out rather than crash in
400 * kmem_alloc() or bcopy() below.
402 if (size
< 0 || size
> XFS_DFORK_SIZE_ARCH(dip
, ip
->i_mount
, whichfork
, ARCH_CONVERT
)) {
403 xfs_fs_cmn_err(CE_WARN
, ip
->i_mount
,
404 "corrupt inode %Lu ((a)extents = %d). Unmount and run xfs_repair.",
406 return XFS_ERROR(EFSCORRUPTED
);
411 ifp
->if_u1
.if_extents
= NULL
;
412 else if (nex
<= XFS_INLINE_EXTS
)
413 ifp
->if_u1
.if_extents
= ifp
->if_u2
.if_inline_ext
;
415 ifp
->if_u1
.if_extents
= kmem_alloc(size
, KM_SLEEP
);
416 ASSERT(ifp
->if_u1
.if_extents
!= NULL
);
419 ifp
->if_bytes
= size
;
420 ifp
->if_real_bytes
= real_size
;
422 xfs_validate_extents(
423 (xfs_bmbt_rec_32_t
*)XFS_DFORK_PTR_ARCH(dip
, whichfork
, ARCH_CONVERT
),
424 nex
, XFS_EXTFMT_INODE(ip
));
425 bcopy(XFS_DFORK_PTR_ARCH(dip
, whichfork
, ARCH_CONVERT
), ifp
->if_u1
.if_extents
,
427 xfs_bmap_trace_exlist("xfs_iformat_extents", ip
, nex
,
429 if (whichfork
!= XFS_DATA_FORK
||
430 XFS_EXTFMT_INODE(ip
) == XFS_EXTFMT_NOSTATE
)
431 if (xfs_check_nostate_extents(
432 ifp
->if_u1
.if_extents
, nex
))
433 return XFS_ERROR(EFSCORRUPTED
);
435 ifp
->if_flags
|= XFS_IFEXTENTS
;
440 * The file has too many extents to fit into
441 * the inode, so they are in B-tree format.
442 * Allocate a buffer for the root of the B-tree
443 * and copy the root into it. The i_extents
444 * field will remain NULL until all of the
445 * extents are read in (when they are needed).
453 xfs_bmdr_block_t
*dfp
;
459 ifp
= XFS_IFORK_PTR(ip
, whichfork
);
460 dfp
= (xfs_bmdr_block_t
*)XFS_DFORK_PTR_ARCH(dip
, whichfork
, ARCH_CONVERT
);
461 size
= XFS_BMAP_BROOT_SPACE(dfp
);
462 nrecs
= XFS_BMAP_BROOT_NUMRECS(dfp
);
465 * blow out if -- fork has less extents than can fit in
466 * fork (fork shouldn't be a btree format), root btree
467 * block has more records than can fit into the fork,
468 * or the number of extents is greater than the number of
471 if (XFS_IFORK_NEXTENTS(ip
, whichfork
) <= ifp
->if_ext_max
472 || XFS_BMDR_SPACE_CALC(nrecs
) >
473 XFS_DFORK_SIZE_ARCH(dip
, ip
->i_mount
, whichfork
, ARCH_CONVERT
)
474 || XFS_IFORK_NEXTENTS(ip
, whichfork
) > ip
->i_d
.di_nblocks
) {
475 xfs_fs_cmn_err(CE_WARN
, ip
->i_mount
,
476 "corrupt inode %Lu (btree). Unmount and run xfs_repair.",
478 return XFS_ERROR(EFSCORRUPTED
);
481 ifp
->if_broot_bytes
= size
;
482 ifp
->if_broot
= kmem_alloc(size
, KM_SLEEP
);
483 ASSERT(ifp
->if_broot
!= NULL
);
485 * Copy and convert from the on-disk structure
486 * to the in-memory structure.
488 xfs_bmdr_to_bmbt(dfp
, XFS_DFORK_SIZE_ARCH(dip
, ip
->i_mount
, whichfork
, ARCH_CONVERT
),
489 ifp
->if_broot
, size
);
490 ifp
->if_flags
&= ~XFS_IFEXTENTS
;
491 ifp
->if_flags
|= XFS_IFBROOT
;
497 * xfs_xlate_dinode_core - translate an xfs_inode_core_t between ondisk
500 * buf = on-disk representation
501 * dip = native representation
502 * dir = direction - +ve -> disk to native
503 * -ve -> native to disk
504 * arch = on-disk architecture
508 xfs_xlate_dinode_core(xfs_caddr_t buf
, xfs_dinode_core_t
*dip
,
509 int dir
, xfs_arch_t arch
)
511 xfs_dinode_core_t
*buf_core
;
512 xfs_dinode_core_t
*mem_core
;
516 buf_core
=(xfs_dinode_core_t
*)buf
;
517 mem_core
=(xfs_dinode_core_t
*)dip
;
519 if (arch
== ARCH_NOCONVERT
) {
521 bcopy((xfs_caddr_t
)buf_core
, (xfs_caddr_t
)mem_core
, sizeof(xfs_dinode_core_t
));
523 bcopy((xfs_caddr_t
)mem_core
, (xfs_caddr_t
)buf_core
, sizeof(xfs_dinode_core_t
));
528 INT_XLATE(buf_core
->di_magic
, mem_core
->di_magic
, dir
, arch
);
529 INT_XLATE(buf_core
->di_mode
, mem_core
->di_mode
, dir
, arch
);
530 INT_XLATE(buf_core
->di_version
, mem_core
->di_version
, dir
, arch
);
531 INT_XLATE(buf_core
->di_format
, mem_core
->di_format
, dir
, arch
);
532 INT_XLATE(buf_core
->di_onlink
, mem_core
->di_onlink
, dir
, arch
);
533 INT_XLATE(buf_core
->di_uid
, mem_core
->di_uid
, dir
, arch
);
534 INT_XLATE(buf_core
->di_gid
, mem_core
->di_gid
, dir
, arch
);
535 INT_XLATE(buf_core
->di_nlink
, mem_core
->di_nlink
, dir
, arch
);
536 INT_XLATE(buf_core
->di_projid
, mem_core
->di_projid
, dir
, arch
);
539 bcopy(buf_core
->di_pad
, mem_core
->di_pad
, sizeof(buf_core
->di_pad
));
541 bcopy(mem_core
->di_pad
, buf_core
->di_pad
, sizeof(buf_core
->di_pad
));
544 INT_XLATE(buf_core
->di_atime
.t_sec
, mem_core
->di_atime
.t_sec
, dir
, arch
);
545 INT_XLATE(buf_core
->di_atime
.t_nsec
,mem_core
->di_atime
.t_nsec
, dir
, arch
);
547 INT_XLATE(buf_core
->di_mtime
.t_sec
, mem_core
->di_mtime
.t_sec
, dir
, arch
);
548 INT_XLATE(buf_core
->di_mtime
.t_nsec
,mem_core
->di_mtime
.t_nsec
, dir
, arch
);
550 INT_XLATE(buf_core
->di_ctime
.t_sec
, mem_core
->di_ctime
.t_sec
, dir
, arch
);
551 INT_XLATE(buf_core
->di_ctime
.t_nsec
,mem_core
->di_ctime
.t_nsec
, dir
, arch
);
553 INT_XLATE(buf_core
->di_size
, mem_core
->di_size
, dir
, arch
);
554 INT_XLATE(buf_core
->di_nblocks
, mem_core
->di_nblocks
, dir
, arch
);
555 INT_XLATE(buf_core
->di_extsize
, mem_core
->di_extsize
, dir
, arch
);
557 INT_XLATE(buf_core
->di_nextents
, mem_core
->di_nextents
, dir
, arch
);
558 INT_XLATE(buf_core
->di_anextents
, mem_core
->di_anextents
, dir
, arch
);
559 INT_XLATE(buf_core
->di_forkoff
, mem_core
->di_forkoff
, dir
, arch
);
560 INT_XLATE(buf_core
->di_aformat
, mem_core
->di_aformat
, dir
, arch
);
561 INT_XLATE(buf_core
->di_dmevmask
, mem_core
->di_dmevmask
, dir
, arch
);
562 INT_XLATE(buf_core
->di_dmstate
, mem_core
->di_dmstate
, dir
, arch
);
563 INT_XLATE(buf_core
->di_flags
, mem_core
->di_flags
, dir
, arch
);
564 INT_XLATE(buf_core
->di_gen
, mem_core
->di_gen
, dir
, arch
);
569 * Given a mount structure and an inode number, return a pointer
570 * to a newly allocated in-core inode coresponding to the given
573 * Initialize the inode's attributes and extent pointers if it
574 * already has them (it will not if the inode has no links).
589 ASSERT(xfs_inode_zone
!= NULL
);
591 ip
= kmem_zone_zalloc(xfs_inode_zone
, KM_SLEEP
);
593 ip
->i_dev
= mp
->m_dev
;
597 * Get pointer's to the on-disk inode and the buffer containing it.
598 * If the inode number refers to a block outside the file system
599 * then xfs_itobp() will return NULL. In this case we should
600 * return NULL as well. Set i_blkno to 0 so that xfs_itobp() will
601 * know that this is a new incore inode.
603 error
= xfs_itobp(mp
, tp
, ip
, &dip
, &bp
, bno
);
606 kmem_zone_free(xfs_inode_zone
, ip
);
611 * Initialize inode's trace buffers.
612 * Do this before xfs_iformat in case it adds entries.
614 #ifdef XFS_BMAP_TRACE
615 ip
->i_xtrace
= ktrace_alloc(XFS_BMAP_KTRACE_SIZE
, KM_SLEEP
);
617 #ifdef XFS_BMBT_TRACE
618 ip
->i_btrace
= ktrace_alloc(XFS_BMBT_KTRACE_SIZE
, KM_SLEEP
);
621 ip
->i_rwtrace
= ktrace_alloc(XFS_RW_KTRACE_SIZE
, KM_SLEEP
);
623 #ifdef XFS_STRAT_TRACE
624 ip
->i_strat_trace
= ktrace_alloc(XFS_STRAT_KTRACE_SIZE
, KM_SLEEP
);
626 #ifdef XFS_ILOCK_TRACE
627 ip
->i_lock_trace
= ktrace_alloc(XFS_ILOCK_KTRACE_SIZE
, KM_SLEEP
);
629 #ifdef XFS_DIR2_TRACE
630 ip
->i_dir_trace
= ktrace_alloc(XFS_DIR2_KTRACE_SIZE
, KM_SLEEP
);
634 * If we got something that isn't an inode it means someone
635 * (nfs or dmi) has a stale handle.
637 if (INT_GET(dip
->di_core
.di_magic
, ARCH_CONVERT
) != XFS_DINODE_MAGIC
) {
638 kmem_zone_free(xfs_inode_zone
, ip
);
639 xfs_trans_brelse(tp
, bp
);
640 return XFS_ERROR(EINVAL
);
644 * If the on-disk inode is already linked to a directory
645 * entry, copy all of the inode into the in-core inode.
646 * xfs_iformat() handles copying in the inode format
647 * specific information.
648 * Otherwise, just get the truly permanent information.
650 if (!INT_ISZERO(dip
->di_core
.di_mode
, ARCH_CONVERT
)) {
651 xfs_xlate_dinode_core((xfs_caddr_t
)&dip
->di_core
,
652 &(ip
->i_d
), 1, ARCH_CONVERT
);
653 error
= xfs_iformat(ip
, dip
);
655 kmem_zone_free(xfs_inode_zone
, ip
);
656 xfs_trans_brelse(tp
, bp
);
660 ip
->i_d
.di_magic
= INT_GET(dip
->di_core
.di_magic
, ARCH_CONVERT
);
661 ip
->i_d
.di_version
= INT_GET(dip
->di_core
.di_version
, ARCH_CONVERT
);
662 ip
->i_d
.di_gen
= INT_GET(dip
->di_core
.di_gen
, ARCH_CONVERT
);
664 * Make sure to pull in the mode here as well in
665 * case the inode is released without being used.
666 * This ensures that xfs_inactive() will see that
667 * the inode is already free and not try to mess
668 * with the uninitialized part of it.
672 * Initialize the per-fork minima and maxima for a new
673 * inode here. xfs_iformat will do it for old inodes.
675 ip
->i_df
.if_ext_max
=
676 XFS_IFORK_DSIZE(ip
) / (uint
)sizeof(xfs_bmbt_rec_t
);
680 * The inode format changed when we moved the link count and
681 * made it 32 bits long. If this is an old format inode,
682 * convert it in memory to look like a new one. If it gets
683 * flushed to disk we will convert back before flushing or
684 * logging it. We zero out the new projid field and the old link
685 * count field. We'll handle clearing the pad field (the remains
686 * of the old uuid field) when we actually convert the inode to
687 * the new format. We don't change the version number so that we
688 * can distinguish this from a real new format inode.
690 if (ip
->i_d
.di_version
== XFS_DINODE_VERSION_1
) {
691 ip
->i_d
.di_nlink
= ip
->i_d
.di_onlink
;
692 ip
->i_d
.di_onlink
= 0;
693 ip
->i_d
.di_projid
= 0;
696 ip
->i_delayed_blks
= 0;
699 * Mark the buffer containing the inode as something to keep
700 * around for a while. This helps to keep recently accessed
701 * meta-data in-core longer.
703 XFS_BUF_SET_REF(bp
, XFS_INO_REF
);
706 * Use xfs_trans_brelse() to release the buffer containing the
707 * on-disk inode, because it was acquired with xfs_trans_read_buf()
708 * in xfs_itobp() above. If tp is NULL, this is just a normal
709 * brelse(). If we're within a transaction, then xfs_trans_brelse()
710 * will only release the buffer if it is not dirty within the
711 * transaction. It will be OK to release the buffer in this case,
712 * because inodes on disk are never destroyed and we will be
713 * locking the new in-core inode before putting it in the hash
714 * table where other processes can find it. Thus we don't have
715 * to worry about the inode being changed just because we released
718 xfs_trans_brelse(tp
, bp
);
724 * Read in extents from a btree-format inode.
725 * Allocate and fill in if_extents. Real work is done in xfs_bmap.c.
737 if (XFS_IFORK_FORMAT(ip
, whichfork
) != XFS_DINODE_FMT_BTREE
)
738 return XFS_ERROR(EFSCORRUPTED
);
739 size
= XFS_IFORK_NEXTENTS(ip
, whichfork
) * (uint
)sizeof(xfs_bmbt_rec_t
);
740 ifp
= XFS_IFORK_PTR(ip
, whichfork
);
742 * We know that the size is legal (it's checked in iformat_btree)
744 ifp
->if_u1
.if_extents
= kmem_alloc(size
, KM_SLEEP
);
745 ASSERT(ifp
->if_u1
.if_extents
!= NULL
);
746 ifp
->if_lastex
= NULLEXTNUM
;
747 ifp
->if_bytes
= ifp
->if_real_bytes
= (int)size
;
748 ifp
->if_flags
|= XFS_IFEXTENTS
;
749 error
= xfs_bmap_read_extents(tp
, ip
, whichfork
);
751 kmem_free(ifp
->if_u1
.if_extents
, size
);
752 ifp
->if_u1
.if_extents
= NULL
;
753 ifp
->if_bytes
= ifp
->if_real_bytes
= 0;
754 ifp
->if_flags
&= ~XFS_IFEXTENTS
;
757 xfs_validate_extents((xfs_bmbt_rec_32_t
*)ifp
->if_u1
.if_extents
,
758 XFS_IFORK_NEXTENTS(ip
, whichfork
), XFS_EXTFMT_INODE(ip
));
763 * Reallocate the space for if_broot based on the number of records
764 * being added or deleted as indicated in rec_diff. Move the records
765 * and pointers in if_broot to fit the new size. When shrinking this
766 * will eliminate holes between the records and pointers created by
767 * the caller. When growing this will create holes to be filled in
770 * The caller must not request to add more records than would fit in
771 * the on-disk inode root. If the if_broot is currently NULL, then
772 * if we adding records one will be allocated. The caller must also
773 * not request that the number of records go below zero, although
776 * ip -- the inode whose if_broot area is changing
777 * ext_diff -- the change in the number of records, positive or negative,
778 * requested for the if_broot array.
788 xfs_bmbt_block_t
*new_broot
;
795 * Handle the degenerate case quietly.
801 ifp
= XFS_IFORK_PTR(ip
, whichfork
);
804 * If there wasn't any memory allocated before, just
805 * allocate it now and get out.
807 if (ifp
->if_broot_bytes
== 0) {
808 new_size
= (size_t)XFS_BMAP_BROOT_SPACE_CALC(rec_diff
);
809 ifp
->if_broot
= (xfs_bmbt_block_t
*)kmem_alloc(new_size
,
811 ifp
->if_broot_bytes
= (int)new_size
;
816 * If there is already an existing if_broot, then we need
817 * to realloc() it and shift the pointers to their new
818 * location. The records don't change location because
819 * they are kept butted up against the btree block header.
821 cur_max
= XFS_BMAP_BROOT_MAXRECS(ifp
->if_broot_bytes
);
822 new_max
= cur_max
+ rec_diff
;
823 new_size
= (size_t)XFS_BMAP_BROOT_SPACE_CALC(new_max
);
824 ifp
->if_broot
= (xfs_bmbt_block_t
*)
825 kmem_realloc(ifp
->if_broot
,
827 (size_t)XFS_BMAP_BROOT_SPACE_CALC(cur_max
), /* old size */
829 op
= (char *)XFS_BMAP_BROOT_PTR_ADDR(ifp
->if_broot
, 1,
830 ifp
->if_broot_bytes
);
831 np
= (char *)XFS_BMAP_BROOT_PTR_ADDR(ifp
->if_broot
, 1,
833 ifp
->if_broot_bytes
= (int)new_size
;
834 ASSERT(ifp
->if_broot_bytes
<=
835 XFS_IFORK_SIZE(ip
, whichfork
) + XFS_BROOT_SIZE_ADJ
);
836 ovbcopy(op
, np
, cur_max
* (uint
)sizeof(xfs_dfsbno_t
));
841 * rec_diff is less than 0. In this case, we are shrinking the
842 * if_broot buffer. It must already exist. If we go to zero
843 * records, just get rid of the root and clear the status bit.
845 ASSERT((ifp
->if_broot
!= NULL
) && (ifp
->if_broot_bytes
> 0));
846 cur_max
= XFS_BMAP_BROOT_MAXRECS(ifp
->if_broot_bytes
);
847 new_max
= cur_max
+ rec_diff
;
848 ASSERT(new_max
>= 0);
850 new_size
= (size_t)XFS_BMAP_BROOT_SPACE_CALC(new_max
);
854 new_broot
= (xfs_bmbt_block_t
*)kmem_alloc(new_size
, KM_SLEEP
);
856 * First copy over the btree block header.
858 bcopy(ifp
->if_broot
, new_broot
, sizeof(xfs_bmbt_block_t
));
861 ifp
->if_flags
&= ~XFS_IFBROOT
;
865 * Only copy the records and pointers if there are any.
869 * First copy the records.
871 op
= (char *)XFS_BMAP_BROOT_REC_ADDR(ifp
->if_broot
, 1,
872 ifp
->if_broot_bytes
);
873 np
= (char *)XFS_BMAP_BROOT_REC_ADDR(new_broot
, 1,
875 bcopy(op
, np
, new_max
* (uint
)sizeof(xfs_bmbt_rec_t
));
878 * Then copy the pointers.
880 op
= (char *)XFS_BMAP_BROOT_PTR_ADDR(ifp
->if_broot
, 1,
881 ifp
->if_broot_bytes
);
882 np
= (char *)XFS_BMAP_BROOT_PTR_ADDR(new_broot
, 1,
884 bcopy(op
, np
, new_max
* (uint
)sizeof(xfs_dfsbno_t
));
886 kmem_free(ifp
->if_broot
, ifp
->if_broot_bytes
);
887 ifp
->if_broot
= new_broot
;
888 ifp
->if_broot_bytes
= (int)new_size
;
889 ASSERT(ifp
->if_broot_bytes
<=
890 XFS_IFORK_SIZE(ip
, whichfork
) + XFS_BROOT_SIZE_ADJ
);
895 * This is called when the amount of space needed for if_extents
896 * is increased or decreased. The change in size is indicated by
897 * the number of extents that need to be added or deleted in the
898 * ext_diff parameter.
900 * If the amount of space needed has decreased below the size of the
901 * inline buffer, then switch to using the inline buffer. Otherwise,
902 * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer
905 * ip -- the inode whose if_extents area is changing
906 * ext_diff -- the change in the number of extents, positive or negative,
907 * requested for the if_extents array.
924 ifp
= XFS_IFORK_PTR(ip
, whichfork
);
925 byte_diff
= ext_diff
* (uint
)sizeof(xfs_bmbt_rec_t
);
926 new_size
= (int)ifp
->if_bytes
+ byte_diff
;
927 ASSERT(new_size
>= 0);
930 if (ifp
->if_u1
.if_extents
!= ifp
->if_u2
.if_inline_ext
) {
931 ASSERT(ifp
->if_real_bytes
!= 0);
932 kmem_free(ifp
->if_u1
.if_extents
, ifp
->if_real_bytes
);
934 ifp
->if_u1
.if_extents
= NULL
;
936 } else if (new_size
<= sizeof(ifp
->if_u2
.if_inline_ext
)) {
938 * If the valid extents can fit in if_inline_ext,
939 * copy them from the malloc'd vector and free it.
941 if (ifp
->if_u1
.if_extents
!= ifp
->if_u2
.if_inline_ext
) {
943 * For now, empty files are format EXTENTS,
944 * so the if_extents pointer is null.
946 if (ifp
->if_u1
.if_extents
) {
947 bcopy(ifp
->if_u1
.if_extents
,
948 ifp
->if_u2
.if_inline_ext
, new_size
);
949 kmem_free(ifp
->if_u1
.if_extents
,
952 ifp
->if_u1
.if_extents
= ifp
->if_u2
.if_inline_ext
;
956 rnew_size
= new_size
;
957 if ((rnew_size
& (rnew_size
- 1)) != 0)
958 rnew_size
= xfs_iroundup(rnew_size
);
960 * Stuck with malloc/realloc.
962 if (ifp
->if_u1
.if_extents
== ifp
->if_u2
.if_inline_ext
) {
963 ifp
->if_u1
.if_extents
= (xfs_bmbt_rec_t
*)
964 kmem_alloc(rnew_size
, KM_SLEEP
);
965 bcopy(ifp
->if_u2
.if_inline_ext
, ifp
->if_u1
.if_extents
,
966 sizeof(ifp
->if_u2
.if_inline_ext
));
967 } else if (rnew_size
!= ifp
->if_real_bytes
) {
968 ifp
->if_u1
.if_extents
= (xfs_bmbt_rec_t
*)
969 kmem_realloc(ifp
->if_u1
.if_extents
,
975 ifp
->if_real_bytes
= rnew_size
;
976 ifp
->if_bytes
= new_size
;
981 * This is called when the amount of space needed for if_data
982 * is increased or decreased. The change in size is indicated by
983 * the number of bytes that need to be added or deleted in the
984 * byte_diff parameter.
986 * If the amount of space needed has decreased below the size of the
987 * inline buffer, then switch to using the inline buffer. Otherwise,
988 * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer
991 * ip -- the inode whose if_data area is changing
992 * byte_diff -- the change in the number of bytes, positive or negative,
993 * requested for the if_data array.
1005 if (byte_diff
== 0) {
1009 ifp
= XFS_IFORK_PTR(ip
, whichfork
);
1010 new_size
= (int)ifp
->if_bytes
+ byte_diff
;
1011 ASSERT(new_size
>= 0);
1013 if (new_size
== 0) {
1014 if (ifp
->if_u1
.if_data
!= ifp
->if_u2
.if_inline_data
) {
1015 kmem_free(ifp
->if_u1
.if_data
, ifp
->if_real_bytes
);
1017 ifp
->if_u1
.if_data
= NULL
;
1019 } else if (new_size
<= sizeof(ifp
->if_u2
.if_inline_data
)) {
1021 * If the valid extents/data can fit in if_inline_ext/data,
1022 * copy them from the malloc'd vector and free it.
1024 if (ifp
->if_u1
.if_data
== NULL
) {
1025 ifp
->if_u1
.if_data
= ifp
->if_u2
.if_inline_data
;
1026 } else if (ifp
->if_u1
.if_data
!= ifp
->if_u2
.if_inline_data
) {
1027 ASSERT(ifp
->if_real_bytes
!= 0);
1028 bcopy(ifp
->if_u1
.if_data
, ifp
->if_u2
.if_inline_data
,
1030 kmem_free(ifp
->if_u1
.if_data
, ifp
->if_real_bytes
);
1031 ifp
->if_u1
.if_data
= ifp
->if_u2
.if_inline_data
;
1036 * Stuck with malloc/realloc.
1037 * For inline data, the underlying buffer must be
1038 * a multiple of 4 bytes in size so that it can be
1039 * logged and stay on word boundaries. We enforce
1042 real_size
= roundup(new_size
, 4);
1043 if (ifp
->if_u1
.if_data
== NULL
) {
1044 ASSERT(ifp
->if_real_bytes
== 0);
1045 ifp
->if_u1
.if_data
= kmem_alloc(real_size
, KM_SLEEP
);
1046 } else if (ifp
->if_u1
.if_data
!= ifp
->if_u2
.if_inline_data
) {
1048 * Only do the realloc if the underlying size
1049 * is really changing.
1051 if (ifp
->if_real_bytes
!= real_size
) {
1052 ifp
->if_u1
.if_data
=
1053 kmem_realloc(ifp
->if_u1
.if_data
,
1059 ASSERT(ifp
->if_real_bytes
== 0);
1060 ifp
->if_u1
.if_data
= kmem_alloc(real_size
, KM_SLEEP
);
1061 bcopy(ifp
->if_u2
.if_inline_data
, ifp
->if_u1
.if_data
,
1065 ifp
->if_real_bytes
= real_size
;
1066 ifp
->if_bytes
= new_size
;
1067 ASSERT(ifp
->if_bytes
<= XFS_IFORK_SIZE(ip
, whichfork
));
1072 * Map inode to disk block and offset.
1074 * mp -- the mount point structure for the current file system
1075 * tp -- the current transaction
1076 * ino -- the inode number of the inode to be located
1077 * imap -- this structure is filled in with the information necessary
1078 * to retrieve the given inode from disk
1079 * flags -- flags to pass to xfs_dilocate indicating whether or not
1080 * lookups in the inode btree were OK or not
1090 xfs_fsblock_t fsbno
;
1095 fsbno
= imap
->im_blkno
?
1096 XFS_DADDR_TO_FSB(mp
, imap
->im_blkno
) : NULLFSBLOCK
;
1097 error
= xfs_dilocate(mp
, tp
, ino
, &fsbno
, &len
, &off
, flags
);
1101 imap
->im_blkno
= XFS_FSB_TO_DADDR(mp
, fsbno
);
1102 imap
->im_len
= XFS_FSB_TO_BB(mp
, len
);
1103 imap
->im_agblkno
= XFS_FSB_TO_AGBNO(mp
, fsbno
);
1104 imap
->im_ioffset
= (ushort
)off
;
1105 imap
->im_boffset
= (ushort
)(off
<< mp
->m_sb
.sb_inodelog
);
1116 ifp
= XFS_IFORK_PTR(ip
, whichfork
);
1117 if (ifp
->if_broot
!= NULL
) {
1118 kmem_free(ifp
->if_broot
, ifp
->if_broot_bytes
);
1119 ifp
->if_broot
= NULL
;
1123 * If the format is local, then we can't have an extents
1124 * array so just look for an inline data array. If we're
1125 * not local then we may or may not have an extents list,
1126 * so check and free it up if we do.
1128 if (XFS_IFORK_FORMAT(ip
, whichfork
) == XFS_DINODE_FMT_LOCAL
) {
1129 if ((ifp
->if_u1
.if_data
!= ifp
->if_u2
.if_inline_data
) &&
1130 (ifp
->if_u1
.if_data
!= NULL
)) {
1131 ASSERT(ifp
->if_real_bytes
!= 0);
1132 kmem_free(ifp
->if_u1
.if_data
, ifp
->if_real_bytes
);
1133 ifp
->if_u1
.if_data
= NULL
;
1134 ifp
->if_real_bytes
= 0;
1136 } else if ((ifp
->if_flags
& XFS_IFEXTENTS
) &&
1137 (ifp
->if_u1
.if_extents
!= NULL
) &&
1138 (ifp
->if_u1
.if_extents
!= ifp
->if_u2
.if_inline_ext
)) {
1139 ASSERT(ifp
->if_real_bytes
!= 0);
1140 kmem_free(ifp
->if_u1
.if_extents
, ifp
->if_real_bytes
);
1141 ifp
->if_u1
.if_extents
= NULL
;
1142 ifp
->if_real_bytes
= 0;
1144 ASSERT(ifp
->if_u1
.if_extents
== NULL
||
1145 ifp
->if_u1
.if_extents
== ifp
->if_u2
.if_inline_ext
);
1146 ASSERT(ifp
->if_real_bytes
== 0);
1147 if (whichfork
== XFS_ATTR_FORK
) {
1148 kmem_zone_free(xfs_ifork_zone
, ip
->i_afp
);
1154 * xfs_iroundup: round up argument to next power of two
1163 if ((v
& (v
- 1)) == 0)
1165 ASSERT((v
& 0x80000000) == 0);
1166 if ((v
& (v
+ 1)) == 0)
1168 for (i
= 0, m
= 1; i
< 31; i
++, m
<<= 1) {
1172 if ((v
& (v
+ 1)) == 0)
1180 * xfs_iextents_copy()
1182 * This is called to copy the REAL extents (as opposed to the delayed
1183 * allocation extents) from the inode into the given buffer. It
1184 * returns the number of bytes copied into the buffer.
1186 * If there are no delayed allocation extents, then we can just
1187 * bcopy() the extents into the buffer. Otherwise, we need to
1188 * examine each extent in turn and skip those which are delayed.
1193 xfs_bmbt_rec_32_t
*buffer
,
1197 xfs_bmbt_rec_32_t
*dest_ep
;
1200 xfs_exntfmt_t fmt
= XFS_EXTFMT_INODE(ip
);
1202 #ifdef XFS_BMAP_TRACE
1203 static char fname
[] = "xfs_iextents_copy";
1208 xfs_fsblock_t start_block
;
1210 ifp
= XFS_IFORK_PTR(ip
, whichfork
);
1211 ASSERT(ismrlocked(&ip
->i_lock
, MR_UPDATE
|MR_ACCESS
));
1212 ASSERT(ifp
->if_bytes
> 0);
1214 nrecs
= ifp
->if_bytes
/ (uint
)sizeof(xfs_bmbt_rec_t
);
1215 xfs_bmap_trace_exlist(fname
, ip
, nrecs
, whichfork
);
1217 if (nrecs
== XFS_IFORK_NEXTENTS(ip
, whichfork
)) {
1219 * There are no delayed allocation extents,
1220 * so just copy everything.
1222 ASSERT(ifp
->if_bytes
<= XFS_IFORK_SIZE(ip
, whichfork
));
1223 ASSERT(ifp
->if_bytes
==
1224 (XFS_IFORK_NEXTENTS(ip
, whichfork
) *
1225 (uint
)sizeof(xfs_bmbt_rec_t
)));
1226 bcopy(ifp
->if_u1
.if_extents
, buffer
, ifp
->if_bytes
);
1227 xfs_validate_extents(buffer
, nrecs
, fmt
);
1228 return ifp
->if_bytes
;
1231 ASSERT(whichfork
== XFS_DATA_FORK
);
1233 * There are some delayed allocation extents in the
1234 * inode, so copy the extents one at a time and skip
1235 * the delayed ones. There must be at least one
1236 * non-delayed extent.
1238 ASSERT(nrecs
> ip
->i_d
.di_nextents
);
1239 ep
= ifp
->if_u1
.if_extents
;
1242 for (i
= 0; i
< nrecs
; i
++) {
1243 start_block
= xfs_bmbt_get_startblock(ep
);
1244 if (ISNULLSTARTBLOCK(start_block
)) {
1246 * It's a delayed allocation extent, so skip it.
1252 *dest_ep
= *(xfs_bmbt_rec_32_t
*)ep
;
1257 ASSERT(copied
!= 0);
1258 ASSERT(copied
== ip
->i_d
.di_nextents
);
1259 ASSERT((copied
* (uint
)sizeof(xfs_bmbt_rec_t
)) <= XFS_IFORK_DSIZE(ip
));
1260 xfs_validate_extents(buffer
, copied
, fmt
);
1262 return (copied
* (uint
)sizeof(xfs_bmbt_rec_t
));
1266 * Each of the following cases stores data into the same region
1267 * of the on-disk inode, so only one of them can be valid at
1268 * any given time. While it is possible to have conflicting formats
1269 * and log flags, e.g. having XFS_ILOG_?DATA set when the fork is
1270 * in EXTENTS format, this can only happen when the fork has
1271 * changed formats after being modified but before being flushed.
1272 * In these cases, the format always takes precedence, because the
1273 * format indicates the current state of the fork.
1279 xfs_inode_log_item_t
*iip
,
1286 #ifdef XFS_TRANS_DEBUG
1289 static const short brootflag
[2] =
1290 { XFS_ILOG_DBROOT
, XFS_ILOG_ABROOT
};
1291 static const short dataflag
[2] =
1292 { XFS_ILOG_DDATA
, XFS_ILOG_ADATA
};
1293 static const short extflag
[2] =
1294 { XFS_ILOG_DEXT
, XFS_ILOG_AEXT
};
1298 ifp
= XFS_IFORK_PTR(ip
, whichfork
);
1300 * This can happen if we gave up in iformat in an error path,
1301 * for the attribute fork.
1304 ASSERT(whichfork
== XFS_ATTR_FORK
);
1307 cp
= XFS_DFORK_PTR_ARCH(dip
, whichfork
, ARCH_CONVERT
);
1309 switch (XFS_IFORK_FORMAT(ip
, whichfork
)) {
1310 case XFS_DINODE_FMT_LOCAL
:
1311 if ((iip
->ili_format
.ilf_fields
& dataflag
[whichfork
]) &&
1312 (ifp
->if_bytes
> 0)) {
1313 ASSERT(ifp
->if_u1
.if_data
!= NULL
);
1314 ASSERT(ifp
->if_bytes
<= XFS_IFORK_SIZE(ip
, whichfork
));
1315 bcopy(ifp
->if_u1
.if_data
, cp
, ifp
->if_bytes
);
1317 if (whichfork
== XFS_DATA_FORK
) {
1318 if (XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp
, dip
)) {
1319 return XFS_ERROR(EFSCORRUPTED
);
1324 case XFS_DINODE_FMT_EXTENTS
:
1325 ASSERT((ifp
->if_flags
& XFS_IFEXTENTS
) ||
1326 !(iip
->ili_format
.ilf_fields
& extflag
[whichfork
]));
1327 ASSERT((ifp
->if_u1
.if_extents
!= NULL
) || (ifp
->if_bytes
== 0));
1328 ASSERT((ifp
->if_u1
.if_extents
== NULL
) || (ifp
->if_bytes
> 0));
1329 if ((iip
->ili_format
.ilf_fields
& extflag
[whichfork
]) &&
1330 (ifp
->if_bytes
> 0)) {
1331 ASSERT(XFS_IFORK_NEXTENTS(ip
, whichfork
) > 0);
1332 (void)xfs_iextents_copy(ip
, (xfs_bmbt_rec_32_t
*)cp
,
1337 case XFS_DINODE_FMT_BTREE
:
1338 if ((iip
->ili_format
.ilf_fields
& brootflag
[whichfork
]) &&
1339 (ifp
->if_broot_bytes
> 0)) {
1340 ASSERT(ifp
->if_broot
!= NULL
);
1341 ASSERT(ifp
->if_broot_bytes
<=
1342 (XFS_IFORK_SIZE(ip
, whichfork
) +
1343 XFS_BROOT_SIZE_ADJ
));
1344 xfs_bmbt_to_bmdr(ifp
->if_broot
, ifp
->if_broot_bytes
,
1345 (xfs_bmdr_block_t
*)cp
,
1346 XFS_DFORK_SIZE_ARCH(dip
, mp
, whichfork
, ARCH_CONVERT
));
1350 case XFS_DINODE_FMT_DEV
:
1351 if (iip
->ili_format
.ilf_fields
& XFS_ILOG_DEV
) {
1352 ASSERT(whichfork
== XFS_DATA_FORK
);
1353 INT_SET(dip
->di_u
.di_dev
, ARCH_CONVERT
, ip
->i_df
.if_u2
.if_rdev
);
1357 case XFS_DINODE_FMT_UUID
:
1358 if (iip
->ili_format
.ilf_fields
& XFS_ILOG_UUID
) {
1359 ASSERT(whichfork
== XFS_DATA_FORK
);
1360 bcopy(&ip
->i_df
.if_u2
.if_uuid
, &dip
->di_u
.di_muuid
,