Linux Audio

Check our new training course

Loading...
v6.2
  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
 12static 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
 42static 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
 62int 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}
 94EXPORT_SYMBOL_GPL(iomap_fiemap);
 95
 96/* legacy ->bmap interface.  0 is the error return (!) */
 97sector_t
 98iomap_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}
124EXPORT_SYMBOL_GPL(iomap_bmap);
v6.13.7
  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
 12static 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
 42static 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
 62int 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}
 94EXPORT_SYMBOL_GPL(iomap_fiemap);
 95
 96/* legacy ->bmap interface.  0 is the error return (!) */
 97sector_t
 98iomap_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}
124EXPORT_SYMBOL_GPL(iomap_bmap);