Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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 */