LCOV - code coverage report
Current view: top level - fs/iomap - fiemap.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-acha @ Mon Jul 31 20:08:06 PDT 2023 Lines: 49 55 89.1 %
Date: 2023-07-31 20:08:07 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     1584062 : static int iomap_to_fiemap(struct fiemap_extent_info *fi,
      13             :                 const struct iomap *iomap, u32 flags)
      14             : {
      15     1584062 :         switch (iomap->type) {
      16             :         case IOMAP_HOLE:
      17             :                 /* skip holes */
      18             :                 return 0;
      19        7013 :         case IOMAP_DELALLOC:
      20        7013 :                 flags |= FIEMAP_EXTENT_DELALLOC | FIEMAP_EXTENT_UNKNOWN;
      21        7013 :                 break;
      22             :         case IOMAP_MAPPED:
      23             :                 break;
      24      282867 :         case IOMAP_UNWRITTEN:
      25      282867 :                 flags |= FIEMAP_EXTENT_UNWRITTEN;
      26      282867 :                 break;
      27           0 :         case IOMAP_INLINE:
      28           0 :                 flags |= FIEMAP_EXTENT_DATA_INLINE;
      29           0 :                 break;
      30             :         }
      31             : 
      32     1387543 :         if (iomap->flags & IOMAP_F_MERGED)
      33          47 :                 flags |= FIEMAP_EXTENT_MERGED;
      34     1387543 :         if (iomap->flags & IOMAP_F_SHARED)
      35      116202 :                 flags |= FIEMAP_EXTENT_SHARED;
      36             : 
      37     2775086 :         return fiemap_fill_next_extent(fi, iomap->offset,
      38     1387543 :                         iomap->addr != IOMAP_NULL_ADDR ? iomap->addr : 0,
      39     1387543 :                         iomap->length, flags);
      40             : }
      41             : 
      42     2706976 : static loff_t iomap_fiemap_iter(const struct iomap_iter *iter,
      43             :                 struct fiemap_extent_info *fi, struct iomap *prev)
      44             : {
      45     2706976 :         int ret;
      46             : 
      47     2706976 :         if (iter->iomap.type == IOMAP_HOLE)
      48     1319436 :                 return iomap_length(iter);
      49             : 
      50     1387540 :         ret = iomap_to_fiemap(fi, prev, 0);
      51     1387532 :         *prev = iter->iomap;
      52     1387532 :         switch (ret) {
      53     1383729 :         case 0:         /* success */
      54     1383729 :                 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     1072755 : int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fi,
      63             :                 u64 start, u64 len, const struct iomap_ops *ops)
      64             : {
      65     1072755 :         struct iomap_iter iter = {
      66             :                 .inode          = inode,
      67             :                 .pos            = start,
      68             :                 .len            = len,
      69             :                 .flags          = IOMAP_REPORT,
      70             :         };
      71     1072755 :         struct iomap prev = {
      72             :                 .type           = IOMAP_HOLE,
      73             :         };
      74     1072755 :         int ret;
      75             : 
      76     1072755 :         ret = fiemap_prep(inode, fi, start, &iter.len, 0);
      77     1072749 :         if (ret)
      78             :                 return ret;
      79             : 
      80     3267357 :         while ((ret = iomap_iter(&iter, ops)) > 0)
      81     2706763 :                 iter.processed = iomap_fiemap_iter(&iter, fi, &prev);
      82             : 
      83      560799 :         if (prev.type != IOMAP_HOLE) {
      84      196519 :                 ret = iomap_to_fiemap(fi, &prev, FIEMAP_EXTENT_LAST);
      85      196519 :                 if (ret < 0)
      86             :                         return ret;
      87             :         }
      88             : 
      89             :         /* inode with no (attribute) mapping will give ENOENT */
      90      560799 :         if (ret < 0 && ret != -ENOENT)
      91           5 :                 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        3844 : iomap_bmap(struct address_space *mapping, sector_t bno,
      99             :                 const struct iomap_ops *ops)
     100             : {
     101        3844 :         struct iomap_iter iter = {
     102        3844 :                 .inode  = mapping->host,
     103        3844 :                 .pos    = (loff_t)bno << mapping->host->i_blkbits,
     104        3844 :                 .len    = i_blocksize(mapping->host),
     105             :                 .flags  = IOMAP_REPORT,
     106             :         };
     107        3844 :         const unsigned int blkshift = mapping->host->i_blkbits - SECTOR_SHIFT;
     108        3844 :         int ret;
     109             : 
     110        3844 :         if (filemap_write_and_wait(mapping))
     111             :                 return 0;
     112             : 
     113             :         bno = 0;
     114        7688 :         while ((ret = iomap_iter(&iter, ops)) > 0) {
     115        3844 :                 if (iter.iomap.type == IOMAP_MAPPED)
     116        3748 :                         bno = iomap_sector(&iter.iomap, iter.pos) >> blkshift;
     117             :                 /* leave iter.processed unset to abort loop */
     118             :         }
     119        3844 :         if (ret)
     120           0 :                 return 0;
     121             : 
     122             :         return bno;
     123             : }
     124             : EXPORT_SYMBOL_GPL(iomap_bmap);

Generated by: LCOV version 1.14