Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
0004  * All Rights Reserved.
0005  */
0006 #ifndef __XFS_INODE_FORK_H__
0007 #define __XFS_INODE_FORK_H__
0008 
0009 struct xfs_inode_log_item;
0010 struct xfs_dinode;
0011 
0012 /*
0013  * File incore extent information, present for each of data & attr forks.
0014  */
0015 struct xfs_ifork {
0016     int64_t         if_bytes;   /* bytes in if_u1 */
0017     struct xfs_btree_block  *if_broot;  /* file's incore btree root */
0018     unsigned int        if_seq;     /* fork mod counter */
0019     int         if_height;  /* height of the extent tree */
0020     union {
0021         void        *if_root;   /* extent tree root */
0022         char        *if_data;   /* inline file data */
0023     } if_u1;
0024     xfs_extnum_t        if_nextents;    /* # of extents in this fork */
0025     short           if_broot_bytes; /* bytes allocated for root */
0026     int8_t          if_format;  /* format of this fork */
0027 };
0028 
0029 /*
0030  * Worst-case increase in the fork extent count when we're adding a single
0031  * extent to a fork and there's no possibility of splitting an existing mapping.
0032  */
0033 #define XFS_IEXT_ADD_NOSPLIT_CNT    (1)
0034 
0035 /*
0036  * Punching out an extent from the middle of an existing extent can cause the
0037  * extent count to increase by 1.
0038  * i.e. | Old extent | Hole | Old extent |
0039  */
0040 #define XFS_IEXT_PUNCH_HOLE_CNT     (1)
0041 
0042 /*
0043  * Adding/removing an xattr can cause XFS_DA_NODE_MAXDEPTH extents to
0044  * be added. One extra extent for dabtree in case a local attr is
0045  * large enough to cause a double split.  It can also cause extent
0046  * count to increase proportional to the size of a remote xattr's
0047  * value.
0048  */
0049 #define XFS_IEXT_ATTR_MANIP_CNT(rmt_blks) \
0050     (XFS_DA_NODE_MAXDEPTH + max(1, rmt_blks))
0051 
0052 /*
0053  * A write to a sub-interval of an existing unwritten extent causes the original
0054  * extent to be split into 3 extents
0055  * i.e. | Unwritten | Real | Unwritten |
0056  * Hence extent count can increase by 2.
0057  */
0058 #define XFS_IEXT_WRITE_UNWRITTEN_CNT    (2)
0059 
0060 
0061 /*
0062  * Moving an extent to data fork can cause a sub-interval of an existing extent
0063  * to be unmapped. This will increase extent count by 1. Mapping in the new
0064  * extent can increase the extent count by 1 again i.e.
0065  * | Old extent | New extent | Old extent |
0066  * Hence number of extents increases by 2.
0067  */
0068 #define XFS_IEXT_REFLINK_END_COW_CNT    (2)
0069 
0070 /*
0071  * Removing an initial range of source/donor file's extent and adding a new
0072  * extent (from donor/source file) in its place will cause extent count to
0073  * increase by 1.
0074  */
0075 #define XFS_IEXT_SWAP_RMAP_CNT      (1)
0076 
0077 /*
0078  * Fork handling.
0079  */
0080 #define XFS_IFORK_MAXEXT(ip, w) \
0081     (xfs_inode_fork_size(ip, w) / sizeof(xfs_bmbt_rec_t))
0082 
0083 static inline bool xfs_ifork_has_extents(struct xfs_ifork *ifp)
0084 {
0085     return ifp->if_format == XFS_DINODE_FMT_EXTENTS ||
0086         ifp->if_format == XFS_DINODE_FMT_BTREE;
0087 }
0088 
0089 static inline xfs_extnum_t xfs_ifork_nextents(struct xfs_ifork *ifp)
0090 {
0091     if (!ifp)
0092         return 0;
0093     return ifp->if_nextents;
0094 }
0095 
0096 static inline int8_t xfs_ifork_format(struct xfs_ifork *ifp)
0097 {
0098     if (!ifp)
0099         return XFS_DINODE_FMT_EXTENTS;
0100     return ifp->if_format;
0101 }
0102 
0103 static inline xfs_extnum_t xfs_iext_max_nextents(bool has_large_extent_counts,
0104                 int whichfork)
0105 {
0106     switch (whichfork) {
0107     case XFS_DATA_FORK:
0108     case XFS_COW_FORK:
0109         if (has_large_extent_counts)
0110             return XFS_MAX_EXTCNT_DATA_FORK_LARGE;
0111         return XFS_MAX_EXTCNT_DATA_FORK_SMALL;
0112 
0113     case XFS_ATTR_FORK:
0114         if (has_large_extent_counts)
0115             return XFS_MAX_EXTCNT_ATTR_FORK_LARGE;
0116         return XFS_MAX_EXTCNT_ATTR_FORK_SMALL;
0117 
0118     default:
0119         ASSERT(0);
0120         return 0;
0121     }
0122 }
0123 
0124 static inline xfs_extnum_t
0125 xfs_dfork_data_extents(
0126     struct xfs_dinode   *dip)
0127 {
0128     if (xfs_dinode_has_large_extent_counts(dip))
0129         return be64_to_cpu(dip->di_big_nextents);
0130 
0131     return be32_to_cpu(dip->di_nextents);
0132 }
0133 
0134 static inline xfs_extnum_t
0135 xfs_dfork_attr_extents(
0136     struct xfs_dinode   *dip)
0137 {
0138     if (xfs_dinode_has_large_extent_counts(dip))
0139         return be32_to_cpu(dip->di_big_anextents);
0140 
0141     return be16_to_cpu(dip->di_anextents);
0142 }
0143 
0144 static inline xfs_extnum_t
0145 xfs_dfork_nextents(
0146     struct xfs_dinode   *dip,
0147     int         whichfork)
0148 {
0149     switch (whichfork) {
0150     case XFS_DATA_FORK:
0151         return xfs_dfork_data_extents(dip);
0152     case XFS_ATTR_FORK:
0153         return xfs_dfork_attr_extents(dip);
0154     default:
0155         ASSERT(0);
0156         break;
0157     }
0158 
0159     return 0;
0160 }
0161 
0162 void xfs_ifork_zap_attr(struct xfs_inode *ip);
0163 void xfs_ifork_init_attr(struct xfs_inode *ip, enum xfs_dinode_fmt format,
0164         xfs_extnum_t nextents);
0165 struct xfs_ifork *xfs_iext_state_to_fork(struct xfs_inode *ip, int state);
0166 
0167 int     xfs_iformat_data_fork(struct xfs_inode *, struct xfs_dinode *);
0168 int     xfs_iformat_attr_fork(struct xfs_inode *, struct xfs_dinode *);
0169 void        xfs_iflush_fork(struct xfs_inode *, struct xfs_dinode *,
0170                 struct xfs_inode_log_item *, int);
0171 void        xfs_idestroy_fork(struct xfs_ifork *ifp);
0172 void        xfs_idata_realloc(struct xfs_inode *ip, int64_t byte_diff,
0173                 int whichfork);
0174 void        xfs_iroot_realloc(struct xfs_inode *, int, int);
0175 int     xfs_iread_extents(struct xfs_trans *, struct xfs_inode *, int);
0176 int     xfs_iextents_copy(struct xfs_inode *, struct xfs_bmbt_rec *,
0177                   int);
0178 void        xfs_init_local_fork(struct xfs_inode *ip, int whichfork,
0179                 const void *data, int64_t size);
0180 
0181 xfs_extnum_t    xfs_iext_count(struct xfs_ifork *ifp);
0182 void        xfs_iext_insert(struct xfs_inode *, struct xfs_iext_cursor *cur,
0183             struct xfs_bmbt_irec *, int);
0184 void        xfs_iext_remove(struct xfs_inode *, struct xfs_iext_cursor *,
0185             int);
0186 void        xfs_iext_destroy(struct xfs_ifork *);
0187 
0188 bool        xfs_iext_lookup_extent(struct xfs_inode *ip,
0189             struct xfs_ifork *ifp, xfs_fileoff_t bno,
0190             struct xfs_iext_cursor *cur,
0191             struct xfs_bmbt_irec *gotp);
0192 bool        xfs_iext_lookup_extent_before(struct xfs_inode *ip,
0193             struct xfs_ifork *ifp, xfs_fileoff_t *end,
0194             struct xfs_iext_cursor *cur,
0195             struct xfs_bmbt_irec *gotp);
0196 bool        xfs_iext_get_extent(struct xfs_ifork *ifp,
0197             struct xfs_iext_cursor *cur,
0198             struct xfs_bmbt_irec *gotp);
0199 void        xfs_iext_update_extent(struct xfs_inode *ip, int state,
0200             struct xfs_iext_cursor *cur,
0201             struct xfs_bmbt_irec *gotp);
0202 
0203 void        xfs_iext_first(struct xfs_ifork *, struct xfs_iext_cursor *);
0204 void        xfs_iext_last(struct xfs_ifork *, struct xfs_iext_cursor *);
0205 void        xfs_iext_next(struct xfs_ifork *, struct xfs_iext_cursor *);
0206 void        xfs_iext_prev(struct xfs_ifork *, struct xfs_iext_cursor *);
0207 
0208 static inline bool xfs_iext_next_extent(struct xfs_ifork *ifp,
0209         struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp)
0210 {
0211     xfs_iext_next(ifp, cur);
0212     return xfs_iext_get_extent(ifp, cur, gotp);
0213 }
0214 
0215 static inline bool xfs_iext_prev_extent(struct xfs_ifork *ifp,
0216         struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp)
0217 {
0218     xfs_iext_prev(ifp, cur);
0219     return xfs_iext_get_extent(ifp, cur, gotp);
0220 }
0221 
0222 /*
0223  * Return the extent after cur in gotp without updating the cursor.
0224  */
0225 static inline bool xfs_iext_peek_next_extent(struct xfs_ifork *ifp,
0226         struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp)
0227 {
0228     struct xfs_iext_cursor ncur = *cur;
0229 
0230     xfs_iext_next(ifp, &ncur);
0231     return xfs_iext_get_extent(ifp, &ncur, gotp);
0232 }
0233 
0234 /*
0235  * Return the extent before cur in gotp without updating the cursor.
0236  */
0237 static inline bool xfs_iext_peek_prev_extent(struct xfs_ifork *ifp,
0238         struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *gotp)
0239 {
0240     struct xfs_iext_cursor ncur = *cur;
0241 
0242     xfs_iext_prev(ifp, &ncur);
0243     return xfs_iext_get_extent(ifp, &ncur, gotp);
0244 }
0245 
0246 #define for_each_xfs_iext(ifp, ext, got)        \
0247     for (xfs_iext_first((ifp), (ext));      \
0248          xfs_iext_get_extent((ifp), (ext), (got));  \
0249          xfs_iext_next((ifp), (ext)))
0250 
0251 extern struct kmem_cache    *xfs_ifork_cache;
0252 
0253 extern void xfs_ifork_init_cow(struct xfs_inode *ip);
0254 
0255 int xfs_ifork_verify_local_data(struct xfs_inode *ip);
0256 int xfs_ifork_verify_local_attr(struct xfs_inode *ip);
0257 int xfs_iext_count_may_overflow(struct xfs_inode *ip, int whichfork,
0258         int nr_to_add);
0259 int xfs_iext_count_upgrade(struct xfs_trans *tp, struct xfs_inode *ip,
0260         uint nr_to_add);
0261 
0262 /* returns true if the fork has extents but they are not read in yet. */
0263 static inline bool xfs_need_iread_extents(struct xfs_ifork *ifp)
0264 {
0265     return ifp->if_format == XFS_DINODE_FMT_BTREE && ifp->if_height == 0;
0266 }
0267 
0268 #endif  /* __XFS_INODE_FORK_H__ */