File Index
Files and directories
Sign in
FILE

seek.c

File preview with syntax highlighting.

linux-6.19.14/fs/iomap/seek.c C
  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/iomap.h>
  7#include <linux/pagemap.h>
  8
  9static int iomap_seek_hole_iter(struct iomap_iter *iter,
 10		loff_t *hole_pos)
 11{
 12	loff_t length = iomap_length(iter);
 13
 14	switch (iter->iomap.type) {
 15	case IOMAP_UNWRITTEN:
 16		*hole_pos = mapping_seek_hole_data(iter->inode->i_mapping,
 17				iter->pos, iter->pos + length, SEEK_HOLE);
 18		if (*hole_pos == iter->pos + length)
 19			return iomap_iter_advance(iter, length);
 20		return 0;
 21	case IOMAP_HOLE:
 22		*hole_pos = iter->pos;
 23		return 0;
 24	default:
 25		return iomap_iter_advance(iter, length);
 26	}
 27}
 28
 29loff_t
 30iomap_seek_hole(struct inode *inode, loff_t pos, const struct iomap_ops *ops)
 31{
 32	loff_t size = i_size_read(inode);
 33	struct iomap_iter iter = {
 34		.inode	= inode,
 35		.pos	= pos,
 36		.flags	= IOMAP_REPORT,
 37	};
 38	int ret;
 39
 40	/* Nothing to be found before or beyond the end of the file. */
 41	if (pos < 0 || pos >= size)
 42		return -ENXIO;
 43
 44	iter.len = size - pos;
 45	while ((ret = iomap_iter(&iter, ops)) > 0)
 46		iter.status = iomap_seek_hole_iter(&iter, &pos);
 47	if (ret < 0)
 48		return ret;
 49	if (iter.len) /* found hole before EOF */
 50		return pos;
 51	return size;
 52}
 53EXPORT_SYMBOL_GPL(iomap_seek_hole);
 54
 55static int iomap_seek_data_iter(struct iomap_iter *iter,
 56		loff_t *hole_pos)
 57{
 58	loff_t length = iomap_length(iter);
 59
 60	switch (iter->iomap.type) {
 61	case IOMAP_HOLE:
 62		return iomap_iter_advance(iter, length);
 63	case IOMAP_UNWRITTEN:
 64		*hole_pos = mapping_seek_hole_data(iter->inode->i_mapping,
 65				iter->pos, iter->pos + length, SEEK_DATA);
 66		if (*hole_pos < 0)
 67			return iomap_iter_advance(iter, length);
 68		return 0;
 69	default:
 70		*hole_pos = iter->pos;
 71		return 0;
 72	}
 73}
 74
 75loff_t
 76iomap_seek_data(struct inode *inode, loff_t pos, const struct iomap_ops *ops)
 77{
 78	loff_t size = i_size_read(inode);
 79	struct iomap_iter iter = {
 80		.inode	= inode,
 81		.pos	= pos,
 82		.flags	= IOMAP_REPORT,
 83	};
 84	int ret;
 85
 86	/* Nothing to be found before or beyond the end of the file. */
 87	if (pos < 0 || pos >= size)
 88		return -ENXIO;
 89
 90	iter.len = size - pos;
 91	while ((ret = iomap_iter(&iter, ops)) > 0)
 92		iter.status = iomap_seek_data_iter(&iter, &pos);
 93	if (ret < 0)
 94		return ret;
 95	if (iter.len) /* found data before EOF */
 96		return pos;
 97	/* We've reached the end of the file without finding data */
 98	return -ENXIO;
 99}
100EXPORT_SYMBOL_GPL(iomap_seek_data);
~/ Read-only file preview.