1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Exports for NTFS kernel cluster (de)allocation. 4 * 5 * Copyright (c) 2004-2005 Anton Altaparmakov 6 */ 7 8 #ifndef _LINUX_NTFS_LCNALLOC_H 9 #define _LINUX_NTFS_LCNALLOC_H 10 11 #include <linux/sched/mm.h> 12 13 #include "attrib.h" 14 15 /* 16 * enum zone_type - Zone identifiers for cluster allocation policy 17 * 18 * FIRST_ZONE For sanity checking. 19 * MFT_ZONE Allocate from $MFT zone. 20 * DATA_ZONE Allocate from $DATA zone. 21 * LAST_ZONE For sanity checking. 22 */ 23 enum { 24 FIRST_ZONE = 0, 25 MFT_ZONE = 0, 26 DATA_ZONE = 1, 27 LAST_ZONE = 1, 28 }; 29 30 struct runlist_element *ntfs_cluster_alloc(struct ntfs_volume *vol, 31 const s64 start_vcn, const s64 count, const s64 start_lcn, 32 const int zone, 33 const bool is_extension, 34 const bool is_contig, 35 const bool is_dealloc); 36 s64 __ntfs_cluster_free(struct ntfs_inode *ni, const s64 start_vcn, 37 s64 count, struct ntfs_attr_search_ctx *ctx, const bool is_rollback); 38 39 /* 40 * ntfs_cluster_free - free clusters on an ntfs volume 41 * @ni: ntfs inode whose runlist describes the clusters to free 42 * @start_vcn: vcn in the runlist of @ni at which to start freeing clusters 43 * @count: number of clusters to free or -1 for all clusters 44 * @ctx: active attribute search context if present or NULL if not 45 * 46 * Free @count clusters starting at the cluster @start_vcn in the runlist 47 * described by the ntfs inode @ni. 48 * 49 * If @count is -1, all clusters from @start_vcn to the end of the runlist are 50 * deallocated. Thus, to completely free all clusters in a runlist, use 51 * @start_vcn = 0 and @count = -1. 52 * 53 * If @ctx is specified, it is an active search context of @ni and its base mft 54 * record. This is needed when ntfs_cluster_free() encounters unmapped runlist 55 * fragments and allows their mapping. If you do not have the mft record 56 * mapped, you can specify @ctx as NULL and ntfs_cluster_free() will perform 57 * the necessary mapping and unmapping. 58 * 59 * Note, ntfs_cluster_free() saves the state of @ctx on entry and restores it 60 * before returning. Thus, @ctx will be left pointing to the same attribute on 61 * return as on entry. However, the actual pointers in @ctx may point to 62 * different memory locations on return, so you must remember to reset any 63 * cached pointers from the @ctx, i.e. after the call to ntfs_cluster_free(), 64 * you will probably want to do: 65 * m = ctx->mrec; 66 * a = ctx->attr; 67 * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that 68 * you cache ctx->mrec in a variable @m of type MFT_RECORD *. 69 * 70 * Note, ntfs_cluster_free() does not modify the runlist, so you have to remove 71 * from the runlist or mark sparse the freed runs later. 72 * 73 * Return the number of deallocated clusters (not counting sparse ones) on 74 * success and -errno on error. 75 * 76 * WARNING: If @ctx is supplied, regardless of whether success or failure is 77 * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx 78 * is no longer valid, i.e. you need to either call 79 * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it. 80 * In that case PTR_ERR(@ctx->mrec) will give you the error code for 81 * why the mapping of the old inode failed. 82 * 83 * Locking: - The runlist described by @ni must be locked for writing on entry 84 * and is locked on return. Note the runlist may be modified when 85 * needed runlist fragments need to be mapped. 86 * - The volume lcn bitmap must be unlocked on entry and is unlocked 87 * on return. 88 * - This function takes the volume lcn bitmap lock for writing and 89 * modifies the bitmap contents. 90 * - If @ctx is NULL, the base mft record of @ni must not be mapped on 91 * entry and it will be left unmapped on return. 92 * - If @ctx is not NULL, the base mft record must be mapped on entry 93 * and it will be left mapped on return. 94 */ 95 static inline s64 ntfs_cluster_free(struct ntfs_inode *ni, const s64 start_vcn, 96 s64 count, struct ntfs_attr_search_ctx *ctx) 97 { 98 return __ntfs_cluster_free(ni, start_vcn, count, ctx, false); 99 } 100 101 int ntfs_cluster_free_from_rl_nolock(struct ntfs_volume *vol, 102 const struct runlist_element *rl); 103 104 /* 105 * ntfs_cluster_free_from_rl - free clusters from runlist 106 * @vol: mounted ntfs volume on which to free the clusters 107 * @rl: runlist describing the clusters to free 108 * 109 * Free all the clusters described by the runlist @rl on the volume @vol. In 110 * the case of an error being returned, at least some of the clusters were not 111 * freed. 112 * 113 * Return 0 on success and -errno on error. 114 * 115 * Locking: - This function takes the volume lcn bitmap lock for writing and 116 * modifies the bitmap contents. 117 * - The caller must have locked the runlist @rl for reading or 118 * writing. 119 */ 120 static inline int ntfs_cluster_free_from_rl(struct ntfs_volume *vol, 121 const struct runlist_element *rl) 122 { 123 int ret; 124 unsigned int memalloc_flags; 125 126 memalloc_flags = memalloc_nofs_save(); 127 down_write(&vol->lcnbmp_lock); 128 ret = ntfs_cluster_free_from_rl_nolock(vol, rl); 129 up_write(&vol->lcnbmp_lock); 130 memalloc_nofs_restore(memalloc_flags); 131 return ret; 132 } 133 134 #endif /* defined _LINUX_NTFS_LCNALLOC_H */ 135