11e9ea7e0SNamjae Jeon /* SPDX-License-Identifier: GPL-2.0-or-later */ 21e9ea7e0SNamjae Jeon /* 3*40796051SNamjae Jeon * Exports for NTFS kernel cluster (de)allocation. 41e9ea7e0SNamjae Jeon * 51e9ea7e0SNamjae Jeon * Copyright (c) 2004-2005 Anton Altaparmakov 61e9ea7e0SNamjae Jeon */ 71e9ea7e0SNamjae Jeon 81e9ea7e0SNamjae Jeon #ifndef _LINUX_NTFS_LCNALLOC_H 91e9ea7e0SNamjae Jeon #define _LINUX_NTFS_LCNALLOC_H 101e9ea7e0SNamjae Jeon 11*40796051SNamjae Jeon #include <linux/sched/mm.h> 121e9ea7e0SNamjae Jeon 131e9ea7e0SNamjae Jeon #include "attrib.h" 141e9ea7e0SNamjae Jeon 15*40796051SNamjae Jeon /* 16*40796051SNamjae Jeon * enum zone_type - Zone identifiers for cluster allocation policy 17*40796051SNamjae Jeon * 18*40796051SNamjae Jeon * FIRST_ZONE For sanity checking. 19*40796051SNamjae Jeon * MFT_ZONE Allocate from $MFT zone. 20*40796051SNamjae Jeon * DATA_ZONE Allocate from $DATA zone. 21*40796051SNamjae Jeon * LAST_ZONE For sanity checking. 22*40796051SNamjae Jeon */ 23*40796051SNamjae Jeon enum { 24*40796051SNamjae Jeon FIRST_ZONE = 0, 25*40796051SNamjae Jeon MFT_ZONE = 0, 26*40796051SNamjae Jeon DATA_ZONE = 1, 27*40796051SNamjae Jeon LAST_ZONE = 1, 28*40796051SNamjae Jeon }; 291e9ea7e0SNamjae Jeon 30*40796051SNamjae Jeon struct runlist_element *ntfs_cluster_alloc(struct ntfs_volume *vol, 31*40796051SNamjae Jeon const s64 start_vcn, const s64 count, const s64 start_lcn, 32*40796051SNamjae Jeon const int zone, 33*40796051SNamjae Jeon const bool is_extension, 34*40796051SNamjae Jeon const bool is_contig, 35*40796051SNamjae Jeon const bool is_dealloc); 36*40796051SNamjae Jeon s64 __ntfs_cluster_free(struct ntfs_inode *ni, const s64 start_vcn, 37*40796051SNamjae Jeon s64 count, struct ntfs_attr_search_ctx *ctx, const bool is_rollback); 381e9ea7e0SNamjae Jeon 39*40796051SNamjae Jeon /* 401e9ea7e0SNamjae Jeon * ntfs_cluster_free - free clusters on an ntfs volume 411e9ea7e0SNamjae Jeon * @ni: ntfs inode whose runlist describes the clusters to free 421e9ea7e0SNamjae Jeon * @start_vcn: vcn in the runlist of @ni at which to start freeing clusters 431e9ea7e0SNamjae Jeon * @count: number of clusters to free or -1 for all clusters 441e9ea7e0SNamjae Jeon * @ctx: active attribute search context if present or NULL if not 451e9ea7e0SNamjae Jeon * 461e9ea7e0SNamjae Jeon * Free @count clusters starting at the cluster @start_vcn in the runlist 471e9ea7e0SNamjae Jeon * described by the ntfs inode @ni. 481e9ea7e0SNamjae Jeon * 491e9ea7e0SNamjae Jeon * If @count is -1, all clusters from @start_vcn to the end of the runlist are 501e9ea7e0SNamjae Jeon * deallocated. Thus, to completely free all clusters in a runlist, use 511e9ea7e0SNamjae Jeon * @start_vcn = 0 and @count = -1. 521e9ea7e0SNamjae Jeon * 531e9ea7e0SNamjae Jeon * If @ctx is specified, it is an active search context of @ni and its base mft 541e9ea7e0SNamjae Jeon * record. This is needed when ntfs_cluster_free() encounters unmapped runlist 551e9ea7e0SNamjae Jeon * fragments and allows their mapping. If you do not have the mft record 561e9ea7e0SNamjae Jeon * mapped, you can specify @ctx as NULL and ntfs_cluster_free() will perform 571e9ea7e0SNamjae Jeon * the necessary mapping and unmapping. 581e9ea7e0SNamjae Jeon * 591e9ea7e0SNamjae Jeon * Note, ntfs_cluster_free() saves the state of @ctx on entry and restores it 601e9ea7e0SNamjae Jeon * before returning. Thus, @ctx will be left pointing to the same attribute on 611e9ea7e0SNamjae Jeon * return as on entry. However, the actual pointers in @ctx may point to 621e9ea7e0SNamjae Jeon * different memory locations on return, so you must remember to reset any 631e9ea7e0SNamjae Jeon * cached pointers from the @ctx, i.e. after the call to ntfs_cluster_free(), 641e9ea7e0SNamjae Jeon * you will probably want to do: 651e9ea7e0SNamjae Jeon * m = ctx->mrec; 661e9ea7e0SNamjae Jeon * a = ctx->attr; 671e9ea7e0SNamjae Jeon * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that 681e9ea7e0SNamjae Jeon * you cache ctx->mrec in a variable @m of type MFT_RECORD *. 691e9ea7e0SNamjae Jeon * 701e9ea7e0SNamjae Jeon * Note, ntfs_cluster_free() does not modify the runlist, so you have to remove 711e9ea7e0SNamjae Jeon * from the runlist or mark sparse the freed runs later. 721e9ea7e0SNamjae Jeon * 731e9ea7e0SNamjae Jeon * Return the number of deallocated clusters (not counting sparse ones) on 741e9ea7e0SNamjae Jeon * success and -errno on error. 751e9ea7e0SNamjae Jeon * 761e9ea7e0SNamjae Jeon * WARNING: If @ctx is supplied, regardless of whether success or failure is 771e9ea7e0SNamjae Jeon * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx 781e9ea7e0SNamjae Jeon * is no longer valid, i.e. you need to either call 791e9ea7e0SNamjae Jeon * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it. 801e9ea7e0SNamjae Jeon * In that case PTR_ERR(@ctx->mrec) will give you the error code for 811e9ea7e0SNamjae Jeon * why the mapping of the old inode failed. 821e9ea7e0SNamjae Jeon * 831e9ea7e0SNamjae Jeon * Locking: - The runlist described by @ni must be locked for writing on entry 841e9ea7e0SNamjae Jeon * and is locked on return. Note the runlist may be modified when 851e9ea7e0SNamjae Jeon * needed runlist fragments need to be mapped. 861e9ea7e0SNamjae Jeon * - The volume lcn bitmap must be unlocked on entry and is unlocked 871e9ea7e0SNamjae Jeon * on return. 881e9ea7e0SNamjae Jeon * - This function takes the volume lcn bitmap lock for writing and 891e9ea7e0SNamjae Jeon * modifies the bitmap contents. 901e9ea7e0SNamjae Jeon * - If @ctx is NULL, the base mft record of @ni must not be mapped on 911e9ea7e0SNamjae Jeon * entry and it will be left unmapped on return. 921e9ea7e0SNamjae Jeon * - If @ctx is not NULL, the base mft record must be mapped on entry 931e9ea7e0SNamjae Jeon * and it will be left mapped on return. 941e9ea7e0SNamjae Jeon */ 95*40796051SNamjae Jeon static inline s64 ntfs_cluster_free(struct ntfs_inode *ni, const s64 start_vcn, 96*40796051SNamjae Jeon s64 count, struct ntfs_attr_search_ctx *ctx) 971e9ea7e0SNamjae Jeon { 981e9ea7e0SNamjae Jeon return __ntfs_cluster_free(ni, start_vcn, count, ctx, false); 991e9ea7e0SNamjae Jeon } 1001e9ea7e0SNamjae Jeon 101*40796051SNamjae Jeon int ntfs_cluster_free_from_rl_nolock(struct ntfs_volume *vol, 102*40796051SNamjae Jeon const struct runlist_element *rl); 1031e9ea7e0SNamjae Jeon 104*40796051SNamjae Jeon /* 1051e9ea7e0SNamjae Jeon * ntfs_cluster_free_from_rl - free clusters from runlist 1061e9ea7e0SNamjae Jeon * @vol: mounted ntfs volume on which to free the clusters 1071e9ea7e0SNamjae Jeon * @rl: runlist describing the clusters to free 1081e9ea7e0SNamjae Jeon * 1091e9ea7e0SNamjae Jeon * Free all the clusters described by the runlist @rl on the volume @vol. In 1101e9ea7e0SNamjae Jeon * the case of an error being returned, at least some of the clusters were not 1111e9ea7e0SNamjae Jeon * freed. 1121e9ea7e0SNamjae Jeon * 1131e9ea7e0SNamjae Jeon * Return 0 on success and -errno on error. 1141e9ea7e0SNamjae Jeon * 1151e9ea7e0SNamjae Jeon * Locking: - This function takes the volume lcn bitmap lock for writing and 1161e9ea7e0SNamjae Jeon * modifies the bitmap contents. 1171e9ea7e0SNamjae Jeon * - The caller must have locked the runlist @rl for reading or 1181e9ea7e0SNamjae Jeon * writing. 1191e9ea7e0SNamjae Jeon */ 120*40796051SNamjae Jeon static inline int ntfs_cluster_free_from_rl(struct ntfs_volume *vol, 121*40796051SNamjae Jeon const struct runlist_element *rl) 1221e9ea7e0SNamjae Jeon { 1231e9ea7e0SNamjae Jeon int ret; 124*40796051SNamjae Jeon unsigned int memalloc_flags; 1251e9ea7e0SNamjae Jeon 126*40796051SNamjae Jeon memalloc_flags = memalloc_nofs_save(); 1271e9ea7e0SNamjae Jeon down_write(&vol->lcnbmp_lock); 1281e9ea7e0SNamjae Jeon ret = ntfs_cluster_free_from_rl_nolock(vol, rl); 1291e9ea7e0SNamjae Jeon up_write(&vol->lcnbmp_lock); 130*40796051SNamjae Jeon memalloc_nofs_restore(memalloc_flags); 1311e9ea7e0SNamjae Jeon return ret; 1321e9ea7e0SNamjae Jeon } 1331e9ea7e0SNamjae Jeon 1341e9ea7e0SNamjae Jeon #endif /* defined _LINUX_NTFS_LCNALLOC_H */ 135