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