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

📄 ntfsresize.c

📁 上一个上传的有问题,这个是好的。visopsys包括系统内核和GUI的全部SOURCE code ,还包括一些基本的docs文档。里面src子目录对应所有SOURCE code.对于想研究操作系统的朋
💻 C
📖 第 1 页 / 共 5 页
字号:
			if (resize->prog && resize->prog->cancel)			  {			    free(bm);			    return (0);			  }				if (a->size <= pos)				goto done;			if (a->bm[pos] == bm[i])				continue;			for (cl = pos * 8; cl < (pos + 1) * 8; cl++) {				char bit;				bit = ntfs_bit_get(a->bm, cl);				if (bit == ntfs_bit_get(bm, i * 8 + cl % 8))					continue;				if (!mismatch && !bit && !backup_boot &&						cl == vol->nr_clusters / 2) {					/* FIXME: call also boot sector check */					backup_boot = 1;					progress_message(resize, "Found backup boot sector in "					       "the middle of the volume.");					continue;				}				if (++mismatch > 10)					continue;				progress_message(resize, "Cluster accounting failed at %lld "						"(0x%llx): %s cluster in "						"$Bitmap", (long long)cl,						(unsigned long long)cl,						bit ? "missing" : "extra");			}		}	}done:	free(bm);	if (mismatch) {		err_printf(resize, "Filesystem check failed!  Total of %d "			   "cluster accounting mismatches.", mismatch);		err_printf(resize, "%s", corrupt_volume_msg);		return (-1);	}	return (0);}#ifndef __VISOPSYS__/** * progress_init * * Create and scale our progress bar. */static void progress_init(struct progress_bar *p, u64 start, u64 stop, int flags){	p->start = start;	p->stop = stop;	p->unit = 100.0 / (stop - start);	p->resolution = 100;	p->flags = flags;}/** * progress_update * * Update the progress bar and tell the user. */static void progress_update(struct progress_bar *p, u64 current){	float percent;	if (!(p->flags & NTFS_PROGBAR))		return;	if (p->flags & NTFS_PROGBAR_SUPPRESS)		return;	/* WARNING: don't modify the texts, external tools grep for them */	percent = p->unit * current;	if (current != p->stop) {		if ((current - p->start) % p->resolution)			return;		printf("%6.2f percent completed\r", percent);	} else		printf("100.00 percent completed\n");	fflush(stdout);}#endif /* __VISOPSYS__ */static int inode_close(ntfs_resize_t *resize, ntfs_inode *ni){	if (ntfs_inode_close(ni)) {		err_printf(resize, "ntfs_inode_close for inode %llu failed",			    (unsigned long long)ni->mft_no);		return -1;	}	return 0;}/** * walk_inodes * * Read each record in the MFT, skipping the unused ones, and build up a bitmap * from all the non-resident attributes. */static int build_allocation_bitmap(ntfs_resize_t *resize, ntfs_volume *vol, ntfsck_t *fsck){	s64 nr_mft_records, inode = 0;	ntfs_inode *ni;	nr_mft_records = vol->mft_na->initialized_size >>			vol->mft_record_size_bits;	progress_message(resize, "Checking filesystem consistency");	for (; inode < nr_mft_records; inode++) {		progress_update(resize->prog, RSZPCNT_CHECK, inode,				(nr_mft_records - 1));		if (resize->prog && resize->prog->cancel)			return (0);		if ((ni = ntfs_inode_open(vol, (MFT_REF)inode)) == NULL) {			/* FIXME: continue only if it make sense, e.g.			   MFT record not in use based on $MFT bitmap */			if (errno == EIO || errno == ENOENT)				continue;			err_printf(resize, "Reading inode %lld failed", inode);			return -1;		}		if (ni->mrec->base_mft_record)			goto close_inode;		fsck->ni = ni;		if (walk_attributes(resize, vol, fsck) != 0) {			inode_close(resize, ni);			return -1;		}close_inode:		if (inode_close(resize, ni) != 0)			return -1;	}	return 0;}static int build_resize_constraints(ntfs_resize_t *resize){	s64 i;	runlist *rl;	if (!resize->ctx->attr->non_resident)		return (0);	if (!(rl = ntfs_mapping_pairs_decompress(resize->vol,						 resize->ctx->attr, NULL)))	  {		err_printf(resize, "ntfs_decompress_mapping_pairs failed");		return (-1);	  }	for (i = 0; rl[i].length; i++) {		/* CHECKME: LCN_RL_NOT_MAPPED check isn't needed */		if (rl[i].lcn == LCN_HOLE || rl[i].lcn == LCN_RL_NOT_MAPPED)			continue;		if (collect_resize_constraints(resize, rl + i) < 0)		  return (-1);		if (resize->shrink)			if (collect_relocation_info(resize, rl + i) != 0)			  return (-1);	}	free(rl);	return (0);}static int resize_constraints_by_attributes(ntfs_resize_t *resize){	if (!(resize->ctx = attr_get_search_ctx(resize, resize->ni, NULL)))	  return (-1);	while (!ntfs_attrs_walk(resize->ctx)) {		if (resize->ctx->attr->type == AT_END)			break;		if (build_resize_constraints(resize) != 0)		  return (-1);	}	ntfs_attr_put_search_ctx(resize->ctx);	return (0);}static int set_resize_constraints(ntfs_resize_t *resize){	s64 nr_mft_records, inode;	ntfs_inode *ni;	progress_message(resize, "Collecting resizing constraints");	nr_mft_records = resize->vol->mft_na->initialized_size >>			resize->vol->mft_record_size_bits;	for (inode = 0; inode < nr_mft_records; inode++) {		ni = ntfs_inode_open(resize->vol, (MFT_REF)inode);		if (ni == NULL) {			if (errno == EIO || errno == ENOENT)				continue;			err_printf(resize, "Reading inode %lld failed", inode);			return (-1);		}		if (ni->mrec->base_mft_record)			goto close_inode;		resize->ni = ni;		if (resize_constraints_by_attributes(resize) != 0)		  return (-1);close_inode:		if (inode_close(resize, ni) != 0)			return (-1);		progress_update(resize->prog, RSZPCNT_SETRSZCONST, inode,				nr_mft_records);		if (resize->prog && resize->prog->cancel)		  return (0);	}	return (0);}static int rl_fixup(ntfs_resize_t *resize, runlist **rl){	runlist *tmp = *rl;	if (tmp->lcn == LCN_RL_NOT_MAPPED) {		s64 unmapped_len = tmp->length;		progress_message(resize, "Skip unmapped run at the beginning ...");		if (!tmp->length)		  {			err_printf(resize, "Empty unmapped runlist!  Please report!");			return (-1);		  }		(*rl)++;		for (tmp = *rl; tmp->length; tmp++)			tmp->vcn -= unmapped_len;	}	for (tmp = *rl; tmp->length; tmp++) {		if (tmp->lcn == LCN_RL_NOT_MAPPED) {			progress_message(resize, "Skip unmapped run at the end  ...");			if (tmp[1].length)			  {				err_printf(resize, "Unmapped runlist in the middle!  "					 "Please report!");				return (-1);			  }			tmp->lcn = LCN_ENOENT;			tmp->length = 0;		}	}	return (0);}static int replace_attribute_runlist(ntfs_resize_t *resize, ntfs_volume *vol,				      ntfs_attr_search_ctx *ctx,				      runlist *rl){	int mp_size, l;	void *mp;	ATTR_RECORD *a = ctx->attr;	if (rl_fixup(resize, &rl) != 0)	  return (-1);	if ((mp_size = ntfs_get_size_for_mapping_pairs(vol, rl, 0)) == -1)	  {		err_printf(resize, "ntfs_get_size_for_mapping_pairs failed");		return (-1);	  }	if (a->name_length) {		u16 name_offs = le16_to_cpu(a->name_offset);		u16 mp_offs = le16_to_cpu(a->mapping_pairs_offset);		if (name_offs >= mp_offs)		  {			err_printf(resize, "Attribute name is after mapping pairs!  "				 "Please report!");			return (-1);		  }	}	/* CHECKME: don't trust mapping_pairs is always the last item in the	   attribute, instead check for the real size/space */	l = (int)le32_to_cpu(a->length) - le16_to_cpu(a->mapping_pairs_offset);	if (mp_size > l) {		s64 remains_size;		char *next_attr;		progress_message(resize, "Enlarging attribute header ...");		mp_size = (mp_size + 7) & ~7;		ntfs_log_verbose("Old mp size      : %d\n", l);		ntfs_log_verbose("New mp size      : %d\n", mp_size);		ntfs_log_verbose("Bytes in use     : %u\n", (unsigned int)				 le32_to_cpu(ctx->mrec->bytes_in_use));		next_attr = (char *)a + le16_to_cpu(a->length);		l = mp_size - l;		ntfs_log_verbose("Bytes in use new : %u\n", l + (unsigned int)				 le32_to_cpu(ctx->mrec->bytes_in_use));		ntfs_log_verbose("Bytes allocated  : %u\n", (unsigned int)				 le32_to_cpu(ctx->mrec->bytes_allocated));		remains_size = le32_to_cpu(ctx->mrec->bytes_in_use);		remains_size -= (next_attr - (char *)ctx->mrec);		ntfs_log_verbose("increase         : %d\n", l);		ntfs_log_verbose("shift            : %lld\n",				 (long long)remains_size);		if (le32_to_cpu(ctx->mrec->bytes_in_use) + l >				le32_to_cpu(ctx->mrec->bytes_allocated))		  {			err_printf(resize, "Extended record needed (%u > %u), not yet "				 "supported!  Please try to free less space.",				 (unsigned int)le32_to_cpu(ctx->mrec->					bytes_in_use) + l,				 (unsigned int)le32_to_cpu(ctx->mrec->					bytes_allocated));			return (-1);		  }		memmove(next_attr + l, next_attr, remains_size);		ctx->mrec->bytes_in_use = cpu_to_le32(l +				le32_to_cpu(ctx->mrec->bytes_in_use));		a->length += l;	}	if (!(mp = calloc(1, mp_size)))	  {		err_printf(resize, "Couldn't get memory");		return (-1);	  }	if (ntfs_mapping_pairs_build(vol, mp, mp_size, rl, 0, NULL))	  {		err_printf(resize, "ntfs_mapping_pairs_build failed");		return (-1);	  }	memmove((u8*)a + le16_to_cpu(a->mapping_pairs_offset), mp, mp_size);	free(mp);	return (0);}static void set_bitmap_range(struct bitmap *bm, s64 pos, s64 length, u8 bit){	while (length--)		ntfs_bit_set(bm->bm, pos++, bit);}static void set_bitmap_clusters(struct bitmap *bm, runlist *rl, u8 bit){	for (; rl->length; rl++)		set_bitmap_range(bm, rl->lcn, rl->length, bit);}static void release_bitmap_clusters(struct bitmap *bm, runlist *rl){	max_free_cluster_range = 0;	set_bitmap_clusters(bm, rl, 0);}static void set_max_free_zone(s64 length, s64 end, runlist_element *rle){	if (length > rle->length) {		rle->lcn = end - length;		rle->length = length;	}}static int find_free_cluster(ntfs_resize_t *resize, struct bitmap *bm,			     runlist_element *rle,			     s64 nr_vol_clusters,			     int hint){	/* FIXME: get rid of this 'static' variable */	static s64 pos = 0;	s64 i, items = rle->length;	s64 free_zone = 0;	if (pos >= nr_vol_clusters)		pos = 0;	if (!max_free_cluster_range)		max_free_cluster_range = nr_vol_clusters;	rle->lcn = rle->length = 0;	if (hint)		pos = nr_vol_clusters / 2;	i = pos;	do {		if (!ntfs_bit_get(bm->bm, i)) {			if (++free_zone == items) {				set_max_free_zone(free_zone, i + 1, rle);				break;			}		} else {			set_max_free_zone(free_zone, i, rle);			free_zone = 0;		}		if (++i == nr_vol_clusters) {			set_max_free_zone(free_zone, i, rle);			i = free_zone = 0;		}		if (rle->length == max_free_cluster_range)			break;	} while (i != pos);	if (i)		set_max_free_zone(free_zone, i, rle);	if (!rle->lcn) {		errno = ENOSPC;		return -1;	}	if (rle->length < items && rle->length < max_free_cluster_range) {		max_free_cluster_range = rle->length;		progress_message(resize, "Max free range: %lld",				 (long long)max_free_cluster_range);	}	pos = rle->lcn + items;	if (pos == nr_vol_clusters)		pos = 0;	set_bitmap_range(bm, rle->lcn, rle->length, 1);	return 0;}static runlist *alloc_cluster(ntfs_resize_t *resize, struct bitmap *bm,			      s64 items,			      s64 nr_vol_clusters,			      int hint){	runlist_element rle;	runlist *rl = NULL;	int rl_size, runs = 0;	s64 vcn = 0;	if (items <= 0) {		errno = EINVAL;		return NULL;	}	while (items > 0) {		if (runs)			hint = 0;		rle.length = items;		if (find_free_cluster(resize, bm, &rle, nr_vol_clusters, hint) == -1)			return NULL;		rl_size = (runs + 2) * sizeof(runlist_element);		if (!(rl = (runlist *)realloc(rl, rl_size)))			return NULL;		rl_set(rl + runs, vcn, rle.lcn, rle.length);		vcn += rle.length;		items -= rle.length;		runs++;	}	rl_set(rl + runs, vcn, -1LL, 0LL);	return rl;}static int read_all(ntfs_resize_t *resize, struct ntfs_device *dev, void *buf, int count){	int i;	while (count > 0) {		i = count;		if (!NDevReadOnly(dev))			i = dev->d_ops->read(dev, buf, count);		if (i < 0) {			if (errno != EAGAIN && errno != EINTR)				return -1;		} else if (i > 0) {			count -= i;			buf = i + (char *)buf;		} else {			err_printf(resize, "Unexpected end of file!");			return (-1);		}	}	return 0;}static int write_all(struct ntfs_device *dev, void *buf, int count){	int i;	while (count > 0) {		i = count;		if (!NDevReadOnly(dev))			i = dev->d_ops->write(dev, buf, count);		if (i < 0) {			if (errno != EAGAIN && errno != EINTR)				return -1;		} else {			count -= i;			buf = i + (char *)buf;		}	}	return 0;}

⌨️ 快捷键说明

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