iomap: add an iomap-based bmap implementation
authorChristoph Hellwig <hch@lst.de>
Fri, 1 Jun 2018 16:03:08 +0000 (09:03 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Sat, 2 Jun 2018 01:37:33 +0000 (18:37 -0700)
This adds a simple iomap-based implementation of the legacy ->bmap
interface.  Note that we can't easily add checks for rt or reflink
files, so these will have to remain in the callers.  This interface
just needs to die..

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
fs/iomap.c
include/linux/iomap.h

index 74cdf8b..b0bc928 100644 (file)
@@ -1307,3 +1307,37 @@ int iomap_swapfile_activate(struct swap_info_struct *sis,
 }
 EXPORT_SYMBOL_GPL(iomap_swapfile_activate);
 #endif /* CONFIG_SWAP */
+
+static loff_t
+iomap_bmap_actor(struct inode *inode, loff_t pos, loff_t length,
+               void *data, struct iomap *iomap)
+{
+       sector_t *bno = data, addr;
+
+       if (iomap->type == IOMAP_MAPPED) {
+               addr = (pos - iomap->offset + iomap->addr) >> inode->i_blkbits;
+               if (addr > INT_MAX)
+                       WARN(1, "would truncate bmap result\n");
+               else
+                       *bno = addr;
+       }
+       return 0;
+}
+
+/* legacy ->bmap interface.  0 is the error return (!) */
+sector_t
+iomap_bmap(struct address_space *mapping, sector_t bno,
+               const struct iomap_ops *ops)
+{
+       struct inode *inode = mapping->host;
+       loff_t pos = bno >> inode->i_blkbits;
+       unsigned blocksize = i_blocksize(inode);
+
+       if (filemap_write_and_wait(mapping))
+               return 0;
+
+       bno = 0;
+       iomap_apply(inode, pos, blocksize, 0, ops, &bno, iomap_bmap_actor);
+       return bno;
+}
+EXPORT_SYMBOL_GPL(iomap_bmap);
index 819e0cd..a044a82 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/types.h>
 
+struct address_space;
 struct fiemap_extent_info;
 struct inode;
 struct iov_iter;
@@ -100,6 +101,8 @@ loff_t iomap_seek_hole(struct inode *inode, loff_t offset,
                const struct iomap_ops *ops);
 loff_t iomap_seek_data(struct inode *inode, loff_t offset,
                const struct iomap_ops *ops);
+sector_t iomap_bmap(struct address_space *mapping, sector_t bno,
+               const struct iomap_ops *ops);
 
 /*
  * Flags for direct I/O ->end_io: