162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * mft.h - Defines for mft record handling in NTFS Linux kernel driver. 462306a36Sopenharmony_ci * Part of the Linux-NTFS project. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (c) 2001-2004 Anton Altaparmakov 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#ifndef _LINUX_NTFS_MFT_H 1062306a36Sopenharmony_ci#define _LINUX_NTFS_MFT_H 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/fs.h> 1362306a36Sopenharmony_ci#include <linux/highmem.h> 1462306a36Sopenharmony_ci#include <linux/pagemap.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include "inode.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ciextern MFT_RECORD *map_mft_record(ntfs_inode *ni); 1962306a36Sopenharmony_ciextern void unmap_mft_record(ntfs_inode *ni); 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ciextern MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref, 2262306a36Sopenharmony_ci ntfs_inode **ntfs_ino); 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistatic inline void unmap_extent_mft_record(ntfs_inode *ni) 2562306a36Sopenharmony_ci{ 2662306a36Sopenharmony_ci unmap_mft_record(ni); 2762306a36Sopenharmony_ci return; 2862306a36Sopenharmony_ci} 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#ifdef NTFS_RW 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/** 3362306a36Sopenharmony_ci * flush_dcache_mft_record_page - flush_dcache_page() for mft records 3462306a36Sopenharmony_ci * @ni: ntfs inode structure of mft record 3562306a36Sopenharmony_ci * 3662306a36Sopenharmony_ci * Call flush_dcache_page() for the page in which an mft record resides. 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * This must be called every time an mft record is modified, just after the 3962306a36Sopenharmony_ci * modification. 4062306a36Sopenharmony_ci */ 4162306a36Sopenharmony_cistatic inline void flush_dcache_mft_record_page(ntfs_inode *ni) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci flush_dcache_page(ni->page); 4462306a36Sopenharmony_ci} 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ciextern void __mark_mft_record_dirty(ntfs_inode *ni); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci/** 4962306a36Sopenharmony_ci * mark_mft_record_dirty - set the mft record and the page containing it dirty 5062306a36Sopenharmony_ci * @ni: ntfs inode describing the mapped mft record 5162306a36Sopenharmony_ci * 5262306a36Sopenharmony_ci * Set the mapped (extent) mft record of the (base or extent) ntfs inode @ni, 5362306a36Sopenharmony_ci * as well as the page containing the mft record, dirty. Also, mark the base 5462306a36Sopenharmony_ci * vfs inode dirty. This ensures that any changes to the mft record are 5562306a36Sopenharmony_ci * written out to disk. 5662306a36Sopenharmony_ci * 5762306a36Sopenharmony_ci * NOTE: Do not do anything if the mft record is already marked dirty. 5862306a36Sopenharmony_ci */ 5962306a36Sopenharmony_cistatic inline void mark_mft_record_dirty(ntfs_inode *ni) 6062306a36Sopenharmony_ci{ 6162306a36Sopenharmony_ci if (!NInoTestSetDirty(ni)) 6262306a36Sopenharmony_ci __mark_mft_record_dirty(ni); 6362306a36Sopenharmony_ci} 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ciextern int ntfs_sync_mft_mirror(ntfs_volume *vol, const unsigned long mft_no, 6662306a36Sopenharmony_ci MFT_RECORD *m, int sync); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ciextern int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync); 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci/** 7162306a36Sopenharmony_ci * write_mft_record - write out a mapped (extent) mft record 7262306a36Sopenharmony_ci * @ni: ntfs inode describing the mapped (extent) mft record 7362306a36Sopenharmony_ci * @m: mapped (extent) mft record to write 7462306a36Sopenharmony_ci * @sync: if true, wait for i/o completion 7562306a36Sopenharmony_ci * 7662306a36Sopenharmony_ci * This is just a wrapper for write_mft_record_nolock() (see mft.c), which 7762306a36Sopenharmony_ci * locks the page for the duration of the write. This ensures that there are 7862306a36Sopenharmony_ci * no race conditions between writing the mft record via the dirty inode code 7962306a36Sopenharmony_ci * paths and via the page cache write back code paths or between writing 8062306a36Sopenharmony_ci * neighbouring mft records residing in the same page. 8162306a36Sopenharmony_ci * 8262306a36Sopenharmony_ci * Locking the page also serializes us against ->read_folio() if the page is not 8362306a36Sopenharmony_ci * uptodate. 8462306a36Sopenharmony_ci * 8562306a36Sopenharmony_ci * On success, clean the mft record and return 0. On error, leave the mft 8662306a36Sopenharmony_ci * record dirty and return -errno. 8762306a36Sopenharmony_ci */ 8862306a36Sopenharmony_cistatic inline int write_mft_record(ntfs_inode *ni, MFT_RECORD *m, int sync) 8962306a36Sopenharmony_ci{ 9062306a36Sopenharmony_ci struct page *page = ni->page; 9162306a36Sopenharmony_ci int err; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci BUG_ON(!page); 9462306a36Sopenharmony_ci lock_page(page); 9562306a36Sopenharmony_ci err = write_mft_record_nolock(ni, m, sync); 9662306a36Sopenharmony_ci unlock_page(page); 9762306a36Sopenharmony_ci return err; 9862306a36Sopenharmony_ci} 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ciextern bool ntfs_may_write_mft_record(ntfs_volume *vol, 10162306a36Sopenharmony_ci const unsigned long mft_no, const MFT_RECORD *m, 10262306a36Sopenharmony_ci ntfs_inode **locked_ni); 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ciextern ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode, 10562306a36Sopenharmony_ci ntfs_inode *base_ni, MFT_RECORD **mrec); 10662306a36Sopenharmony_ciextern int ntfs_extent_mft_record_free(ntfs_inode *ni, MFT_RECORD *m); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci#endif /* NTFS_RW */ 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci#endif /* _LINUX_NTFS_MFT_H */ 111