linux/fs/xfs/libxfs/xfs_rmap.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2016 Oracle.  All Rights Reserved.
   3 *
   4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version 2
   9 * of the License, or (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it would be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write the Free Software Foundation,
  18 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
  19 */
  20#ifndef __XFS_RMAP_H__
  21#define __XFS_RMAP_H__
  22
  23static inline void
  24xfs_rmap_ag_owner(
  25        struct xfs_owner_info   *oi,
  26        uint64_t                owner)
  27{
  28        oi->oi_owner = owner;
  29        oi->oi_offset = 0;
  30        oi->oi_flags = 0;
  31}
  32
  33static inline void
  34xfs_rmap_ino_bmbt_owner(
  35        struct xfs_owner_info   *oi,
  36        xfs_ino_t               ino,
  37        int                     whichfork)
  38{
  39        oi->oi_owner = ino;
  40        oi->oi_offset = 0;
  41        oi->oi_flags = XFS_OWNER_INFO_BMBT_BLOCK;
  42        if (whichfork == XFS_ATTR_FORK)
  43                oi->oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
  44}
  45
  46static inline void
  47xfs_rmap_ino_owner(
  48        struct xfs_owner_info   *oi,
  49        xfs_ino_t               ino,
  50        int                     whichfork,
  51        xfs_fileoff_t           offset)
  52{
  53        oi->oi_owner = ino;
  54        oi->oi_offset = offset;
  55        oi->oi_flags = 0;
  56        if (whichfork == XFS_ATTR_FORK)
  57                oi->oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
  58}
  59
  60static inline void
  61xfs_rmap_skip_owner_update(
  62        struct xfs_owner_info   *oi)
  63{
  64        xfs_rmap_ag_owner(oi, XFS_RMAP_OWN_NULL);
  65}
  66
  67static inline bool
  68xfs_rmap_should_skip_owner_update(
  69        struct xfs_owner_info   *oi)
  70{
  71        return oi->oi_owner == XFS_RMAP_OWN_NULL;
  72}
  73
  74static inline void
  75xfs_rmap_any_owner_update(
  76        struct xfs_owner_info   *oi)
  77{
  78        xfs_rmap_ag_owner(oi, XFS_RMAP_OWN_UNKNOWN);
  79}
  80
  81/* Reverse mapping functions. */
  82
  83struct xfs_buf;
  84
  85static inline __u64
  86xfs_rmap_irec_offset_pack(
  87        const struct xfs_rmap_irec      *irec)
  88{
  89        __u64                   x;
  90
  91        x = XFS_RMAP_OFF(irec->rm_offset);
  92        if (irec->rm_flags & XFS_RMAP_ATTR_FORK)
  93                x |= XFS_RMAP_OFF_ATTR_FORK;
  94        if (irec->rm_flags & XFS_RMAP_BMBT_BLOCK)
  95                x |= XFS_RMAP_OFF_BMBT_BLOCK;
  96        if (irec->rm_flags & XFS_RMAP_UNWRITTEN)
  97                x |= XFS_RMAP_OFF_UNWRITTEN;
  98        return x;
  99}
 100
 101static inline int
 102xfs_rmap_irec_offset_unpack(
 103        __u64                   offset,
 104        struct xfs_rmap_irec    *irec)
 105{
 106        if (offset & ~(XFS_RMAP_OFF_MASK | XFS_RMAP_OFF_FLAGS))
 107                return -EFSCORRUPTED;
 108        irec->rm_offset = XFS_RMAP_OFF(offset);
 109        if (offset & XFS_RMAP_OFF_ATTR_FORK)
 110                irec->rm_flags |= XFS_RMAP_ATTR_FORK;
 111        if (offset & XFS_RMAP_OFF_BMBT_BLOCK)
 112                irec->rm_flags |= XFS_RMAP_BMBT_BLOCK;
 113        if (offset & XFS_RMAP_OFF_UNWRITTEN)
 114                irec->rm_flags |= XFS_RMAP_UNWRITTEN;
 115        return 0;
 116}
 117
 118static inline void
 119xfs_owner_info_unpack(
 120        struct xfs_owner_info   *oinfo,
 121        uint64_t                *owner,
 122        uint64_t                *offset,
 123        unsigned int            *flags)
 124{
 125        unsigned int            r = 0;
 126
 127        *owner = oinfo->oi_owner;
 128        *offset = oinfo->oi_offset;
 129        if (oinfo->oi_flags & XFS_OWNER_INFO_ATTR_FORK)
 130                r |= XFS_RMAP_ATTR_FORK;
 131        if (oinfo->oi_flags & XFS_OWNER_INFO_BMBT_BLOCK)
 132                r |= XFS_RMAP_BMBT_BLOCK;
 133        *flags = r;
 134}
 135
 136static inline void
 137xfs_owner_info_pack(
 138        struct xfs_owner_info   *oinfo,
 139        uint64_t                owner,
 140        uint64_t                offset,
 141        unsigned int            flags)
 142{
 143        oinfo->oi_owner = owner;
 144        oinfo->oi_offset = XFS_RMAP_OFF(offset);
 145        oinfo->oi_flags = 0;
 146        if (flags & XFS_RMAP_ATTR_FORK)
 147                oinfo->oi_flags |= XFS_OWNER_INFO_ATTR_FORK;
 148        if (flags & XFS_RMAP_BMBT_BLOCK)
 149                oinfo->oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
 150}
 151
 152int xfs_rmap_alloc(struct xfs_trans *tp, struct xfs_buf *agbp,
 153                   xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len,
 154                   struct xfs_owner_info *oinfo);
 155int xfs_rmap_free(struct xfs_trans *tp, struct xfs_buf *agbp,
 156                  xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len,
 157                  struct xfs_owner_info *oinfo);
 158
 159int xfs_rmap_lookup_le(struct xfs_btree_cur *cur, xfs_agblock_t bno,
 160                xfs_extlen_t len, uint64_t owner, uint64_t offset,
 161                unsigned int flags, int *stat);
 162int xfs_rmap_lookup_eq(struct xfs_btree_cur *cur, xfs_agblock_t bno,
 163                xfs_extlen_t len, uint64_t owner, uint64_t offset,
 164                unsigned int flags, int *stat);
 165int xfs_rmap_insert(struct xfs_btree_cur *rcur, xfs_agblock_t agbno,
 166                xfs_extlen_t len, uint64_t owner, uint64_t offset,
 167                unsigned int flags);
 168int xfs_rmap_get_rec(struct xfs_btree_cur *cur, struct xfs_rmap_irec *irec,
 169                int *stat);
 170
 171typedef int (*xfs_rmap_query_range_fn)(
 172        struct xfs_btree_cur    *cur,
 173        struct xfs_rmap_irec    *rec,
 174        void                    *priv);
 175
 176int xfs_rmap_query_range(struct xfs_btree_cur *cur,
 177                struct xfs_rmap_irec *low_rec, struct xfs_rmap_irec *high_rec,
 178                xfs_rmap_query_range_fn fn, void *priv);
 179int xfs_rmap_query_all(struct xfs_btree_cur *cur, xfs_rmap_query_range_fn fn,
 180                void *priv);
 181
 182enum xfs_rmap_intent_type {
 183        XFS_RMAP_MAP,
 184        XFS_RMAP_MAP_SHARED,
 185        XFS_RMAP_UNMAP,
 186        XFS_RMAP_UNMAP_SHARED,
 187        XFS_RMAP_CONVERT,
 188        XFS_RMAP_CONVERT_SHARED,
 189        XFS_RMAP_ALLOC,
 190        XFS_RMAP_FREE,
 191};
 192
 193struct xfs_rmap_intent {
 194        struct list_head                        ri_list;
 195        enum xfs_rmap_intent_type               ri_type;
 196        uint64_t                                ri_owner;
 197        int                                     ri_whichfork;
 198        struct xfs_bmbt_irec                    ri_bmap;
 199};
 200
 201/* functions for updating the rmapbt based on bmbt map/unmap operations */
 202int xfs_rmap_map_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops,
 203                struct xfs_inode *ip, int whichfork,
 204                struct xfs_bmbt_irec *imap);
 205int xfs_rmap_unmap_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops,
 206                struct xfs_inode *ip, int whichfork,
 207                struct xfs_bmbt_irec *imap);
 208int xfs_rmap_convert_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops,
 209                struct xfs_inode *ip, int whichfork,
 210                struct xfs_bmbt_irec *imap);
 211int xfs_rmap_alloc_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops,
 212                xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len,
 213                uint64_t owner);
 214int xfs_rmap_free_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops,
 215                xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len,
 216                uint64_t owner);
 217
 218void xfs_rmap_finish_one_cleanup(struct xfs_trans *tp,
 219                struct xfs_btree_cur *rcur, int error);
 220int xfs_rmap_finish_one(struct xfs_trans *tp, enum xfs_rmap_intent_type type,
 221                uint64_t owner, int whichfork, xfs_fileoff_t startoff,
 222                xfs_fsblock_t startblock, xfs_filblks_t blockcount,
 223                xfs_exntst_t state, struct xfs_btree_cur **pcur);
 224
 225int xfs_rmap_find_left_neighbor(struct xfs_btree_cur *cur, xfs_agblock_t bno,
 226                uint64_t owner, uint64_t offset, unsigned int flags,
 227                struct xfs_rmap_irec *irec, int *stat);
 228int xfs_rmap_lookup_le_range(struct xfs_btree_cur *cur, xfs_agblock_t bno,
 229                uint64_t owner, uint64_t offset, unsigned int flags,
 230                struct xfs_rmap_irec *irec, int *stat);
 231int xfs_rmap_compare(const struct xfs_rmap_irec *a,
 232                const struct xfs_rmap_irec *b);
 233union xfs_btree_rec;
 234int xfs_rmap_btrec_to_irec(union xfs_btree_rec *rec,
 235                struct xfs_rmap_irec *irec);
 236
 237#endif  /* __XFS_RMAP_H__ */
 238