xref: /OK3568_Linux_fs/kernel/fs/ntfs/index.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * index.h - Defines for NTFS kernel index handling.  Part of the Linux-NTFS
4*4882a593Smuzhiyun  *	     project.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (c) 2004 Anton Altaparmakov
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #ifndef _LINUX_NTFS_INDEX_H
10*4882a593Smuzhiyun #define _LINUX_NTFS_INDEX_H
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/fs.h>
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include "types.h"
15*4882a593Smuzhiyun #include "layout.h"
16*4882a593Smuzhiyun #include "inode.h"
17*4882a593Smuzhiyun #include "attrib.h"
18*4882a593Smuzhiyun #include "mft.h"
19*4882a593Smuzhiyun #include "aops.h"
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun /**
22*4882a593Smuzhiyun  * @idx_ni:	index inode containing the @entry described by this context
23*4882a593Smuzhiyun  * @entry:	index entry (points into @ir or @ia)
24*4882a593Smuzhiyun  * @data:	index entry data (points into @entry)
25*4882a593Smuzhiyun  * @data_len:	length in bytes of @data
26*4882a593Smuzhiyun  * @is_in_root:	'true' if @entry is in @ir and 'false' if it is in @ia
27*4882a593Smuzhiyun  * @ir:		index root if @is_in_root and NULL otherwise
28*4882a593Smuzhiyun  * @actx:	attribute search context if @is_in_root and NULL otherwise
29*4882a593Smuzhiyun  * @base_ni:	base inode if @is_in_root and NULL otherwise
30*4882a593Smuzhiyun  * @ia:		index block if @is_in_root is 'false' and NULL otherwise
31*4882a593Smuzhiyun  * @page:	page if @is_in_root is 'false' and NULL otherwise
32*4882a593Smuzhiyun  *
33*4882a593Smuzhiyun  * @idx_ni is the index inode this context belongs to.
34*4882a593Smuzhiyun  *
35*4882a593Smuzhiyun  * @entry is the index entry described by this context.  @data and @data_len
36*4882a593Smuzhiyun  * are the index entry data and its length in bytes, respectively.  @data
37*4882a593Smuzhiyun  * simply points into @entry.  This is probably what the user is interested in.
38*4882a593Smuzhiyun  *
39*4882a593Smuzhiyun  * If @is_in_root is 'true', @entry is in the index root attribute @ir described
40*4882a593Smuzhiyun  * by the attribute search context @actx and the base inode @base_ni.  @ia and
41*4882a593Smuzhiyun  * @page are NULL in this case.
42*4882a593Smuzhiyun  *
43*4882a593Smuzhiyun  * If @is_in_root is 'false', @entry is in the index allocation attribute and @ia
44*4882a593Smuzhiyun  * and @page point to the index allocation block and the mapped, locked page it
45*4882a593Smuzhiyun  * is in, respectively.  @ir, @actx and @base_ni are NULL in this case.
46*4882a593Smuzhiyun  *
47*4882a593Smuzhiyun  * To obtain a context call ntfs_index_ctx_get().
48*4882a593Smuzhiyun  *
49*4882a593Smuzhiyun  * We use this context to allow ntfs_index_lookup() to return the found index
50*4882a593Smuzhiyun  * @entry and its @data without having to allocate a buffer and copy the @entry
51*4882a593Smuzhiyun  * and/or its @data into it.
52*4882a593Smuzhiyun  *
53*4882a593Smuzhiyun  * When finished with the @entry and its @data, call ntfs_index_ctx_put() to
54*4882a593Smuzhiyun  * free the context and other associated resources.
55*4882a593Smuzhiyun  *
56*4882a593Smuzhiyun  * If the index entry was modified, call flush_dcache_index_entry_page()
57*4882a593Smuzhiyun  * immediately after the modification and either ntfs_index_entry_mark_dirty()
58*4882a593Smuzhiyun  * or ntfs_index_entry_write() before the call to ntfs_index_ctx_put() to
59*4882a593Smuzhiyun  * ensure that the changes are written to disk.
60*4882a593Smuzhiyun  */
61*4882a593Smuzhiyun typedef struct {
62*4882a593Smuzhiyun 	ntfs_inode *idx_ni;
63*4882a593Smuzhiyun 	INDEX_ENTRY *entry;
64*4882a593Smuzhiyun 	void *data;
65*4882a593Smuzhiyun 	u16 data_len;
66*4882a593Smuzhiyun 	bool is_in_root;
67*4882a593Smuzhiyun 	INDEX_ROOT *ir;
68*4882a593Smuzhiyun 	ntfs_attr_search_ctx *actx;
69*4882a593Smuzhiyun 	ntfs_inode *base_ni;
70*4882a593Smuzhiyun 	INDEX_ALLOCATION *ia;
71*4882a593Smuzhiyun 	struct page *page;
72*4882a593Smuzhiyun } ntfs_index_context;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun extern ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *idx_ni);
75*4882a593Smuzhiyun extern void ntfs_index_ctx_put(ntfs_index_context *ictx);
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun extern int ntfs_index_lookup(const void *key, const int key_len,
78*4882a593Smuzhiyun 		ntfs_index_context *ictx);
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun #ifdef NTFS_RW
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun /**
83*4882a593Smuzhiyun  * ntfs_index_entry_flush_dcache_page - flush_dcache_page() for index entries
84*4882a593Smuzhiyun  * @ictx:	ntfs index context describing the index entry
85*4882a593Smuzhiyun  *
86*4882a593Smuzhiyun  * Call flush_dcache_page() for the page in which an index entry resides.
87*4882a593Smuzhiyun  *
88*4882a593Smuzhiyun  * This must be called every time an index entry is modified, just after the
89*4882a593Smuzhiyun  * modification.
90*4882a593Smuzhiyun  *
91*4882a593Smuzhiyun  * If the index entry is in the index root attribute, simply flush the page
92*4882a593Smuzhiyun  * containing the mft record containing the index root attribute.
93*4882a593Smuzhiyun  *
94*4882a593Smuzhiyun  * If the index entry is in an index block belonging to the index allocation
95*4882a593Smuzhiyun  * attribute, simply flush the page cache page containing the index block.
96*4882a593Smuzhiyun  */
ntfs_index_entry_flush_dcache_page(ntfs_index_context * ictx)97*4882a593Smuzhiyun static inline void ntfs_index_entry_flush_dcache_page(ntfs_index_context *ictx)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun 	if (ictx->is_in_root)
100*4882a593Smuzhiyun 		flush_dcache_mft_record_page(ictx->actx->ntfs_ino);
101*4882a593Smuzhiyun 	else
102*4882a593Smuzhiyun 		flush_dcache_page(ictx->page);
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun /**
106*4882a593Smuzhiyun  * ntfs_index_entry_mark_dirty - mark an index entry dirty
107*4882a593Smuzhiyun  * @ictx:	ntfs index context describing the index entry
108*4882a593Smuzhiyun  *
109*4882a593Smuzhiyun  * Mark the index entry described by the index entry context @ictx dirty.
110*4882a593Smuzhiyun  *
111*4882a593Smuzhiyun  * If the index entry is in the index root attribute, simply mark the mft
112*4882a593Smuzhiyun  * record containing the index root attribute dirty.  This ensures the mft
113*4882a593Smuzhiyun  * record, and hence the index root attribute, will be written out to disk
114*4882a593Smuzhiyun  * later.
115*4882a593Smuzhiyun  *
116*4882a593Smuzhiyun  * If the index entry is in an index block belonging to the index allocation
117*4882a593Smuzhiyun  * attribute, mark the buffers belonging to the index record as well as the
118*4882a593Smuzhiyun  * page cache page the index block is in dirty.  This automatically marks the
119*4882a593Smuzhiyun  * VFS inode of the ntfs index inode to which the index entry belongs dirty,
120*4882a593Smuzhiyun  * too (I_DIRTY_PAGES) and this in turn ensures the page buffers, and hence the
121*4882a593Smuzhiyun  * dirty index block, will be written out to disk later.
122*4882a593Smuzhiyun  */
ntfs_index_entry_mark_dirty(ntfs_index_context * ictx)123*4882a593Smuzhiyun static inline void ntfs_index_entry_mark_dirty(ntfs_index_context *ictx)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun 	if (ictx->is_in_root)
126*4882a593Smuzhiyun 		mark_mft_record_dirty(ictx->actx->ntfs_ino);
127*4882a593Smuzhiyun 	else
128*4882a593Smuzhiyun 		mark_ntfs_record_dirty(ictx->page,
129*4882a593Smuzhiyun 				(u8*)ictx->ia - (u8*)page_address(ictx->page));
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun #endif /* NTFS_RW */
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun #endif /* _LINUX_NTFS_INDEX_H */
135