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

Generated by: LCOV version 1.14