xref: /openbmc/linux/fs/xfs/libxfs/xfs_inode_fork.h (revision e9e2eae8)
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