18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 48c2ecf20Sopenharmony_ci * All Rights Reserved. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci#ifndef __XFS_INODE_FORK_H__ 78c2ecf20Sopenharmony_ci#define __XFS_INODE_FORK_H__ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_cistruct xfs_inode_log_item; 108c2ecf20Sopenharmony_cistruct xfs_dinode; 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci/* 138c2ecf20Sopenharmony_ci * File incore extent information, present for each of data & attr forks. 148c2ecf20Sopenharmony_ci */ 158c2ecf20Sopenharmony_cistruct xfs_ifork { 168c2ecf20Sopenharmony_ci int64_t if_bytes; /* bytes in if_u1 */ 178c2ecf20Sopenharmony_ci struct xfs_btree_block *if_broot; /* file's incore btree root */ 188c2ecf20Sopenharmony_ci unsigned int if_seq; /* fork mod counter */ 198c2ecf20Sopenharmony_ci int if_height; /* height of the extent tree */ 208c2ecf20Sopenharmony_ci union { 218c2ecf20Sopenharmony_ci void *if_root; /* extent tree root */ 228c2ecf20Sopenharmony_ci char *if_data; /* inline file data */ 238c2ecf20Sopenharmony_ci } if_u1; 248c2ecf20Sopenharmony_ci short if_broot_bytes; /* bytes allocated for root */ 258c2ecf20Sopenharmony_ci unsigned char if_flags; /* per-fork flags */ 268c2ecf20Sopenharmony_ci int8_t if_format; /* format of this fork */ 278c2ecf20Sopenharmony_ci xfs_extnum_t if_nextents; /* # of extents in this fork */ 288c2ecf20Sopenharmony_ci}; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* 318c2ecf20Sopenharmony_ci * Per-fork incore inode flags. 328c2ecf20Sopenharmony_ci */ 338c2ecf20Sopenharmony_ci#define XFS_IFINLINE 0x01 /* Inline data is read in */ 348c2ecf20Sopenharmony_ci#define XFS_IFEXTENTS 0x02 /* All extent pointers are read in */ 358c2ecf20Sopenharmony_ci#define XFS_IFBROOT 0x04 /* i_broot points to the bmap b-tree root */ 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* 388c2ecf20Sopenharmony_ci * Fork handling. 398c2ecf20Sopenharmony_ci */ 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci#define XFS_IFORK_Q(ip) ((ip)->i_d.di_forkoff != 0) 428c2ecf20Sopenharmony_ci#define XFS_IFORK_BOFF(ip) ((int)((ip)->i_d.di_forkoff << 3)) 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci#define XFS_IFORK_PTR(ip,w) \ 458c2ecf20Sopenharmony_ci ((w) == XFS_DATA_FORK ? \ 468c2ecf20Sopenharmony_ci &(ip)->i_df : \ 478c2ecf20Sopenharmony_ci ((w) == XFS_ATTR_FORK ? \ 488c2ecf20Sopenharmony_ci (ip)->i_afp : \ 498c2ecf20Sopenharmony_ci (ip)->i_cowfp)) 508c2ecf20Sopenharmony_ci#define XFS_IFORK_DSIZE(ip) \ 518c2ecf20Sopenharmony_ci (XFS_IFORK_Q(ip) ? XFS_IFORK_BOFF(ip) : XFS_LITINO((ip)->i_mount)) 528c2ecf20Sopenharmony_ci#define XFS_IFORK_ASIZE(ip) \ 538c2ecf20Sopenharmony_ci (XFS_IFORK_Q(ip) ? XFS_LITINO((ip)->i_mount) - XFS_IFORK_BOFF(ip) : 0) 548c2ecf20Sopenharmony_ci#define XFS_IFORK_SIZE(ip,w) \ 558c2ecf20Sopenharmony_ci ((w) == XFS_DATA_FORK ? \ 568c2ecf20Sopenharmony_ci XFS_IFORK_DSIZE(ip) : \ 578c2ecf20Sopenharmony_ci ((w) == XFS_ATTR_FORK ? \ 588c2ecf20Sopenharmony_ci XFS_IFORK_ASIZE(ip) : \ 598c2ecf20Sopenharmony_ci 0)) 608c2ecf20Sopenharmony_ci#define XFS_IFORK_MAXEXT(ip, w) \ 618c2ecf20Sopenharmony_ci (XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t)) 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic inline bool xfs_ifork_has_extents(struct xfs_ifork *ifp) 648c2ecf20Sopenharmony_ci{ 658c2ecf20Sopenharmony_ci return ifp->if_format == XFS_DINODE_FMT_EXTENTS || 668c2ecf20Sopenharmony_ci ifp->if_format == XFS_DINODE_FMT_BTREE; 678c2ecf20Sopenharmony_ci} 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_cistatic inline xfs_extnum_t xfs_ifork_nextents(struct xfs_ifork *ifp) 708c2ecf20Sopenharmony_ci{ 718c2ecf20Sopenharmony_ci if (!ifp) 728c2ecf20Sopenharmony_ci return 0; 738c2ecf20Sopenharmony_ci return ifp->if_nextents; 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistatic inline int8_t xfs_ifork_format(struct xfs_ifork *ifp) 778c2ecf20Sopenharmony_ci{ 788c2ecf20Sopenharmony_ci if (!ifp) 798c2ecf20Sopenharmony_ci return XFS_DINODE_FMT_EXTENTS; 808c2ecf20Sopenharmony_ci return ifp->if_format; 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistruct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state); 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ciint xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *); 868c2ecf20Sopenharmony_ciint xfs_iformat_attr_fork(struct xfs_inode *, struct xfs_dinode *); 878c2ecf20Sopenharmony_civoid xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, 888c2ecf20Sopenharmony_ci struct xfs_inode_log_item *, int); 898c2ecf20Sopenharmony_civoid xfs_idestroy_fork(struct xfs_ifork *ifp); 908c2ecf20Sopenharmony_civoid xfs_idata_realloc(struct xfs_inode *ip, int64_t byte_diff, 918c2ecf20Sopenharmony_ci int whichfork); 928c2ecf20Sopenharmony_civoid xfs_iroot_realloc(struct xfs_inode *, int, int); 938c2ecf20Sopenharmony_ciint xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int); 948c2ecf20Sopenharmony_ciint xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *, 958c2ecf20Sopenharmony_ci int); 968c2ecf20Sopenharmony_civoid xfs_init_local_fork(struct xfs_inode *ip, int whichfork, 978c2ecf20Sopenharmony_ci const void *data, int64_t size); 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_cixfs_extnum_t xfs_iext_count(struct xfs_ifork *ifp); 1008c2ecf20Sopenharmony_civoid xfs_iext_insert(struct xfs_inode *, struct xfs_iext_cursor *cur, 1018c2ecf20Sopenharmony_ci struct xfs_bmbt_irec *, int); 1028c2ecf20Sopenharmony_civoid xfs_iext_remove(struct xfs_inode *, struct xfs_iext_cursor *, 1038c2ecf20Sopenharmony_ci int); 1048c2ecf20Sopenharmony_civoid xfs_iext_destroy(struct xfs_ifork *); 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cibool xfs_iext_lookup_extent(struct xfs_inode *ip, 1078c2ecf20Sopenharmony_ci struct xfs_ifork *ifp, xfs_fileoff_t bno, 1088c2ecf20Sopenharmony_ci struct xfs_iext_cursor *cur, 1098c2ecf20Sopenharmony_ci struct xfs_bmbt_irec *gotp); 1108c2ecf20Sopenharmony_cibool xfs_iext_lookup_extent_before(struct xfs_inode *ip, 1118c2ecf20Sopenharmony_ci struct xfs_ifork *ifp, xfs_fileoff_t *end, 1128c2ecf20Sopenharmony_ci struct xfs_iext_cursor *cur, 1138c2ecf20Sopenharmony_ci struct xfs_bmbt_irec *gotp); 1148c2ecf20Sopenharmony_cibool xfs_iext_get_extent(struct xfs_ifork *ifp, 1158c2ecf20Sopenharmony_ci struct xfs_iext_cursor *cur, 1168c2ecf20Sopenharmony_ci struct xfs_bmbt_irec *gotp); 1178c2ecf20Sopenharmony_civoid xfs_iext_update_extent(struct xfs_inode *ip, int state, 1188c2ecf20Sopenharmony_ci struct xfs_iext_cursor *cur, 1198c2ecf20Sopenharmony_ci struct xfs_bmbt_irec *gotp); 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_civoid xfs_iext_first(struct xfs_ifork *, struct xfs_iext_cursor *); 1228c2ecf20Sopenharmony_civoid xfs_iext_last(struct xfs_ifork *, struct xfs_iext_cursor *); 1238c2ecf20Sopenharmony_civoid xfs_iext_next(struct xfs_ifork *, struct xfs_iext_cursor *); 1248c2ecf20Sopenharmony_civoid xfs_iext_prev(struct xfs_ifork *, struct xfs_iext_cursor *); 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic inline bool xfs_iext_next_extent(struct xfs_ifork *ifp, 1278c2ecf20Sopenharmony_ci struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) 1288c2ecf20Sopenharmony_ci{ 1298c2ecf20Sopenharmony_ci xfs_iext_next(ifp, cur); 1308c2ecf20Sopenharmony_ci return xfs_iext_get_extent(ifp, cur, gotp); 1318c2ecf20Sopenharmony_ci} 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_cistatic inline bool xfs_iext_prev_extent(struct xfs_ifork *ifp, 1348c2ecf20Sopenharmony_ci struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) 1358c2ecf20Sopenharmony_ci{ 1368c2ecf20Sopenharmony_ci xfs_iext_prev(ifp, cur); 1378c2ecf20Sopenharmony_ci return xfs_iext_get_extent(ifp, cur, gotp); 1388c2ecf20Sopenharmony_ci} 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci/* 1418c2ecf20Sopenharmony_ci * Return the extent after cur in gotp without updating the cursor. 1428c2ecf20Sopenharmony_ci */ 1438c2ecf20Sopenharmony_cistatic inline bool xfs_iext_peek_next_extent(struct xfs_ifork *ifp, 1448c2ecf20Sopenharmony_ci struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) 1458c2ecf20Sopenharmony_ci{ 1468c2ecf20Sopenharmony_ci struct xfs_iext_cursor ncur = *cur; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci xfs_iext_next(ifp, &ncur); 1498c2ecf20Sopenharmony_ci return xfs_iext_get_extent(ifp, &ncur, gotp); 1508c2ecf20Sopenharmony_ci} 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci/* 1538c2ecf20Sopenharmony_ci * Return the extent before cur in gotp without updating the cursor. 1548c2ecf20Sopenharmony_ci */ 1558c2ecf20Sopenharmony_cistatic inline bool xfs_iext_peek_prev_extent(struct xfs_ifork *ifp, 1568c2ecf20Sopenharmony_ci struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) 1578c2ecf20Sopenharmony_ci{ 1588c2ecf20Sopenharmony_ci struct xfs_iext_cursor ncur = *cur; 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci xfs_iext_prev(ifp, &ncur); 1618c2ecf20Sopenharmony_ci return xfs_iext_get_extent(ifp, &ncur, gotp); 1628c2ecf20Sopenharmony_ci} 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci#define for_each_xfs_iext(ifp, ext, got) \ 1658c2ecf20Sopenharmony_ci for (xfs_iext_first((ifp), (ext)); \ 1668c2ecf20Sopenharmony_ci xfs_iext_get_extent((ifp), (ext), (got)); \ 1678c2ecf20Sopenharmony_ci xfs_iext_next((ifp), (ext))) 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ciextern struct kmem_zone *xfs_ifork_zone; 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ciextern void xfs_ifork_init_cow(struct xfs_inode *ip); 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ciint xfs_ifork_verify_local_data(struct xfs_inode *ip); 1748c2ecf20Sopenharmony_ciint xfs_ifork_verify_local_attr(struct xfs_inode *ip); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci#endif /* __XFS_INODE_FORK_H__ */ 177