~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/iomap/fiemap.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 static int iomap_to_fiemap(struct fiemap_extent_info *fi,
 13                 const struct iomap *iomap, u32 flags)
 14 {
 15         switch (iomap->type) {
 16         case IOMAP_HOLE:
 17                 /* skip holes */
 18                 return 0;
 19         case IOMAP_DELALLOC:
 20                 flags |= FIEMAP_EXTENT_DELALLOC | FIEMAP_EXTENT_UNKNOWN;
 21                 break;
 22         case IOMAP_MAPPED:
 23                 break;
 24         case IOMAP_UNWRITTEN:
 25                 flags |= FIEMAP_EXTENT_UNWRITTEN;
 26                 break;
 27         case IOMAP_INLINE:
 28                 flags |= FIEMAP_EXTENT_DATA_INLINE;
 29                 break;
 30         }
 31 
 32         if (iomap->flags & IOMAP_F_MERGED)
 33                 flags |= FIEMAP_EXTENT_MERGED;
 34         if (iomap->flags & IOMAP_F_SHARED)
 35                 flags |= FIEMAP_EXTENT_SHARED;
 36 
 37         return fiemap_fill_next_extent(fi, iomap->offset,
 38                         iomap->addr != IOMAP_NULL_ADDR ? iomap->addr : 0,
 39                         iomap->length, flags);
 40 }
 41 
 42 static loff_t iomap_fiemap_iter(const struct iomap_iter *iter,
 43                 struct fiemap_extent_info *fi, struct iomap *prev)
 44 {
 45         int ret;
 46 
 47         if (iter->iomap.type == IOMAP_HOLE)
 48                 return iomap_length(iter);
 49 
 50         ret = iomap_to_fiemap(fi, prev, 0);
 51         *prev = iter->iomap;
 52         switch (ret) {
 53         case 0:         /* success */
 54                 return iomap_length(iter);
 55         case 1:         /* extent array full */
 56                 return 0;
 57         default:        /* error */
 58                 return ret;
 59         }
 60 }
 61 
 62 int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fi,
 63                 u64 start, u64 len, const struct iomap_ops *ops)
 64 {
 65         struct iomap_iter iter = {
 66                 .inode          = inode,
 67                 .pos            = start,
 68                 .len            = len,
 69                 .flags          = IOMAP_REPORT,
 70         };
 71         struct iomap prev = {
 72                 .type           = IOMAP_HOLE,
 73         };
 74         int ret;
 75 
 76         ret = fiemap_prep(inode, fi, start, &iter.len, 0);
 77         if (ret)
 78                 return ret;
 79 
 80         while ((ret = iomap_iter(&iter, ops)) > 0)
 81                 iter.processed = iomap_fiemap_iter(&iter, fi, &prev);
 82 
 83         if (prev.type != IOMAP_HOLE) {
 84                 ret = iomap_to_fiemap(fi, &prev, FIEMAP_EXTENT_LAST);
 85                 if (ret < 0)
 86                         return ret;
 87         }
 88 
 89         /* inode with no (attribute) mapping will give ENOENT */
 90         if (ret < 0 && ret != -ENOENT)
 91                 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 iomap_bmap(struct address_space *mapping, sector_t bno,
 99                 const struct iomap_ops *ops)
100 {
101         struct iomap_iter iter = {
102                 .inode  = mapping->host,
103                 .pos    = (loff_t)bno << mapping->host->i_blkbits,
104                 .len    = i_blocksize(mapping->host),
105                 .flags  = IOMAP_REPORT,
106         };
107         const unsigned int blkshift = mapping->host->i_blkbits - SECTOR_SHIFT;
108         int ret;
109 
110         if (filemap_write_and_wait(mapping))
111                 return 0;
112 
113         bno = 0;
114         while ((ret = iomap_iter(&iter, ops)) > 0) {
115                 if (iter.iomap.type == IOMAP_MAPPED)
116                         bno = iomap_sector(&iter.iomap, iter.pos) >> blkshift;
117                 /* leave iter.processed unset to abort loop */
118         }
119         if (ret)
120                 return 0;
121 
122         return bno;
123 }
124 EXPORT_SYMBOL_GPL(iomap_bmap);
125 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php