xref: /OK3568_Linux_fs/kernel/fs/ntfs/mft.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * mft.h - Defines for mft record handling in NTFS Linux kernel driver.
4*4882a593Smuzhiyun  *	   Part of the Linux-NTFS project.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (c) 2001-2004 Anton Altaparmakov
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #ifndef _LINUX_NTFS_MFT_H
10*4882a593Smuzhiyun #define _LINUX_NTFS_MFT_H
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/fs.h>
13*4882a593Smuzhiyun #include <linux/highmem.h>
14*4882a593Smuzhiyun #include <linux/pagemap.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #include "inode.h"
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun extern MFT_RECORD *map_mft_record(ntfs_inode *ni);
19*4882a593Smuzhiyun extern void unmap_mft_record(ntfs_inode *ni);
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun extern MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
22*4882a593Smuzhiyun 		ntfs_inode **ntfs_ino);
23*4882a593Smuzhiyun 
unmap_extent_mft_record(ntfs_inode * ni)24*4882a593Smuzhiyun static inline void unmap_extent_mft_record(ntfs_inode *ni)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun 	unmap_mft_record(ni);
27*4882a593Smuzhiyun 	return;
28*4882a593Smuzhiyun }
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #ifdef NTFS_RW
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun /**
33*4882a593Smuzhiyun  * flush_dcache_mft_record_page - flush_dcache_page() for mft records
34*4882a593Smuzhiyun  * @ni:		ntfs inode structure of mft record
35*4882a593Smuzhiyun  *
36*4882a593Smuzhiyun  * Call flush_dcache_page() for the page in which an mft record resides.
37*4882a593Smuzhiyun  *
38*4882a593Smuzhiyun  * This must be called every time an mft record is modified, just after the
39*4882a593Smuzhiyun  * modification.
40*4882a593Smuzhiyun  */
flush_dcache_mft_record_page(ntfs_inode * ni)41*4882a593Smuzhiyun static inline void flush_dcache_mft_record_page(ntfs_inode *ni)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun 	flush_dcache_page(ni->page);
44*4882a593Smuzhiyun }
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun extern void __mark_mft_record_dirty(ntfs_inode *ni);
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun /**
49*4882a593Smuzhiyun  * mark_mft_record_dirty - set the mft record and the page containing it dirty
50*4882a593Smuzhiyun  * @ni:		ntfs inode describing the mapped mft record
51*4882a593Smuzhiyun  *
52*4882a593Smuzhiyun  * Set the mapped (extent) mft record of the (base or extent) ntfs inode @ni,
53*4882a593Smuzhiyun  * as well as the page containing the mft record, dirty.  Also, mark the base
54*4882a593Smuzhiyun  * vfs inode dirty.  This ensures that any changes to the mft record are
55*4882a593Smuzhiyun  * written out to disk.
56*4882a593Smuzhiyun  *
57*4882a593Smuzhiyun  * NOTE:  Do not do anything if the mft record is already marked dirty.
58*4882a593Smuzhiyun  */
mark_mft_record_dirty(ntfs_inode * ni)59*4882a593Smuzhiyun static inline void mark_mft_record_dirty(ntfs_inode *ni)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun 	if (!NInoTestSetDirty(ni))
62*4882a593Smuzhiyun 		__mark_mft_record_dirty(ni);
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun extern int ntfs_sync_mft_mirror(ntfs_volume *vol, const unsigned long mft_no,
66*4882a593Smuzhiyun 		MFT_RECORD *m, int sync);
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun extern int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync);
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun /**
71*4882a593Smuzhiyun  * write_mft_record - write out a mapped (extent) mft record
72*4882a593Smuzhiyun  * @ni:		ntfs inode describing the mapped (extent) mft record
73*4882a593Smuzhiyun  * @m:		mapped (extent) mft record to write
74*4882a593Smuzhiyun  * @sync:	if true, wait for i/o completion
75*4882a593Smuzhiyun  *
76*4882a593Smuzhiyun  * This is just a wrapper for write_mft_record_nolock() (see mft.c), which
77*4882a593Smuzhiyun  * locks the page for the duration of the write.  This ensures that there are
78*4882a593Smuzhiyun  * no race conditions between writing the mft record via the dirty inode code
79*4882a593Smuzhiyun  * paths and via the page cache write back code paths or between writing
80*4882a593Smuzhiyun  * neighbouring mft records residing in the same page.
81*4882a593Smuzhiyun  *
82*4882a593Smuzhiyun  * Locking the page also serializes us against ->readpage() if the page is not
83*4882a593Smuzhiyun  * uptodate.
84*4882a593Smuzhiyun  *
85*4882a593Smuzhiyun  * On success, clean the mft record and return 0.  On error, leave the mft
86*4882a593Smuzhiyun  * record dirty and return -errno.
87*4882a593Smuzhiyun  */
write_mft_record(ntfs_inode * ni,MFT_RECORD * m,int sync)88*4882a593Smuzhiyun static inline int write_mft_record(ntfs_inode *ni, MFT_RECORD *m, int sync)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun 	struct page *page = ni->page;
91*4882a593Smuzhiyun 	int err;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	BUG_ON(!page);
94*4882a593Smuzhiyun 	lock_page(page);
95*4882a593Smuzhiyun 	err = write_mft_record_nolock(ni, m, sync);
96*4882a593Smuzhiyun 	unlock_page(page);
97*4882a593Smuzhiyun 	return err;
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun extern bool ntfs_may_write_mft_record(ntfs_volume *vol,
101*4882a593Smuzhiyun 		const unsigned long mft_no, const MFT_RECORD *m,
102*4882a593Smuzhiyun 		ntfs_inode **locked_ni);
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun extern ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode,
105*4882a593Smuzhiyun 		ntfs_inode *base_ni, MFT_RECORD **mrec);
106*4882a593Smuzhiyun extern int ntfs_extent_mft_record_free(ntfs_inode *ni, MFT_RECORD *m);
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun #endif /* NTFS_RW */
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun #endif /* _LINUX_NTFS_MFT_H */
111