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

iter.c (2407B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) 2010 Red Hat, Inc.
      4 * Copyright (c) 2016-2021 Christoph Hellwig.
      5 */
      6#include <linux/fs.h>
      7#include <linux/iomap.h>
      8#include "trace.h"
      9
     10static inline int iomap_iter_advance(struct iomap_iter *iter)
     11{
     12	/* handle the previous iteration (if any) */
     13	if (iter->iomap.length) {
     14		if (iter->processed <= 0)
     15			return iter->processed;
     16		if (WARN_ON_ONCE(iter->processed > iomap_length(iter)))
     17			return -EIO;
     18		iter->pos += iter->processed;
     19		iter->len -= iter->processed;
     20		if (!iter->len)
     21			return 0;
     22	}
     23
     24	/* clear the state for the next iteration */
     25	iter->processed = 0;
     26	memset(&iter->iomap, 0, sizeof(iter->iomap));
     27	memset(&iter->srcmap, 0, sizeof(iter->srcmap));
     28	return 1;
     29}
     30
     31static inline void iomap_iter_done(struct iomap_iter *iter)
     32{
     33	WARN_ON_ONCE(iter->iomap.offset > iter->pos);
     34	WARN_ON_ONCE(iter->iomap.length == 0);
     35	WARN_ON_ONCE(iter->iomap.offset + iter->iomap.length <= iter->pos);
     36
     37	trace_iomap_iter_dstmap(iter->inode, &iter->iomap);
     38	if (iter->srcmap.type != IOMAP_HOLE)
     39		trace_iomap_iter_srcmap(iter->inode, &iter->srcmap);
     40}
     41
     42/**
     43 * iomap_iter - iterate over a ranges in a file
     44 * @iter: iteration structue
     45 * @ops: iomap ops provided by the file system
     46 *
     47 * Iterate over filesystem-provided space mappings for the provided file range.
     48 *
     49 * This function handles cleanup of resources acquired for iteration when the
     50 * filesystem indicates there are no more space mappings, which means that this
     51 * function must be called in a loop that continues as long it returns a
     52 * positive value.  If 0 or a negative value is returned, the caller must not
     53 * return to the loop body.  Within a loop body, there are two ways to break out
     54 * of the loop body:  leave @iter.processed unchanged, or set it to a negative
     55 * errno.
     56 */
     57int iomap_iter(struct iomap_iter *iter, const struct iomap_ops *ops)
     58{
     59	int ret;
     60
     61	if (iter->iomap.length && ops->iomap_end) {
     62		ret = ops->iomap_end(iter->inode, iter->pos, iomap_length(iter),
     63				iter->processed > 0 ? iter->processed : 0,
     64				iter->flags, &iter->iomap);
     65		if (ret < 0 && !iter->processed)
     66			return ret;
     67	}
     68
     69	trace_iomap_iter(iter, ops, _RET_IP_);
     70	ret = iomap_iter_advance(iter);
     71	if (ret <= 0)
     72		return ret;
     73
     74	ret = ops->iomap_begin(iter->inode, iter->pos, iter->len, iter->flags,
     75			       &iter->iomap, &iter->srcmap);
     76	if (ret < 0)
     77		return ret;
     78	iomap_iter_done(iter);
     79	return 1;
     80}