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

📄 lcnalloc.c

📁 上一个上传的有问题,这个是好的。visopsys包括系统内核和GUI的全部SOURCE code ,还包括一些基本的docs文档。里面src子目录对应所有SOURCE code.对于想研究操作系统的朋
💻 C
📖 第 1 页 / 共 2 页
字号:
			/*			 * 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 = 0;				break;			default:				NTFS_BUG("switch (search_zone) 2");			}			/* Sanity check. */			if (zone_end < zone_start)				zone_end = zone_start;			bmp_pos = zone_start;			ntfs_log_trace("Continuing outer while loop, pass = 2, "					"zone_start = 0x%llx, zone_end = "					"0x%llx, bmp_pos = 0x%llx.\n",					zone_start, zone_end, bmp_pos);			continue;		} /* pass == 2 */done_zones_check:		ntfs_log_trace("At done_zones_check, search_zone = %i, done_zones "				"before = 0x%x, done_zones after = 0x%x.\n",				search_zone, done_zones, done_zones | search_zone);		done_zones |= search_zone;		if (done_zones < 7) {			ntfs_log_trace("Switching zone.\n");			/* Now switch to the next zone we haven't done yet. */			pass = 1;			switch (search_zone) {			case 1:				ntfs_log_trace("Switching from mft zone to data1 "						"zone.\n");				/* Update mft zone position. */				if (rlpos) {					LCN tc;					ntfs_log_trace("Before checks, vol->mft_zone_pos = 0x%llx.\n",							(long long) vol->mft_zone_pos);					tc = rl[rlpos - 1].lcn +							rl[rlpos - 1].length;					if (tc >= vol->mft_zone_end) {						vol->mft_zone_pos =								vol->mft_lcn;						if (!vol->mft_zone_end)							vol->mft_zone_pos = 0;					} else if ((bmp_initial_pos >=							vol->mft_zone_pos ||							tc > vol->mft_zone_pos)							&& tc >= vol->mft_lcn)						vol->mft_zone_pos = tc;					ntfs_log_trace("After checks, vol->mft_zone_pos = 0x%llx.\n",							(long long) vol->mft_zone_pos);				}				/* Switch from mft zone to data1 zone. */switch_to_data1_zone:		search_zone = 2;				zone_start = bmp_initial_pos =						vol->data1_zone_pos;				zone_end = vol->nr_clusters;				if (zone_start == vol->mft_zone_end)					pass = 2;				if (zone_start >= zone_end) {					vol->data1_zone_pos = zone_start =							vol->mft_zone_end;					pass = 2;				}				break;			case 2:				ntfs_log_trace("Switching from data1 zone to data2 "						"zone.\n");				/* Update data1 zone position. */				if (rlpos) {					LCN tc;					ntfs_log_trace("Before checks, vol->data1_zone_pos = 0x%llx.\n",							(long long) vol->data1_zone_pos);					tc = rl[rlpos - 1].lcn +							rl[rlpos - 1].length;					if (tc >= vol->nr_clusters)						vol->data1_zone_pos =							     vol->mft_zone_end;					else if ((bmp_initial_pos >=						    vol->data1_zone_pos ||						    tc > vol->data1_zone_pos)						    && tc >= vol->mft_zone_end)						vol->data1_zone_pos = tc;					ntfs_log_trace("After checks, vol->data1_zone_pos = 0x%llx.\n",							(long long) vol->data1_zone_pos);				}				/* Switch from data1 zone to data2 zone. */				search_zone = 4;				zone_start = bmp_initial_pos =						vol->data2_zone_pos;				zone_end = vol->mft_zone_start;				if (!zone_start)					pass = 2;				if (zone_start >= zone_end) {					vol->data2_zone_pos = zone_start =							bmp_initial_pos = 0;					pass = 2;				}				break;			case 4:				ntfs_log_debug("Switching from data2 zone to data1 "						"zone.\n");				/* Update data2 zone position. */				if (rlpos) {					LCN tc;					ntfs_log_trace("Before checks, vol->data2_zone_pos = 0x%llx.\n",							(long long) vol->data2_zone_pos);					tc = rl[rlpos - 1].lcn +							rl[rlpos - 1].length;					if (tc >= vol->mft_zone_start)						vol->data2_zone_pos = 0;					else if (bmp_initial_pos >=						      vol->data2_zone_pos ||						      tc > vol->data2_zone_pos)						vol->data2_zone_pos = tc;					ntfs_log_trace("After checks, vol->data2_zone_pos = 0x%llx.\n",							(long long) vol->data2_zone_pos);				}				/* Switch from data2 zone to data1 zone. */				goto switch_to_data1_zone; /* See above. */			default:				NTFS_BUG("switch (search_zone) 3");			}			ntfs_log_trace("After zone switch, search_zone = %i, pass = "					"%i, bmp_initial_pos = 0x%llx, "					"zone_start = 0x%llx, zone_end = "					"0x%llx.\n", search_zone, pass,					(long long)bmp_initial_pos,					(long long)zone_start,					(long long)zone_end);			bmp_pos = zone_start;			if (zone_start == zone_end) {				ntfs_log_trace("Empty zone, going to "						"done_zones_check.\n");				/* Empty zone. Don't bother searching it. */				goto done_zones_check;			}			ntfs_log_trace("Continuing outer while loop.\n");			continue;		} /* done_zones == 7 */		ntfs_log_trace("All zones are finished.\n");		/*		 * All zones are finished! If DATA_ZONE, shrink mft zone. If		 * MFT_ZONE, we have really run out of space.		 */		mft_zone_size = vol->mft_zone_end - vol->mft_zone_start;		ntfs_log_trace("vol->mft_zone_start = 0x%llx, vol->mft_zone_end = "				"0x%llx, mft_zone_size = 0x%llx.\n",				(long long)vol->mft_zone_start,				(long long)vol->mft_zone_end,				(long long)mft_zone_size);		if (zone == MFT_ZONE || mft_zone_size <= 0) {			ntfs_log_trace("No free clusters left, going to err_ret.\n");			/* Really no more space left on device. */			err = ENOSPC;			goto err_ret;		} /* zone == DATA_ZONE && mft_zone_size > 0 */		ntfs_log_trace("Shrinking mft zone.\n");		zone_end = vol->mft_zone_end;		mft_zone_size >>= 1;		if (mft_zone_size > 0)			vol->mft_zone_end = vol->mft_zone_start + mft_zone_size;		else /* mft zone and data2 zone no longer exist. */			vol->data2_zone_pos = vol->mft_zone_start =					vol->mft_zone_end = 0;		if (vol->mft_zone_pos >= vol->mft_zone_end) {			vol->mft_zone_pos = vol->mft_lcn;			if (!vol->mft_zone_end)				vol->mft_zone_pos = 0;		}		bmp_pos = zone_start = bmp_initial_pos =				vol->data1_zone_pos = vol->mft_zone_end;		search_zone = 2;		pass = 2;		done_zones &= ~2;		ntfs_log_trace("After shrinking mft zone, mft_zone_size = 0x%llx, "				"vol->mft_zone_start = 0x%llx, "				"vol->mft_zone_end = 0x%llx, vol->mft_zone_pos "				"= 0x%llx, search_zone = 2, pass = 2, "				"dones_zones = 0x%x, zone_start = 0x%llx, "				"zone_end = 0x%llx, vol->data1_zone_pos = "				"0x%llx, continuing outer while loop.\n",				(long long)mft_zone_size,				(long long)vol->mft_zone_start,				(long long)vol->mft_zone_end,				(long long)vol->mft_zone_pos,				done_zones,				(long long)zone_start,				(long long)zone_end,				(long long)vol->data1_zone_pos);	}	ntfs_log_debug("After outer while loop.\n");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 (need_writeback) {		s64 bw;		ntfs_log_trace("Writing back.\n");		need_writeback = 0;		bw = ntfs_attr_pwrite(vol->lcnbmp_na, last_read_pos, br, buf);		if (bw != br) {			if (bw < 0)				err = errno;			else				err = EIO;			ntfs_log_trace("Bitmap writeback failed in done code path "					"with error code %i.\n", err);			goto err_ret;		}	}done_err_ret:	ntfs_log_debug("At done_err_ret (follows done_ret).\n");	free(buf);	/* Done! */	if (!err)		return rl;	ntfs_log_trace("Failed to allocate clusters. Returning with error code "			"%i.\n", err);	errno = err;	return NULL;wb_err_ret:	ntfs_log_trace("At wb_err_ret.\n");	if (need_writeback) {		s64 bw;		ntfs_log_trace("Writing back.\n");		need_writeback = 0;		bw = ntfs_attr_pwrite(vol->lcnbmp_na, last_read_pos, br, buf);		if (bw != br) {			if (bw < 0)				err = errno;			else				err = EIO;			ntfs_log_trace("Bitmap writeback failed in error code path "					"with error code %i.\n", err);		}	}err_ret:	ntfs_log_trace("At err_ret.\n");	if (rl) {		if (err == ENOSPC) {			ntfs_log_trace("err = ENOSPC, first free lcn = 0x%llx, could "					"allocate up to = 0x%llx clusters.\n",					(long long)rl[0].lcn,					(long long)count - clusters);		}		/* 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;		/* Deallocate all allocated clusters. */		ntfs_log_trace("Deallocating allocated clusters.\n");		ntfs_cluster_free_from_rl(vol, rl);		/* Free the runlist. */		free(rl);		rl = NULL;	} else {		if (err == ENOSPC) {			ntfs_log_trace("No space left at all, err = ENOSPC, first "					"free lcn = 0x%llx.\n",					(long long)vol->data1_zone_pos);		}	}	ntfs_log_trace("rl = NULL, going to done_err_ret.\n");	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){	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 && ntfs_bitmap_clear_run(vol->lcnbmp_na,				rl->lcn, rl->length)) {			int eo = errno;			ntfs_log_trace("Eeek! Deallocation of clusters failed.\n");			errno = eo;			return -1;		}	}	return 0;}/** * 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 nr_freed, delta, to_free;	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_trace("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)			return 0;		else			return -1;	}	if (rl->lcn < 0 && rl->lcn != LCN_HOLE) {		errno = EIO;		return -1;	}	/* 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))			return -1;		/* We have freed @to_free real clusters. */		nr_freed = to_free;	} else {		/* No real clusters were freed. */		nr_freed = 0;	}	/* 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)			ntfs_log_trace("Eeek! invalid lcn (= %lli).  Should attempt "					"to map runlist!  Leaving inconsistent "					"metadata!\n", (long long)rl->lcn);			errno = EIO;			return -1;		}		/* 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) {			/* Do the actual freeing of the clusters in the run. */			if (ntfs_bitmap_clear_run(vol->lcnbmp_na, rl->lcn,					to_free)) {				int eo = errno;				// FIXME: Eeek! We need rollback! (AIA)				ntfs_log_trace("Eeek!  bitmap clear run failed.  "						"Leaving inconsistent metadata!\n");				errno = eo;				return -1;			}			/* We have freed @to_free real clusters. */			nr_freed += to_free;		}		if (count >= 0)			count -= to_free;	}	if (count != -1 && count != 0) {		// FIXME: Eeek! BUG()		ntfs_log_trace("Eeek!  count still not zero (= %lli).  Leaving "				"inconsistent metadata!\n", (long long)count);		errno = EIO;		return -1;	}	/* Done. Return the number of actual clusters that were freed. */	return nr_freed;}

⌨️ 快捷键说明

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