1987da915Sopenharmony_ci/** 2987da915Sopenharmony_ci * lcnalloc.c - Cluster (de)allocation code. Originated from the Linux-NTFS project. 3987da915Sopenharmony_ci * 4987da915Sopenharmony_ci * Copyright (c) 2002-2004 Anton Altaparmakov 5987da915Sopenharmony_ci * Copyright (c) 2004 Yura Pakhuchiy 6987da915Sopenharmony_ci * Copyright (c) 2004-2008 Szabolcs Szakacsits 7987da915Sopenharmony_ci * Copyright (c) 2008-2009 Jean-Pierre Andre 8987da915Sopenharmony_ci * 9987da915Sopenharmony_ci * This program/include file is free software; you can redistribute it and/or 10987da915Sopenharmony_ci * modify it under the terms of the GNU General Public License as published 11987da915Sopenharmony_ci * by the Free Software Foundation; either version 2 of the License, or 12987da915Sopenharmony_ci * (at your option) any later version. 13987da915Sopenharmony_ci * 14987da915Sopenharmony_ci * This program/include file is distributed in the hope that it will be 15987da915Sopenharmony_ci * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 16987da915Sopenharmony_ci * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17987da915Sopenharmony_ci * GNU General Public License for more details. 18987da915Sopenharmony_ci * 19987da915Sopenharmony_ci * You should have received a copy of the GNU General Public License 20987da915Sopenharmony_ci * along with this program (in the main directory of the NTFS-3G 21987da915Sopenharmony_ci * distribution in the file COPYING); if not, write to the Free Software 22987da915Sopenharmony_ci * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23987da915Sopenharmony_ci */ 24987da915Sopenharmony_ci 25987da915Sopenharmony_ci#ifdef HAVE_CONFIG_H 26987da915Sopenharmony_ci#include "config.h" 27987da915Sopenharmony_ci#endif 28987da915Sopenharmony_ci 29987da915Sopenharmony_ci#ifdef HAVE_STDLIB_H 30987da915Sopenharmony_ci#include <stdlib.h> 31987da915Sopenharmony_ci#endif 32987da915Sopenharmony_ci#ifdef HAVE_STDIO_H 33987da915Sopenharmony_ci#include <stdio.h> 34987da915Sopenharmony_ci#endif 35987da915Sopenharmony_ci#ifdef HAVE_ERRNO_H 36987da915Sopenharmony_ci#include <errno.h> 37987da915Sopenharmony_ci#endif 38987da915Sopenharmony_ci 39987da915Sopenharmony_ci#include "types.h" 40987da915Sopenharmony_ci#include "attrib.h" 41987da915Sopenharmony_ci#include "bitmap.h" 42987da915Sopenharmony_ci#include "debug.h" 43987da915Sopenharmony_ci#include "runlist.h" 44987da915Sopenharmony_ci#include "volume.h" 45987da915Sopenharmony_ci#include "lcnalloc.h" 46987da915Sopenharmony_ci#include "logging.h" 47987da915Sopenharmony_ci#include "misc.h" 48987da915Sopenharmony_ci 49987da915Sopenharmony_ci/* 50987da915Sopenharmony_ci * Plenty possibilities for big optimizations all over in the cluster 51987da915Sopenharmony_ci * allocation, however at the moment the dominant bottleneck (~ 90%) is 52987da915Sopenharmony_ci * the update of the mapping pairs which converges to the cubic Faulhaber's 53987da915Sopenharmony_ci * formula as the function of the number of extents (fragments, runs). 54987da915Sopenharmony_ci */ 55987da915Sopenharmony_ci#define NTFS_LCNALLOC_BSIZE 4096 56987da915Sopenharmony_ci#define NTFS_LCNALLOC_SKIP NTFS_LCNALLOC_BSIZE 57987da915Sopenharmony_ci 58987da915Sopenharmony_cienum { 59987da915Sopenharmony_ci ZONE_MFT = 1, 60987da915Sopenharmony_ci ZONE_DATA1 = 2, 61987da915Sopenharmony_ci ZONE_DATA2 = 4 62987da915Sopenharmony_ci} ; 63987da915Sopenharmony_ci 64987da915Sopenharmony_cistatic void ntfs_cluster_set_zone_pos(LCN start, LCN end, LCN *pos, LCN tc) 65987da915Sopenharmony_ci{ 66987da915Sopenharmony_ci ntfs_log_trace("pos: %lld tc: %lld\n", (long long)*pos, (long long)tc); 67987da915Sopenharmony_ci 68987da915Sopenharmony_ci if (tc >= end) 69987da915Sopenharmony_ci *pos = start; 70987da915Sopenharmony_ci else if (tc >= start) 71987da915Sopenharmony_ci *pos = tc; 72987da915Sopenharmony_ci} 73987da915Sopenharmony_ci 74987da915Sopenharmony_cistatic void ntfs_cluster_update_zone_pos(ntfs_volume *vol, u8 zone, LCN tc) 75987da915Sopenharmony_ci{ 76987da915Sopenharmony_ci ntfs_log_trace("tc = %lld, zone = %d\n", (long long)tc, zone); 77987da915Sopenharmony_ci 78987da915Sopenharmony_ci if (zone == ZONE_MFT) 79987da915Sopenharmony_ci ntfs_cluster_set_zone_pos(vol->mft_lcn, vol->mft_zone_end, 80987da915Sopenharmony_ci &vol->mft_zone_pos, tc); 81987da915Sopenharmony_ci else if (zone == ZONE_DATA1) 82987da915Sopenharmony_ci ntfs_cluster_set_zone_pos(vol->mft_zone_end, vol->nr_clusters, 83987da915Sopenharmony_ci &vol->data1_zone_pos, tc); 84987da915Sopenharmony_ci else /* zone == ZONE_DATA2 */ 85987da915Sopenharmony_ci ntfs_cluster_set_zone_pos(0, vol->mft_zone_start, 86987da915Sopenharmony_ci &vol->data2_zone_pos, tc); 87987da915Sopenharmony_ci} 88987da915Sopenharmony_ci 89987da915Sopenharmony_ci/* 90987da915Sopenharmony_ci * Unmark full zones when a cluster has been freed in a full zone 91987da915Sopenharmony_ci * 92987da915Sopenharmony_ci * Next allocation will reuse the freed cluster 93987da915Sopenharmony_ci */ 94987da915Sopenharmony_ci 95987da915Sopenharmony_cistatic void update_full_status(ntfs_volume *vol, LCN lcn) 96987da915Sopenharmony_ci{ 97987da915Sopenharmony_ci if (lcn >= vol->mft_zone_end) { 98987da915Sopenharmony_ci if (vol->full_zones & ZONE_DATA1) { 99987da915Sopenharmony_ci ntfs_cluster_update_zone_pos(vol, ZONE_DATA1, lcn); 100987da915Sopenharmony_ci vol->full_zones &= ~ZONE_DATA1; 101987da915Sopenharmony_ci } 102987da915Sopenharmony_ci } else 103987da915Sopenharmony_ci if (lcn < vol->mft_zone_start) { 104987da915Sopenharmony_ci if (vol->full_zones & ZONE_DATA2) { 105987da915Sopenharmony_ci ntfs_cluster_update_zone_pos(vol, ZONE_DATA2, lcn); 106987da915Sopenharmony_ci vol->full_zones &= ~ZONE_DATA2; 107987da915Sopenharmony_ci } 108987da915Sopenharmony_ci } else { 109987da915Sopenharmony_ci if (vol->full_zones & ZONE_MFT) { 110987da915Sopenharmony_ci ntfs_cluster_update_zone_pos(vol, ZONE_MFT, lcn); 111987da915Sopenharmony_ci vol->full_zones &= ~ZONE_MFT; 112987da915Sopenharmony_ci } 113987da915Sopenharmony_ci } 114987da915Sopenharmony_ci} 115987da915Sopenharmony_ci 116987da915Sopenharmony_cistatic s64 max_empty_bit_range(unsigned char *buf, int size) 117987da915Sopenharmony_ci{ 118987da915Sopenharmony_ci int i, j, run = 0; 119987da915Sopenharmony_ci int max_range = 0; 120987da915Sopenharmony_ci s64 start_pos = -1; 121987da915Sopenharmony_ci 122987da915Sopenharmony_ci ntfs_log_trace("Entering\n"); 123987da915Sopenharmony_ci 124987da915Sopenharmony_ci i = 0; 125987da915Sopenharmony_ci while (i < size) { 126987da915Sopenharmony_ci switch (*buf) { 127987da915Sopenharmony_ci case 0 : 128987da915Sopenharmony_ci do { 129987da915Sopenharmony_ci buf++; 130987da915Sopenharmony_ci run += 8; 131987da915Sopenharmony_ci i++; 132987da915Sopenharmony_ci } while ((i < size) && !*buf); 133987da915Sopenharmony_ci break; 134987da915Sopenharmony_ci case 255 : 135987da915Sopenharmony_ci if (run > max_range) { 136987da915Sopenharmony_ci max_range = run; 137987da915Sopenharmony_ci start_pos = (s64)i * 8 - run; 138987da915Sopenharmony_ci } 139987da915Sopenharmony_ci run = 0; 140987da915Sopenharmony_ci do { 141987da915Sopenharmony_ci buf++; 142987da915Sopenharmony_ci i++; 143987da915Sopenharmony_ci } while ((i < size) && (*buf == 255)); 144987da915Sopenharmony_ci break; 145987da915Sopenharmony_ci default : 146987da915Sopenharmony_ci for (j = 0; j < 8; j++) { 147987da915Sopenharmony_ci 148987da915Sopenharmony_ci int bit = *buf & (1 << j); 149987da915Sopenharmony_ci 150987da915Sopenharmony_ci if (bit) { 151987da915Sopenharmony_ci if (run > max_range) { 152987da915Sopenharmony_ci max_range = run; 153987da915Sopenharmony_ci start_pos = (s64)i * 8 + (j - run); 154987da915Sopenharmony_ci } 155987da915Sopenharmony_ci run = 0; 156987da915Sopenharmony_ci } else 157987da915Sopenharmony_ci run++; 158987da915Sopenharmony_ci } 159987da915Sopenharmony_ci i++; 160987da915Sopenharmony_ci buf++; 161987da915Sopenharmony_ci 162987da915Sopenharmony_ci } 163987da915Sopenharmony_ci } 164987da915Sopenharmony_ci 165987da915Sopenharmony_ci if (run > max_range) 166987da915Sopenharmony_ci start_pos = (s64)i * 8 - run; 167987da915Sopenharmony_ci 168987da915Sopenharmony_ci return start_pos; 169987da915Sopenharmony_ci} 170987da915Sopenharmony_ci 171987da915Sopenharmony_cistatic int bitmap_writeback(ntfs_volume *vol, s64 pos, s64 size, void *b, 172987da915Sopenharmony_ci u8 *writeback) 173987da915Sopenharmony_ci{ 174987da915Sopenharmony_ci s64 written; 175987da915Sopenharmony_ci 176987da915Sopenharmony_ci ntfs_log_trace("Entering\n"); 177987da915Sopenharmony_ci 178987da915Sopenharmony_ci if (!*writeback) 179987da915Sopenharmony_ci return 0; 180987da915Sopenharmony_ci 181987da915Sopenharmony_ci *writeback = 0; 182987da915Sopenharmony_ci 183987da915Sopenharmony_ci written = ntfs_attr_pwrite(vol->lcnbmp_na, pos, size, b); 184987da915Sopenharmony_ci if (written != size) { 185987da915Sopenharmony_ci if (!written) 186987da915Sopenharmony_ci errno = EIO; 187987da915Sopenharmony_ci ntfs_log_perror("Bitmap write error (%lld, %lld)", 188987da915Sopenharmony_ci (long long)pos, (long long)size); 189987da915Sopenharmony_ci return -1; 190987da915Sopenharmony_ci } 191987da915Sopenharmony_ci 192987da915Sopenharmony_ci return 0; 193987da915Sopenharmony_ci} 194987da915Sopenharmony_ci 195987da915Sopenharmony_ci/** 196987da915Sopenharmony_ci * ntfs_cluster_alloc - allocate clusters on an ntfs volume 197987da915Sopenharmony_ci * @vol: mounted ntfs volume on which to allocate the clusters 198987da915Sopenharmony_ci * @start_vcn: vcn to use for the first allocated cluster 199987da915Sopenharmony_ci * @count: number of clusters to allocate 200987da915Sopenharmony_ci * @start_lcn: starting lcn at which to allocate the clusters (or -1 if none) 201987da915Sopenharmony_ci * @zone: zone from which to allocate the clusters 202987da915Sopenharmony_ci * 203987da915Sopenharmony_ci * Allocate @count clusters preferably starting at cluster @start_lcn or at the 204987da915Sopenharmony_ci * current allocator position if @start_lcn is -1, on the mounted ntfs volume 205987da915Sopenharmony_ci * @vol. @zone is either DATA_ZONE for allocation of normal clusters and 206987da915Sopenharmony_ci * MFT_ZONE for allocation of clusters for the master file table, i.e. the 207987da915Sopenharmony_ci * $MFT/$DATA attribute. 208987da915Sopenharmony_ci * 209987da915Sopenharmony_ci * On success return a runlist describing the allocated cluster(s). 210987da915Sopenharmony_ci * 211987da915Sopenharmony_ci * On error return NULL with errno set to the error code. 212987da915Sopenharmony_ci * 213987da915Sopenharmony_ci * Notes on the allocation algorithm 214987da915Sopenharmony_ci * ================================= 215987da915Sopenharmony_ci * 216987da915Sopenharmony_ci * There are two data zones. First is the area between the end of the mft zone 217987da915Sopenharmony_ci * and the end of the volume, and second is the area between the start of the 218987da915Sopenharmony_ci * volume and the start of the mft zone. On unmodified/standard NTFS 1.x 219987da915Sopenharmony_ci * volumes, the second data zone doesn't exist due to the mft zone being 220987da915Sopenharmony_ci * expanded to cover the start of the volume in order to reserve space for the 221987da915Sopenharmony_ci * mft bitmap attribute. 222987da915Sopenharmony_ci * 223987da915Sopenharmony_ci * The complexity stems from the need of implementing the mft vs data zoned 224987da915Sopenharmony_ci * approach and from the fact that we have access to the lcn bitmap via up to 225987da915Sopenharmony_ci * NTFS_LCNALLOC_BSIZE bytes at a time, so we need to cope with crossing over 226987da915Sopenharmony_ci * boundaries of two buffers. Further, the fact that the allocator allows for 227987da915Sopenharmony_ci * caller supplied hints as to the location of where allocation should begin 228987da915Sopenharmony_ci * and the fact that the allocator keeps track of where in the data zones the 229987da915Sopenharmony_ci * next natural allocation should occur, contribute to the complexity of the 230987da915Sopenharmony_ci * function. But it should all be worthwhile, because this allocator: 231987da915Sopenharmony_ci * 1) implements MFT zone reservation 232987da915Sopenharmony_ci * 2) causes reduction in fragmentation. 233987da915Sopenharmony_ci * The code is not optimized for speed. 234987da915Sopenharmony_ci */ 235987da915Sopenharmony_cirunlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count, 236987da915Sopenharmony_ci LCN start_lcn, const NTFS_CLUSTER_ALLOCATION_ZONES zone) 237987da915Sopenharmony_ci{ 238987da915Sopenharmony_ci LCN zone_start, zone_end; /* current search range */ 239987da915Sopenharmony_ci LCN last_read_pos, lcn; 240987da915Sopenharmony_ci LCN bmp_pos; /* current bit position inside the bitmap */ 241987da915Sopenharmony_ci LCN prev_lcn = 0, prev_run_len = 0; 242987da915Sopenharmony_ci s64 clusters, br; 243987da915Sopenharmony_ci runlist *rl = NULL, *trl; 244987da915Sopenharmony_ci u8 *buf, *byte, bit, writeback; 245987da915Sopenharmony_ci u8 pass = 1; /* 1: inside zone; 2: start of zone */ 246987da915Sopenharmony_ci u8 search_zone; /* 4: data2 (start) 1: mft (middle) 2: data1 (end) */ 247987da915Sopenharmony_ci u8 done_zones = 0; 248987da915Sopenharmony_ci u8 has_guess, used_zone_pos; 249987da915Sopenharmony_ci int err = 0, rlpos, rlsize, buf_size; 250987da915Sopenharmony_ci 251987da915Sopenharmony_ci ntfs_log_enter("Entering with count = 0x%llx, start_lcn = 0x%llx, " 252987da915Sopenharmony_ci "zone = %s_ZONE.\n", (long long)count, (long long) 253987da915Sopenharmony_ci start_lcn, zone == MFT_ZONE ? "MFT" : "DATA"); 254987da915Sopenharmony_ci 255987da915Sopenharmony_ci if (!vol || count < 0 || start_lcn < -1 || !vol->lcnbmp_na || 256987da915Sopenharmony_ci (s8)zone < FIRST_ZONE || zone > LAST_ZONE) { 257987da915Sopenharmony_ci errno = EINVAL; 258987da915Sopenharmony_ci ntfs_log_perror("%s: vcn: %lld, count: %lld, lcn: %lld", 259987da915Sopenharmony_ci __FUNCTION__, (long long)start_vcn, 260987da915Sopenharmony_ci (long long)count, (long long)start_lcn); 261987da915Sopenharmony_ci goto out; 262987da915Sopenharmony_ci } 263987da915Sopenharmony_ci 264987da915Sopenharmony_ci /* Return empty runlist if @count == 0 */ 265987da915Sopenharmony_ci if (!count) { 266987da915Sopenharmony_ci rl = ntfs_malloc(0x1000); 267987da915Sopenharmony_ci if (rl) { 268987da915Sopenharmony_ci rl[0].vcn = start_vcn; 269987da915Sopenharmony_ci rl[0].lcn = LCN_RL_NOT_MAPPED; 270987da915Sopenharmony_ci rl[0].length = 0; 271987da915Sopenharmony_ci } 272987da915Sopenharmony_ci goto out; 273987da915Sopenharmony_ci } 274987da915Sopenharmony_ci 275987da915Sopenharmony_ci buf = ntfs_malloc(NTFS_LCNALLOC_BSIZE); 276987da915Sopenharmony_ci if (!buf) 277987da915Sopenharmony_ci goto out; 278987da915Sopenharmony_ci /* 279987da915Sopenharmony_ci * If no @start_lcn was requested, use the current zone 280987da915Sopenharmony_ci * position otherwise use the requested @start_lcn. 281987da915Sopenharmony_ci */ 282987da915Sopenharmony_ci has_guess = 1; 283987da915Sopenharmony_ci zone_start = start_lcn; 284987da915Sopenharmony_ci 285987da915Sopenharmony_ci if (zone_start < 0) { 286987da915Sopenharmony_ci if (zone == DATA_ZONE) 287987da915Sopenharmony_ci zone_start = vol->data1_zone_pos; 288987da915Sopenharmony_ci else 289987da915Sopenharmony_ci zone_start = vol->mft_zone_pos; 290987da915Sopenharmony_ci has_guess = 0; 291987da915Sopenharmony_ci } 292987da915Sopenharmony_ci 293987da915Sopenharmony_ci used_zone_pos = has_guess ? 0 : 1; 294987da915Sopenharmony_ci 295987da915Sopenharmony_ci if (!zone_start || zone_start == vol->mft_zone_start || 296987da915Sopenharmony_ci zone_start == vol->mft_zone_end) 297987da915Sopenharmony_ci pass = 2; 298987da915Sopenharmony_ci 299987da915Sopenharmony_ci if (zone_start < vol->mft_zone_start) { 300987da915Sopenharmony_ci zone_end = vol->mft_zone_start; 301987da915Sopenharmony_ci search_zone = ZONE_DATA2; 302987da915Sopenharmony_ci } else if (zone_start < vol->mft_zone_end) { 303987da915Sopenharmony_ci zone_end = vol->mft_zone_end; 304987da915Sopenharmony_ci search_zone = ZONE_MFT; 305987da915Sopenharmony_ci } else { 306987da915Sopenharmony_ci zone_end = vol->nr_clusters; 307987da915Sopenharmony_ci search_zone = ZONE_DATA1; 308987da915Sopenharmony_ci } 309987da915Sopenharmony_ci 310987da915Sopenharmony_ci bmp_pos = zone_start; 311987da915Sopenharmony_ci 312987da915Sopenharmony_ci /* Loop until all clusters are allocated. */ 313987da915Sopenharmony_ci clusters = count; 314987da915Sopenharmony_ci rlpos = rlsize = 0; 315987da915Sopenharmony_ci while (1) { 316987da915Sopenharmony_ci /* check whether we have exhausted the current zone */ 317987da915Sopenharmony_ci if (search_zone & vol->full_zones) 318987da915Sopenharmony_ci goto zone_pass_done; 319987da915Sopenharmony_ci last_read_pos = bmp_pos >> 3; 320987da915Sopenharmony_ci br = ntfs_attr_pread(vol->lcnbmp_na, last_read_pos, 321987da915Sopenharmony_ci NTFS_LCNALLOC_BSIZE, buf); 322987da915Sopenharmony_ci if (br <= 0) { 323987da915Sopenharmony_ci if (!br) 324987da915Sopenharmony_ci goto zone_pass_done; 325987da915Sopenharmony_ci err = errno; 326987da915Sopenharmony_ci ntfs_log_perror("Reading $BITMAP failed"); 327987da915Sopenharmony_ci goto err_ret; 328987da915Sopenharmony_ci } 329987da915Sopenharmony_ci /* 330987da915Sopenharmony_ci * We might have read less than NTFS_LCNALLOC_BSIZE bytes 331987da915Sopenharmony_ci * if we are close to the end of the attribute. 332987da915Sopenharmony_ci */ 333987da915Sopenharmony_ci buf_size = (int)br << 3; 334987da915Sopenharmony_ci lcn = bmp_pos & 7; 335987da915Sopenharmony_ci bmp_pos &= ~7; 336987da915Sopenharmony_ci writeback = 0; 337987da915Sopenharmony_ci 338987da915Sopenharmony_ci while (lcn < buf_size) { 339987da915Sopenharmony_ci byte = buf + (lcn >> 3); 340987da915Sopenharmony_ci bit = 1 << (lcn & 7); 341987da915Sopenharmony_ci if (has_guess) { 342987da915Sopenharmony_ci if (*byte & bit) { 343987da915Sopenharmony_ci has_guess = 0; 344987da915Sopenharmony_ci break; 345987da915Sopenharmony_ci } 346987da915Sopenharmony_ci } else { 347987da915Sopenharmony_ci lcn = max_empty_bit_range(buf, br); 348987da915Sopenharmony_ci if (lcn < 0) 349987da915Sopenharmony_ci break; 350987da915Sopenharmony_ci has_guess = 1; 351987da915Sopenharmony_ci continue; 352987da915Sopenharmony_ci } 353987da915Sopenharmony_ci 354987da915Sopenharmony_ci /* First free bit is at lcn + bmp_pos. */ 355987da915Sopenharmony_ci 356987da915Sopenharmony_ci /* Reallocate memory if necessary. */ 357987da915Sopenharmony_ci if ((rlpos + 2) * (int)sizeof(runlist) >= rlsize) { 358987da915Sopenharmony_ci rlsize += 4096; 359987da915Sopenharmony_ci trl = realloc(rl, rlsize); 360987da915Sopenharmony_ci if (!trl) { 361987da915Sopenharmony_ci err = ENOMEM; 362987da915Sopenharmony_ci ntfs_log_perror("realloc() failed"); 363987da915Sopenharmony_ci goto wb_err_ret; 364987da915Sopenharmony_ci } 365987da915Sopenharmony_ci rl = trl; 366987da915Sopenharmony_ci } 367987da915Sopenharmony_ci 368987da915Sopenharmony_ci /* Allocate the bitmap bit. */ 369987da915Sopenharmony_ci *byte |= bit; 370987da915Sopenharmony_ci writeback = 1; 371987da915Sopenharmony_ci if (NVolFreeSpaceKnown(vol)) { 372987da915Sopenharmony_ci if (vol->free_clusters <= 0) 373987da915Sopenharmony_ci ntfs_log_error("Non-positive free" 374987da915Sopenharmony_ci " clusters (%lld)!\n", 375987da915Sopenharmony_ci (long long)vol->free_clusters); 376987da915Sopenharmony_ci else 377987da915Sopenharmony_ci vol->free_clusters--; 378987da915Sopenharmony_ci } 379987da915Sopenharmony_ci 380987da915Sopenharmony_ci /* 381987da915Sopenharmony_ci * Coalesce with previous run if adjacent LCNs. 382987da915Sopenharmony_ci * Otherwise, append a new run. 383987da915Sopenharmony_ci */ 384987da915Sopenharmony_ci if (prev_lcn == lcn + bmp_pos - prev_run_len && rlpos) { 385987da915Sopenharmony_ci ntfs_log_debug("Cluster coalesce: prev_lcn: " 386987da915Sopenharmony_ci "%lld lcn: %lld bmp_pos: %lld " 387987da915Sopenharmony_ci "prev_run_len: %lld\n", 388987da915Sopenharmony_ci (long long)prev_lcn, 389987da915Sopenharmony_ci (long long)lcn, (long long)bmp_pos, 390987da915Sopenharmony_ci (long long)prev_run_len); 391987da915Sopenharmony_ci rl[rlpos - 1].length = ++prev_run_len; 392987da915Sopenharmony_ci } else { 393987da915Sopenharmony_ci if (rlpos) 394987da915Sopenharmony_ci rl[rlpos].vcn = rl[rlpos - 1].vcn + 395987da915Sopenharmony_ci prev_run_len; 396987da915Sopenharmony_ci else { 397987da915Sopenharmony_ci rl[rlpos].vcn = start_vcn; 398987da915Sopenharmony_ci ntfs_log_debug("Start_vcn: %lld\n", 399987da915Sopenharmony_ci (long long)start_vcn); 400987da915Sopenharmony_ci } 401987da915Sopenharmony_ci 402987da915Sopenharmony_ci rl[rlpos].lcn = prev_lcn = lcn + bmp_pos; 403987da915Sopenharmony_ci rl[rlpos].length = prev_run_len = 1; 404987da915Sopenharmony_ci rlpos++; 405987da915Sopenharmony_ci } 406987da915Sopenharmony_ci 407987da915Sopenharmony_ci ntfs_log_debug("RUN: %-16lld %-16lld %-16lld\n", 408987da915Sopenharmony_ci (long long)rl[rlpos - 1].vcn, 409987da915Sopenharmony_ci (long long)rl[rlpos - 1].lcn, 410987da915Sopenharmony_ci (long long)rl[rlpos - 1].length); 411987da915Sopenharmony_ci /* Done? */ 412987da915Sopenharmony_ci if (!--clusters) { 413987da915Sopenharmony_ci if (used_zone_pos) 414987da915Sopenharmony_ci ntfs_cluster_update_zone_pos(vol, 415987da915Sopenharmony_ci search_zone, lcn + bmp_pos + 1 + 416987da915Sopenharmony_ci NTFS_LCNALLOC_SKIP); 417987da915Sopenharmony_ci goto done_ret; 418987da915Sopenharmony_ci } 419987da915Sopenharmony_ci 420987da915Sopenharmony_ci lcn++; 421987da915Sopenharmony_ci } 422987da915Sopenharmony_ci 423987da915Sopenharmony_ci if (bitmap_writeback(vol, last_read_pos, br, buf, &writeback)) { 424987da915Sopenharmony_ci err = errno; 425987da915Sopenharmony_ci goto err_ret; 426987da915Sopenharmony_ci } 427987da915Sopenharmony_ci 428987da915Sopenharmony_ci if (!used_zone_pos) { 429987da915Sopenharmony_ci 430987da915Sopenharmony_ci used_zone_pos = 1; 431987da915Sopenharmony_ci 432987da915Sopenharmony_ci if (search_zone == ZONE_MFT) 433987da915Sopenharmony_ci zone_start = vol->mft_zone_pos; 434987da915Sopenharmony_ci else if (search_zone == ZONE_DATA1) 435987da915Sopenharmony_ci zone_start = vol->data1_zone_pos; 436987da915Sopenharmony_ci else 437987da915Sopenharmony_ci zone_start = vol->data2_zone_pos; 438987da915Sopenharmony_ci 439987da915Sopenharmony_ci if (!zone_start || zone_start == vol->mft_zone_start || 440987da915Sopenharmony_ci zone_start == vol->mft_zone_end) 441987da915Sopenharmony_ci pass = 2; 442987da915Sopenharmony_ci bmp_pos = zone_start; 443987da915Sopenharmony_ci } else 444987da915Sopenharmony_ci bmp_pos += buf_size; 445987da915Sopenharmony_ci 446987da915Sopenharmony_ci if (bmp_pos < zone_end) 447987da915Sopenharmony_ci continue; 448987da915Sopenharmony_ci 449987da915Sopenharmony_cizone_pass_done: 450987da915Sopenharmony_ci ntfs_log_trace("Finished current zone pass(%i).\n", pass); 451987da915Sopenharmony_ci if (pass == 1) { 452987da915Sopenharmony_ci pass = 2; 453987da915Sopenharmony_ci zone_end = zone_start; 454987da915Sopenharmony_ci 455987da915Sopenharmony_ci if (search_zone == ZONE_MFT) 456987da915Sopenharmony_ci zone_start = vol->mft_zone_start; 457987da915Sopenharmony_ci else if (search_zone == ZONE_DATA1) 458987da915Sopenharmony_ci zone_start = vol->mft_zone_end; 459987da915Sopenharmony_ci else 460987da915Sopenharmony_ci zone_start = 0; 461987da915Sopenharmony_ci 462987da915Sopenharmony_ci /* Sanity check. */ 463987da915Sopenharmony_ci if (zone_end < zone_start) 464987da915Sopenharmony_ci zone_end = zone_start; 465987da915Sopenharmony_ci 466987da915Sopenharmony_ci bmp_pos = zone_start; 467987da915Sopenharmony_ci 468987da915Sopenharmony_ci continue; 469987da915Sopenharmony_ci } 470987da915Sopenharmony_ci /* pass == 2 */ 471987da915Sopenharmony_cidone_zones_check: 472987da915Sopenharmony_ci done_zones |= search_zone; 473987da915Sopenharmony_ci vol->full_zones |= search_zone; 474987da915Sopenharmony_ci if (done_zones < (ZONE_MFT + ZONE_DATA1 + ZONE_DATA2)) { 475987da915Sopenharmony_ci ntfs_log_trace("Switching zone.\n"); 476987da915Sopenharmony_ci pass = 1; 477987da915Sopenharmony_ci if (rlpos) { 478987da915Sopenharmony_ci LCN tc = rl[rlpos - 1].lcn + 479987da915Sopenharmony_ci rl[rlpos - 1].length + NTFS_LCNALLOC_SKIP; 480987da915Sopenharmony_ci 481987da915Sopenharmony_ci if (used_zone_pos) 482987da915Sopenharmony_ci ntfs_cluster_update_zone_pos(vol, 483987da915Sopenharmony_ci search_zone, tc); 484987da915Sopenharmony_ci } 485987da915Sopenharmony_ci 486987da915Sopenharmony_ci switch (search_zone) { 487987da915Sopenharmony_ci case ZONE_MFT: 488987da915Sopenharmony_ci ntfs_log_trace("Zone switch: mft -> data1\n"); 489987da915Sopenharmony_ciswitch_to_data1_zone: search_zone = ZONE_DATA1; 490987da915Sopenharmony_ci zone_start = vol->data1_zone_pos; 491987da915Sopenharmony_ci zone_end = vol->nr_clusters; 492987da915Sopenharmony_ci if (zone_start == vol->mft_zone_end) 493987da915Sopenharmony_ci pass = 2; 494987da915Sopenharmony_ci break; 495987da915Sopenharmony_ci case ZONE_DATA1: 496987da915Sopenharmony_ci ntfs_log_trace("Zone switch: data1 -> data2\n"); 497987da915Sopenharmony_ci search_zone = ZONE_DATA2; 498987da915Sopenharmony_ci zone_start = vol->data2_zone_pos; 499987da915Sopenharmony_ci zone_end = vol->mft_zone_start; 500987da915Sopenharmony_ci if (!zone_start) 501987da915Sopenharmony_ci pass = 2; 502987da915Sopenharmony_ci break; 503987da915Sopenharmony_ci case ZONE_DATA2: 504987da915Sopenharmony_ci if (!(done_zones & ZONE_DATA1)) { 505987da915Sopenharmony_ci ntfs_log_trace("data2 -> data1\n"); 506987da915Sopenharmony_ci goto switch_to_data1_zone; 507987da915Sopenharmony_ci } 508987da915Sopenharmony_ci ntfs_log_trace("Zone switch: data2 -> mft\n"); 509987da915Sopenharmony_ci search_zone = ZONE_MFT; 510987da915Sopenharmony_ci zone_start = vol->mft_zone_pos; 511987da915Sopenharmony_ci zone_end = vol->mft_zone_end; 512987da915Sopenharmony_ci if (zone_start == vol->mft_zone_start) 513987da915Sopenharmony_ci pass = 2; 514987da915Sopenharmony_ci break; 515987da915Sopenharmony_ci } 516987da915Sopenharmony_ci 517987da915Sopenharmony_ci bmp_pos = zone_start; 518987da915Sopenharmony_ci 519987da915Sopenharmony_ci if (zone_start == zone_end) { 520987da915Sopenharmony_ci ntfs_log_trace("Empty zone, skipped.\n"); 521987da915Sopenharmony_ci goto done_zones_check; 522987da915Sopenharmony_ci } 523987da915Sopenharmony_ci 524987da915Sopenharmony_ci continue; 525987da915Sopenharmony_ci } 526987da915Sopenharmony_ci 527987da915Sopenharmony_ci ntfs_log_trace("All zones are finished, no space on device.\n"); 528987da915Sopenharmony_ci err = ENOSPC; 529987da915Sopenharmony_ci goto err_ret; 530987da915Sopenharmony_ci } 531987da915Sopenharmony_cidone_ret: 532987da915Sopenharmony_ci ntfs_log_debug("At done_ret.\n"); 533987da915Sopenharmony_ci /* Add runlist terminator element. */ 534987da915Sopenharmony_ci rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length; 535987da915Sopenharmony_ci rl[rlpos].lcn = LCN_RL_NOT_MAPPED; 536987da915Sopenharmony_ci rl[rlpos].length = 0; 537987da915Sopenharmony_ci if (bitmap_writeback(vol, last_read_pos, br, buf, &writeback)) { 538987da915Sopenharmony_ci err = errno; 539987da915Sopenharmony_ci goto err_ret; 540987da915Sopenharmony_ci } 541987da915Sopenharmony_cidone_err_ret: 542987da915Sopenharmony_ci free(buf); 543987da915Sopenharmony_ci if (err) { 544987da915Sopenharmony_ci errno = err; 545987da915Sopenharmony_ci ntfs_log_perror("Failed to allocate clusters"); 546987da915Sopenharmony_ci rl = NULL; 547987da915Sopenharmony_ci } 548987da915Sopenharmony_ciout: 549987da915Sopenharmony_ci ntfs_log_leave("\n"); 550987da915Sopenharmony_ci return rl; 551987da915Sopenharmony_ci 552987da915Sopenharmony_ciwb_err_ret: 553987da915Sopenharmony_ci ntfs_log_trace("At wb_err_ret.\n"); 554987da915Sopenharmony_ci if (bitmap_writeback(vol, last_read_pos, br, buf, &writeback)) 555987da915Sopenharmony_ci err = errno; 556987da915Sopenharmony_cierr_ret: 557987da915Sopenharmony_ci ntfs_log_trace("At err_ret.\n"); 558987da915Sopenharmony_ci if (rl) { 559987da915Sopenharmony_ci /* Add runlist terminator element. */ 560987da915Sopenharmony_ci rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length; 561987da915Sopenharmony_ci rl[rlpos].lcn = LCN_RL_NOT_MAPPED; 562987da915Sopenharmony_ci rl[rlpos].length = 0; 563987da915Sopenharmony_ci ntfs_debug_runlist_dump(rl); 564987da915Sopenharmony_ci ntfs_cluster_free_from_rl(vol, rl); 565987da915Sopenharmony_ci free(rl); 566987da915Sopenharmony_ci rl = NULL; 567987da915Sopenharmony_ci } 568987da915Sopenharmony_ci goto done_err_ret; 569987da915Sopenharmony_ci} 570987da915Sopenharmony_ci 571987da915Sopenharmony_ci/** 572987da915Sopenharmony_ci * ntfs_cluster_free_from_rl - free clusters from runlist 573987da915Sopenharmony_ci * @vol: mounted ntfs volume on which to free the clusters 574987da915Sopenharmony_ci * @rl: runlist from which deallocate clusters 575987da915Sopenharmony_ci * 576987da915Sopenharmony_ci * On success return 0 and on error return -1 with errno set to the error code. 577987da915Sopenharmony_ci */ 578987da915Sopenharmony_ciint ntfs_cluster_free_from_rl(ntfs_volume *vol, runlist *rl) 579987da915Sopenharmony_ci{ 580987da915Sopenharmony_ci s64 nr_freed = 0; 581987da915Sopenharmony_ci int ret = -1; 582987da915Sopenharmony_ci 583987da915Sopenharmony_ci ntfs_log_trace("Entering.\n"); 584987da915Sopenharmony_ci 585987da915Sopenharmony_ci for (; rl->length; rl++) { 586987da915Sopenharmony_ci 587987da915Sopenharmony_ci ntfs_log_trace("Dealloc lcn 0x%llx, len 0x%llx.\n", 588987da915Sopenharmony_ci (long long)rl->lcn, (long long)rl->length); 589987da915Sopenharmony_ci 590987da915Sopenharmony_ci if (rl->lcn >= 0) { 591987da915Sopenharmony_ci update_full_status(vol,rl->lcn); 592987da915Sopenharmony_ci if (ntfs_bitmap_clear_run(vol->lcnbmp_na, rl->lcn, 593987da915Sopenharmony_ci rl->length)) { 594987da915Sopenharmony_ci ntfs_log_perror("Cluster deallocation failed " 595987da915Sopenharmony_ci "(%lld, %lld)", 596987da915Sopenharmony_ci (long long)rl->lcn, 597987da915Sopenharmony_ci (long long)rl->length); 598987da915Sopenharmony_ci goto out; 599987da915Sopenharmony_ci } 600987da915Sopenharmony_ci nr_freed += rl->length ; 601987da915Sopenharmony_ci } 602987da915Sopenharmony_ci } 603987da915Sopenharmony_ci 604987da915Sopenharmony_ci ret = 0; 605987da915Sopenharmony_ciout: 606987da915Sopenharmony_ci vol->free_clusters += nr_freed; 607987da915Sopenharmony_ci if (NVolFreeSpaceKnown(vol) 608987da915Sopenharmony_ci && (vol->free_clusters > vol->nr_clusters)) 609987da915Sopenharmony_ci ntfs_log_error("Too many free clusters (%lld > %lld)!", 610987da915Sopenharmony_ci (long long)vol->free_clusters, 611987da915Sopenharmony_ci (long long)vol->nr_clusters); 612987da915Sopenharmony_ci return ret; 613987da915Sopenharmony_ci} 614987da915Sopenharmony_ci 615987da915Sopenharmony_ci/* 616987da915Sopenharmony_ci * Basic cluster run free 617987da915Sopenharmony_ci * Returns 0 if successful 618987da915Sopenharmony_ci */ 619987da915Sopenharmony_ci 620987da915Sopenharmony_ciint ntfs_cluster_free_basic(ntfs_volume *vol, s64 lcn, s64 count) 621987da915Sopenharmony_ci{ 622987da915Sopenharmony_ci s64 nr_freed = 0; 623987da915Sopenharmony_ci int ret = -1; 624987da915Sopenharmony_ci 625987da915Sopenharmony_ci ntfs_log_trace("Entering.\n"); 626987da915Sopenharmony_ci ntfs_log_trace("Dealloc lcn 0x%llx, len 0x%llx.\n", 627987da915Sopenharmony_ci (long long)lcn, (long long)count); 628987da915Sopenharmony_ci 629987da915Sopenharmony_ci if (lcn >= 0) { 630987da915Sopenharmony_ci update_full_status(vol,lcn); 631987da915Sopenharmony_ci if (ntfs_bitmap_clear_run(vol->lcnbmp_na, lcn, 632987da915Sopenharmony_ci count)) { 633987da915Sopenharmony_ci ntfs_log_perror("Cluster deallocation failed " 634987da915Sopenharmony_ci "(%lld, %lld)", 635987da915Sopenharmony_ci (long long)lcn, 636987da915Sopenharmony_ci (long long)count); 637987da915Sopenharmony_ci goto out; 638987da915Sopenharmony_ci } 639987da915Sopenharmony_ci nr_freed += count; 640987da915Sopenharmony_ci } 641987da915Sopenharmony_ci ret = 0; 642987da915Sopenharmony_ciout: 643987da915Sopenharmony_ci vol->free_clusters += nr_freed; 644987da915Sopenharmony_ci if (vol->free_clusters > vol->nr_clusters) 645987da915Sopenharmony_ci ntfs_log_error("Too many free clusters (%lld > %lld)!", 646987da915Sopenharmony_ci (long long)vol->free_clusters, 647987da915Sopenharmony_ci (long long)vol->nr_clusters); 648987da915Sopenharmony_ci return ret; 649987da915Sopenharmony_ci} 650987da915Sopenharmony_ci 651987da915Sopenharmony_ci/** 652987da915Sopenharmony_ci * ntfs_cluster_free - free clusters on an ntfs volume 653987da915Sopenharmony_ci * @vol: mounted ntfs volume on which to free the clusters 654987da915Sopenharmony_ci * @na: attribute whose runlist describes the clusters to free 655987da915Sopenharmony_ci * @start_vcn: vcn in @rl at which to start freeing clusters 656987da915Sopenharmony_ci * @count: number of clusters to free or -1 for all clusters 657987da915Sopenharmony_ci * 658987da915Sopenharmony_ci * Free @count clusters starting at the cluster @start_vcn in the runlist 659987da915Sopenharmony_ci * described by the attribute @na from the mounted ntfs volume @vol. 660987da915Sopenharmony_ci * 661987da915Sopenharmony_ci * If @count is -1, all clusters from @start_vcn to the end of the runlist 662987da915Sopenharmony_ci * are deallocated. 663987da915Sopenharmony_ci * 664987da915Sopenharmony_ci * On success return the number of deallocated clusters (not counting sparse 665987da915Sopenharmony_ci * clusters) and on error return -1 with errno set to the error code. 666987da915Sopenharmony_ci */ 667987da915Sopenharmony_ciint ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count) 668987da915Sopenharmony_ci{ 669987da915Sopenharmony_ci runlist *rl; 670987da915Sopenharmony_ci s64 delta, to_free, nr_freed = 0; 671987da915Sopenharmony_ci int ret = -1; 672987da915Sopenharmony_ci 673987da915Sopenharmony_ci if (!vol || !vol->lcnbmp_na || !na || start_vcn < 0 || 674987da915Sopenharmony_ci (count < 0 && count != -1)) { 675987da915Sopenharmony_ci ntfs_log_trace("Invalid arguments!\n"); 676987da915Sopenharmony_ci errno = EINVAL; 677987da915Sopenharmony_ci return -1; 678987da915Sopenharmony_ci } 679987da915Sopenharmony_ci 680987da915Sopenharmony_ci ntfs_log_enter("Entering for inode 0x%llx, attr 0x%x, count 0x%llx, " 681987da915Sopenharmony_ci "vcn 0x%llx.\n", (unsigned long long)na->ni->mft_no, 682987da915Sopenharmony_ci le32_to_cpu(na->type), (long long)count, (long long)start_vcn); 683987da915Sopenharmony_ci 684987da915Sopenharmony_ci rl = ntfs_attr_find_vcn(na, start_vcn); 685987da915Sopenharmony_ci if (!rl) { 686987da915Sopenharmony_ci if (errno == ENOENT) 687987da915Sopenharmony_ci ret = 0; 688987da915Sopenharmony_ci goto leave; 689987da915Sopenharmony_ci } 690987da915Sopenharmony_ci 691987da915Sopenharmony_ci if (rl->lcn < 0 && rl->lcn != LCN_HOLE) { 692987da915Sopenharmony_ci errno = EIO; 693987da915Sopenharmony_ci ntfs_log_perror("%s: Unexpected lcn (%lld)", __FUNCTION__, 694987da915Sopenharmony_ci (long long)rl->lcn); 695987da915Sopenharmony_ci goto leave; 696987da915Sopenharmony_ci } 697987da915Sopenharmony_ci 698987da915Sopenharmony_ci /* Find the starting cluster inside the run that needs freeing. */ 699987da915Sopenharmony_ci delta = start_vcn - rl->vcn; 700987da915Sopenharmony_ci 701987da915Sopenharmony_ci /* The number of clusters in this run that need freeing. */ 702987da915Sopenharmony_ci to_free = rl->length - delta; 703987da915Sopenharmony_ci if (count >= 0 && to_free > count) 704987da915Sopenharmony_ci to_free = count; 705987da915Sopenharmony_ci 706987da915Sopenharmony_ci if (rl->lcn != LCN_HOLE) { 707987da915Sopenharmony_ci /* Do the actual freeing of the clusters in this run. */ 708987da915Sopenharmony_ci update_full_status(vol,rl->lcn + delta); 709987da915Sopenharmony_ci if (ntfs_bitmap_clear_run(vol->lcnbmp_na, rl->lcn + delta, 710987da915Sopenharmony_ci to_free)) 711987da915Sopenharmony_ci goto leave; 712987da915Sopenharmony_ci nr_freed = to_free; 713987da915Sopenharmony_ci } 714987da915Sopenharmony_ci 715987da915Sopenharmony_ci /* Go to the next run and adjust the number of clusters left to free. */ 716987da915Sopenharmony_ci ++rl; 717987da915Sopenharmony_ci if (count >= 0) 718987da915Sopenharmony_ci count -= to_free; 719987da915Sopenharmony_ci 720987da915Sopenharmony_ci /* 721987da915Sopenharmony_ci * Loop over the remaining runs, using @count as a capping value, and 722987da915Sopenharmony_ci * free them. 723987da915Sopenharmony_ci */ 724987da915Sopenharmony_ci for (; rl->length && count != 0; ++rl) { 725987da915Sopenharmony_ci // FIXME: Need to try ntfs_attr_map_runlist() for attribute 726987da915Sopenharmony_ci // list support! (AIA) 727987da915Sopenharmony_ci if (rl->lcn < 0 && rl->lcn != LCN_HOLE) { 728987da915Sopenharmony_ci // FIXME: Eeek! We need rollback! (AIA) 729987da915Sopenharmony_ci errno = EIO; 730987da915Sopenharmony_ci ntfs_log_perror("%s: Invalid lcn (%lli)", 731987da915Sopenharmony_ci __FUNCTION__, (long long)rl->lcn); 732987da915Sopenharmony_ci goto out; 733987da915Sopenharmony_ci } 734987da915Sopenharmony_ci 735987da915Sopenharmony_ci /* The number of clusters in this run that need freeing. */ 736987da915Sopenharmony_ci to_free = rl->length; 737987da915Sopenharmony_ci if (count >= 0 && to_free > count) 738987da915Sopenharmony_ci to_free = count; 739987da915Sopenharmony_ci 740987da915Sopenharmony_ci if (rl->lcn != LCN_HOLE) { 741987da915Sopenharmony_ci update_full_status(vol,rl->lcn); 742987da915Sopenharmony_ci if (ntfs_bitmap_clear_run(vol->lcnbmp_na, rl->lcn, 743987da915Sopenharmony_ci to_free)) { 744987da915Sopenharmony_ci // FIXME: Eeek! We need rollback! (AIA) 745987da915Sopenharmony_ci ntfs_log_perror("%s: Clearing bitmap run failed", 746987da915Sopenharmony_ci __FUNCTION__); 747987da915Sopenharmony_ci goto out; 748987da915Sopenharmony_ci } 749987da915Sopenharmony_ci nr_freed += to_free; 750987da915Sopenharmony_ci } 751987da915Sopenharmony_ci 752987da915Sopenharmony_ci if (count >= 0) 753987da915Sopenharmony_ci count -= to_free; 754987da915Sopenharmony_ci } 755987da915Sopenharmony_ci 756987da915Sopenharmony_ci if (count != -1 && count != 0) { 757987da915Sopenharmony_ci // FIXME: Eeek! BUG() 758987da915Sopenharmony_ci errno = EIO; 759987da915Sopenharmony_ci ntfs_log_perror("%s: count still not zero (%lld)", __FUNCTION__, 760987da915Sopenharmony_ci (long long)count); 761987da915Sopenharmony_ci goto out; 762987da915Sopenharmony_ci } 763987da915Sopenharmony_ci 764987da915Sopenharmony_ci ret = nr_freed; 765987da915Sopenharmony_ciout: 766987da915Sopenharmony_ci vol->free_clusters += nr_freed ; 767987da915Sopenharmony_ci if (vol->free_clusters > vol->nr_clusters) 768987da915Sopenharmony_ci ntfs_log_error("Too many free clusters (%lld > %lld)!", 769987da915Sopenharmony_ci (long long)vol->free_clusters, 770987da915Sopenharmony_ci (long long)vol->nr_clusters); 771987da915Sopenharmony_cileave: 772987da915Sopenharmony_ci ntfs_log_leave("\n"); 773987da915Sopenharmony_ci return ret; 774987da915Sopenharmony_ci} 775