@@ -26,6 +26,7 @@
#include <linux/user_namespace.h>
#include <linux/seq_file.h>
#include <linux/blkdev.h>
+#include <linux/iomap.h>
#include "isofs.h"
#include "zisofs.h"
@@ -1142,31 +1143,63 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock,
return rv != 0 ? rv : error;
}
-/*
- * Used by the standard interfaces.
- */
-static int isofs_get_block(struct inode *inode, sector_t iblock,
- struct buffer_head *bh_result, int create)
+static int isofs_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
+ unsigned flags, struct iomap *iomap, struct iomap *srcmap)
{
- int ret;
+ struct inode *ninode = inode;
+ int section = 0;
+ loff_t start = 0;
+ int err = -EIO;
+ struct iso_inode_info *ei;
- if (create) {
- printk(KERN_DEBUG "%s: Kernel tries to allocate a block\n", __func__);
- return -EROFS;
+ for (;;) {
+ unsigned long nextblk, nextoff;
+
+ ei = ISOFS_I(ninode);
+ if (pos < start + ei->i_section_size)
+ break;
+ start += ei->i_section_size;
+ if (++section > 100)
+ goto abort;
+ nextblk = ei->i_next_section_block;
+ if (!nextblk)
+ goto abort;
+ nextoff = ei->i_next_section_offset;
+ if (ninode != inode)
+ iput(ninode);
+ ninode = isofs_iget(inode->i_sb, nextblk, nextoff);
+ if (IS_ERR(ninode)) {
+ err = PTR_ERR(ninode);
+ goto abort;
+ }
}
- ret = isofs_get_blocks(inode, iblock, &bh_result, 1);
- return ret < 0 ? ret : 0;
+ iomap->addr = (u64)ei->i_first_extent << inode->i_blkbits;
+ iomap->offset = start;
+ iomap->length = ei->i_section_size;
+ iomap->type = IOMAP_MAPPED;
+ iomap->flags = 0;
+ iomap->bdev = inode->i_bdev;
+ err = 0;
+abort:
+ if (ninode != inode)
+ iput(ninode);
+ return err;
}
+const struct iomap_ops isofs_iomap_ops = {
+ .iomap_begin = isofs_iomap_begin,
+};
+
static int isofs_bmap(struct inode *inode, sector_t block)
{
struct buffer_head dummy;
+ struct buffer_head *bhp = &dummy;
int error;
dummy.b_state = 0;
dummy.b_blocknr = -1000;
- error = isofs_get_block(inode, block, &dummy, 0);
+ error = isofs_get_blocks(inode, block, &bhp, 1);
if (!error)
return dummy.b_blocknr;
return 0;
@@ -1182,17 +1215,17 @@ struct buffer_head *isofs_bread(struct inode *inode, sector_t block)
static int isofs_readpage(struct file *file, struct page *page)
{
- return mpage_readpage(page, isofs_get_block);
+ return iomap_readpage(page, &isofs_iomap_ops);
}
static void isofs_readahead(struct readahead_control *rac)
{
- mpage_readahead(rac, isofs_get_block);
+ iomap_readahead(rac, &isofs_iomap_ops);
}
static sector_t _isofs_bmap(struct address_space *mapping, sector_t block)
{
- return generic_block_bmap(mapping,block,isofs_get_block);
+ return iomap_bmap(mapping, block, &isofs_iomap_ops);
}
static const struct address_space_operations isofs_aops = {