LCOV - code coverage report
Current view: top level - fs/iomap - seek.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsa @ Mon Jul 31 20:08:27 PDT 2023 Lines: 44 46 95.7 %
Date: 2023-07-31 20:08:27 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         456 : static loff_t iomap_seek_hole_iter(const struct iomap_iter *iter,
      14             :                 loff_t *hole_pos)
      15             : {
      16         456 :         loff_t length = iomap_length(iter);
      17             : 
      18         456 :         switch (iter->iomap.type) {
      19         108 :         case IOMAP_UNWRITTEN:
      20         216 :                 *hole_pos = mapping_seek_hole_data(iter->inode->i_mapping,
      21         108 :                                 iter->pos, iter->pos + length, SEEK_HOLE);
      22         108 :                 if (*hole_pos == iter->pos + length)
      23           4 :                         return length;
      24             :                 return 0;
      25         158 :         case IOMAP_HOLE:
      26         158 :                 *hole_pos = iter->pos;
      27         158 :                 return 0;
      28             :         default:
      29             :                 return length;
      30             :         }
      31             : }
      32             : 
      33             : loff_t
      34         326 : iomap_seek_hole(struct inode *inode, loff_t pos, const struct iomap_ops *ops)
      35             : {
      36         326 :         loff_t size = i_size_read(inode);
      37         326 :         struct iomap_iter iter = {
      38             :                 .inode  = inode,
      39             :                 .pos    = pos,
      40             :                 .flags  = IOMAP_REPORT,
      41             :         };
      42         326 :         int ret;
      43             : 
      44             :         /* Nothing to be found before or beyond the end of the file. */
      45         326 :         if (pos < 0 || pos >= size)
      46             :                 return -ENXIO;
      47             : 
      48         298 :         iter.len = size - pos;
      49         754 :         while ((ret = iomap_iter(&iter, ops)) > 0)
      50         456 :                 iter.processed = iomap_seek_hole_iter(&iter, &pos);
      51         298 :         if (ret < 0)
      52           0 :                 return ret;
      53         298 :         if (iter.len) /* found hole before EOF */
      54         262 :                 return pos;
      55             :         return size;
      56             : }
      57             : EXPORT_SYMBOL_GPL(iomap_seek_hole);
      58             : 
      59      439819 : static loff_t iomap_seek_data_iter(const struct iomap_iter *iter,
      60             :                 loff_t *hole_pos)
      61             : {
      62      439819 :         loff_t length = iomap_length(iter);
      63             : 
      64      439819 :         switch (iter->iomap.type) {
      65             :         case IOMAP_HOLE:
      66             :                 return length;
      67       56306 :         case IOMAP_UNWRITTEN:
      68      112612 :                 *hole_pos = mapping_seek_hole_data(iter->inode->i_mapping,
      69       56306 :                                 iter->pos, iter->pos + length, SEEK_DATA);
      70       56306 :                 if (*hole_pos < 0)
      71       49689 :                         return length;
      72             :                 return 0;
      73      171611 :         default:
      74      171611 :                 *hole_pos = iter->pos;
      75      171611 :                 return 0;
      76             :         }
      77             : }
      78             : 
      79             : loff_t
      80      232163 : iomap_seek_data(struct inode *inode, loff_t pos, const struct iomap_ops *ops)
      81             : {
      82      232163 :         loff_t size = i_size_read(inode);
      83      232163 :         struct iomap_iter iter = {
      84             :                 .inode  = inode,
      85             :                 .pos    = pos,
      86             :                 .flags  = IOMAP_REPORT,
      87             :         };
      88      232163 :         int ret;
      89             : 
      90             :         /* Nothing to be found before or beyond the end of the file. */
      91      232163 :         if (pos < 0 || pos >= size)
      92             :                 return -ENXIO;
      93             : 
      94      192103 :         iter.len = size - pos;
      95      631922 :         while ((ret = iomap_iter(&iter, ops)) > 0)
      96      439819 :                 iter.processed = iomap_seek_data_iter(&iter, &pos);
      97      192103 :         if (ret < 0)
      98           0 :                 return ret;
      99      192103 :         if (iter.len) /* found data before EOF */
     100      178228 :                 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