cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

seek.c (2400B)


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