10b61f8a4SDave Chinner // SPDX-License-Identifier: GPL-2.0 284be0ffcSDave Chinner /* 384be0ffcSDave Chinner * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 484be0ffcSDave Chinner * All Rights Reserved. 584be0ffcSDave Chinner */ 684be0ffcSDave Chinner #ifndef __XFS_INODE_FORK_H__ 784be0ffcSDave Chinner #define __XFS_INODE_FORK_H__ 884be0ffcSDave Chinner 984be0ffcSDave Chinner struct xfs_inode_log_item; 1084be0ffcSDave Chinner struct xfs_dinode; 1184be0ffcSDave Chinner 1284be0ffcSDave Chinner /* 1384be0ffcSDave Chinner * File incore extent information, present for each of data & attr forks. 1484be0ffcSDave Chinner */ 153ba738dfSChristoph Hellwig struct xfs_ifork { 163f8a4f1dSDave Chinner int64_t if_bytes; /* bytes in if_u1 */ 1784be0ffcSDave Chinner struct xfs_btree_block *if_broot; /* file's incore btree root */ 183f8a4f1dSDave Chinner unsigned int if_seq; /* fork mod counter */ 196bdcf26aSChristoph Hellwig int if_height; /* height of the extent tree */ 2084be0ffcSDave Chinner union { 216bdcf26aSChristoph Hellwig void *if_root; /* extent tree root */ 2284be0ffcSDave Chinner char *if_data; /* inline file data */ 2384be0ffcSDave Chinner } if_u1; 243f8a4f1dSDave Chinner short if_broot_bytes; /* bytes allocated for root */ 253f8a4f1dSDave Chinner unsigned char if_flags; /* per-fork flags */ 263ba738dfSChristoph Hellwig }; 2784be0ffcSDave Chinner 2884be0ffcSDave Chinner /* 2984be0ffcSDave Chinner * Per-fork incore inode flags. 3084be0ffcSDave Chinner */ 3184be0ffcSDave Chinner #define XFS_IFINLINE 0x01 /* Inline data is read in */ 3284be0ffcSDave Chinner #define XFS_IFEXTENTS 0x02 /* All extent pointers are read in */ 3384be0ffcSDave Chinner #define XFS_IFBROOT 0x04 /* i_broot points to the bmap b-tree root */ 3484be0ffcSDave Chinner 3584be0ffcSDave Chinner /* 3684be0ffcSDave Chinner * Fork handling. 3784be0ffcSDave Chinner */ 3884be0ffcSDave Chinner 3984be0ffcSDave Chinner #define XFS_IFORK_Q(ip) ((ip)->i_d.di_forkoff != 0) 4084be0ffcSDave Chinner #define XFS_IFORK_BOFF(ip) ((int)((ip)->i_d.di_forkoff << 3)) 4184be0ffcSDave Chinner 4284be0ffcSDave Chinner #define XFS_IFORK_PTR(ip,w) \ 4384be0ffcSDave Chinner ((w) == XFS_DATA_FORK ? \ 4484be0ffcSDave Chinner &(ip)->i_df : \ 453993baebSDarrick J. Wong ((w) == XFS_ATTR_FORK ? \ 463993baebSDarrick J. Wong (ip)->i_afp : \ 473993baebSDarrick J. Wong (ip)->i_cowfp)) 4884be0ffcSDave Chinner #define XFS_IFORK_DSIZE(ip) \ 49e9e2eae8SChristoph Hellwig (XFS_IFORK_Q(ip) ? XFS_IFORK_BOFF(ip) : XFS_LITINO((ip)->i_mount)) 5084be0ffcSDave Chinner #define XFS_IFORK_ASIZE(ip) \ 51e9e2eae8SChristoph Hellwig (XFS_IFORK_Q(ip) ? XFS_LITINO((ip)->i_mount) - XFS_IFORK_BOFF(ip) : 0) 5284be0ffcSDave Chinner #define XFS_IFORK_SIZE(ip,w) \ 5384be0ffcSDave Chinner ((w) == XFS_DATA_FORK ? \ 5484be0ffcSDave Chinner XFS_IFORK_DSIZE(ip) : \ 553993baebSDarrick J. Wong ((w) == XFS_ATTR_FORK ? \ 563993baebSDarrick J. Wong XFS_IFORK_ASIZE(ip) : \ 573993baebSDarrick J. Wong 0)) 5884be0ffcSDave Chinner #define XFS_IFORK_FORMAT(ip,w) \ 5984be0ffcSDave Chinner ((w) == XFS_DATA_FORK ? \ 6084be0ffcSDave Chinner (ip)->i_d.di_format : \ 613993baebSDarrick J. Wong ((w) == XFS_ATTR_FORK ? \ 623993baebSDarrick J. Wong (ip)->i_d.di_aformat : \ 633993baebSDarrick J. Wong (ip)->i_cformat)) 6484be0ffcSDave Chinner #define XFS_IFORK_FMT_SET(ip,w,n) \ 6584be0ffcSDave Chinner ((w) == XFS_DATA_FORK ? \ 6684be0ffcSDave Chinner ((ip)->i_d.di_format = (n)) : \ 673993baebSDarrick J. Wong ((w) == XFS_ATTR_FORK ? \ 683993baebSDarrick J. Wong ((ip)->i_d.di_aformat = (n)) : \ 693993baebSDarrick J. Wong ((ip)->i_cformat = (n)))) 7084be0ffcSDave Chinner #define XFS_IFORK_NEXTENTS(ip,w) \ 7184be0ffcSDave Chinner ((w) == XFS_DATA_FORK ? \ 7284be0ffcSDave Chinner (ip)->i_d.di_nextents : \ 733993baebSDarrick J. Wong ((w) == XFS_ATTR_FORK ? \ 743993baebSDarrick J. Wong (ip)->i_d.di_anextents : \ 753993baebSDarrick J. Wong (ip)->i_cnextents)) 7684be0ffcSDave Chinner #define XFS_IFORK_NEXT_SET(ip,w,n) \ 7784be0ffcSDave Chinner ((w) == XFS_DATA_FORK ? \ 7884be0ffcSDave Chinner ((ip)->i_d.di_nextents = (n)) : \ 793993baebSDarrick J. Wong ((w) == XFS_ATTR_FORK ? \ 803993baebSDarrick J. Wong ((ip)->i_d.di_anextents = (n)) : \ 813993baebSDarrick J. Wong ((ip)->i_cnextents = (n)))) 8284be0ffcSDave Chinner #define XFS_IFORK_MAXEXT(ip, w) \ 8384be0ffcSDave Chinner (XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t)) 8484be0ffcSDave Chinner 852fe4f928SDarrick J. Wong #define xfs_ifork_has_extents(ip, w) \ 862fe4f928SDarrick J. Wong (XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_EXTENTS || \ 872fe4f928SDarrick J. Wong XFS_IFORK_FORMAT((ip), (w)) == XFS_DINODE_FMT_BTREE) 882fe4f928SDarrick J. Wong 893993baebSDarrick J. Wong struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state); 903993baebSDarrick J. Wong 9184be0ffcSDave Chinner int xfs_iformat_fork(struct xfs_inode *, struct xfs_dinode *); 9278420281SDarrick J. Wong void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, 9384be0ffcSDave Chinner struct xfs_inode_log_item *, int); 9484be0ffcSDave Chinner void xfs_idestroy_fork(struct xfs_inode *, int); 953f8a4f1dSDave Chinner void xfs_idata_realloc(struct xfs_inode *ip, int64_t byte_diff, 963f8a4f1dSDave Chinner int whichfork); 9784be0ffcSDave Chinner void xfs_iroot_realloc(struct xfs_inode *, int, int); 9884be0ffcSDave Chinner int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int); 9984be0ffcSDave Chinner int xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *, 10084be0ffcSDave Chinner int); 1013f8a4f1dSDave Chinner void xfs_init_local_fork(struct xfs_inode *ip, int whichfork, 1023f8a4f1dSDave Chinner const void *data, int64_t size); 10384be0ffcSDave Chinner 1046bdcf26aSChristoph Hellwig xfs_extnum_t xfs_iext_count(struct xfs_ifork *ifp); 105b2b1712aSChristoph Hellwig void xfs_iext_insert(struct xfs_inode *, struct xfs_iext_cursor *cur, 1060254c2f2SChristoph Hellwig struct xfs_bmbt_irec *, int); 107b2b1712aSChristoph Hellwig void xfs_iext_remove(struct xfs_inode *, struct xfs_iext_cursor *, 108c38ccf59SChristoph Hellwig int); 10984be0ffcSDave Chinner void xfs_iext_destroy(struct xfs_ifork *); 11084be0ffcSDave Chinner 11193533c78SChristoph Hellwig bool xfs_iext_lookup_extent(struct xfs_inode *ip, 11293533c78SChristoph Hellwig struct xfs_ifork *ifp, xfs_fileoff_t bno, 113b2b1712aSChristoph Hellwig struct xfs_iext_cursor *cur, 114b2b1712aSChristoph Hellwig struct xfs_bmbt_irec *gotp); 115dc56015fSChristoph Hellwig bool xfs_iext_lookup_extent_before(struct xfs_inode *ip, 116dc56015fSChristoph Hellwig struct xfs_ifork *ifp, xfs_fileoff_t *end, 117b2b1712aSChristoph Hellwig struct xfs_iext_cursor *cur, 118b2b1712aSChristoph Hellwig struct xfs_bmbt_irec *gotp); 119b2b1712aSChristoph Hellwig bool xfs_iext_get_extent(struct xfs_ifork *ifp, 120b2b1712aSChristoph Hellwig struct xfs_iext_cursor *cur, 12193533c78SChristoph Hellwig struct xfs_bmbt_irec *gotp); 122ca5d8e5bSChristoph Hellwig void xfs_iext_update_extent(struct xfs_inode *ip, int state, 123b2b1712aSChristoph Hellwig struct xfs_iext_cursor *cur, 124b2b1712aSChristoph Hellwig struct xfs_bmbt_irec *gotp); 125b2b1712aSChristoph Hellwig 1266bdcf26aSChristoph Hellwig void xfs_iext_first(struct xfs_ifork *, struct xfs_iext_cursor *); 1276bdcf26aSChristoph Hellwig void xfs_iext_last(struct xfs_ifork *, struct xfs_iext_cursor *); 1286bdcf26aSChristoph Hellwig void xfs_iext_next(struct xfs_ifork *, struct xfs_iext_cursor *); 1296bdcf26aSChristoph Hellwig void xfs_iext_prev(struct xfs_ifork *, struct xfs_iext_cursor *); 130b2b1712aSChristoph Hellwig 131b2b1712aSChristoph Hellwig static inline bool xfs_iext_next_extent(struct xfs_ifork *ifp, 132b2b1712aSChristoph Hellwig struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) 133b2b1712aSChristoph Hellwig { 134b2b1712aSChristoph Hellwig xfs_iext_next(ifp, cur); 135b2b1712aSChristoph Hellwig return xfs_iext_get_extent(ifp, cur, gotp); 136b2b1712aSChristoph Hellwig } 137b2b1712aSChristoph Hellwig 138b2b1712aSChristoph Hellwig static inline bool xfs_iext_prev_extent(struct xfs_ifork *ifp, 139b2b1712aSChristoph Hellwig struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) 140b2b1712aSChristoph Hellwig { 141b2b1712aSChristoph Hellwig xfs_iext_prev(ifp, cur); 142b2b1712aSChristoph Hellwig return xfs_iext_get_extent(ifp, cur, gotp); 143b2b1712aSChristoph Hellwig } 144b2b1712aSChristoph Hellwig 145b2b1712aSChristoph Hellwig /* 146b2b1712aSChristoph Hellwig * Return the extent after cur in gotp without updating the cursor. 147b2b1712aSChristoph Hellwig */ 148b2b1712aSChristoph Hellwig static inline bool xfs_iext_peek_next_extent(struct xfs_ifork *ifp, 149b2b1712aSChristoph Hellwig struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) 150b2b1712aSChristoph Hellwig { 151b2b1712aSChristoph Hellwig struct xfs_iext_cursor ncur = *cur; 152b2b1712aSChristoph Hellwig 153b2b1712aSChristoph Hellwig xfs_iext_next(ifp, &ncur); 154b2b1712aSChristoph Hellwig return xfs_iext_get_extent(ifp, &ncur, gotp); 155b2b1712aSChristoph Hellwig } 156b2b1712aSChristoph Hellwig 157b2b1712aSChristoph Hellwig /* 158b2b1712aSChristoph Hellwig * Return the extent before cur in gotp without updating the cursor. 159b2b1712aSChristoph Hellwig */ 160b2b1712aSChristoph Hellwig static inline bool xfs_iext_peek_prev_extent(struct xfs_ifork *ifp, 161b2b1712aSChristoph Hellwig struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) 162b2b1712aSChristoph Hellwig { 163b2b1712aSChristoph Hellwig struct xfs_iext_cursor ncur = *cur; 164b2b1712aSChristoph Hellwig 165b2b1712aSChristoph Hellwig xfs_iext_prev(ifp, &ncur); 166b2b1712aSChristoph Hellwig return xfs_iext_get_extent(ifp, &ncur, gotp); 167b2b1712aSChristoph Hellwig } 168b2b1712aSChristoph Hellwig 169b2b1712aSChristoph Hellwig #define for_each_xfs_iext(ifp, ext, got) \ 170b2b1712aSChristoph Hellwig for (xfs_iext_first((ifp), (ext)); \ 171b2b1712aSChristoph Hellwig xfs_iext_get_extent((ifp), (ext), (got)); \ 172b2b1712aSChristoph Hellwig xfs_iext_next((ifp), (ext))) 17393533c78SChristoph Hellwig 17484be0ffcSDave Chinner extern struct kmem_zone *xfs_ifork_zone; 17584be0ffcSDave Chinner 1763993baebSDarrick J. Wong extern void xfs_ifork_init_cow(struct xfs_inode *ip); 1773993baebSDarrick J. Wong 1789cfb9b47SDarrick J. Wong typedef xfs_failaddr_t (*xfs_ifork_verifier_t)(struct xfs_inode *); 1799cfb9b47SDarrick J. Wong 1809cfb9b47SDarrick J. Wong struct xfs_ifork_ops { 1819cfb9b47SDarrick J. Wong xfs_ifork_verifier_t verify_symlink; 1829cfb9b47SDarrick J. Wong xfs_ifork_verifier_t verify_dir; 1839cfb9b47SDarrick J. Wong xfs_ifork_verifier_t verify_attr; 1849cfb9b47SDarrick J. Wong }; 1859cfb9b47SDarrick J. Wong extern struct xfs_ifork_ops xfs_default_ifork_ops; 1869cfb9b47SDarrick J. Wong 1879cfb9b47SDarrick J. Wong xfs_failaddr_t xfs_ifork_verify_data(struct xfs_inode *ip, 1889cfb9b47SDarrick J. Wong struct xfs_ifork_ops *ops); 1899cfb9b47SDarrick J. Wong xfs_failaddr_t xfs_ifork_verify_attr(struct xfs_inode *ip, 1909cfb9b47SDarrick J. Wong struct xfs_ifork_ops *ops); 1919cfb9b47SDarrick J. Wong 19284be0ffcSDave Chinner #endif /* __XFS_INODE_FORK_H__ */ 193