📄 super.c
字号:
} else /* if (zone == MFT_ZONE) */ { zone_end = vol->mft_zone_end; search_zone = 1; } /* * buf_pos is the current bit position inside the bitmap. We use * initial_location to determine whether or not to do a zone switch. */ buf_pos = initial_location = zone_start; /* Loop until all clusters are allocated, i.e. clusters == 0. */ clusters = *count; rlpos = rlsize = 0; if (*count <= 0) { ntfs_debug(DEBUG_OTHER, "%s(): *count <= 0, " "returning -EINVAL.\n", __FUNCTION__); err = -EINVAL; goto err_ret; } while (1) { ntfs_debug(DEBUG_OTHER, "%s(): Start of outer while " "loop: done_zones = 0x%x, search_zone = %i, " "pass = %i, zone_start = 0x%x, zone_end = " "0x%x, initial_location = 0x%x, buf_pos = " "0x%x, rlpos = %i, rlsize = %i.\n", __FUNCTION__, done_zones, search_zone, pass, zone_start, zone_end, initial_location, buf_pos, rlpos, rlsize); /* Loop until we run out of free clusters. */ io.param = buf; io.size = PAGE_SIZE; io.do_read = 1; last_read_pos = buf_pos >> 3; ntfs_debug(DEBUG_OTHER, "%s(): last_read_pos = 0x%x.\n", __FUNCTION__, last_read_pos); err = ntfs_readwrite_attr(vol->bitmap, data, last_read_pos, &io); if (err) { ntfs_debug(DEBUG_OTHER, "%s(): ntfs_read_attr failed " "with error code %i, going to " "err_ret.\n", __FUNCTION__, -err); goto err_ret; } if (!io.size) { ntfs_debug(DEBUG_OTHER, "%s(): !io.size, going to " "zone_pass_done.\n", __FUNCTION__); goto zone_pass_done; } buf_size = io.size << 3; lcn = buf_pos & 7; buf_pos &= ~7; need_writeback = 0; ntfs_debug(DEBUG_OTHER, "%s(): Before inner while " "loop: buf_size = 0x%x, lcn = 0x%x, buf_pos = " "0x%x, need_writeback = %i.\n", __FUNCTION__, buf_size, lcn, buf_pos, need_writeback); while (lcn < buf_size && lcn + buf_pos < zone_end) { byte = buf + (lcn >> 3); ntfs_debug(DEBUG_OTHER, "%s(): In inner while loop: " "buf_size = 0x%x, lcn = 0x%x, buf_pos " "= 0x%x, need_writeback = %i, byte ofs " "= 0x%x, *byte = 0x%x.\n", __FUNCTION__, buf_size, lcn, buf_pos, need_writeback, lcn >> 3, *byte); /* Skip full bytes. */ if (*byte == 0xff) { lcn += 8; ntfs_debug(DEBUG_OTHER, "%s(): continuing while" " loop 1.\n", __FUNCTION__); continue; } bit = 1 << (lcn & 7); ntfs_debug(DEBUG_OTHER, "%s(): bit = %i.\n", __FUNCTION__, bit); /* If the bit is already set, go onto the next one. */ if (*byte & bit) { lcn++; ntfs_debug(DEBUG_OTHER, "%s(): continuing while" " loop 2.\n", __FUNCTION__); continue; } /* Allocate the bitmap bit. */ *byte |= bit; /* We need to write this bitmap buffer back to disk! */ need_writeback = 1; ntfs_debug(DEBUG_OTHER, "%s(): *byte = 0x%x, " "need_writeback = %i.\n", __FUNCTION__, *byte, need_writeback); /* Reallocate memory if necessary. */ if ((rlpos + 2) * sizeof(ntfs_runlist) >= rlsize) { ntfs_debug(DEBUG_OTHER, "%s(): Reallocating " "space.\n", __FUNCTION__); /* Setup first free bit return value. */ if (!rl2) { *location = lcn + buf_pos; ntfs_debug(DEBUG_OTHER, "%s(): " "*location = 0x%x.\n", __FUNCTION__, *location); } rlsize += PAGE_SIZE; rlt = ntfs_vmalloc(rlsize); if (!rlt) { err = -ENOMEM; ntfs_debug(DEBUG_OTHER, "%s(): Failed " "to allocate memory, " "returning -ENOMEM, " "going to wb_err_ret.\n", __FUNCTION__); goto wb_err_ret; } if (rl2) { ntfs_memcpy(rlt, rl2, rlsize - PAGE_SIZE); ntfs_vfree(rl2); } rl2 = rlt; ntfs_debug(DEBUG_OTHER, "%s(): Reallocated " "memory, rlsize = 0x%x.\n", __FUNCTION__, rlsize); } /* * Coalesce with previous run if adjacent LCNs. * Otherwise, append a new run. */ ntfs_debug(DEBUG_OTHER, "%s(): Adding run (lcn 0x%x, " "len 0x%x), prev_lcn = 0x%x, lcn = " "0x%x, buf_pos = 0x%x, prev_run_len = " "0x%x, rlpos = %i.\n", __FUNCTION__, lcn + buf_pos, 1, prev_lcn, lcn, buf_pos, prev_run_len, rlpos); if (prev_lcn == lcn + buf_pos - prev_run_len && rlpos) { ntfs_debug(DEBUG_OTHER, "%s(): Coalescing to " "run (lcn 0x%x, len 0x%x).\n", __FUNCTION__, rl2[rlpos - 1].lcn, rl2[rlpos - 1].len); rl2[rlpos - 1].len = ++prev_run_len; ntfs_debug(DEBUG_OTHER, "%s(): Run now (lcn " "0x%x, len 0x%x), prev_run_len " "= 0x%x.\n", __FUNCTION__, rl2[rlpos - 1].lcn, rl2[rlpos - 1].len, prev_run_len); } else { if (rlpos) ntfs_debug(DEBUG_OTHER, "%s(): Adding " "new run, (previous " "run lcn 0x%x, " "len 0x%x).\n", __FUNCTION__, rl2[rlpos - 1].lcn, rl2[rlpos - 1].len); else ntfs_debug(DEBUG_OTHER, "%s(): Adding " "new run, is first " "run.\n", __FUNCTION__); rl2[rlpos].lcn = prev_lcn = lcn + buf_pos; rl2[rlpos].len = prev_run_len = (ntfs_cluster_t)1; rlpos++; } /* Done? */ if (!--clusters) { ntfs_cluster_t tc; /* * Update the current zone position. Positions * of already scanned zones have been updated * during the respective zone switches. */ tc = lcn + buf_pos + 1; ntfs_debug(DEBUG_OTHER, "%s(): Done. Updating " "current zone position, tc = " "0x%x, search_zone = %i.\n", __FUNCTION__, tc, search_zone); switch (search_zone) { case 1: ntfs_debug(DEBUG_OTHER, "%s(): Before checks, " "vol->mft_zone_pos = " "0x%x.\n", __FUNCTION__, vol->mft_zone_pos); if (tc >= vol->mft_zone_end) { vol->mft_zone_pos = vol->mft_lcn; if (!vol->mft_zone_end) vol->mft_zone_pos = (ntfs_cluster_t)0; } else if ((initial_location >= vol->mft_zone_pos || tc > vol->mft_zone_pos) && tc >= vol->mft_lcn) vol->mft_zone_pos = tc; ntfs_debug(DEBUG_OTHER, "%s(): After checks, " "vol->mft_zone_pos = " "0x%x.\n", __FUNCTION__, vol->mft_zone_pos); break; case 2: ntfs_debug(DEBUG_OTHER, "%s(): Before checks, " "vol->data1_zone_pos = " "0x%x.\n", __FUNCTION__, vol->data1_zone_pos); if (tc >= vol->nr_clusters) vol->data1_zone_pos = vol->mft_zone_end; else if ((initial_location >= vol->data1_zone_pos || tc > vol->data1_zone_pos) && tc >= vol->mft_zone_end) vol->data1_zone_pos = tc; ntfs_debug(DEBUG_OTHER, "%s(): After checks, " "vol->data1_zone_pos = " "0x%x.\n", __FUNCTION__, vol->data1_zone_pos); break; case 4: ntfs_debug(DEBUG_OTHER, "%s(): Before checks, " "vol->data2_zone_pos = " "0x%x.\n", __FUNCTION__, vol->data2_zone_pos); if (tc >= vol->mft_zone_start) vol->data2_zone_pos = (ntfs_cluster_t)0; else if (initial_location >= vol->data2_zone_pos || tc > vol->data2_zone_pos) vol->data2_zone_pos = tc; ntfs_debug(DEBUG_OTHER, "%s(): After checks, " "vol->data2_zone_pos = " "0x%x.\n", __FUNCTION__, vol->data2_zone_pos); break; default: BUG(); } ntfs_debug(DEBUG_OTHER, "%s(): Going to " "done_ret.\n", __FUNCTION__); goto done_ret; } lcn++; } buf_pos += buf_size; ntfs_debug(DEBUG_OTHER, "%s(): After inner while " "loop: buf_size = 0x%x, lcn = 0x%x, buf_pos = " "0x%x, need_writeback = %i.\n", __FUNCTION__, buf_size, lcn, buf_pos, need_writeback); if (need_writeback) { ntfs_debug(DEBUG_OTHER, "%s(): Writing back.\n", __FUNCTION__); need_writeback = 0; io.param = buf; io.do_read = 0; err = ntfs_readwrite_attr(vol->bitmap, data, last_read_pos, &io); if (err) { ntfs_error("%s(): Bitmap writeback failed " "in read next buffer code " "path with error code %i.\n", __FUNCTION__, -err); goto err_ret; } } if (buf_pos < zone_end) { ntfs_debug(DEBUG_OTHER, "%s(): Continuing " "outer while loop, buf_pos = 0x%x, " "zone_end = 0x%x.\n", __FUNCTION__, buf_pos, zone_end); continue; }zone_pass_done: /* Finished with the current zone pass. */ ntfs_debug(DEBUG_OTHER, "%s(): At zone_pass_done, pass = %i.\n", __FUNCTION__, pass); if (pass == 1) { /* * Now do pass 2, scanning the first part of the zone * we omitted in pass 1. */ pass = 2; zone_end = zone_start; switch (search_zone) { case 1: /* mft_zone */ zone_start = vol->mft_zone_start; break; case 2: /* data1_zone */ zone_start = vol->mft_zone_end; break; case 4: /* data2_zone */ zone_start = (ntfs_cluster_t)0; break; default: BUG(); } /* Sanity check. */ if (zone_end < zone_start) zone_end = zone_start; buf_pos = zone_start; ntfs_debug(DEBUG_OTHER, "%s(): Continuing " "outer while loop, pass = 2, " "zone_start = 0x%x, zone_end = 0x%x, " "buf_pos = 0x%x.\n", __FUNCTION__, zone_start, zone_end, buf_pos); continue; } /* pass == 2 */done_zones_check: ntfs_debug(DEBUG_OTHER, "%s(): At done_zones_check, " "search_zone = %i, done_zones before = 0x%x, " "done_zones after = 0x%x.\n", __FUNCTION__, search_zone, done_zones, done_zones | search_zone); done_zones |= search_zone; if (done_zones < 7) { ntfs_debug(DEBUG_OTHER, "%s(): Switching zone.\n", __FUNCTION__); /* Now switch to the next zone we haven't done yet. */ pass = 1; switch (search_zone) { case 1: ntfs_debug(DEBUG_OTHER, "%s(): Switching from " "mft zone to data1 zone.\n", __FUNCTION__); /* Update mft zone position. */ if (rlpos) { ntfs_cluster_t tc; ntfs_debug(DEBUG_OTHER, "%s(): Before checks, " "vol->mft_zone_pos = " "0x%x.\n", __FUNCTION__, vol->mft_zone_pos); tc = rl2[rlpos - 1].lcn + rl2[rlpos - 1].len; if (tc >= vol->mft_zone_end) { vol->mft_zone_pos = vol->mft_lcn; if (!vol->mft_zone_end) vol->mft_zone_pos = (ntfs_cluster_t)0; } else if ((initial_location >= vol->mft_zone_pos || tc > vol->mft_zone_pos) && tc >= vol->mft_lcn) vol->mft_zone_pos = tc; ntfs_debug(DEBUG_OTHER, "%s(): After checks, " "vol->mft_zone_pos = " "0x%x.\n", __FUNCTION__, vol->mft_zone_pos); } /* Switch from mft zone to data1 zone. */switch_to_data1_zone: search_zone = 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -