xref: /openbmc/linux/fs/ntfs/mft.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1a1d312deSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * mft.h - Defines for mft record handling in NTFS Linux kernel driver.
41da177e4SLinus Torvalds  *	   Part of the Linux-NTFS project.
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  * Copyright (c) 2001-2004 Anton Altaparmakov
71da177e4SLinus Torvalds  */
81da177e4SLinus Torvalds 
91da177e4SLinus Torvalds #ifndef _LINUX_NTFS_MFT_H
101da177e4SLinus Torvalds #define _LINUX_NTFS_MFT_H
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds #include <linux/fs.h>
131da177e4SLinus Torvalds #include <linux/highmem.h>
141da177e4SLinus Torvalds #include <linux/pagemap.h>
151da177e4SLinus Torvalds 
161da177e4SLinus Torvalds #include "inode.h"
171da177e4SLinus Torvalds 
181da177e4SLinus Torvalds extern MFT_RECORD *map_mft_record(ntfs_inode *ni);
191da177e4SLinus Torvalds extern void unmap_mft_record(ntfs_inode *ni);
201da177e4SLinus Torvalds 
211da177e4SLinus Torvalds extern MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
221da177e4SLinus Torvalds 		ntfs_inode **ntfs_ino);
231da177e4SLinus Torvalds 
unmap_extent_mft_record(ntfs_inode * ni)241da177e4SLinus Torvalds static inline void unmap_extent_mft_record(ntfs_inode *ni)
251da177e4SLinus Torvalds {
261da177e4SLinus Torvalds 	unmap_mft_record(ni);
271da177e4SLinus Torvalds 	return;
281da177e4SLinus Torvalds }
291da177e4SLinus Torvalds 
301da177e4SLinus Torvalds #ifdef NTFS_RW
311da177e4SLinus Torvalds 
321da177e4SLinus Torvalds /**
331da177e4SLinus Torvalds  * flush_dcache_mft_record_page - flush_dcache_page() for mft records
341da177e4SLinus Torvalds  * @ni:		ntfs inode structure of mft record
351da177e4SLinus Torvalds  *
361da177e4SLinus Torvalds  * Call flush_dcache_page() for the page in which an mft record resides.
371da177e4SLinus Torvalds  *
381da177e4SLinus Torvalds  * This must be called every time an mft record is modified, just after the
391da177e4SLinus Torvalds  * modification.
401da177e4SLinus Torvalds  */
flush_dcache_mft_record_page(ntfs_inode * ni)411da177e4SLinus Torvalds static inline void flush_dcache_mft_record_page(ntfs_inode *ni)
421da177e4SLinus Torvalds {
431da177e4SLinus Torvalds 	flush_dcache_page(ni->page);
441da177e4SLinus Torvalds }
451da177e4SLinus Torvalds 
461da177e4SLinus Torvalds extern void __mark_mft_record_dirty(ntfs_inode *ni);
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds /**
491da177e4SLinus Torvalds  * mark_mft_record_dirty - set the mft record and the page containing it dirty
501da177e4SLinus Torvalds  * @ni:		ntfs inode describing the mapped mft record
511da177e4SLinus Torvalds  *
521da177e4SLinus Torvalds  * Set the mapped (extent) mft record of the (base or extent) ntfs inode @ni,
531da177e4SLinus Torvalds  * as well as the page containing the mft record, dirty.  Also, mark the base
541da177e4SLinus Torvalds  * vfs inode dirty.  This ensures that any changes to the mft record are
551da177e4SLinus Torvalds  * written out to disk.
561da177e4SLinus Torvalds  *
571da177e4SLinus Torvalds  * NOTE:  Do not do anything if the mft record is already marked dirty.
581da177e4SLinus Torvalds  */
mark_mft_record_dirty(ntfs_inode * ni)591da177e4SLinus Torvalds static inline void mark_mft_record_dirty(ntfs_inode *ni)
601da177e4SLinus Torvalds {
611da177e4SLinus Torvalds 	if (!NInoTestSetDirty(ni))
621da177e4SLinus Torvalds 		__mark_mft_record_dirty(ni);
631da177e4SLinus Torvalds }
641da177e4SLinus Torvalds 
651da177e4SLinus Torvalds extern int ntfs_sync_mft_mirror(ntfs_volume *vol, const unsigned long mft_no,
661da177e4SLinus Torvalds 		MFT_RECORD *m, int sync);
671da177e4SLinus Torvalds 
681da177e4SLinus Torvalds extern int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync);
691da177e4SLinus Torvalds 
701da177e4SLinus Torvalds /**
711da177e4SLinus Torvalds  * write_mft_record - write out a mapped (extent) mft record
721da177e4SLinus Torvalds  * @ni:		ntfs inode describing the mapped (extent) mft record
731da177e4SLinus Torvalds  * @m:		mapped (extent) mft record to write
741da177e4SLinus Torvalds  * @sync:	if true, wait for i/o completion
751da177e4SLinus Torvalds  *
761da177e4SLinus Torvalds  * This is just a wrapper for write_mft_record_nolock() (see mft.c), which
771da177e4SLinus Torvalds  * locks the page for the duration of the write.  This ensures that there are
781da177e4SLinus Torvalds  * no race conditions between writing the mft record via the dirty inode code
791da177e4SLinus Torvalds  * paths and via the page cache write back code paths or between writing
801da177e4SLinus Torvalds  * neighbouring mft records residing in the same page.
811da177e4SLinus Torvalds  *
82*933906f8SMatthew Wilcox (Oracle)  * Locking the page also serializes us against ->read_folio() if the page is not
831da177e4SLinus Torvalds  * uptodate.
841da177e4SLinus Torvalds  *
851da177e4SLinus Torvalds  * On success, clean the mft record and return 0.  On error, leave the mft
86f95c4018SAnton Altaparmakov  * record dirty and return -errno.
871da177e4SLinus Torvalds  */
write_mft_record(ntfs_inode * ni,MFT_RECORD * m,int sync)881da177e4SLinus Torvalds static inline int write_mft_record(ntfs_inode *ni, MFT_RECORD *m, int sync)
891da177e4SLinus Torvalds {
901da177e4SLinus Torvalds 	struct page *page = ni->page;
911da177e4SLinus Torvalds 	int err;
921da177e4SLinus Torvalds 
931da177e4SLinus Torvalds 	BUG_ON(!page);
941da177e4SLinus Torvalds 	lock_page(page);
951da177e4SLinus Torvalds 	err = write_mft_record_nolock(ni, m, sync);
961da177e4SLinus Torvalds 	unlock_page(page);
971da177e4SLinus Torvalds 	return err;
981da177e4SLinus Torvalds }
991da177e4SLinus Torvalds 
100c49c3111SRichard Knutsson extern bool ntfs_may_write_mft_record(ntfs_volume *vol,
1011da177e4SLinus Torvalds 		const unsigned long mft_no, const MFT_RECORD *m,
1021da177e4SLinus Torvalds 		ntfs_inode **locked_ni);
1031da177e4SLinus Torvalds 
1041da177e4SLinus Torvalds extern ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode,
1051da177e4SLinus Torvalds 		ntfs_inode *base_ni, MFT_RECORD **mrec);
1061da177e4SLinus Torvalds extern int ntfs_extent_mft_record_free(ntfs_inode *ni, MFT_RECORD *m);
1071da177e4SLinus Torvalds 
1081da177e4SLinus Torvalds #endif /* NTFS_RW */
1091da177e4SLinus Torvalds 
1101da177e4SLinus Torvalds #endif /* _LINUX_NTFS_MFT_H */
111