// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. */ #include "xfs.h" #include "xfs_fs.h" #include "xfs_shared.h" #include "xfs_format.h" #include "xfs_log_format.h" #include "xfs_trans_resv.h" #include "xfs_bit.h" #include "xfs_mount.h" #include "xfs_inode.h" #include "xfs_bmap.h" #include "xfs_trans.h" #include "xfs_rtalloc.h" #include "xfs_error.h" #include "xfs_rtbitmap.h" #include "xfs_health.h" /* * Realtime allocator bitmap functions shared with userspace. */ /* * Real time buffers need verifiers to avoid runtime warnings during IO. * We don't have anything to verify, however, so these are just dummy * operations. */ static void xfs_rtbuf_verify_read( struct xfs_buf *bp) { … } static void xfs_rtbuf_verify_write( struct xfs_buf *bp) { … } const struct xfs_buf_ops xfs_rtbuf_ops = …; /* Release cached rt bitmap and summary buffers. */ void xfs_rtbuf_cache_relse( struct xfs_rtalloc_args *args) { … } /* * Get a buffer for the bitmap or summary file block specified. * The buffer is returned read and locked. */ int xfs_rtbuf_get( struct xfs_rtalloc_args *args, xfs_fileoff_t block, /* block number in bitmap or summary */ int issum) /* is summary not bitmap */ { … } /* * Searching backward from start to limit, find the first block whose * allocated/free state is different from start's. */ int xfs_rtfind_back( struct xfs_rtalloc_args *args, xfs_rtxnum_t start, /* starting rtext to look at */ xfs_rtxnum_t limit, /* last rtext to look at */ xfs_rtxnum_t *rtx) /* out: start rtext found */ { … } /* * Searching forward from start to limit, find the first block whose * allocated/free state is different from start's. */ int xfs_rtfind_forw( struct xfs_rtalloc_args *args, xfs_rtxnum_t start, /* starting rtext to look at */ xfs_rtxnum_t limit, /* last rtext to look at */ xfs_rtxnum_t *rtx) /* out: start rtext found */ { … } /* Log rtsummary counter at @infoword. */ static inline void xfs_trans_log_rtsummary( struct xfs_rtalloc_args *args, unsigned int infoword) { … } /* * Modify the summary information for a given extent size, bitmap block * combination. */ int xfs_rtmodify_summary( struct xfs_rtalloc_args *args, int log, /* log2 of extent size */ xfs_fileoff_t bbno, /* bitmap block number */ int delta) /* in/out: summary block number */ { … } /* * Read and return the summary information for a given extent size, bitmap block * combination. */ int xfs_rtget_summary( struct xfs_rtalloc_args *args, int log, /* log2 of extent size */ xfs_fileoff_t bbno, /* bitmap block number */ xfs_suminfo_t *sum) /* out: summary info for this block */ { … } /* Log rtbitmap block from the word @from to the byte before @next. */ static inline void xfs_trans_log_rtbitmap( struct xfs_rtalloc_args *args, unsigned int from, unsigned int next) { … } /* * Set the given range of bitmap bits to the given value. * Do whatever I/O and logging is required. */ int xfs_rtmodify_range( struct xfs_rtalloc_args *args, xfs_rtxnum_t start, /* starting rtext to modify */ xfs_rtxlen_t len, /* length of extent to modify */ int val) /* 1 for free, 0 for allocated */ { … } /* * Mark an extent specified by start and len freed. * Updates all the summary information as well as the bitmap. */ int xfs_rtfree_range( struct xfs_rtalloc_args *args, xfs_rtxnum_t start, /* starting rtext to free */ xfs_rtxlen_t len) /* in/out: summary block number */ { … } /* * Check that the given range is either all allocated (val = 0) or * all free (val = 1). */ int xfs_rtcheck_range( struct xfs_rtalloc_args *args, xfs_rtxnum_t start, /* starting rtext number of extent */ xfs_rtxlen_t len, /* length of extent */ int val, /* 1 for free, 0 for allocated */ xfs_rtxnum_t *new, /* out: first rtext not matching */ int *stat) /* out: 1 for matches, 0 for not */ { … } #ifdef DEBUG /* * Check that the given extent (block range) is allocated already. */ STATIC int xfs_rtcheck_alloc_range( struct xfs_rtalloc_args *args, xfs_rtxnum_t start, /* starting rtext number of extent */ xfs_rtxlen_t len) /* length of extent */ { … } #else #define xfs_rtcheck_alloc_range … #endif /* * Free an extent in the realtime subvolume. Length is expressed in * realtime extents, as is the block number. */ int xfs_rtfree_extent( struct xfs_trans *tp, /* transaction pointer */ xfs_rtxnum_t start, /* starting rtext number to free */ xfs_rtxlen_t len) /* length of extent freed */ { … } /* * Free some blocks in the realtime subvolume. rtbno and rtlen are in units of * rt blocks, not rt extents; must be aligned to the rt extent size; and rtlen * cannot exceed XFS_MAX_BMBT_EXTLEN. */ int xfs_rtfree_blocks( struct xfs_trans *tp, xfs_fsblock_t rtbno, xfs_filblks_t rtlen) { … } /* Find all the free records within a given range. */ int xfs_rtalloc_query_range( struct xfs_mount *mp, struct xfs_trans *tp, const struct xfs_rtalloc_rec *low_rec, const struct xfs_rtalloc_rec *high_rec, xfs_rtalloc_query_range_fn fn, void *priv) { … } /* Find all the free records. */ int xfs_rtalloc_query_all( struct xfs_mount *mp, struct xfs_trans *tp, xfs_rtalloc_query_range_fn fn, void *priv) { … } /* Is the given extent all free? */ int xfs_rtalloc_extent_is_free( struct xfs_mount *mp, struct xfs_trans *tp, xfs_rtxnum_t start, xfs_rtxlen_t len, bool *is_free) { … } /* * Compute the number of rtbitmap blocks needed to track the given number of rt * extents. */ xfs_filblks_t xfs_rtbitmap_blockcount( struct xfs_mount *mp, xfs_rtbxlen_t rtextents) { … } /* * Compute the number of rtbitmap words needed to populate every block of a * bitmap that is large enough to track the given number of rt extents. */ unsigned long long xfs_rtbitmap_wordcount( struct xfs_mount *mp, xfs_rtbxlen_t rtextents) { … } /* Compute the number of rtsummary blocks needed to track the given rt space. */ xfs_filblks_t xfs_rtsummary_blockcount( struct xfs_mount *mp, unsigned int rsumlevels, xfs_extlen_t rbmblocks) { … } /* * Compute the number of rtsummary info words needed to populate every block of * a summary file that is large enough to track the given rt space. */ unsigned long long xfs_rtsummary_wordcount( struct xfs_mount *mp, unsigned int rsumlevels, xfs_extlen_t rbmblocks) { … } /* * Lock both realtime free space metadata inodes for a freespace update. If a * transaction is given, the inodes will be joined to the transaction and the * ILOCKs will be released on transaction commit. */ void xfs_rtbitmap_lock( struct xfs_trans *tp, struct xfs_mount *mp) { … } /* Unlock both realtime free space metadata inodes after a freespace update. */ void xfs_rtbitmap_unlock( struct xfs_mount *mp) { … } /* * Lock the realtime free space metadata inodes for a freespace scan. Callers * must walk metadata blocks in order of increasing file offset. */ void xfs_rtbitmap_lock_shared( struct xfs_mount *mp, unsigned int rbmlock_flags) { … } /* Unlock the realtime free space metadata inodes after a freespace scan. */ void xfs_rtbitmap_unlock_shared( struct xfs_mount *mp, unsigned int rbmlock_flags) { … }