LCOV - code coverage report
Current view: top level - fs/iomap - seek.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 44 46 95.7 %
Date: 2023-07-31 20:08:12 Functions: 4 4 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (C) 2017 Red Hat, Inc.
       4             :  * Copyright (c) 2018-2021 Christoph Hellwig.
       5             :  */
       6             : #include <linux/module.h>
       7             : #include <linux/compiler.h>
       8             : #include <linux/fs.h>
       9             : #include <linux/iomap.h>
      10             : #include <linux/pagemap.h>
      11             : #include <linux/pagevec.h>
      12             : 
      13        2178 : static loff_t iomap_seek_hole_iter(const struct iomap_iter *iter,
      14             :                 loff_t *hole_pos)
      15             : {
      16        2178 :         loff_t length = iomap_length(iter);
      17             : 
      18        2178 :         switch (iter->iomap.type) {
      19         774 :         case IOMAP_UNWRITTEN:
      20        1548 :                 *hole_pos = mapping_seek_hole_data(iter->inode->i_mapping,
      21         774 :                                 iter->pos, iter->pos + length, SEEK_HOLE);
      22         774 :                 if (*hole_pos == iter->pos + length)
      23         285 :                         return length;
      24             :                 return 0;
      25         755 :         case IOMAP_HOLE:
      26         755 :                 *hole_pos = iter->pos;
      27         755 :                 return 0;
      28             :         default:
      29             :                 return length;
      30             :         }
      31             : }
      32             : 
      33             : loff_t
      34        1601 : iomap_seek_hole(struct inode *inode, loff_t pos, const struct iomap_ops *ops)
      35             : {
      36        1601 :         loff_t size = i_size_read(inode);
      37        1601 :         struct iomap_iter iter = {
      38             :                 .inode  = inode,
      39             :                 .pos    = pos,
      40             :                 .flags  = IOMAP_REPORT,
      41             :         };
      42        1601 :         int ret;
      43             : 
      44             :         /* Nothing to be found before or beyond the end of the file. */
      45        1601 :         if (pos < 0 || pos >= size)
      46             :                 return -ENXIO;
      47             : 
      48        1433 :         iter.len = size - pos;
      49        3611 :         while ((ret = iomap_iter(&iter, ops)) > 0)
      50        2178 :                 iter.processed = iomap_seek_hole_iter(&iter, &pos);
      51        1433 :         if (ret < 0)
      52           0 :                 return ret;
      53        1433 :         if (iter.len) /* found hole before EOF */
      54        1244 :                 return pos;
      55             :         return size;
      56             : }
      57             : EXPORT_SYMBOL_GPL(iomap_seek_hole);
      58             : 
      59      435886 : static loff_t iomap_seek_data_iter(const struct iomap_iter *iter,
      60             :                 loff_t *hole_pos)
      61             : {
      62      435886 :         loff_t length = iomap_length(iter);
      63             : 
      64      435886 :         switch (iter->iomap.type) {
      65             :         case IOMAP_HOLE:
      66             :                 return length;
      67       47756 :         case IOMAP_UNWRITTEN:
      68       95512 :                 *hole_pos = mapping_seek_hole_data(iter->inode->i_mapping,
      69       47756 :                                 iter->pos, iter->pos + length, SEEK_DATA);
      70       47756 :                 if (*hole_pos < 0)
      71       30303 :                         return length;
      72             :                 return 0;
      73      175474 :         default:
      74      175474 :                 *hole_pos = iter->pos;
      75      175474 :                 return 0;
      76             :         }
      77             : }
      78             : 
      79             : loff_t
      80      243021 : iomap_seek_data(struct inode *inode, loff_t pos, const struct iomap_ops *ops)
      81             : {
      82      243021 :         loff_t size = i_size_read(inode);
      83      243021 :         struct iomap_iter iter = {
      84             :                 .inode  = inode,
      85             :                 .pos    = pos,
      86             :                 .flags  = IOMAP_REPORT,
      87             :         };
      88      243021 :         int ret;
      89             : 
      90             :         /* Nothing to be found before or beyond the end of the file. */
      91      243021 :         if (pos < 0 || pos >= size)
      92             :                 return -ENXIO;
      93             : 
      94      204128 :         iter.len = size - pos;
      95      640014 :         while ((ret = iomap_iter(&iter, ops)) > 0)
      96      435886 :                 iter.processed = iomap_seek_data_iter(&iter, &pos);
      97      204128 :         if (ret < 0)
      98           0 :                 return ret;
      99      204128 :         if (iter.len) /* found data before EOF */
     100      192927 :                 return pos;
     101             :         /* We've reached the end of the file without finding data */
     102             :         return -ENXIO;
     103             : }
     104             : EXPORT_SYMBOL_GPL(iomap_seek_data);

Generated by: LCOV version 1.14