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