162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * aops.h - Defines for NTFS kernel address space operations and page cache
462306a36Sopenharmony_ci *	    handling.  Part of the Linux-NTFS project.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (c) 2001-2004 Anton Altaparmakov
762306a36Sopenharmony_ci * Copyright (c) 2002 Richard Russon
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#ifndef _LINUX_NTFS_AOPS_H
1162306a36Sopenharmony_ci#define _LINUX_NTFS_AOPS_H
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/mm.h>
1462306a36Sopenharmony_ci#include <linux/highmem.h>
1562306a36Sopenharmony_ci#include <linux/pagemap.h>
1662306a36Sopenharmony_ci#include <linux/fs.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#include "inode.h"
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci/**
2162306a36Sopenharmony_ci * ntfs_unmap_page - release a page that was mapped using ntfs_map_page()
2262306a36Sopenharmony_ci * @page:	the page to release
2362306a36Sopenharmony_ci *
2462306a36Sopenharmony_ci * Unpin, unmap and release a page that was obtained from ntfs_map_page().
2562306a36Sopenharmony_ci */
2662306a36Sopenharmony_cistatic inline void ntfs_unmap_page(struct page *page)
2762306a36Sopenharmony_ci{
2862306a36Sopenharmony_ci	kunmap(page);
2962306a36Sopenharmony_ci	put_page(page);
3062306a36Sopenharmony_ci}
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/**
3362306a36Sopenharmony_ci * ntfs_map_page - map a page into accessible memory, reading it if necessary
3462306a36Sopenharmony_ci * @mapping:	address space for which to obtain the page
3562306a36Sopenharmony_ci * @index:	index into the page cache for @mapping of the page to map
3662306a36Sopenharmony_ci *
3762306a36Sopenharmony_ci * Read a page from the page cache of the address space @mapping at position
3862306a36Sopenharmony_ci * @index, where @index is in units of PAGE_SIZE, and not in bytes.
3962306a36Sopenharmony_ci *
4062306a36Sopenharmony_ci * If the page is not in memory it is loaded from disk first using the
4162306a36Sopenharmony_ci * read_folio method defined in the address space operations of @mapping
4262306a36Sopenharmony_ci * and the page is added to the page cache of @mapping in the process.
4362306a36Sopenharmony_ci *
4462306a36Sopenharmony_ci * If the page belongs to an mst protected attribute and it is marked as such
4562306a36Sopenharmony_ci * in its ntfs inode (NInoMstProtected()) the mst fixups are applied but no
4662306a36Sopenharmony_ci * error checking is performed.  This means the caller has to verify whether
4762306a36Sopenharmony_ci * the ntfs record(s) contained in the page are valid or not using one of the
4862306a36Sopenharmony_ci * ntfs_is_XXXX_record{,p}() macros, where XXXX is the record type you are
4962306a36Sopenharmony_ci * expecting to see.  (For details of the macros, see fs/ntfs/layout.h.)
5062306a36Sopenharmony_ci *
5162306a36Sopenharmony_ci * If the page is in high memory it is mapped into memory directly addressible
5262306a36Sopenharmony_ci * by the kernel.
5362306a36Sopenharmony_ci *
5462306a36Sopenharmony_ci * Finally the page count is incremented, thus pinning the page into place.
5562306a36Sopenharmony_ci *
5662306a36Sopenharmony_ci * The above means that page_address(page) can be used on all pages obtained
5762306a36Sopenharmony_ci * with ntfs_map_page() to get the kernel virtual address of the page.
5862306a36Sopenharmony_ci *
5962306a36Sopenharmony_ci * When finished with the page, the caller has to call ntfs_unmap_page() to
6062306a36Sopenharmony_ci * unpin, unmap and release the page.
6162306a36Sopenharmony_ci *
6262306a36Sopenharmony_ci * Note this does not grant exclusive access. If such is desired, the caller
6362306a36Sopenharmony_ci * must provide it independently of the ntfs_{un}map_page() calls by using
6462306a36Sopenharmony_ci * a {rw_}semaphore or other means of serialization. A spin lock cannot be
6562306a36Sopenharmony_ci * used as ntfs_map_page() can block.
6662306a36Sopenharmony_ci *
6762306a36Sopenharmony_ci * The unlocked and uptodate page is returned on success or an encoded error
6862306a36Sopenharmony_ci * on failure. Caller has to test for error using the IS_ERR() macro on the
6962306a36Sopenharmony_ci * return value. If that evaluates to 'true', the negative error code can be
7062306a36Sopenharmony_ci * obtained using PTR_ERR() on the return value of ntfs_map_page().
7162306a36Sopenharmony_ci */
7262306a36Sopenharmony_cistatic inline struct page *ntfs_map_page(struct address_space *mapping,
7362306a36Sopenharmony_ci		unsigned long index)
7462306a36Sopenharmony_ci{
7562306a36Sopenharmony_ci	struct page *page = read_mapping_page(mapping, index, NULL);
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci	if (!IS_ERR(page))
7862306a36Sopenharmony_ci		kmap(page);
7962306a36Sopenharmony_ci	return page;
8062306a36Sopenharmony_ci}
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci#ifdef NTFS_RW
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ciextern void mark_ntfs_record_dirty(struct page *page, const unsigned int ofs);
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci#endif /* NTFS_RW */
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci#endif /* _LINUX_NTFS_AOPS_H */
89