// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2000-2006 Silicon Graphics, Inc. * Copyright (c) 2012 Red Hat, 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_defer.h" #include "xfs_inode.h" #include "xfs_btree.h" #include "xfs_trans.h" #include "xfs_alloc.h" #include "xfs_bmap.h" #include "xfs_bmap_util.h" #include "xfs_bmap_btree.h" #include "xfs_rtalloc.h" #include "xfs_error.h" #include "xfs_quota.h" #include "xfs_trans_space.h" #include "xfs_trace.h" #include "xfs_icache.h" #include "xfs_iomap.h" #include "xfs_reflink.h" #include "xfs_rtbitmap.h" /* Kernel only BMAP related definitions and functions */ /* * Convert the given file system block to a disk block. We have to treat it * differently based on whether the file is a real time file or not, because the * bmap code does. */ xfs_daddr_t xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb) { … } /* * Routine to zero an extent on disk allocated to the specific inode. * * The VFS functions take a linearised filesystem block offset, so we have to * convert the sparse xfs fsb to the right format first. * VFS types are real funky, too. */ int xfs_zero_extent( struct xfs_inode *ip, xfs_fsblock_t start_fsb, xfs_off_t count_fsb) { … } /* * Extent tree block counting routines. */ /* * Count leaf blocks given a range of extent records. Delayed allocation * extents are not counted towards the totals. */ xfs_extnum_t xfs_bmap_count_leaves( struct xfs_ifork *ifp, xfs_filblks_t *count) { … } /* * Count fsblocks of the given fork. Delayed allocation extents are * not counted towards the totals. */ int xfs_bmap_count_blocks( struct xfs_trans *tp, struct xfs_inode *ip, int whichfork, xfs_extnum_t *nextents, xfs_filblks_t *count) { … } static int xfs_getbmap_report_one( struct xfs_inode *ip, struct getbmapx *bmv, struct kgetbmap *out, int64_t bmv_end, struct xfs_bmbt_irec *got) { … } static void xfs_getbmap_report_hole( struct xfs_inode *ip, struct getbmapx *bmv, struct kgetbmap *out, int64_t bmv_end, xfs_fileoff_t bno, xfs_fileoff_t end) { … } static inline bool xfs_getbmap_full( struct getbmapx *bmv) { … } static bool xfs_getbmap_next_rec( struct xfs_bmbt_irec *rec, xfs_fileoff_t total_end) { … } /* * Get inode's extents as described in bmv, and format for output. * Calls formatter to fill the user's buffer until all extents * are mapped, until the passed-in bmv->bmv_count slots have * been filled, or until the formatter short-circuits the loop, * if it is tracking filled-in extents on its own. */ int /* error code */ xfs_getbmap( struct xfs_inode *ip, struct getbmapx *bmv, /* user bmap structure */ struct kgetbmap *out) { … } /* * Dead simple method of punching delalyed allocation blocks from a range in * the inode. This will always punch out both the start and end blocks, even * if the ranges only partially overlap them, so it is up to the caller to * ensure that partial blocks are not passed in. */ void xfs_bmap_punch_delalloc_range( struct xfs_inode *ip, xfs_off_t start_byte, xfs_off_t end_byte) { … } /* * Test whether it is appropriate to check an inode for and free post EOF * blocks. */ bool xfs_can_free_eofblocks( struct xfs_inode *ip) { … } /* * This is called to free any blocks beyond eof. The caller must hold * IOLOCK_EXCL unless we are in the inode reclaim path and have the only * reference to the inode. */ int xfs_free_eofblocks( struct xfs_inode *ip) { … } int xfs_alloc_file_space( struct xfs_inode *ip, xfs_off_t offset, xfs_off_t len) { … } static int xfs_unmap_extent( struct xfs_inode *ip, xfs_fileoff_t startoffset_fsb, xfs_filblks_t len_fsb, int *done) { … } /* Caller must first wait for the completion of any pending DIOs if required. */ int xfs_flush_unmap_range( struct xfs_inode *ip, xfs_off_t offset, xfs_off_t len) { … } int xfs_free_file_space( struct xfs_inode *ip, xfs_off_t offset, xfs_off_t len) { … } static int xfs_prepare_shift( struct xfs_inode *ip, loff_t offset) { … } /* * xfs_collapse_file_space() * This routine frees disk space and shift extent for the given file. * The first thing we do is to free data blocks in the specified range * by calling xfs_free_file_space(). It would also sync dirty data * and invalidate page cache over the region on which collapse range * is working. And Shift extent records to the left to cover a hole. * RETURNS: * 0 on success * errno on error * */ int xfs_collapse_file_space( struct xfs_inode *ip, xfs_off_t offset, xfs_off_t len) { … } /* * xfs_insert_file_space() * This routine create hole space by shifting extents for the given file. * The first thing we do is to sync dirty data and invalidate page cache * over the region on which insert range is working. And split an extent * to two extents at given offset by calling xfs_bmap_split_extent. * And shift all extent records which are laying between [offset, * last allocated extent] to the right to reserve hole range. * RETURNS: * 0 on success * errno on error */ int xfs_insert_file_space( struct xfs_inode *ip, loff_t offset, loff_t len) { … } /* * We need to check that the format of the data fork in the temporary inode is * valid for the target inode before doing the swap. This is not a problem with * attr1 because of the fixed fork offset, but attr2 has a dynamically sized * data fork depending on the space the attribute fork is taking so we can get * invalid formats on the target inode. * * E.g. target has space for 7 extents in extent format, temp inode only has * space for 6. If we defragment down to 7 extents, then the tmp format is a * btree, but when swapped it needs to be in extent format. Hence we can't just * blindly swap data forks on attr2 filesystems. * * Note that we check the swap in both directions so that we don't end up with * a corrupt temporary inode, either. * * Note that fixing the way xfs_fsr sets up the attribute fork in the source * inode will prevent this situation from occurring, so all we do here is * reject and log the attempt. basically we are putting the responsibility on * userspace to get this right. */ static int xfs_swap_extents_check_format( struct xfs_inode *ip, /* target inode */ struct xfs_inode *tip) /* tmp inode */ { … } static int xfs_swap_extent_flush( struct xfs_inode *ip) { … } /* * Move extents from one file to another, when rmap is enabled. */ STATIC int xfs_swap_extent_rmap( struct xfs_trans **tpp, struct xfs_inode *ip, struct xfs_inode *tip) { … } /* Swap the extents of two files by swapping data forks. */ STATIC int xfs_swap_extent_forks( struct xfs_trans *tp, struct xfs_inode *ip, struct xfs_inode *tip, int *src_log_flags, int *target_log_flags) { … } /* * Fix up the owners of the bmbt blocks to refer to the current inode. The * change owner scan attempts to order all modified buffers in the current * transaction. In the event of ordered buffer failure, the offending buffer is * physically logged as a fallback and the scan returns -EAGAIN. We must roll * the transaction in this case to replenish the fallback log reservation and * restart the scan. This process repeats until the scan completes. */ static int xfs_swap_change_owner( struct xfs_trans **tpp, struct xfs_inode *ip, struct xfs_inode *tmpip) { … } int xfs_swap_extents( struct xfs_inode *ip, /* target inode */ struct xfs_inode *tip, /* tmp inode */ struct xfs_swapext *sxp) { … }