0001
0002
0003
0004
0005
0006 #ifndef __XFS_RMAP_H__
0007 #define __XFS_RMAP_H__
0008
0009 struct xfs_perag;
0010
0011 static inline void
0012 xfs_rmap_ino_bmbt_owner(
0013 struct xfs_owner_info *oi,
0014 xfs_ino_t ino,
0015 int whichfork)
0016 {
0017 oi->oi_owner = ino;
0018 oi->oi_offset = 0;
0019 oi->oi_flags = XFS_OWNER_INFO_BMBT_BLOCK;
0020 if (whichfork == XFS_ATTR_FORK)
0021 oi->oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
0022 }
0023
0024 static inline void
0025 xfs_rmap_ino_owner(
0026 struct xfs_owner_info *oi,
0027 xfs_ino_t ino,
0028 int whichfork,
0029 xfs_fileoff_t offset)
0030 {
0031 oi->oi_owner = ino;
0032 oi->oi_offset = offset;
0033 oi->oi_flags = 0;
0034 if (whichfork == XFS_ATTR_FORK)
0035 oi->oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
0036 }
0037
0038 static inline bool
0039 xfs_rmap_should_skip_owner_update(
0040 const struct xfs_owner_info *oi)
0041 {
0042 return oi->oi_owner == XFS_RMAP_OWN_NULL;
0043 }
0044
0045
0046
0047 struct xfs_buf;
0048
0049 static inline __u64
0050 xfs_rmap_irec_offset_pack(
0051 const struct xfs_rmap_irec *irec)
0052 {
0053 __u64 x;
0054
0055 x = XFS_RMAP_OFF(irec->rm_offset);
0056 if (irec->rm_flags & XFS_RMAP_ATTR_FORK)
0057 x |= XFS_RMAP_OFF_ATTR_FORK;
0058 if (irec->rm_flags & XFS_RMAP_BMBT_BLOCK)
0059 x |= XFS_RMAP_OFF_BMBT_BLOCK;
0060 if (irec->rm_flags & XFS_RMAP_UNWRITTEN)
0061 x |= XFS_RMAP_OFF_UNWRITTEN;
0062 return x;
0063 }
0064
0065 static inline int
0066 xfs_rmap_irec_offset_unpack(
0067 __u64 offset,
0068 struct xfs_rmap_irec *irec)
0069 {
0070 if (offset & ~(XFS_RMAP_OFF_MASK | XFS_RMAP_OFF_FLAGS))
0071 return -EFSCORRUPTED;
0072 irec->rm_offset = XFS_RMAP_OFF(offset);
0073 irec->rm_flags = 0;
0074 if (offset & XFS_RMAP_OFF_ATTR_FORK)
0075 irec->rm_flags |= XFS_RMAP_ATTR_FORK;
0076 if (offset & XFS_RMAP_OFF_BMBT_BLOCK)
0077 irec->rm_flags |= XFS_RMAP_BMBT_BLOCK;
0078 if (offset & XFS_RMAP_OFF_UNWRITTEN)
0079 irec->rm_flags |= XFS_RMAP_UNWRITTEN;
0080 return 0;
0081 }
0082
0083 static inline void
0084 xfs_owner_info_unpack(
0085 const struct xfs_owner_info *oinfo,
0086 uint64_t *owner,
0087 uint64_t *offset,
0088 unsigned int *flags)
0089 {
0090 unsigned int r = 0;
0091
0092 *owner = oinfo->oi_owner;
0093 *offset = oinfo->oi_offset;
0094 if (oinfo->oi_flags & XFS_OWNER_INFO_ATTR_FORK)
0095 r |= XFS_RMAP_ATTR_FORK;
0096 if (oinfo->oi_flags & XFS_OWNER_INFO_BMBT_BLOCK)
0097 r |= XFS_RMAP_BMBT_BLOCK;
0098 *flags = r;
0099 }
0100
0101 static inline void
0102 xfs_owner_info_pack(
0103 struct xfs_owner_info *oinfo,
0104 uint64_t owner,
0105 uint64_t offset,
0106 unsigned int flags)
0107 {
0108 oinfo->oi_owner = owner;
0109 oinfo->oi_offset = XFS_RMAP_OFF(offset);
0110 oinfo->oi_flags = 0;
0111 if (flags & XFS_RMAP_ATTR_FORK)
0112 oinfo->oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
0113 if (flags & XFS_RMAP_BMBT_BLOCK)
0114 oinfo->oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
0115 }
0116
0117 int xfs_rmap_alloc(struct xfs_trans *tp, struct xfs_buf *agbp,
0118 struct xfs_perag *pag, xfs_agblock_t bno, xfs_extlen_t len,
0119 const struct xfs_owner_info *oinfo);
0120 int xfs_rmap_free(struct xfs_trans *tp, struct xfs_buf *agbp,
0121 struct xfs_perag *pag, xfs_agblock_t bno, xfs_extlen_t len,
0122 const struct xfs_owner_info *oinfo);
0123
0124 int xfs_rmap_lookup_le(struct xfs_btree_cur *cur, xfs_agblock_t bno,
0125 uint64_t owner, uint64_t offset, unsigned int flags,
0126 struct xfs_rmap_irec *irec, int *stat);
0127 int xfs_rmap_lookup_eq(struct xfs_btree_cur *cur, xfs_agblock_t bno,
0128 xfs_extlen_t len, uint64_t owner, uint64_t offset,
0129 unsigned int flags, int *stat);
0130 int xfs_rmap_insert(struct xfs_btree_cur *rcur, xfs_agblock_t agbno,
0131 xfs_extlen_t len, uint64_t owner, uint64_t offset,
0132 unsigned int flags);
0133 int xfs_rmap_get_rec(struct xfs_btree_cur *cur, struct xfs_rmap_irec *irec,
0134 int *stat);
0135
0136 typedef int (*xfs_rmap_query_range_fn)(
0137 struct xfs_btree_cur *cur,
0138 const struct xfs_rmap_irec *rec,
0139 void *priv);
0140
0141 int xfs_rmap_query_range(struct xfs_btree_cur *cur,
0142 const struct xfs_rmap_irec *low_rec,
0143 const struct xfs_rmap_irec *high_rec,
0144 xfs_rmap_query_range_fn fn, void *priv);
0145 int xfs_rmap_query_all(struct xfs_btree_cur *cur, xfs_rmap_query_range_fn fn,
0146 void *priv);
0147
0148 enum xfs_rmap_intent_type {
0149 XFS_RMAP_MAP,
0150 XFS_RMAP_MAP_SHARED,
0151 XFS_RMAP_UNMAP,
0152 XFS_RMAP_UNMAP_SHARED,
0153 XFS_RMAP_CONVERT,
0154 XFS_RMAP_CONVERT_SHARED,
0155 XFS_RMAP_ALLOC,
0156 XFS_RMAP_FREE,
0157 };
0158
0159 struct xfs_rmap_intent {
0160 struct list_head ri_list;
0161 enum xfs_rmap_intent_type ri_type;
0162 int ri_whichfork;
0163 uint64_t ri_owner;
0164 struct xfs_bmbt_irec ri_bmap;
0165 };
0166
0167
0168 void xfs_rmap_map_extent(struct xfs_trans *tp, struct xfs_inode *ip,
0169 int whichfork, struct xfs_bmbt_irec *imap);
0170 void xfs_rmap_unmap_extent(struct xfs_trans *tp, struct xfs_inode *ip,
0171 int whichfork, struct xfs_bmbt_irec *imap);
0172 void xfs_rmap_convert_extent(struct xfs_mount *mp, struct xfs_trans *tp,
0173 struct xfs_inode *ip, int whichfork,
0174 struct xfs_bmbt_irec *imap);
0175 void xfs_rmap_alloc_extent(struct xfs_trans *tp, xfs_agnumber_t agno,
0176 xfs_agblock_t bno, xfs_extlen_t len, uint64_t owner);
0177 void xfs_rmap_free_extent(struct xfs_trans *tp, xfs_agnumber_t agno,
0178 xfs_agblock_t bno, xfs_extlen_t len, uint64_t owner);
0179
0180 void xfs_rmap_finish_one_cleanup(struct xfs_trans *tp,
0181 struct xfs_btree_cur *rcur, int error);
0182 int xfs_rmap_finish_one(struct xfs_trans *tp, enum xfs_rmap_intent_type type,
0183 uint64_t owner, int whichfork, xfs_fileoff_t startoff,
0184 xfs_fsblock_t startblock, xfs_filblks_t blockcount,
0185 xfs_exntst_t state, struct xfs_btree_cur **pcur);
0186
0187 int xfs_rmap_lookup_le_range(struct xfs_btree_cur *cur, xfs_agblock_t bno,
0188 uint64_t owner, uint64_t offset, unsigned int flags,
0189 struct xfs_rmap_irec *irec, int *stat);
0190 int xfs_rmap_compare(const struct xfs_rmap_irec *a,
0191 const struct xfs_rmap_irec *b);
0192 union xfs_btree_rec;
0193 int xfs_rmap_btrec_to_irec(const union xfs_btree_rec *rec,
0194 struct xfs_rmap_irec *irec);
0195 int xfs_rmap_has_record(struct xfs_btree_cur *cur, xfs_agblock_t bno,
0196 xfs_extlen_t len, bool *exists);
0197 int xfs_rmap_record_exists(struct xfs_btree_cur *cur, xfs_agblock_t bno,
0198 xfs_extlen_t len, const struct xfs_owner_info *oinfo,
0199 bool *has_rmap);
0200 int xfs_rmap_has_other_keys(struct xfs_btree_cur *cur, xfs_agblock_t bno,
0201 xfs_extlen_t len, const struct xfs_owner_info *oinfo,
0202 bool *has_rmap);
0203 int xfs_rmap_map_raw(struct xfs_btree_cur *cur, struct xfs_rmap_irec *rmap);
0204
0205 extern const struct xfs_owner_info XFS_RMAP_OINFO_SKIP_UPDATE;
0206 extern const struct xfs_owner_info XFS_RMAP_OINFO_ANY_OWNER;
0207 extern const struct xfs_owner_info XFS_RMAP_OINFO_FS;
0208 extern const struct xfs_owner_info XFS_RMAP_OINFO_LOG;
0209 extern const struct xfs_owner_info XFS_RMAP_OINFO_AG;
0210 extern const struct xfs_owner_info XFS_RMAP_OINFO_INOBT;
0211 extern const struct xfs_owner_info XFS_RMAP_OINFO_INODES;
0212 extern const struct xfs_owner_info XFS_RMAP_OINFO_REFC;
0213 extern const struct xfs_owner_info XFS_RMAP_OINFO_COW;
0214
0215 extern struct kmem_cache *xfs_rmap_intent_cache;
0216
0217 int __init xfs_rmap_intent_init_cache(void);
0218 void xfs_rmap_intent_destroy_cache(void);
0219
0220 #endif