cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fiemap.rst (10059B)


      1.. SPDX-License-Identifier: GPL-2.0
      2
      3============
      4Fiemap Ioctl
      5============
      6
      7The fiemap ioctl is an efficient method for userspace to get file
      8extent mappings. Instead of block-by-block mapping (such as bmap), fiemap
      9returns a list of extents.
     10
     11
     12Request Basics
     13--------------
     14
     15A fiemap request is encoded within struct fiemap::
     16
     17  struct fiemap {
     18	__u64	fm_start;	 /* logical offset (inclusive) at
     19				  * which to start mapping (in) */
     20	__u64	fm_length;	 /* logical length of mapping which
     21				  * userspace cares about (in) */
     22	__u32	fm_flags;	 /* FIEMAP_FLAG_* flags for request (in/out) */
     23	__u32	fm_mapped_extents; /* number of extents that were
     24				    * mapped (out) */
     25	__u32	fm_extent_count; /* size of fm_extents array (in) */
     26	__u32	fm_reserved;
     27	struct fiemap_extent fm_extents[0]; /* array of mapped extents (out) */
     28  };
     29
     30
     31fm_start, and fm_length specify the logical range within the file
     32which the process would like mappings for. Extents returned mirror
     33those on disk - that is, the logical offset of the 1st returned extent
     34may start before fm_start, and the range covered by the last returned
     35extent may end after fm_length. All offsets and lengths are in bytes.
     36
     37Certain flags to modify the way in which mappings are looked up can be
     38set in fm_flags. If the kernel doesn't understand some particular
     39flags, it will return EBADR and the contents of fm_flags will contain
     40the set of flags which caused the error. If the kernel is compatible
     41with all flags passed, the contents of fm_flags will be unmodified.
     42It is up to userspace to determine whether rejection of a particular
     43flag is fatal to its operation. This scheme is intended to allow the
     44fiemap interface to grow in the future but without losing
     45compatibility with old software.
     46
     47fm_extent_count specifies the number of elements in the fm_extents[] array
     48that can be used to return extents.  If fm_extent_count is zero, then the
     49fm_extents[] array is ignored (no extents will be returned), and the
     50fm_mapped_extents count will hold the number of extents needed in
     51fm_extents[] to hold the file's current mapping.  Note that there is
     52nothing to prevent the file from changing between calls to FIEMAP.
     53
     54The following flags can be set in fm_flags:
     55
     56FIEMAP_FLAG_SYNC
     57  If this flag is set, the kernel will sync the file before mapping extents.
     58
     59FIEMAP_FLAG_XATTR
     60  If this flag is set, the extents returned will describe the inodes
     61  extended attribute lookup tree, instead of its data tree.
     62
     63
     64Extent Mapping
     65--------------
     66
     67Extent information is returned within the embedded fm_extents array
     68which userspace must allocate along with the fiemap structure. The
     69number of elements in the fiemap_extents[] array should be passed via
     70fm_extent_count. The number of extents mapped by kernel will be
     71returned via fm_mapped_extents. If the number of fiemap_extents
     72allocated is less than would be required to map the requested range,
     73the maximum number of extents that can be mapped in the fm_extent[]
     74array will be returned and fm_mapped_extents will be equal to
     75fm_extent_count. In that case, the last extent in the array will not
     76complete the requested range and will not have the FIEMAP_EXTENT_LAST
     77flag set (see the next section on extent flags).
     78
     79Each extent is described by a single fiemap_extent structure as
     80returned in fm_extents::
     81
     82    struct fiemap_extent {
     83	    __u64	fe_logical;  /* logical offset in bytes for the start of
     84				* the extent */
     85	    __u64	fe_physical; /* physical offset in bytes for the start
     86				* of the extent */
     87	    __u64	fe_length;   /* length in bytes for the extent */
     88	    __u64	fe_reserved64[2];
     89	    __u32	fe_flags;    /* FIEMAP_EXTENT_* flags for this extent */
     90	    __u32	fe_reserved[3];
     91    };
     92
     93All offsets and lengths are in bytes and mirror those on disk.  It is valid
     94for an extents logical offset to start before the request or its logical
     95length to extend past the request.  Unless FIEMAP_EXTENT_NOT_ALIGNED is
     96returned, fe_logical, fe_physical, and fe_length will be aligned to the
     97block size of the file system.  With the exception of extents flagged as
     98FIEMAP_EXTENT_MERGED, adjacent extents will not be merged.
     99
    100The fe_flags field contains flags which describe the extent returned.
    101A special flag, FIEMAP_EXTENT_LAST is always set on the last extent in
    102the file so that the process making fiemap calls can determine when no
    103more extents are available, without having to call the ioctl again.
    104
    105Some flags are intentionally vague and will always be set in the
    106presence of other more specific flags. This way a program looking for
    107a general property does not have to know all existing and future flags
    108which imply that property.
    109
    110For example, if FIEMAP_EXTENT_DATA_INLINE or FIEMAP_EXTENT_DATA_TAIL
    111are set, FIEMAP_EXTENT_NOT_ALIGNED will also be set. A program looking
    112for inline or tail-packed data can key on the specific flag. Software
    113which simply cares not to try operating on non-aligned extents
    114however, can just key on FIEMAP_EXTENT_NOT_ALIGNED, and not have to
    115worry about all present and future flags which might imply unaligned
    116data. Note that the opposite is not true - it would be valid for
    117FIEMAP_EXTENT_NOT_ALIGNED to appear alone.
    118
    119FIEMAP_EXTENT_LAST
    120  This is generally the last extent in the file. A mapping attempt past
    121  this extent may return nothing. Some implementations set this flag to
    122  indicate this extent is the last one in the range queried by the user
    123  (via fiemap->fm_length).
    124
    125FIEMAP_EXTENT_UNKNOWN
    126  The location of this extent is currently unknown. This may indicate
    127  the data is stored on an inaccessible volume or that no storage has
    128  been allocated for the file yet.
    129
    130FIEMAP_EXTENT_DELALLOC
    131  This will also set FIEMAP_EXTENT_UNKNOWN.
    132
    133  Delayed allocation - while there is data for this extent, its
    134  physical location has not been allocated yet.
    135
    136FIEMAP_EXTENT_ENCODED
    137  This extent does not consist of plain filesystem blocks but is
    138  encoded (e.g. encrypted or compressed).  Reading the data in this
    139  extent via I/O to the block device will have undefined results.
    140
    141Note that it is *always* undefined to try to update the data
    142in-place by writing to the indicated location without the
    143assistance of the filesystem, or to access the data using the
    144information returned by the FIEMAP interface while the filesystem
    145is mounted.  In other words, user applications may only read the
    146extent data via I/O to the block device while the filesystem is
    147unmounted, and then only if the FIEMAP_EXTENT_ENCODED flag is
    148clear; user applications must not try reading or writing to the
    149filesystem via the block device under any other circumstances.
    150
    151FIEMAP_EXTENT_DATA_ENCRYPTED
    152  This will also set FIEMAP_EXTENT_ENCODED
    153  The data in this extent has been encrypted by the file system.
    154
    155FIEMAP_EXTENT_NOT_ALIGNED
    156  Extent offsets and length are not guaranteed to be block aligned.
    157
    158FIEMAP_EXTENT_DATA_INLINE
    159  This will also set FIEMAP_EXTENT_NOT_ALIGNED
    160  Data is located within a meta data block.
    161
    162FIEMAP_EXTENT_DATA_TAIL
    163  This will also set FIEMAP_EXTENT_NOT_ALIGNED
    164  Data is packed into a block with data from other files.
    165
    166FIEMAP_EXTENT_UNWRITTEN
    167  Unwritten extent - the extent is allocated but its data has not been
    168  initialized.  This indicates the extent's data will be all zero if read
    169  through the filesystem but the contents are undefined if read directly from
    170  the device.
    171
    172FIEMAP_EXTENT_MERGED
    173  This will be set when a file does not support extents, i.e., it uses a block
    174  based addressing scheme.  Since returning an extent for each block back to
    175  userspace would be highly inefficient, the kernel will try to merge most
    176  adjacent blocks into 'extents'.
    177
    178
    179VFS -> File System Implementation
    180---------------------------------
    181
    182File systems wishing to support fiemap must implement a ->fiemap callback on
    183their inode_operations structure. The fs ->fiemap call is responsible for
    184defining its set of supported fiemap flags, and calling a helper function on
    185each discovered extent::
    186
    187  struct inode_operations {
    188       ...
    189
    190       int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
    191                     u64 len);
    192
    193->fiemap is passed struct fiemap_extent_info which describes the
    194fiemap request::
    195
    196  struct fiemap_extent_info {
    197	unsigned int fi_flags;		/* Flags as passed from user */
    198	unsigned int fi_extents_mapped;	/* Number of mapped extents */
    199	unsigned int fi_extents_max;	/* Size of fiemap_extent array */
    200	struct fiemap_extent *fi_extents_start;	/* Start of fiemap_extent array */
    201  };
    202
    203It is intended that the file system should not need to access any of this
    204structure directly. Filesystem handlers should be tolerant to signals and return
    205EINTR once fatal signal received.
    206
    207
    208Flag checking should be done at the beginning of the ->fiemap callback via the
    209fiemap_prep() helper::
    210
    211  int fiemap_prep(struct inode *inode, struct fiemap_extent_info *fieinfo,
    212		  u64 start, u64 *len, u32 supported_flags);
    213
    214The struct fieinfo should be passed in as received from ioctl_fiemap(). The
    215set of fiemap flags which the fs understands should be passed via fs_flags. If
    216fiemap_prep finds invalid user flags, it will place the bad values in
    217fieinfo->fi_flags and return -EBADR. If the file system gets -EBADR, from
    218fiemap_prep(), it should immediately exit, returning that error back to
    219ioctl_fiemap().  Additionally the range is validate against the supported
    220maximum file size.
    221
    222
    223For each extent in the request range, the file system should call
    224the helper function, fiemap_fill_next_extent()::
    225
    226  int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical,
    227			      u64 phys, u64 len, u32 flags, u32 dev);
    228
    229fiemap_fill_next_extent() will use the passed values to populate the
    230next free extent in the fm_extents array. 'General' extent flags will
    231automatically be set from specific flags on behalf of the calling file
    232system so that the userspace API is not broken.
    233
    234fiemap_fill_next_extent() returns 0 on success, and 1 when the
    235user-supplied fm_extents array is full. If an error is encountered
    236while copying the extent to user memory, -EFAULT will be returned.