^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) * lcnalloc.c - Cluster (de)allocation code. Part of the Linux-NTFS project.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2004-2005 Anton Altaparmakov
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #ifdef NTFS_RW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "lcnalloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "bitmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "volume.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 "malloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "aops.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "ntfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * ntfs_cluster_free_from_rl_nolock - free clusters from runlist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * @vol: mounted ntfs volume on which to free the clusters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * @rl: runlist describing the clusters to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Free all the clusters described by the runlist @rl on the volume @vol. In
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * the case of an error being returned, at least some of the clusters were not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * Return 0 on success and -errno on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * Locking: - The volume lcn bitmap must be locked for writing on entry and is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * left locked on return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) const runlist_element *rl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct inode *lcnbmp_vi = vol->lcnbmp_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) ntfs_debug("Entering.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (!rl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) for (; rl->length; rl++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (rl->lcn < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) err = ntfs_bitmap_clear_run(lcnbmp_vi, rl->lcn, rl->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (unlikely(err && (!ret || ret == -ENOMEM) && ret != err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ret = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) ntfs_debug("Done.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * ntfs_cluster_alloc - allocate clusters on an ntfs volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * @vol: mounted ntfs volume on which to allocate the clusters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * @start_vcn: vcn to use for the first allocated cluster
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * @count: number of clusters to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * @start_lcn: starting lcn at which to allocate the clusters (or -1 if none)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * @zone: zone from which to allocate the clusters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * @is_extension: if 'true', this is an attribute extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * Allocate @count clusters preferably starting at cluster @start_lcn or at the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * current allocator position if @start_lcn is -1, on the mounted ntfs volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * @vol. @zone is either DATA_ZONE for allocation of normal clusters or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * MFT_ZONE for allocation of clusters for the master file table, i.e. the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * $MFT/$DATA attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * @start_vcn specifies the vcn of the first allocated cluster. This makes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * merging the resulting runlist with the old runlist easier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * If @is_extension is 'true', the caller is allocating clusters to extend an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * attribute and if it is 'false', the caller is allocating clusters to fill a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * hole in an attribute. Practically the difference is that if @is_extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * is 'true' the returned runlist will be terminated with LCN_ENOENT and if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * @is_extension is 'false' the runlist will be terminated with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * LCN_RL_NOT_MAPPED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * You need to check the return value with IS_ERR(). If this is false, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * function was successful and the return value is a runlist describing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * allocated cluster(s). If IS_ERR() is true, the function failed and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * PTR_ERR() gives you the error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * Notes on the allocation algorithm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * =================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * There are two data zones. First is the area between the end of the mft zone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * and the end of the volume, and second is the area between the start of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * volume and the start of the mft zone. On unmodified/standard NTFS 1.x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * volumes, the second data zone does not exist due to the mft zone being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * expanded to cover the start of the volume in order to reserve space for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * mft bitmap attribute.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * This is not the prettiest function but the complexity stems from the need of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * implementing the mft vs data zoned approach and from the fact that we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * access to the lcn bitmap in portions of up to 8192 bytes at a time, so we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * need to cope with crossing over boundaries of two buffers. Further, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * fact that the allocator allows for caller supplied hints as to the location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * of where allocation should begin and the fact that the allocator keeps track
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * of where in the data zones the next natural allocation should occur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * contribute to the complexity of the function. But it should all be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * worthwhile, because this allocator should: 1) be a full implementation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * the MFT zone approach used by Windows NT, 2) cause reduction in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * fragmentation, and 3) be speedy in allocations (the code is not optimized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * for speed, but the algorithm is, so further speed improvements are probably
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * possible).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * FIXME: We should be monitoring cluster allocation and increment the MFT zone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * size dynamically but this is something for the future. We will just cause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * heavier fragmentation by not doing it and I am not even sure Windows would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * grow the MFT zone dynamically, so it might even be correct not to do this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * The overhead in doing dynamic MFT zone expansion would be very large and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * unlikely worth the effort. (AIA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * TODO: I have added in double the required zone position pointer wrap around
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * logic which can be optimized to having only one of the two logic sets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * However, having the double logic will work fine, but if we have only one of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * the sets and we get it wrong somewhere, then we get into trouble, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * removing the duplicate logic requires _very_ careful consideration of _all_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * possible code paths. So at least for now, I am leaving the double logic -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * better safe than sorry... (AIA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * Locking: - The volume lcn bitmap must be unlocked on entry and is unlocked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * on return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * - This function takes the volume lcn bitmap lock for writing and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * modifies the bitmap contents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) const s64 count, const LCN start_lcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) const NTFS_CLUSTER_ALLOCATION_ZONES zone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) const bool is_extension)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) s64 clusters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) loff_t i_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct inode *lcnbmp_vi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) runlist_element *rl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct address_space *mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct page *page = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) u8 *buf, *byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int err = 0, rlpos, rlsize, buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) u8 pass, done_zones, search_zone, need_writeback = 0, bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ntfs_debug("Entering for start_vcn 0x%llx, count 0x%llx, start_lcn "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) "0x%llx, zone %s_ZONE.", (unsigned long long)start_vcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) (unsigned long long)count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) (unsigned long long)start_lcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) zone == MFT_ZONE ? "MFT" : "DATA");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) BUG_ON(!vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) lcnbmp_vi = vol->lcnbmp_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) BUG_ON(!lcnbmp_vi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) BUG_ON(start_vcn < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) BUG_ON(count < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) BUG_ON(start_lcn < -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) BUG_ON(zone < FIRST_ZONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) BUG_ON(zone > LAST_ZONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* Return NULL if @count is zero. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (!count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* Take the lcnbmp lock for writing. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) down_write(&vol->lcnbmp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * If no specific @start_lcn was requested, use the current data zone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * position, otherwise use the requested @start_lcn but make sure it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * lies outside the mft zone. Also set done_zones to 0 (no zones done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * and pass depending on whether we are starting inside a zone (1) or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * at the beginning of a zone (2). If requesting from the MFT_ZONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * we either start at the current position within the mft zone or at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * the specified position. If the latter is out of bounds then we start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * at the beginning of the MFT_ZONE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) done_zones = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) pass = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * zone_start and zone_end are the current search range. search_zone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * is 1 for mft zone, 2 for data zone 1 (end of mft zone till end of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * volume) and 4 for data zone 2 (start of volume till start of mft
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * zone).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) zone_start = start_lcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (zone_start < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (zone == DATA_ZONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) zone_start = vol->data1_zone_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) zone_start = vol->mft_zone_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (!zone_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * Zone starts at beginning of volume which means a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * single pass is sufficient.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) pass = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) } else if (zone == DATA_ZONE && zone_start >= vol->mft_zone_start &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) zone_start < vol->mft_zone_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) zone_start = vol->mft_zone_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * Starting at beginning of data1_zone which means a single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * pass in this zone is sufficient.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) pass = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) } else if (zone == MFT_ZONE && (zone_start < vol->mft_zone_start ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) zone_start >= vol->mft_zone_end)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) zone_start = vol->mft_lcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (!vol->mft_zone_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) zone_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * Starting at beginning of volume which means a single pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * is sufficient.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) pass = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (zone == MFT_ZONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) zone_end = vol->mft_zone_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) search_zone = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) } else /* if (zone == DATA_ZONE) */ {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* Skip searching the mft zone. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) done_zones |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (zone_start >= vol->mft_zone_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) zone_end = vol->nr_clusters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) search_zone = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) zone_end = vol->mft_zone_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) search_zone = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * bmp_pos is the current bit position inside the bitmap. We use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * bmp_initial_pos to determine whether or not to do a zone switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) bmp_pos = bmp_initial_pos = zone_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* Loop until all clusters are allocated, i.e. clusters == 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) clusters = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) rlpos = rlsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) mapping = lcnbmp_vi->i_mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) i_size = i_size_read(lcnbmp_vi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ntfs_debug("Start of outer while loop: done_zones 0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) "search_zone %i, pass %i, zone_start 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) "zone_end 0x%llx, bmp_initial_pos 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) "bmp_pos 0x%llx, rlpos %i, rlsize %i.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) done_zones, search_zone, pass,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) (unsigned long long)zone_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) (unsigned long long)zone_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) (unsigned long long)bmp_initial_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) (unsigned long long)bmp_pos, rlpos, rlsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* Loop until we run out of free clusters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) last_read_pos = bmp_pos >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) ntfs_debug("last_read_pos 0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) (unsigned long long)last_read_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (last_read_pos > i_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ntfs_debug("End of attribute reached. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) "Skipping to zone_pass_done.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) goto zone_pass_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (likely(page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (need_writeback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ntfs_debug("Marking page dirty.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) flush_dcache_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) set_page_dirty(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) need_writeback = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ntfs_unmap_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) page = ntfs_map_page(mapping, last_read_pos >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (IS_ERR(page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) err = PTR_ERR(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ntfs_error(vol->sb, "Failed to map page.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) buf_size = last_read_pos & ~PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) buf = page_address(page) + buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) buf_size = PAGE_SIZE - buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (unlikely(last_read_pos + buf_size > i_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) buf_size = i_size - last_read_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) buf_size <<= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) lcn = bmp_pos & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) bmp_pos &= ~(LCN)7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ntfs_debug("Before inner while loop: buf_size %i, lcn 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) "bmp_pos 0x%llx, need_writeback %i.", buf_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) (unsigned long long)lcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) (unsigned long long)bmp_pos, need_writeback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) while (lcn < buf_size && lcn + bmp_pos < zone_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) byte = buf + (lcn >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) ntfs_debug("In inner while loop: buf_size %i, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) "lcn 0x%llx, bmp_pos 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) "need_writeback %i, byte ofs 0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) "*byte 0x%x.", buf_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) (unsigned long long)lcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) (unsigned long long)bmp_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) need_writeback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) (unsigned int)(lcn >> 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) (unsigned int)*byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* Skip full bytes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (*byte == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) lcn = (lcn + 8) & ~(LCN)7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ntfs_debug("Continuing while loop 1.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) bit = 1 << (lcn & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ntfs_debug("bit 0x%x.", bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* If the bit is already set, go onto the next one. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (*byte & bit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) lcn++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ntfs_debug("Continuing while loop 2.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * Allocate more memory if needed, including space for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * the terminator element.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * ntfs_malloc_nofs() operates on whole pages only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if ((rlpos + 2) * sizeof(*rl) > rlsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) runlist_element *rl2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ntfs_debug("Reallocating memory.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (!rl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ntfs_debug("First free bit is at LCN "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) "0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) (lcn + bmp_pos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) rl2 = ntfs_malloc_nofs(rlsize + (int)PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (unlikely(!rl2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) ntfs_error(vol->sb, "Failed to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) "allocate memory.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) memcpy(rl2, rl, rlsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ntfs_free(rl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) rl = rl2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) rlsize += PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) ntfs_debug("Reallocated memory, rlsize 0x%x.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) rlsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /* Allocate the bitmap bit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) *byte |= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /* We need to write this bitmap page to disk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) need_writeback = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ntfs_debug("*byte 0x%x, need_writeback is set.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) (unsigned int)*byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * Coalesce with previous run if adjacent LCNs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * Otherwise, append a new run.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ntfs_debug("Adding run (lcn 0x%llx, len 0x%llx), "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) "prev_lcn 0x%llx, lcn 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) "bmp_pos 0x%llx, prev_run_len 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) "rlpos %i.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) (unsigned long long)(lcn + bmp_pos),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 1ULL, (unsigned long long)prev_lcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) (unsigned long long)lcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) (unsigned long long)bmp_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) (unsigned long long)prev_run_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) rlpos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (prev_lcn == lcn + bmp_pos - prev_run_len && rlpos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ntfs_debug("Coalescing to run (lcn 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) "len 0x%llx).",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) rl[rlpos - 1].lcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) rl[rlpos - 1].length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) rl[rlpos - 1].length = ++prev_run_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) ntfs_debug("Run now (lcn 0x%llx, len 0x%llx), "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) "prev_run_len 0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) rl[rlpos - 1].lcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) rl[rlpos - 1].length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) prev_run_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (likely(rlpos)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) ntfs_debug("Adding new run, (previous "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) "run lcn 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) "len 0x%llx).",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) rl[rlpos - 1].lcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) rl[rlpos - 1].length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) rl[rlpos].vcn = rl[rlpos - 1].vcn +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) prev_run_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) ntfs_debug("Adding new run, is first "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) "run.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) rl[rlpos].vcn = start_vcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) rl[rlpos].lcn = prev_lcn = lcn + bmp_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) rl[rlpos].length = prev_run_len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) rlpos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /* Done? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (!--clusters) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) LCN tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * Update the current zone position. Positions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * of already scanned zones have been updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * during the respective zone switches.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) tc = lcn + bmp_pos + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) ntfs_debug("Done. Updating current zone "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) "position, tc 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) "search_zone %i.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) (unsigned long long)tc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) search_zone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) switch (search_zone) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) ntfs_debug("Before checks, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) "vol->mft_zone_pos "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) "0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) vol->mft_zone_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (tc >= vol->mft_zone_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) vol->mft_zone_pos =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) vol->mft_lcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (!vol->mft_zone_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) vol->mft_zone_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) } else if ((bmp_initial_pos >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) vol->mft_zone_pos ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) tc > vol->mft_zone_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) && tc >= vol->mft_lcn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) vol->mft_zone_pos = tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ntfs_debug("After checks, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) "vol->mft_zone_pos "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) "0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) vol->mft_zone_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ntfs_debug("Before checks, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) "vol->data1_zone_pos "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) "0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) vol->data1_zone_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (tc >= vol->nr_clusters)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) vol->data1_zone_pos =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) vol->mft_zone_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) else if ((bmp_initial_pos >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) vol->data1_zone_pos ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) tc > vol->data1_zone_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) && tc >= vol->mft_zone_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) vol->data1_zone_pos = tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ntfs_debug("After checks, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) "vol->data1_zone_pos "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) "0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) vol->data1_zone_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ntfs_debug("Before checks, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) "vol->data2_zone_pos "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) "0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) vol->data2_zone_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (tc >= vol->mft_zone_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) vol->data2_zone_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) else if (bmp_initial_pos >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) vol->data2_zone_pos ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) tc > vol->data2_zone_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) vol->data2_zone_pos = tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ntfs_debug("After checks, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) "vol->data2_zone_pos "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) "0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) vol->data2_zone_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) ntfs_debug("Finished. Going to out.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) lcn++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) bmp_pos += buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) ntfs_debug("After inner while loop: buf_size 0x%x, lcn "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) "0x%llx, bmp_pos 0x%llx, need_writeback %i.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) buf_size, (unsigned long long)lcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) (unsigned long long)bmp_pos, need_writeback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (bmp_pos < zone_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ntfs_debug("Continuing outer while loop, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) "bmp_pos 0x%llx, zone_end 0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) (unsigned long long)bmp_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) (unsigned long long)zone_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) zone_pass_done: /* Finished with the current zone pass. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ntfs_debug("At zone_pass_done, pass %i.", pass);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (pass == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * Now do pass 2, scanning the first part of the zone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * we omitted in pass 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) pass = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) zone_end = zone_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) switch (search_zone) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) case 1: /* mft_zone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) zone_start = vol->mft_zone_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) case 2: /* data1_zone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) zone_start = vol->mft_zone_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) case 4: /* data2_zone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) zone_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /* Sanity check. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (zone_end < zone_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) zone_end = zone_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) bmp_pos = zone_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) ntfs_debug("Continuing outer while loop, pass 2, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) "zone_start 0x%llx, zone_end 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) "bmp_pos 0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) (unsigned long long)zone_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) (unsigned long long)zone_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) (unsigned long long)bmp_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) } /* pass == 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) done_zones_check:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) ntfs_debug("At done_zones_check, search_zone %i, done_zones "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) "before 0x%x, done_zones after 0x%x.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) search_zone, done_zones,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) done_zones | search_zone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) done_zones |= search_zone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (done_zones < 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ntfs_debug("Switching zone.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /* Now switch to the next zone we haven't done yet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) pass = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) switch (search_zone) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) ntfs_debug("Switching from mft zone to data1 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) "zone.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) /* Update mft zone position. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (rlpos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) LCN tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ntfs_debug("Before checks, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) "vol->mft_zone_pos "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) "0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) vol->mft_zone_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) tc = rl[rlpos - 1].lcn +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) rl[rlpos - 1].length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (tc >= vol->mft_zone_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) vol->mft_zone_pos =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) vol->mft_lcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (!vol->mft_zone_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) vol->mft_zone_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) } else if ((bmp_initial_pos >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) vol->mft_zone_pos ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) tc > vol->mft_zone_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) && tc >= vol->mft_lcn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) vol->mft_zone_pos = tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) ntfs_debug("After checks, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) "vol->mft_zone_pos "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) "0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) vol->mft_zone_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* Switch from mft zone to data1 zone. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) switch_to_data1_zone: search_zone = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) zone_start = bmp_initial_pos =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) vol->data1_zone_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) zone_end = vol->nr_clusters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (zone_start == vol->mft_zone_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) pass = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (zone_start >= zone_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) vol->data1_zone_pos = zone_start =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) vol->mft_zone_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) pass = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) ntfs_debug("Switching from data1 zone to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) "data2 zone.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /* Update data1 zone position. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (rlpos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) LCN tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) ntfs_debug("Before checks, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) "vol->data1_zone_pos "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) "0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) vol->data1_zone_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) tc = rl[rlpos - 1].lcn +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) rl[rlpos - 1].length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (tc >= vol->nr_clusters)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) vol->data1_zone_pos =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) vol->mft_zone_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) else if ((bmp_initial_pos >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) vol->data1_zone_pos ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) tc > vol->data1_zone_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) && tc >= vol->mft_zone_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) vol->data1_zone_pos = tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ntfs_debug("After checks, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) "vol->data1_zone_pos "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) "0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) vol->data1_zone_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /* Switch from data1 zone to data2 zone. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) search_zone = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) zone_start = bmp_initial_pos =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) vol->data2_zone_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) zone_end = vol->mft_zone_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (!zone_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) pass = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (zone_start >= zone_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) vol->data2_zone_pos = zone_start =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) bmp_initial_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) pass = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) ntfs_debug("Switching from data2 zone to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) "data1 zone.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /* Update data2 zone position. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (rlpos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) LCN tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) ntfs_debug("Before checks, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) "vol->data2_zone_pos "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) "0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) vol->data2_zone_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) tc = rl[rlpos - 1].lcn +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) rl[rlpos - 1].length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (tc >= vol->mft_zone_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) vol->data2_zone_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) else if (bmp_initial_pos >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) vol->data2_zone_pos ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) tc > vol->data2_zone_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) vol->data2_zone_pos = tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) ntfs_debug("After checks, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) "vol->data2_zone_pos "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) "0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) vol->data2_zone_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /* Switch from data2 zone to data1 zone. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) goto switch_to_data1_zone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) ntfs_debug("After zone switch, search_zone %i, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) "pass %i, bmp_initial_pos 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) "zone_start 0x%llx, zone_end 0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) search_zone, pass,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) (unsigned long long)bmp_initial_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) (unsigned long long)zone_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) (unsigned long long)zone_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) bmp_pos = zone_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (zone_start == zone_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) ntfs_debug("Empty zone, going to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) "done_zones_check.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) /* Empty zone. Don't bother searching it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) goto done_zones_check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) ntfs_debug("Continuing outer while loop.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) } /* done_zones == 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) ntfs_debug("All zones are finished.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * All zones are finished! If DATA_ZONE, shrink mft zone. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) * MFT_ZONE, we have really run out of space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) mft_zone_size = vol->mft_zone_end - vol->mft_zone_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) ntfs_debug("vol->mft_zone_start 0x%llx, vol->mft_zone_end "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) "0x%llx, mft_zone_size 0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) (unsigned long long)vol->mft_zone_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) (unsigned long long)vol->mft_zone_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) (unsigned long long)mft_zone_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (zone == MFT_ZONE || mft_zone_size <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) ntfs_debug("No free clusters left, going to out.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) /* Really no more space left on device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) err = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) } /* zone == DATA_ZONE && mft_zone_size > 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) ntfs_debug("Shrinking mft zone.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) zone_end = vol->mft_zone_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) mft_zone_size >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (mft_zone_size > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) vol->mft_zone_end = vol->mft_zone_start + mft_zone_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) else /* mft zone and data2 zone no longer exist. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) vol->data2_zone_pos = vol->mft_zone_start =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) vol->mft_zone_end = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (vol->mft_zone_pos >= vol->mft_zone_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) vol->mft_zone_pos = vol->mft_lcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (!vol->mft_zone_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) vol->mft_zone_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) bmp_pos = zone_start = bmp_initial_pos =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) vol->data1_zone_pos = vol->mft_zone_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) search_zone = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) pass = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) done_zones &= ~2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) ntfs_debug("After shrinking mft zone, mft_zone_size 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) "vol->mft_zone_start 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) "vol->mft_zone_end 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) "vol->mft_zone_pos 0x%llx, search_zone 2, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) "pass 2, dones_zones 0x%x, zone_start 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) "zone_end 0x%llx, vol->data1_zone_pos 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) "continuing outer while loop.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) (unsigned long long)mft_zone_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) (unsigned long long)vol->mft_zone_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) (unsigned long long)vol->mft_zone_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) (unsigned long long)vol->mft_zone_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) done_zones, (unsigned long long)zone_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) (unsigned long long)zone_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) (unsigned long long)vol->data1_zone_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) ntfs_debug("After outer while loop.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) ntfs_debug("At out.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) /* Add runlist terminator element. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (likely(rl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) rl[rlpos].lcn = is_extension ? LCN_ENOENT : LCN_RL_NOT_MAPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) rl[rlpos].length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (likely(page && !IS_ERR(page))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (need_writeback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) ntfs_debug("Marking page dirty.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) flush_dcache_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) set_page_dirty(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) need_writeback = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) ntfs_unmap_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (likely(!err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) up_write(&vol->lcnbmp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) ntfs_debug("Done.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) return rl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) ntfs_error(vol->sb, "Failed to allocate clusters, aborting "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) "(error %i).", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (rl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) int err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (err == -ENOSPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) ntfs_debug("Not enough space to complete allocation, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) "err -ENOSPC, first free lcn 0x%llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) "could allocate up to 0x%llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) "clusters.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) (unsigned long long)rl[0].lcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) (unsigned long long)(count - clusters));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) /* Deallocate all allocated clusters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) ntfs_debug("Attempting rollback...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) err2 = ntfs_cluster_free_from_rl_nolock(vol, rl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (err2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) ntfs_error(vol->sb, "Failed to rollback (error %i). "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) "Leaving inconsistent metadata! "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) "Unmount and run chkdsk.", err2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) NVolSetErrors(vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) /* Free the runlist. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) ntfs_free(rl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) } else if (err == -ENOSPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) ntfs_debug("No space left at all, err = -ENOSPC, first free "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) "lcn = 0x%llx.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) (long long)vol->data1_zone_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) up_write(&vol->lcnbmp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * __ntfs_cluster_free - free clusters on an ntfs volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * @ni: ntfs inode whose runlist describes the clusters to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) * @start_vcn: vcn in the runlist of @ni at which to start freeing clusters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * @count: number of clusters to free or -1 for all clusters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * @ctx: active attribute search context if present or NULL if not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * @is_rollback: true if this is a rollback operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) * Free @count clusters starting at the cluster @start_vcn in the runlist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) * described by the vfs inode @ni.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) * If @count is -1, all clusters from @start_vcn to the end of the runlist are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * deallocated. Thus, to completely free all clusters in a runlist, use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) * @start_vcn = 0 and @count = -1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * If @ctx is specified, it is an active search context of @ni and its base mft
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * record. This is needed when __ntfs_cluster_free() encounters unmapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) * runlist fragments and allows their mapping. If you do not have the mft
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) * record mapped, you can specify @ctx as NULL and __ntfs_cluster_free() will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * perform the necessary mapping and unmapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * Note, __ntfs_cluster_free() saves the state of @ctx on entry and restores it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * before returning. Thus, @ctx will be left pointing to the same attribute on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * return as on entry. However, the actual pointers in @ctx may point to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * different memory locations on return, so you must remember to reset any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * cached pointers from the @ctx, i.e. after the call to __ntfs_cluster_free(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) * you will probably want to do:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * m = ctx->mrec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * a = ctx->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * you cache ctx->mrec in a variable @m of type MFT_RECORD *.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * @is_rollback should always be 'false', it is for internal use to rollback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * errors. You probably want to use ntfs_cluster_free() instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * Note, __ntfs_cluster_free() does not modify the runlist, so you have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * remove from the runlist or mark sparse the freed runs later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) * Return the number of deallocated clusters (not counting sparse ones) on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) * success and -errno on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) * WARNING: If @ctx is supplied, regardless of whether success or failure is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * is no longer valid, i.e. you need to either call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * In that case PTR_ERR(@ctx->mrec) will give you the error code for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) * why the mapping of the old inode failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * Locking: - The runlist described by @ni must be locked for writing on entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) * and is locked on return. Note the runlist may be modified when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) * needed runlist fragments need to be mapped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) * - The volume lcn bitmap must be unlocked on entry and is unlocked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) * on return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) * - This function takes the volume lcn bitmap lock for writing and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) * modifies the bitmap contents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) * - If @ctx is NULL, the base mft record of @ni must not be mapped on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) * entry and it will be left unmapped on return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * - If @ctx is not NULL, the base mft record must be mapped on entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) * and it will be left mapped on return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ntfs_attr_search_ctx *ctx, const bool is_rollback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) s64 delta, to_free, total_freed, real_freed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) ntfs_volume *vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) struct inode *lcnbmp_vi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) runlist_element *rl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) BUG_ON(!ni);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) ntfs_debug("Entering for i_ino 0x%lx, start_vcn 0x%llx, count "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) "0x%llx.%s", ni->mft_no, (unsigned long long)start_vcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) (unsigned long long)count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) is_rollback ? " (rollback)" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) vol = ni->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) lcnbmp_vi = vol->lcnbmp_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) BUG_ON(!lcnbmp_vi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) BUG_ON(start_vcn < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) BUG_ON(count < -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) * Lock the lcn bitmap for writing but only if not rolling back. We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) * must hold the lock all the way including through rollback otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) * rollback is not possible because once we have cleared a bit and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) * dropped the lock, anyone could have set the bit again, thus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) * allocating the cluster for another use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (likely(!is_rollback))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) down_write(&vol->lcnbmp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) total_freed = real_freed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (IS_ERR(rl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (!is_rollback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) ntfs_error(vol->sb, "Failed to find first runlist "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) "element (error %li), aborting.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) PTR_ERR(rl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) err = PTR_ERR(rl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (unlikely(rl->lcn < LCN_HOLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (!is_rollback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) ntfs_error(vol->sb, "First runlist element has "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) "invalid lcn, aborting.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) /* Find the starting cluster inside the run that needs freeing. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) delta = start_vcn - rl->vcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) /* The number of clusters in this run that need freeing. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) to_free = rl->length - delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (count >= 0 && to_free > count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) to_free = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (likely(rl->lcn >= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) /* Do the actual freeing of the clusters in this run. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) err = ntfs_bitmap_set_bits_in_run(lcnbmp_vi, rl->lcn + delta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) to_free, likely(!is_rollback) ? 0 : 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (!is_rollback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ntfs_error(vol->sb, "Failed to clear first run "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) "(error %i), aborting.", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) /* We have freed @to_free real clusters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) real_freed = to_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) /* Go to the next run and adjust the number of clusters left to free. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) ++rl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (count >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) count -= to_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) /* Keep track of the total "freed" clusters, including sparse ones. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) total_freed = to_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) * Loop over the remaining runs, using @count as a capping value, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) * free them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) for (; rl->length && count != 0; ++rl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (unlikely(rl->lcn < LCN_HOLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) VCN vcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) /* Attempt to map runlist. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) vcn = rl->vcn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) rl = ntfs_attr_find_vcn_nolock(ni, vcn, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (IS_ERR(rl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) err = PTR_ERR(rl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (!is_rollback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) ntfs_error(vol->sb, "Failed to map "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) "runlist fragment or "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) "failed to find "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) "subsequent runlist "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) "element.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (unlikely(rl->lcn < LCN_HOLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (!is_rollback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) ntfs_error(vol->sb, "Runlist element "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) "has invalid lcn "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) "(0x%llx).",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) (unsigned long long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) rl->lcn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) /* The number of clusters in this run that need freeing. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) to_free = rl->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (count >= 0 && to_free > count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) to_free = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (likely(rl->lcn >= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) /* Do the actual freeing of the clusters in the run. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) err = ntfs_bitmap_set_bits_in_run(lcnbmp_vi, rl->lcn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) to_free, likely(!is_rollback) ? 0 : 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (!is_rollback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) ntfs_error(vol->sb, "Failed to clear "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) "subsequent run.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) /* We have freed @to_free real clusters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) real_freed += to_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) /* Adjust the number of clusters left to free. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (count >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) count -= to_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) /* Update the total done clusters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) total_freed += to_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (likely(!is_rollback))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) up_write(&vol->lcnbmp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) BUG_ON(count > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) /* We are done. Return the number of actually freed clusters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) ntfs_debug("Done.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) return real_freed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (is_rollback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) /* If no real clusters were freed, no need to rollback. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (!real_freed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) up_write(&vol->lcnbmp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) * Attempt to rollback and if that succeeds just return the error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) * If rollback fails, set the volume errors flag, emit an error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) * message, and return the error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) delta = __ntfs_cluster_free(ni, start_vcn, total_freed, ctx, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (delta < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) ntfs_error(vol->sb, "Failed to rollback (error %i). Leaving "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) "inconsistent metadata! Unmount and run "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) "chkdsk.", (int)delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) NVolSetErrors(vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) up_write(&vol->lcnbmp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) ntfs_error(vol->sb, "Aborting (error %i).", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) #endif /* NTFS_RW */