11e9ea7e0SNamjae Jeon /* SPDX-License-Identifier: GPL-2.0-or-later */ 21e9ea7e0SNamjae Jeon /* 3*40796051SNamjae Jeon * Defines for runlist handling in NTFS Linux kernel driver. 41e9ea7e0SNamjae Jeon * 51e9ea7e0SNamjae Jeon * Copyright (c) 2001-2005 Anton Altaparmakov 61e9ea7e0SNamjae Jeon * Copyright (c) 2002 Richard Russon 7*40796051SNamjae Jeon * Copyright (c) 2025 LG Electronics Co., Ltd. 81e9ea7e0SNamjae Jeon */ 91e9ea7e0SNamjae Jeon 101e9ea7e0SNamjae Jeon #ifndef _LINUX_NTFS_RUNLIST_H 111e9ea7e0SNamjae Jeon #define _LINUX_NTFS_RUNLIST_H 121e9ea7e0SNamjae Jeon 131e9ea7e0SNamjae Jeon #include "volume.h" 141e9ea7e0SNamjae Jeon 15*40796051SNamjae Jeon /* 161e9ea7e0SNamjae Jeon * runlist_element - in memory vcn to lcn mapping array element 171e9ea7e0SNamjae Jeon * @vcn: starting vcn of the current array element 181e9ea7e0SNamjae Jeon * @lcn: starting lcn of the current array element 191e9ea7e0SNamjae Jeon * @length: length in clusters of the current array element 201e9ea7e0SNamjae Jeon * 211e9ea7e0SNamjae Jeon * The last vcn (in fact the last vcn + 1) is reached when length == 0. 221e9ea7e0SNamjae Jeon * 231e9ea7e0SNamjae Jeon * When lcn == -1 this means that the count vcns starting at vcn are not 241e9ea7e0SNamjae Jeon * physically allocated (i.e. this is a hole / data is sparse). 25*40796051SNamjae Jeon * 26*40796051SNamjae Jeon * In memory vcn to lcn mapping structure element. 27*40796051SNamjae Jeon * @vcn: vcn = Starting virtual cluster number. 28*40796051SNamjae Jeon * @lcn: lcn = Starting logical cluster number. 29*40796051SNamjae Jeon * @length: Run length in clusters. 301e9ea7e0SNamjae Jeon */ 31*40796051SNamjae Jeon struct runlist_element { 32*40796051SNamjae Jeon s64 vcn; 33*40796051SNamjae Jeon s64 lcn; 34*40796051SNamjae Jeon s64 length; 35*40796051SNamjae Jeon }; 361e9ea7e0SNamjae Jeon 37*40796051SNamjae Jeon /* 381e9ea7e0SNamjae Jeon * runlist - in memory vcn to lcn mapping array including a read/write lock 391e9ea7e0SNamjae Jeon * @rl: pointer to an array of runlist elements 401e9ea7e0SNamjae Jeon * @lock: read/write spinlock for serializing access to @rl 41*40796051SNamjae Jeon * @rl_hint: hint/cache pointing to the last accessed runlist element 421e9ea7e0SNamjae Jeon */ 43*40796051SNamjae Jeon struct runlist { 44*40796051SNamjae Jeon struct runlist_element *rl; 451e9ea7e0SNamjae Jeon struct rw_semaphore lock; 46*40796051SNamjae Jeon size_t count; 47*40796051SNamjae Jeon int rl_hint; 48*40796051SNamjae Jeon }; 491e9ea7e0SNamjae Jeon 50*40796051SNamjae Jeon static inline void ntfs_init_runlist(struct runlist *rl) 511e9ea7e0SNamjae Jeon { 521e9ea7e0SNamjae Jeon rl->rl = NULL; 531e9ea7e0SNamjae Jeon init_rwsem(&rl->lock); 54*40796051SNamjae Jeon rl->count = 0; 55*40796051SNamjae Jeon rl->rl_hint = -1; 561e9ea7e0SNamjae Jeon } 571e9ea7e0SNamjae Jeon 58*40796051SNamjae Jeon enum { 59*40796051SNamjae Jeon LCN_DELALLOC = -1, 60*40796051SNamjae Jeon LCN_HOLE = -2, 61*40796051SNamjae Jeon LCN_RL_NOT_MAPPED = -3, 62*40796051SNamjae Jeon LCN_ENOENT = -4, 63*40796051SNamjae Jeon LCN_ENOMEM = -5, 64*40796051SNamjae Jeon LCN_EIO = -6, 65*40796051SNamjae Jeon LCN_EINVAL = -7, 66*40796051SNamjae Jeon }; 671e9ea7e0SNamjae Jeon 68*40796051SNamjae Jeon struct runlist_element *ntfs_runlists_merge(struct runlist *d_runlist, 69*40796051SNamjae Jeon struct runlist_element *srl, size_t s_rl_count, 70*40796051SNamjae Jeon size_t *new_rl_count); 71*40796051SNamjae Jeon struct runlist_element *ntfs_mapping_pairs_decompress(const struct ntfs_volume *vol, 72*40796051SNamjae Jeon const struct attr_record *attr, struct runlist *old_runlist, 73*40796051SNamjae Jeon size_t *new_rl_count); 74*40796051SNamjae Jeon s64 ntfs_rl_vcn_to_lcn(const struct runlist_element *rl, const s64 vcn); 75*40796051SNamjae Jeon struct runlist_element *ntfs_rl_find_vcn_nolock(struct runlist_element *rl, const s64 vcn); 76*40796051SNamjae Jeon int ntfs_get_size_for_mapping_pairs(const struct ntfs_volume *vol, 77*40796051SNamjae Jeon const struct runlist_element *rl, const s64 first_vcn, 78*40796051SNamjae Jeon const s64 last_vcn, int max_mp_size); 79*40796051SNamjae Jeon int ntfs_mapping_pairs_build(const struct ntfs_volume *vol, s8 *dst, 80*40796051SNamjae Jeon const int dst_len, const struct runlist_element *rl, 81*40796051SNamjae Jeon const s64 first_vcn, const s64 last_vcn, s64 *const stop_vcn, 82*40796051SNamjae Jeon struct runlist_element **stop_rl, unsigned int *de_cluster_count); 83*40796051SNamjae Jeon int ntfs_rl_truncate_nolock(const struct ntfs_volume *vol, 84*40796051SNamjae Jeon struct runlist *const runlist, const s64 new_length); 85*40796051SNamjae Jeon int ntfs_rl_sparse(struct runlist_element *rl); 86*40796051SNamjae Jeon s64 ntfs_rl_get_compressed_size(struct ntfs_volume *vol, struct runlist_element *rl); 87*40796051SNamjae Jeon struct runlist_element *ntfs_rl_insert_range(struct runlist_element *dst_rl, int dst_cnt, 88*40796051SNamjae Jeon struct runlist_element *src_rl, int src_cnt, size_t *new_cnt); 89*40796051SNamjae Jeon struct runlist_element *ntfs_rl_punch_hole(struct runlist_element *dst_rl, int dst_cnt, 90*40796051SNamjae Jeon s64 start_vcn, s64 len, struct runlist_element **punch_rl, 91*40796051SNamjae Jeon size_t *new_rl_cnt); 92*40796051SNamjae Jeon struct runlist_element *ntfs_rl_collapse_range(struct runlist_element *dst_rl, int dst_cnt, 93*40796051SNamjae Jeon s64 start_vcn, s64 len, struct runlist_element **punch_rl, 94*40796051SNamjae Jeon size_t *new_rl_cnt); 95*40796051SNamjae Jeon struct runlist_element *ntfs_rl_realloc(struct runlist_element *rl, int old_size, 96*40796051SNamjae Jeon int new_size); 971e9ea7e0SNamjae Jeon #endif /* _LINUX_NTFS_RUNLIST_H */ 98