⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntfsresize.c

📁 上一个上传的有问题,这个是好的。visopsys包括系统内核和GUI的全部SOURCE code ,还包括一些基本的docs文档。里面src子目录对应所有SOURCE code.对于想研究操作系统的朋
💻 C
📖 第 1 页 / 共 5 页
字号:
/** * write_mft_record * * Write an MFT Record back to the disk.  If the read-only command line option * was given, this function will do nothing. */static int write_mft_record(ntfs_resize_t *resize, ntfs_volume *v, const MFT_REF mref, MFT_RECORD *buf){	if (ntfs_mft_record_write(v, mref, buf))	  {		err_printf(resize, "ntfs_mft_record_write failed");		return (-1);	  }//	if (v->dev->d_ops->sync(v->dev) == -1)//		perr_exit("Failed to sync device");	return 0;}static int lseek_to_cluster(ntfs_resize_t *resize, ntfs_volume *vol, s64 lcn){	off_t pos;	pos = (off_t)(lcn * vol->cluster_size);	if (vol->dev->d_ops->seek(vol->dev, pos, SEEK_SET) == (off_t)-1)	  {		err_printf(resize, "Seek failed to position %lld", lcn);		return (-1);	  }	return (0);}static int copy_clusters(ntfs_resize_t *resize, s64 dest, s64 src, s64 len){	s64 i;	char *buff = NULL; /* overflow checked at mount time */	ntfs_volume *vol = resize->vol;	if (!(buff = malloc(NTFS_MAX_CLUSTER_SIZE)))	  return (-1);	for (i = 0; i < len; i++) {		if (lseek_to_cluster(resize, vol, src + i) < 0)		    goto err_out;		if (read_all(resize, vol->dev, buff, vol->cluster_size) == -1) {			err_printf(resize, "Failed to read from the disk");			if (errno == EIO)				err_printf(resize, "%s", bad_sectors_warning_msg);			goto err_out;		}		if (lseek_to_cluster(resize, vol, dest + i) < 0)		  goto err_out;		if (write_all(vol->dev, buff, vol->cluster_size) == -1) {			err_printf(resize, "Failed to write to the disk");			if (errno == EIO)				err_printf(resize, "%s", bad_sectors_warning_msg);			goto err_out;		}		resize->relocations++;	}	free(buff);	return (0); err_out:	free(buff);	return (-1);}static int relocate_clusters(ntfs_resize_t *r, runlist *dest_rl, s64 src_lcn){	/* collect_shrink_constraints() ensured $MFTMir DATA is one run */	if (r->mref == FILE_MFTMirr && r->ctx->attr->type == AT_DATA) {		if (!r->mftmir_old) {			r->mftmir_rl.lcn = dest_rl->lcn;			r->mftmir_rl.length = dest_rl->length;			r->mftmir_old = src_lcn;		} else {			err_printf(r, "Multi-run $MFTMirr.  Please report!");			return (-1);		}	}	for (; dest_rl->length; src_lcn += dest_rl->length, dest_rl++) {		if (copy_clusters(r, dest_rl->lcn, src_lcn, dest_rl->length) < 0)			return (-1);	}	return (0);}static int rl_split_run(ntfs_resize_t *resize, runlist **rl, int run, s64 pos){	runlist *rl_new, *rle_new, *rle;	int items, new_size, size_head, size_tail;	s64 len_head, len_tail;	items = rl_items(*rl);	new_size = (items + 1) * sizeof(runlist_element);	size_head = run * sizeof(runlist_element);	size_tail = (items - run - 1) * sizeof(runlist_element);	if (!(rl_new = (runlist *)malloc(new_size)))	  {		err_printf(resize, "malloc failed");		return (-1);	  }	rle_new = rl_new + run;	rle = *rl + run;	memmove(rl_new, *rl, size_head);	memmove(rle_new + 2, rle + 1, size_tail);	len_tail = rle->length - (pos - rle->lcn);	len_head = rle->length - len_tail;	rl_set(rle_new, rle->vcn, rle->lcn, len_head);	rl_set(rle_new + 1, rle->vcn + len_head, rle->lcn + len_head, len_tail);	progress_message(resize, "Splitting run at cluster %lld:", (long long)pos);	free(*rl);	*rl = rl_new;	return (0);}static int rl_insert_at_run(ntfs_resize_t *resize, runlist **rl, int run, runlist *ins){	int items, ins_items;	int new_size, size_tail;	runlist *rle;	s64 vcn;	items  = rl_items(*rl);	ins_items = rl_items(ins) - 1;	new_size = ((items - 1) + ins_items) * sizeof(runlist_element);	size_tail = (items - run - 1) * sizeof(runlist_element);	if (!(*rl = (runlist *)realloc(*rl, new_size)))	  {		err_printf(resize, "realloc failed");		return (-1);	  }	rle = *rl + run;	memmove(rle + ins_items, rle + 1, size_tail);	for (vcn = rle->vcn; ins->length; rle++, vcn += ins->length, ins++) {		rl_set(rle, vcn, ins->lcn, ins->length);//		dump_run(rle);	}	return (0);	/* FIXME: fast path if ins_items = 1 *///	(*rl + run)->lcn = ins->lcn;}static int relocate_run(ntfs_resize_t *resize, runlist **rl, int run){	s64 lcn, lcn_length;	s64 new_vol_size;	/* (last LCN on the volume) + 1 */	runlist *relocate_rl;	/* relocate runlist to relocate_rl */	int hint;	lcn = (*rl + run)->lcn;	lcn_length = (*rl + run)->length;	new_vol_size = resize->new_volume_size;	if (lcn + lcn_length <= new_vol_size)		return (0);	if (lcn < new_vol_size) {		if (rl_split_run(resize, rl, run, new_vol_size) < 0)			return (-1);		return (0);	}	hint = (resize->mref == FILE_MFTMirr) ? 1 : 0;	if (!(relocate_rl = alloc_cluster(resize, &resize->lcn_bitmap, lcn_length,					  new_vol_size, hint)))	  {		err_printf(resize, "Cluster allocation failed for %llu:%lld",			  resize->mref, lcn_length);		return (-1);	  }	/* FIXME: check $MFTMirr DATA isn't multi-run (or support it) */	progress_message(resize, "Relocate record %llu 0x%llx->0x%llx",			 (unsigned long long)resize->mref,			 (unsigned long long)lcn,			 (unsigned long long)relocate_rl->lcn);	if (relocate_clusters(resize, relocate_rl, lcn) < 0)		return (-1);	if (rl_insert_at_run(resize, rl, run, relocate_rl) < 0)		return (-1);	/* We don't release old clusters in the bitmap, that area isn't	   used by the allocator and will be truncated later on */	free(relocate_rl);	resize->dirty_inode = DIRTY_ATTRIB;	return (0);}static int relocate_attribute(ntfs_resize_t *resize){	ATTR_RECORD *a;	runlist *rl;	int i;	a = resize->ctx->attr;	if (!a->non_resident)		return (0);	if (!(rl = ntfs_mapping_pairs_decompress(resize->vol, a, NULL))) {		err_printf(resize, "ntfs_decompress_mapping_pairs failed");		return (-1);	}	for (i = 0; rl[i].length; i++) {		s64 lcn = rl[i].lcn;		s64 lcn_length = rl[i].length;		if (lcn == LCN_HOLE || lcn == LCN_RL_NOT_MAPPED)			continue;		/* FIXME: ntfs_mapping_pairs_decompress should return error */		if (lcn < 0 || lcn_length <= 0)		  {			err_printf(resize, "Corrupt runlist in MTF %llu attr %x LCN "				 "%llx length %llx", resize->mref,				 (unsigned int)le32_to_cpu(a->type),				 lcn, lcn_length);			return (-1);		  }		if (relocate_run(resize, &rl, i) < 0)			return (-1);	}	if (resize->dirty_inode == DIRTY_ATTRIB) {		if (replace_attribute_runlist(resize, resize->vol, resize->ctx, rl) < 0)			return (-1);		resize->dirty_inode = DIRTY_INODE;	}	free(rl);	return (0);}static int is_mftdata(ntfs_resize_t *resize){	if (resize->ctx->attr->type != AT_DATA)		return 0;	if (resize->mref == 0)		return 1;	if (  MREF(resize->mrec->base_mft_record) == 0  &&	    MSEQNO(resize->mrec->base_mft_record) != 0)		return 1;	return 0;}static int handle_mftdata(ntfs_resize_t *resize, int do_mftdata){	ATTR_RECORD *attr = resize->ctx->attr;	VCN highest_vcn, lowest_vcn;	if (do_mftdata) {		if (!is_mftdata(resize))			return 0;		highest_vcn = sle64_to_cpu(attr->highest_vcn);		lowest_vcn  = sle64_to_cpu(attr->lowest_vcn);		if (resize->mft_highest_vcn != highest_vcn)			return 0;		if (lowest_vcn == 0)			resize->mft_highest_vcn = lowest_vcn;		else			resize->mft_highest_vcn = lowest_vcn - 1;	} else if (is_mftdata(resize)) {		highest_vcn = sle64_to_cpu(attr->highest_vcn);		if (resize->mft_highest_vcn < highest_vcn)			resize->mft_highest_vcn = highest_vcn;		return 0;	}	return 1;}static int relocate_attributes(ntfs_resize_t *resize, int do_mftdata){	int ret;	if (!(resize->ctx = attr_get_search_ctx(resize, NULL, resize->mrec)))		return (-1);	while (!ntfs_attrs_walk(resize->ctx)) {		if (resize->ctx->attr->type == AT_END)			break;		if (handle_mftdata(resize, do_mftdata) == 0)			continue;		ret = ntfs_inode_badclus_bad(resize->mref, resize->ctx->attr);		if (ret == -1)		  {			err_printf(resize, "Bad sector list check failed");			return (-1);		  }		else if (ret == 1)			continue;		if (resize->mref == FILE_Bitmap &&		    resize->ctx->attr->type == AT_DATA)			continue;		if (relocate_attribute(resize) < 0)			return (-1);	}	ntfs_attr_put_search_ctx(resize->ctx);	return (0);}static int relocate_inode(ntfs_resize_t *resize, MFT_REF mref, int do_mftdata){	if (ntfs_file_record_read(resize->vol, mref, &resize->mrec, NULL)) {		/* FIXME: continue only if it make sense, e.g.		   MFT record not in use based on $MFT bitmap */		if (errno == EIO || errno == ENOENT)			return (0);		err_printf(resize, "ntfs_file_record_read failed");		return (-1);	}	if (!(resize->mrec->flags & MFT_RECORD_IN_USE))		return (0);	resize->mref = mref;	resize->dirty_inode = DIRTY_NONE;	if (relocate_attributes(resize, do_mftdata) != 0)		return (-1);	if (resize->dirty_inode == DIRTY_INODE) {//		if (vol->dev->d_ops->sync(vol->dev) == -1)//			perr_exit("Failed to sync device");		if (write_mft_record(resize, resize->vol, mref, resize->mrec))		  {			err_printf(resize, "Couldn't update record %llu", mref);			return (-1);		  }	}	return (0);}static int relocate_inodes(ntfs_resize_t *resize){	s64 nr_mft_records;	MFT_REF mref;	VCN highest_vcn;	progress_message(resize, "Relocating needed data");	resize->relocations = 0;	resize->mrec = (MFT_RECORD *)malloc(resize->vol->mft_record_size);	if (!resize->mrec)	  {		err_printf(resize, "malloc failed");		return (-1);	  }	nr_mft_records = resize->vol->mft_na->initialized_size >>			resize->vol->mft_record_size_bits;	for (mref = 0; mref < (MFT_REF)nr_mft_records; mref++) {		if (relocate_inode(resize, mref, 0) != 0)			return (-1);	}	while (1) {		highest_vcn = resize->mft_highest_vcn;		mref = nr_mft_records;		do {			if (relocate_inode(resize, --mref, 1) != 0)				return (-1);			if (resize->mft_highest_vcn == 0)				goto done;		} while (mref);		if (highest_vcn == resize->mft_highest_vcn) {			err_printf(resize, "Sanity check failed!  Highest_vcn = %lld.  "				   "Please report!", highest_vcn);			return (-1);		  }	}done:	if (resize->mrec)		free(resize->mrec);	return (0);}#ifndef __VISOPSYS__static void print_hint(ntfs_volume *vol, const char *s, struct llcn_t llcn){	s64 runs_b, runs_mb;	if (llcn.lcn == 0)		return;	runs_b = llcn.lcn * vol->cluster_size;	runs_mb = rounded_up_division(runs_b, NTFS_MBYTE);	printf("%-19s: %9lld MB      %8lld\n", s, (long long)runs_mb,			(long long)llcn.inode);}/** * advise_on_resize * * The metadata file $Bitmap has one bit for each cluster on disk.  This has * already been read into lcn_bitmap.  By looking for the last used cluster on * the disk, we can work out by how much we can shrink the volume. */static void advise_on_resize(ntfs_resize_t *resize){	ntfs_volume *vol = resize->vol;	if (opt.verbose) {		printf("Estimating smallest shrunken size supported ...\n");		printf("File feature         Last used at      By inode\n");		print_hint(vol, "$MFT",		resize->last_mft);		print_hint(vol, "Multi-Record", resize->last_multi_mft);		print_hint(vol, "$MFTMirr",	resize->last_mftmir);		print_hint(vol, "Compressed",	resize->last_compressed);		print_hint(vol, "Sparse",	resize->last_sparse);		print_hint(vol, "Ordinary",	resize->last_lcn);	}	print_advise(vol, resize->last_unsupp);}#endif /* __VISOPSYS__ */static int rl_expand(ntfs_resize_t *resize, runlist **rl, const VCN last_vcn){	int len;	runlist *p = *rl;	len = rl_items(p) - 1;	if (len <= 0)	  {		err_printf(resize, "rl_expand: bad runlist length: %d", len);		return (-1);	  }	if (p[len].vcn > last_vcn)	  {		err_printf(resize, "rl_expand: length is already more than requested "			 "(%lld > %lld)", p[len].vcn, last_vcn);		return (-1);	  }	if (p[len - 1].lcn == LCN_HOLE) {		p[len - 1].length += last_vcn - p[len].vcn;		p[len].vcn = last_vcn;	} else if (p[len - 1].lcn >= 0) {		p = realloc(*rl, (++len + 1) * sizeof(runlist_element));		if (!p)		  {			err_printf(resize, "rl_expand: realloc failed");			return (-1);		  }		p[len - 1].lcn = LCN_HOLE;		p[len - 1].length = last_vcn - p[len - 1].vcn;		rl_set(p + len, last_vcn, LCN_ENOENT, 0LL);		*rl = p;	} else {		err_printf(resize, "rl_expand: bad LCN: %lld", p[len - 1].lcn);		return (-1);	}	return (0);}static int rl_truncate(ntfs_resize_t *resize, runlist **rl, const VCN last_vcn){	int len;	VCN vcn;	len = rl_items(*rl) - 1;	if (len <= 0)	  {		err_printf(resize, "rl_truncate: bad runlist length: %d", len);		return (-1);	  }	vcn = (*rl)[len].vcn;	if (vcn < last_vcn)	  {		if (rl_expand(resize, rl, last_vcn) < 0)		return (-1);	  }	else if (vcn > last_vcn)		if (ntfs_rl_truncate(rl, last_vcn) == -1)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -