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