cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xfs_inode_fork.h (8474B)


      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
      9struct xfs_inode_log_item;
     10struct xfs_dinode;
     11
     12/*
     13 * File incore extent information, present for each of data & attr forks.
     14 */
     15struct xfs_ifork {
     16	int64_t			if_bytes;	/* bytes in if_u1 */
     17	struct xfs_btree_block	*if_broot;	/* file's incore btree root */
     18	unsigned int		if_seq;		/* fork mod counter */
     19	int			if_height;	/* height of the extent tree */
     20	union {
     21		void		*if_root;	/* extent tree root */
     22		char		*if_data;	/* inline file data */
     23	} if_u1;
     24	xfs_extnum_t		if_nextents;	/* # of extents in this fork */
     25	short			if_broot_bytes;	/* bytes allocated for root */
     26	int8_t			if_format;	/* format of this fork */
     27};
     28
     29/*
     30 * Worst-case increase in the fork extent count when we're adding a single
     31 * extent to a fork and there's no possibility of splitting an existing mapping.
     32 */
     33#define XFS_IEXT_ADD_NOSPLIT_CNT	(1)
     34
     35/*
     36 * Punching out an extent from the middle of an existing extent can cause the
     37 * extent count to increase by 1.
     38 * i.e. | Old extent | Hole | Old extent |
     39 */
     40#define XFS_IEXT_PUNCH_HOLE_CNT		(1)
     41
     42/*
     43 * Adding/removing an xattr can cause XFS_DA_NODE_MAXDEPTH extents to
     44 * be added. One extra extent for dabtree in case a local attr is
     45 * large enough to cause a double split.  It can also cause extent
     46 * count to increase proportional to the size of a remote xattr's
     47 * value.
     48 */
     49#define XFS_IEXT_ATTR_MANIP_CNT(rmt_blks) \
     50	(XFS_DA_NODE_MAXDEPTH + max(1, rmt_blks))
     51
     52/*
     53 * A write to a sub-interval of an existing unwritten extent causes the original
     54 * extent to be split into 3 extents
     55 * i.e. | Unwritten | Real | Unwritten |
     56 * Hence extent count can increase by 2.
     57 */
     58#define XFS_IEXT_WRITE_UNWRITTEN_CNT	(2)
     59
     60
     61/*
     62 * Moving an extent to data fork can cause a sub-interval of an existing extent
     63 * to be unmapped. This will increase extent count by 1. Mapping in the new
     64 * extent can increase the extent count by 1 again i.e.
     65 * | Old extent | New extent | Old extent |
     66 * Hence number of extents increases by 2.
     67 */
     68#define XFS_IEXT_REFLINK_END_COW_CNT	(2)
     69
     70/*
     71 * Removing an initial range of source/donor file's extent and adding a new
     72 * extent (from donor/source file) in its place will cause extent count to
     73 * increase by 1.
     74 */
     75#define XFS_IEXT_SWAP_RMAP_CNT		(1)
     76
     77/*
     78 * Fork handling.
     79 */
     80
     81#define XFS_IFORK_Q(ip)			((ip)->i_forkoff != 0)
     82#define XFS_IFORK_BOFF(ip)		((int)((ip)->i_forkoff << 3))
     83
     84#define XFS_IFORK_PTR(ip,w)		\
     85	((w) == XFS_DATA_FORK ? \
     86		&(ip)->i_df : \
     87		((w) == XFS_ATTR_FORK ? \
     88			(ip)->i_afp : \
     89			(ip)->i_cowfp))
     90#define XFS_IFORK_DSIZE(ip) \
     91	(XFS_IFORK_Q(ip) ? XFS_IFORK_BOFF(ip) : XFS_LITINO((ip)->i_mount))
     92#define XFS_IFORK_ASIZE(ip) \
     93	(XFS_IFORK_Q(ip) ? XFS_LITINO((ip)->i_mount) - XFS_IFORK_BOFF(ip) : 0)
     94#define XFS_IFORK_SIZE(ip,w) \
     95	((w) == XFS_DATA_FORK ? \
     96		XFS_IFORK_DSIZE(ip) : \
     97		((w) == XFS_ATTR_FORK ? \
     98			XFS_IFORK_ASIZE(ip) : \
     99			0))
    100#define XFS_IFORK_MAXEXT(ip, w) \
    101	(XFS_IFORK_SIZE(ip, w) / sizeof(xfs_bmbt_rec_t))
    102
    103static inline bool xfs_ifork_has_extents(struct xfs_ifork *ifp)
    104{
    105	return ifp->if_format == XFS_DINODE_FMT_EXTENTS ||
    106		ifp->if_format == XFS_DINODE_FMT_BTREE;
    107}
    108
    109static inline xfs_extnum_t xfs_ifork_nextents(struct xfs_ifork *ifp)
    110{
    111	if (!ifp)
    112		return 0;
    113	return ifp->if_nextents;
    114}
    115
    116static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp)
    117{
    118	if (!ifp)
    119		return XFS_DINODE_FMT_EXTENTS;
    120	return ifp->if_format;
    121}
    122
    123static inline xfs_extnum_t xfs_iext_max_nextents(bool has_large_extent_counts,
    124				int whichfork)
    125{
    126	switch (whichfork) {
    127	case XFS_DATA_FORK:
    128	case XFS_COW_FORK:
    129		if (has_large_extent_counts)
    130			return XFS_MAX_EXTCNT_DATA_FORK_LARGE;
    131		return XFS_MAX_EXTCNT_DATA_FORK_SMALL;
    132
    133	case XFS_ATTR_FORK:
    134		if (has_large_extent_counts)
    135			return XFS_MAX_EXTCNT_ATTR_FORK_LARGE;
    136		return XFS_MAX_EXTCNT_ATTR_FORK_SMALL;
    137
    138	default:
    139		ASSERT(0);
    140		return 0;
    141	}
    142}
    143
    144static inline xfs_extnum_t
    145xfs_dfork_data_extents(
    146	struct xfs_dinode	*dip)
    147{
    148	if (xfs_dinode_has_large_extent_counts(dip))
    149		return be64_to_cpu(dip->di_big_nextents);
    150
    151	return be32_to_cpu(dip->di_nextents);
    152}
    153
    154static inline xfs_extnum_t
    155xfs_dfork_attr_extents(
    156	struct xfs_dinode	*dip)
    157{
    158	if (xfs_dinode_has_large_extent_counts(dip))
    159		return be32_to_cpu(dip->di_big_anextents);
    160
    161	return be16_to_cpu(dip->di_anextents);
    162}
    163
    164static inline xfs_extnum_t
    165xfs_dfork_nextents(
    166	struct xfs_dinode	*dip,
    167	int			whichfork)
    168{
    169	switch (whichfork) {
    170	case XFS_DATA_FORK:
    171		return xfs_dfork_data_extents(dip);
    172	case XFS_ATTR_FORK:
    173		return xfs_dfork_attr_extents(dip);
    174	default:
    175		ASSERT(0);
    176		break;
    177	}
    178
    179	return 0;
    180}
    181
    182struct xfs_ifork *xfs_ifork_alloc(enum xfs_dinode_fmt format,
    183				xfs_extnum_t nextents);
    184struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state);
    185
    186int		xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *);
    187int		xfs_iformat_attr_fork(struct xfs_inode *, struct xfs_dinode *);
    188void		xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *,
    189				struct xfs_inode_log_item *, int);
    190void		xfs_idestroy_fork(struct xfs_ifork *ifp);
    191void		xfs_idata_realloc(struct xfs_inode *ip, int64_t byte_diff,
    192				int whichfork);
    193void		xfs_iroot_realloc(struct xfs_inode *, int, int);
    194int		xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int);
    195int		xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *,
    196				  int);
    197void		xfs_init_local_fork(struct xfs_inode *ip, int whichfork,
    198				const void *data, int64_t size);
    199
    200xfs_extnum_t	xfs_iext_count(struct xfs_ifork *ifp);
    201void		xfs_iext_insert(struct xfs_inode *, struct xfs_iext_cursor *cur,
    202			struct xfs_bmbt_irec *, int);
    203void		xfs_iext_remove(struct xfs_inode *, struct xfs_iext_cursor *,
    204			int);
    205void		xfs_iext_destroy(struct xfs_ifork *);
    206
    207bool		xfs_iext_lookup_extent(struct xfs_inode *ip,
    208			struct xfs_ifork *ifp, xfs_fileoff_t bno,
    209			struct xfs_iext_cursor *cur,
    210			struct xfs_bmbt_irec *gotp);
    211bool		xfs_iext_lookup_extent_before(struct xfs_inode *ip,
    212			struct xfs_ifork *ifp, xfs_fileoff_t *end,
    213			struct xfs_iext_cursor *cur,
    214			struct xfs_bmbt_irec *gotp);
    215bool		xfs_iext_get_extent(struct xfs_ifork *ifp,
    216			struct xfs_iext_cursor *cur,
    217			struct xfs_bmbt_irec *gotp);
    218void		xfs_iext_update_extent(struct xfs_inode *ip, int state,
    219			struct xfs_iext_cursor *cur,
    220			struct xfs_bmbt_irec *gotp);
    221
    222void		xfs_iext_first(struct xfs_ifork *, struct xfs_iext_cursor *);
    223void		xfs_iext_last(struct xfs_ifork *, struct xfs_iext_cursor *);
    224void		xfs_iext_next(struct xfs_ifork *, struct xfs_iext_cursor *);
    225void		xfs_iext_prev(struct xfs_ifork *, struct xfs_iext_cursor *);
    226
    227static inline bool xfs_iext_next_extent(struct xfs_ifork *ifp,
    228		struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp)
    229{
    230	xfs_iext_next(ifp, cur);
    231	return xfs_iext_get_extent(ifp, cur, gotp);
    232}
    233
    234static inline bool xfs_iext_prev_extent(struct xfs_ifork *ifp,
    235		struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp)
    236{
    237	xfs_iext_prev(ifp, cur);
    238	return xfs_iext_get_extent(ifp, cur, gotp);
    239}
    240
    241/*
    242 * Return the extent after cur in gotp without updating the cursor.
    243 */
    244static inline bool xfs_iext_peek_next_extent(struct xfs_ifork *ifp,
    245		struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp)
    246{
    247	struct xfs_iext_cursor ncur = *cur;
    248
    249	xfs_iext_next(ifp, &ncur);
    250	return xfs_iext_get_extent(ifp, &ncur, gotp);
    251}
    252
    253/*
    254 * Return the extent before cur in gotp without updating the cursor.
    255 */
    256static inline bool xfs_iext_peek_prev_extent(struct xfs_ifork *ifp,
    257		struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp)
    258{
    259	struct xfs_iext_cursor ncur = *cur;
    260
    261	xfs_iext_prev(ifp, &ncur);
    262	return xfs_iext_get_extent(ifp, &ncur, gotp);
    263}
    264
    265#define for_each_xfs_iext(ifp, ext, got)		\
    266	for (xfs_iext_first((ifp), (ext));		\
    267	     xfs_iext_get_extent((ifp), (ext), (got));	\
    268	     xfs_iext_next((ifp), (ext)))
    269
    270extern struct kmem_cache	*xfs_ifork_cache;
    271
    272extern void xfs_ifork_init_cow(struct xfs_inode *ip);
    273
    274int xfs_ifork_verify_local_data(struct xfs_inode *ip);
    275int xfs_ifork_verify_local_attr(struct xfs_inode *ip);
    276int xfs_iext_count_may_overflow(struct xfs_inode *ip, int whichfork,
    277		int nr_to_add);
    278int xfs_iext_count_upgrade(struct xfs_trans *tp, struct xfs_inode *ip,
    279		uint nr_to_add);
    280
    281/* returns true if the fork has extents but they are not read in yet. */
    282static inline bool xfs_need_iread_extents(struct xfs_ifork *ifp)
    283{
    284	return ifp->if_format == XFS_DINODE_FMT_BTREE && ifp->if_height == 0;
    285}
    286
    287#endif	/* __XFS_INODE_FORK_H__ */