1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. 4 * All Rights Reserved. 5 */ 6 #ifndef __XFS_INODE_FORK_H__ 7 #define __XFS_INODE_FORK_H__ 8 9 struct xfs_inode_log_item; 10 struct xfs_dinode; 11 12 /* 13 * File incore extent information, present for each of data & attr forks. 14 */ 15 struct xfs_ifork { 16 int if_bytes; /* bytes in if_u1 */ 17 unsigned int if_seq; /* cow fork mod counter */ 18 struct xfs_btree_block *if_broot; /* file's incore btree root */ 19 short if_broot_bytes; /* bytes allocated for root */ 20 unsigned char if_flags; /* per-fork flags */ 21 int if_height; /* height of the extent tree */ 22 union { 23 void *if_root; /* extent tree root */ 24 char *if_data; /* inline file data */ 25 } if_u1; 26 }; 27 28 /* 29 * Per-fork incore inode flags. 30 */ 31 #define XFS_IFINLINE 0x01 /* Inline data is read in */ 32 #define XFS_IFEXTENTS 0x02 /* All extent pointers are read in */ 33 #define XFS_IFBROOT 0x04 /* i_broot points to the bmap b-tree root */ 34 35 /* 36 * Fork handling. 37 */ 38 39 #define XFS_IFORK_Q(ip) ((ip)->i_d.di_forkoff != 0) 40 #define XFS_IFORK_BOFF(ip) ((int)((ip)->i_d.di_forkoff << 3)) 41 42 #define XFS_IFORK_PTR(ip,w) \ 43 ((w) == XFS_DATA_FORK ? \ 44 &(ip)->i_df : \ 45 ((w) == XFS_ATTR_FORK ? \ 46 (ip)->i_afp : \ 47 (ip)->i_cowfp)) 48 #define XFS_IFORK_DSIZE(ip) \ 49 (XFS_IFORK_Q(ip) ? \ 50 XFS_IFORK_BOFF(ip) : \ 51 XFS_LITINO((ip)->i_mount, (ip)->i_d.di_version)) 52 #define XFS_IFORK_ASIZE(ip) \ 53 (XFS_IFORK_Q(ip) ? \ 54 XFS_LITINO((ip)->i_mount, (ip)->i_d.di_version) - \ 55 XFS_IFORK_BOFF(ip) : \ 56 0) 57 #define XFS_IFORK_SIZE(ip,w) \ 58 ((w) == XFS_DATA_FORK ? \ 59 XFS_IFORK_DSIZE(ip) : \ 60 ((w) == XFS_ATTR_FORK ? \ 61 XFS_IFORK_ASIZE(ip) : \ 62 0)) 63 #define XFS_IFORK_FORMAT(ip,w) \ 64 ((w) == XFS_DATA_FORK ? \ 65 (ip)->i_d.di_format : \ 66 ((w) == XFS_ATTR_FORK ? \ 67 (ip)->i_d.di_aformat : \ 68 (ip)->i_cformat)) 69 #define XFS_IFORK_FMT_SET(ip,w,n) \ 70 ((w) == XFS_DATA_FORK ? \ 71 ((ip)->i_d.di_format = (n)) : \ 72 ((w) == XFS_ATTR_FORK ? \ 73 ((ip)->i_d.di_aformat = (n)) : \ 74 ((ip)->i_cformat = (n)))) 75 #define XFS_IFORK_NEXTENTS(ip,w) \ 76 ((w) == XFS_DATA_FORK ? \ 77 (ip)->i_d.di_nextents : \ 78 ((w) == XFS_ATTR_FORK ? \ 79 (ip)->i_d.di_anextents : \ 80 (ip)->i_cnextents)) 81 #define XFS_IFORK_NEXT_SET(ip,w,n) \ 82 ((w) == XFS_DATA_FORK ? \ 83 ((ip)->i_d.di_nextents = (n)) : \ 84 ((w) == XFS_ATTR_FORK ? \ 85 ((ip)->i_d.di_anextents = (n)) : \ 86 ((ip)->i_cnextents = (n)))) 87 #define XFS_IFORK_MAXEXT(ip, w) \ 88 (XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t)) 89 90 struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state); 91 92 int xfs_iformat_fork(struct xfs_inode *, struct xfs_dinode *); 93 void xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *, 94 struct xfs_inode_log_item *, int); 95 void xfs_idestroy_fork(struct xfs_inode *, int); 96 void xfs_idata_realloc(struct xfs_inode *, int, int); 97 void xfs_iroot_realloc(struct xfs_inode *, int, int); 98 int xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int); 99 int xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *, 100 int); 101 void xfs_init_local_fork(struct xfs_inode *, int, const void *, int); 102 103 xfs_extnum_t xfs_iext_count(struct xfs_ifork *ifp); 104 void xfs_iext_insert(struct xfs_inode *, struct xfs_iext_cursor *cur, 105 struct xfs_bmbt_irec *, int); 106 void xfs_iext_remove(struct xfs_inode *, struct xfs_iext_cursor *, 107 int); 108 void xfs_iext_destroy(struct xfs_ifork *); 109 110 bool xfs_iext_lookup_extent(struct xfs_inode *ip, 111 struct xfs_ifork *ifp, xfs_fileoff_t bno, 112 struct xfs_iext_cursor *cur, 113 struct xfs_bmbt_irec *gotp); 114 bool xfs_iext_lookup_extent_before(struct xfs_inode *ip, 115 struct xfs_ifork *ifp, xfs_fileoff_t *end, 116 struct xfs_iext_cursor *cur, 117 struct xfs_bmbt_irec *gotp); 118 bool xfs_iext_get_extent(struct xfs_ifork *ifp, 119 struct xfs_iext_cursor *cur, 120 struct xfs_bmbt_irec *gotp); 121 void xfs_iext_update_extent(struct xfs_inode *ip, int state, 122 struct xfs_iext_cursor *cur, 123 struct xfs_bmbt_irec *gotp); 124 125 void xfs_iext_first(struct xfs_ifork *, struct xfs_iext_cursor *); 126 void xfs_iext_last(struct xfs_ifork *, struct xfs_iext_cursor *); 127 void xfs_iext_next(struct xfs_ifork *, struct xfs_iext_cursor *); 128 void xfs_iext_prev(struct xfs_ifork *, struct xfs_iext_cursor *); 129 130 static inline bool xfs_iext_next_extent(struct xfs_ifork *ifp, 131 struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) 132 { 133 xfs_iext_next(ifp, cur); 134 return xfs_iext_get_extent(ifp, cur, gotp); 135 } 136 137 static inline bool xfs_iext_prev_extent(struct xfs_ifork *ifp, 138 struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) 139 { 140 xfs_iext_prev(ifp, cur); 141 return xfs_iext_get_extent(ifp, cur, gotp); 142 } 143 144 /* 145 * Return the extent after cur in gotp without updating the cursor. 146 */ 147 static inline bool xfs_iext_peek_next_extent(struct xfs_ifork *ifp, 148 struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) 149 { 150 struct xfs_iext_cursor ncur = *cur; 151 152 xfs_iext_next(ifp, &ncur); 153 return xfs_iext_get_extent(ifp, &ncur, gotp); 154 } 155 156 /* 157 * Return the extent before cur in gotp without updating the cursor. 158 */ 159 static inline bool xfs_iext_peek_prev_extent(struct xfs_ifork *ifp, 160 struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp) 161 { 162 struct xfs_iext_cursor ncur = *cur; 163 164 xfs_iext_prev(ifp, &ncur); 165 return xfs_iext_get_extent(ifp, &ncur, gotp); 166 } 167 168 #define for_each_xfs_iext(ifp, ext, got) \ 169 for (xfs_iext_first((ifp), (ext)); \ 170 xfs_iext_get_extent((ifp), (ext), (got)); \ 171 xfs_iext_next((ifp), (ext))) 172 173 extern struct kmem_zone *xfs_ifork_zone; 174 175 extern void xfs_ifork_init_cow(struct xfs_inode *ip); 176 177 typedef xfs_failaddr_t (*xfs_ifork_verifier_t)(struct xfs_inode *); 178 179 struct xfs_ifork_ops { 180 xfs_ifork_verifier_t verify_symlink; 181 xfs_ifork_verifier_t verify_dir; 182 xfs_ifork_verifier_t verify_attr; 183 }; 184 extern struct xfs_ifork_ops xfs_default_ifork_ops; 185 186 xfs_failaddr_t xfs_ifork_verify_data(struct xfs_inode *ip, 187 struct xfs_ifork_ops *ops); 188 xfs_failaddr_t xfs_ifork_verify_attr(struct xfs_inode *ip, 189 struct xfs_ifork_ops *ops); 190 191 #endif /* __XFS_INODE_FORK_H__ */ 192