LCOV - code coverage report
Current view: top level - fs/iomap - fiemap.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-djwx @ Mon Jul 31 20:08:22 PDT 2023 Lines: 52 55 94.5 %
Date: 2023-07-31 20:08:22 Functions: 4 4 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (c) 2016-2021 Christoph Hellwig.
       4             :  */
       5             : #include <linux/module.h>
       6             : #include <linux/compiler.h>
       7             : #include <linux/fs.h>
       8             : #include <linux/iomap.h>
       9             : #include <linux/fiemap.h>
      10             : #include <linux/pagemap.h>
      11             : 
      12     5496839 : static int iomap_to_fiemap(struct fiemap_extent_info *fi,
      13             :                 const struct iomap *iomap, u32 flags)
      14             : {
      15     5496839 :         switch (iomap->type) {
      16             :         case IOMAP_HOLE:
      17             :                 /* skip holes */
      18             :                 return 0;
      19        7617 :         case IOMAP_DELALLOC:
      20        7617 :                 flags |= FIEMAP_EXTENT_DELALLOC | FIEMAP_EXTENT_UNKNOWN;
      21        7617 :                 break;
      22             :         case IOMAP_MAPPED:
      23             :                 break;
      24     1440088 :         case IOMAP_UNWRITTEN:
      25     1440088 :                 flags |= FIEMAP_EXTENT_UNWRITTEN;
      26     1440088 :                 break;
      27           4 :         case IOMAP_INLINE:
      28           4 :                 flags |= FIEMAP_EXTENT_DATA_INLINE;
      29           4 :                 break;
      30             :         }
      31             : 
      32     5010118 :         if (iomap->flags & IOMAP_F_MERGED)
      33          31 :                 flags |= FIEMAP_EXTENT_MERGED;
      34     5010118 :         if (iomap->flags & IOMAP_F_SHARED)
      35      304551 :                 flags |= FIEMAP_EXTENT_SHARED;
      36             : 
      37     5010118 :         return fiemap_fill_next_extent(fi, iomap->offset,
      38     5010118 :                         iomap->addr != IOMAP_NULL_ADDR ? iomap->addr : 0,
      39     5010118 :                         iomap->length, flags);
      40             : }
      41             : 
      42     8217385 : static loff_t iomap_fiemap_iter(const struct iomap_iter *iter,
      43             :                 struct fiemap_extent_info *fi, struct iomap *prev)
      44             : {
      45     8217385 :         int ret;
      46             : 
      47     8217385 :         if (iter->iomap.type == IOMAP_HOLE)
      48     3207551 :                 return iomap_length(iter);
      49             : 
      50     5009834 :         ret = iomap_to_fiemap(fi, prev, 0);
      51     5010123 :         *prev = iter->iomap;
      52     5010123 :         switch (ret) {
      53     4997963 :         case 0:         /* success */
      54     4997963 :                 return iomap_length(iter);
      55             :         case 1:         /* extent array full */
      56             :                 return 0;
      57           0 :         default:        /* error */
      58           0 :                 return ret;
      59             :         }
      60             : }
      61             : 
      62     1589353 : int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fi,
      63             :                 u64 start, u64 len, const struct iomap_ops *ops)
      64             : {
      65     1589353 :         struct iomap_iter iter = {
      66             :                 .inode          = inode,
      67             :                 .pos            = start,
      68             :                 .len            = len,
      69             :                 .flags          = IOMAP_REPORT,
      70             :         };
      71     1589353 :         struct iomap prev = {
      72             :                 .type           = IOMAP_HOLE,
      73             :         };
      74     1589353 :         int ret;
      75             : 
      76     1589353 :         ret = fiemap_prep(inode, fi, start, &iter.len, 0);
      77     1589332 :         if (ret)
      78             :                 return ret;
      79             : 
      80     9179225 :         while ((ret = iomap_iter(&iter, ops)) > 0)
      81     8216053 :                 iter.processed = iomap_fiemap_iter(&iter, fi, &prev);
      82             : 
      83      962462 :         if (prev.type != IOMAP_HOLE) {
      84      486774 :                 ret = iomap_to_fiemap(fi, &prev, FIEMAP_EXTENT_LAST);
      85      486777 :                 if (ret < 0)
      86             :                         return ret;
      87             :         }
      88             : 
      89             :         /* inode with no (attribute) mapping will give ENOENT */
      90      962465 :         if (ret < 0 && ret != -ENOENT)
      91           4 :                 return ret;
      92             :         return 0;
      93             : }
      94             : EXPORT_SYMBOL_GPL(iomap_fiemap);
      95             : 
      96             : /* legacy ->bmap interface.  0 is the error return (!) */
      97             : sector_t
      98       17867 : iomap_bmap(struct address_space *mapping, sector_t bno,
      99             :                 const struct iomap_ops *ops)
     100             : {
     101       53601 :         struct iomap_iter iter = {
     102       17867 :                 .inode  = mapping->host,
     103       17867 :                 .pos    = (loff_t)bno << mapping->host->i_blkbits,
     104       17867 :                 .len    = i_blocksize(mapping->host),
     105             :                 .flags  = IOMAP_REPORT,
     106             :         };
     107       17867 :         const unsigned int blkshift = mapping->host->i_blkbits - SECTOR_SHIFT;
     108       17867 :         int ret;
     109             : 
     110       17867 :         if (filemap_write_and_wait(mapping))
     111             :                 return 0;
     112             : 
     113             :         bno = 0;
     114       35734 :         while ((ret = iomap_iter(&iter, ops)) > 0) {
     115       17867 :                 if (iter.iomap.type == IOMAP_MAPPED)
     116       16459 :                         bno = iomap_sector(&iter.iomap, iter.pos) >> blkshift;
     117             :                 /* leave iter.processed unset to abort loop */
     118             :         }
     119       17867 :         if (ret)
     120           0 :                 return 0;
     121             : 
     122             :         return bno;
     123             : }
     124             : EXPORT_SYMBOL_GPL(iomap_bmap);

Generated by: LCOV version 1.14