📄 lcnalloc.c
字号:
ntfs_log_debug("Start_vcn: %lld\n", start_vcn); } rl[rlpos].lcn = prev_lcn = lcn + bmp_pos; rl[rlpos].length = prev_run_len = 1; rlpos++; } ntfs_log_debug("RUN: %-16lld %-16lld %-16lld\n", rl[rlpos - 1].vcn, rl[rlpos - 1].lcn, rl[rlpos - 1].length); /* Done? */ if (!--clusters) { if (used_zone_pos) ntfs_cluster_update_zone_pos(vol, search_zone, lcn + bmp_pos + 1 + NTFS_LCNALLOC_SKIP); goto done_ret; } lcn++; } if (bitmap_writeback(vol, last_read_pos, br, buf, &writeback)) { err = errno; goto err_ret; } if (!used_zone_pos) { used_zone_pos = 1; if (search_zone == 1) zone_start = vol->mft_zone_pos; else if (search_zone == 2) zone_start = vol->data1_zone_pos; else zone_start = vol->data2_zone_pos; if (!zone_start || zone_start == vol->mft_zone_start || zone_start == vol->mft_zone_end) pass = 2; bmp_pos = zone_start; } else bmp_pos += buf_size; if (bmp_pos < zone_end) continue;zone_pass_done: ntfs_log_trace("Finished current zone pass(%i).\n", pass); if (pass == 1) { pass = 2; zone_end = zone_start; if (search_zone == 1) zone_start = vol->mft_zone_start; else if (search_zone == 2) zone_start = vol->mft_zone_end; else zone_start = 0; /* Sanity check. */ if (zone_end < zone_start) zone_end = zone_start; bmp_pos = zone_start; continue; } /* pass == 2 */done_zones_check: done_zones |= search_zone; if (done_zones < 7) { ntfs_log_trace("Switching zone.\n"); pass = 1; if (rlpos) { LCN tc = tc = rl[rlpos - 1].lcn + rl[rlpos - 1].length + NTFS_LCNALLOC_SKIP; if (used_zone_pos) ntfs_cluster_update_zone_pos(vol, search_zone, tc); } switch (search_zone) { case 1: ntfs_log_trace("Zone switch: mft -> data1\n");switch_to_data1_zone: search_zone = 2; zone_start = vol->data1_zone_pos; zone_end = vol->nr_clusters; if (zone_start == vol->mft_zone_end) pass = 2; break; case 2: ntfs_log_trace("Zone switch: data1 -> data2\n"); search_zone = 4; zone_start = vol->data2_zone_pos; zone_end = vol->mft_zone_start; if (!zone_start) pass = 2; break; case 4: if (!(done_zones & 2)) { ntfs_log_trace("data2 -> data1\n"); goto switch_to_data1_zone; } ntfs_log_trace("Zone switch: data2 -> mft\n"); search_zone = 1; zone_start = vol->mft_zone_pos; zone_end = vol->mft_zone_end; if (!zone_start == vol->mft_zone_start) pass = 2; break; } bmp_pos = zone_start; if (zone_start == zone_end) { ntfs_log_trace("Empty zone, skipped.\n"); goto done_zones_check; } continue; } ntfs_log_trace("All zones are finished, no space on device.\n"); err = ENOSPC; goto err_ret; }done_ret: ntfs_log_debug("At done_ret.\n"); /* Add runlist terminator element. */ rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length; rl[rlpos].lcn = LCN_RL_NOT_MAPPED; rl[rlpos].length = 0; if (bitmap_writeback(vol, last_read_pos, br, buf, &writeback)) { err = errno; goto err_ret; }done_err_ret: free(buf); if (err) { errno = err; ntfs_log_perror("Failed to allocate clusters"); rl = NULL; }out: ntfs_log_leave("\n"); return rl;wb_err_ret: ntfs_log_trace("At wb_err_ret.\n"); if (bitmap_writeback(vol, last_read_pos, br, buf, &writeback)) err = errno;err_ret: ntfs_log_trace("At err_ret.\n"); if (rl) { /* Add runlist terminator element. */ rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length; rl[rlpos].lcn = LCN_RL_NOT_MAPPED; rl[rlpos].length = 0; ntfs_debug_runlist_dump(rl); ntfs_cluster_free_from_rl(vol, rl); free(rl); rl = NULL; } goto done_err_ret;}/** * ntfs_cluster_free_from_rl - free clusters from runlist * @vol: mounted ntfs volume on which to free the clusters * @rl: runlist from which deallocate clusters * * On success return 0 and on error return -1 with errno set to the error code. */int ntfs_cluster_free_from_rl(ntfs_volume *vol, runlist *rl){ s64 nr_freed = 0; int ret = -1; ntfs_log_trace("Entering.\n"); for (; rl->length; rl++) { ntfs_log_trace("Dealloc lcn 0x%llx, len 0x%llx.\n", (long long)rl->lcn, (long long)rl->length); if (rl->lcn >= 0) { if (ntfs_bitmap_clear_run(vol->lcnbmp_na, rl->lcn, rl->length)) { ntfs_log_perror("Cluster deallocation failed " "(%lld, %lld)", (long long)rl->lcn, (long long)rl->length); goto out; } nr_freed += rl->length ; } } ret = 0;out: vol->free_clusters += nr_freed; if (vol->free_clusters > vol->nr_clusters) ntfs_log_error("Too many free clusters (%lld > %lld)!", (long long)vol->free_clusters, (long long)vol->nr_clusters); return ret;}/** * ntfs_cluster_free - free clusters on an ntfs volume * @vol: mounted ntfs volume on which to free the clusters * @na: attribute whose runlist describes the clusters to free * @start_vcn: vcn in @rl at which to start freeing clusters * @count: number of clusters to free or -1 for all clusters * * Free @count clusters starting at the cluster @start_vcn in the runlist * described by the attribute @na from the mounted ntfs volume @vol. * * If @count is -1, all clusters from @start_vcn to the end of the runlist * are deallocated. * * On success return the number of deallocated clusters (not counting sparse * clusters) and on error return -1 with errno set to the error code. */int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count){ runlist *rl; s64 delta, to_free, nr_freed = 0; int ret = -1; if (!vol || !vol->lcnbmp_na || !na || start_vcn < 0 || (count < 0 && count != -1)) { ntfs_log_trace("Invalid arguments!\n"); errno = EINVAL; return -1; } ntfs_log_enter("Entering for inode 0x%llx, attr 0x%x, count 0x%llx, " "vcn 0x%llx.\n", (unsigned long long)na->ni->mft_no, na->type, (long long)count, (long long)start_vcn); rl = ntfs_attr_find_vcn(na, start_vcn); if (!rl) { if (errno == ENOENT) ret = 0; goto leave; } if (rl->lcn < 0 && rl->lcn != LCN_HOLE) { errno = EIO; ntfs_log_perror("%s: Unexpected lcn (%lld)", __FUNCTION__, (long long)rl->lcn); goto leave; } /* Find the starting cluster inside the run that needs freeing. */ delta = start_vcn - rl->vcn; /* The number of clusters in this run that need freeing. */ to_free = rl->length - delta; if (count >= 0 && to_free > count) to_free = count; if (rl->lcn != LCN_HOLE) { /* Do the actual freeing of the clusters in this run. */ if (ntfs_bitmap_clear_run(vol->lcnbmp_na, rl->lcn + delta, to_free)) goto leave; nr_freed = to_free; } /* Go to the next run and adjust the number of clusters left to free. */ ++rl; if (count >= 0) count -= to_free; /* * Loop over the remaining runs, using @count as a capping value, and * free them. */ for (; rl->length && count != 0; ++rl) { // FIXME: Need to try ntfs_attr_map_runlist() for attribute // list support! (AIA) if (rl->lcn < 0 && rl->lcn != LCN_HOLE) { // FIXME: Eeek! We need rollback! (AIA) errno = EIO; ntfs_log_perror("%s: Invalid lcn (%lli)", __FUNCTION__, (long long)rl->lcn); goto out; } /* The number of clusters in this run that need freeing. */ to_free = rl->length; if (count >= 0 && to_free > count) to_free = count; if (rl->lcn != LCN_HOLE) { if (ntfs_bitmap_clear_run(vol->lcnbmp_na, rl->lcn, to_free)) { // FIXME: Eeek! We need rollback! (AIA) ntfs_log_perror("%s: Clearing bitmap run failed", __FUNCTION__); goto out; } nr_freed += to_free; } if (count >= 0) count -= to_free; } if (count != -1 && count != 0) { // FIXME: Eeek! BUG() errno = EIO; ntfs_log_perror("%s: count still not zero (%lld)", __FUNCTION__, (long long)count); goto out; } ret = nr_freed;out: vol->free_clusters += nr_freed ; if (vol->free_clusters > vol->nr_clusters) ntfs_log_error("Too many free clusters (%lld > %lld)!", (long long)vol->free_clusters, (long long)vol->nr_clusters);leave: ntfs_log_leave("\n"); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -