// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2000-2006 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_mount.h" #include "xfs_inode.h" #include "xfs_trans.h" #include "xfs_inode_item.h" #include "xfs_btree.h" #include "xfs_bmap_btree.h" #include "xfs_bmap.h" #include "xfs_error.h" #include "xfs_trace.h" #include "xfs_da_format.h" #include "xfs_da_btree.h" #include "xfs_dir2_priv.h" #include "xfs_attr_leaf.h" #include "xfs_types.h" #include "xfs_errortag.h" #include "xfs_health.h" #include "xfs_symlink_remote.h" struct kmem_cache *xfs_ifork_cache; void xfs_init_local_fork( struct xfs_inode *ip, int whichfork, const void *data, int64_t size) { … } /* * The file is in-lined in the on-disk inode. */ STATIC int xfs_iformat_local( struct xfs_inode *ip, struct xfs_dinode *dip, int whichfork, int size) { … } /* * The file consists of a set of extents all of which fit into the on-disk * inode. */ STATIC int xfs_iformat_extents( struct xfs_inode *ip, struct xfs_dinode *dip, int whichfork) { … } /* * The file has too many extents to fit into * the inode, so they are in B-tree format. * Allocate a buffer for the root of the B-tree * and copy the root into it. The i_extents * field will remain NULL until all of the * extents are read in (when they are needed). */ STATIC int xfs_iformat_btree( struct xfs_inode *ip, struct xfs_dinode *dip, int whichfork) { … } int xfs_iformat_data_fork( struct xfs_inode *ip, struct xfs_dinode *dip) { … } static uint16_t xfs_dfork_attr_shortform_size( struct xfs_dinode *dip) { … } void xfs_ifork_init_attr( struct xfs_inode *ip, enum xfs_dinode_fmt format, xfs_extnum_t nextents) { … } void xfs_ifork_zap_attr( struct xfs_inode *ip) { … } int xfs_iformat_attr_fork( struct xfs_inode *ip, struct xfs_dinode *dip) { … } /* * Reallocate the space for if_broot based on the number of records * being added or deleted as indicated in rec_diff. Move the records * and pointers in if_broot to fit the new size. When shrinking this * will eliminate holes between the records and pointers created by * the caller. When growing this will create holes to be filled in * by the caller. * * The caller must not request to add more records than would fit in * the on-disk inode root. If the if_broot is currently NULL, then * if we are adding records, one will be allocated. The caller must also * not request that the number of records go below zero, although * it can go to zero. * * ip -- the inode whose if_broot area is changing * ext_diff -- the change in the number of records, positive or negative, * requested for the if_broot array. */ void xfs_iroot_realloc( xfs_inode_t *ip, int rec_diff, int whichfork) { … } /* * This is called when the amount of space needed for if_data * is increased or decreased. The change in size is indicated by * the number of bytes that need to be added or deleted in the * byte_diff parameter. * * If the amount of space needed has decreased below the size of the * inline buffer, then switch to using the inline buffer. Otherwise, * use krealloc() or kmalloc() to adjust the size of the buffer * to what is needed. * * ip -- the inode whose if_data area is changing * byte_diff -- the change in the number of bytes, positive or negative, * requested for the if_data array. */ void * xfs_idata_realloc( struct xfs_inode *ip, int64_t byte_diff, int whichfork) { … } /* Free all memory and reset a fork back to its initial state. */ void xfs_idestroy_fork( struct xfs_ifork *ifp) { … } /* * Convert in-core extents to on-disk form * * In the case of the data fork, the in-core and on-disk fork sizes can be * different due to delayed allocation extents. We only copy on-disk extents * here, so callers must always use the physical fork size to determine the * size of the buffer passed to this routine. We will return the size actually * used. */ int xfs_iextents_copy( struct xfs_inode *ip, struct xfs_bmbt_rec *dp, int whichfork) { … } /* * Each of the following cases stores data into the same region * of the on-disk inode, so only one of them can be valid at * any given time. While it is possible to have conflicting formats * and log flags, e.g. having XFS_ILOG_?DATA set when the fork is * in EXTENTS format, this can only happen when the fork has * changed formats after being modified but before being flushed. * In these cases, the format always takes precedence, because the * format indicates the current state of the fork. */ void xfs_iflush_fork( struct xfs_inode *ip, struct xfs_dinode *dip, struct xfs_inode_log_item *iip, int whichfork) { … } /* Convert bmap state flags to an inode fork. */ struct xfs_ifork * xfs_iext_state_to_fork( struct xfs_inode *ip, int state) { … } /* * Initialize an inode's copy-on-write fork. */ void xfs_ifork_init_cow( struct xfs_inode *ip) { … } /* Verify the inline contents of the data fork of an inode. */ int xfs_ifork_verify_local_data( struct xfs_inode *ip) { … } /* Verify the inline contents of the attr fork of an inode. */ int xfs_ifork_verify_local_attr( struct xfs_inode *ip) { … } /* * Check if the inode fork supports adding nr_to_add more extents. * * If it doesn't but we can upgrade it to large extent counters, do the upgrade. * If we can't upgrade or are already using big counters but still can't fit the * additional extents, return -EFBIG. */ int xfs_iext_count_extend( struct xfs_trans *tp, struct xfs_inode *ip, int whichfork, uint nr_to_add) { … } /* Decide if a file mapping is on the realtime device or not. */ bool xfs_ifork_is_realtime( struct xfs_inode *ip, int whichfork) { … }