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

📄 super.c

📁 ARM 嵌入式 系统 设计与实例开发 实验教材 二源码
💻 C
📖 第 1 页 / 共 4 页
字号:
				/* Switch from mft zone to data1 zone. */switch_to_data1_zone:		search_zone = 2;				zone_start = initial_location =						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_debug(DEBUG_OTHER, __FUNCTION__ "(): "						"Switching from data1 zone to "						"data2 zone.\n");				/* Update data1 zone position. */				if (rlpos) {					ntfs_cluster_t tc;					ntfs_debug(DEBUG_OTHER, __FUNCTION__							"(): Before checks, "							"vol->data1_zone_pos = "							"0x%x.\n",							vol->data1_zone_pos);					tc = rl2[rlpos - 1].lcn +							rl2[rlpos - 1].len;					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, __FUNCTION__							"(): After checks, "							"vol->data1_zone_pos = "							"0x%x.\n",							vol->data1_zone_pos);				}				/* Switch from data1 zone to data2 zone. */				search_zone = 4;				zone_start = initial_location =						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 =							initial_location =							(ntfs_cluster_t)0;					pass = 2;				}				break;			case 4:				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "						"Switching from data2 zone to "						"data1 zone.\n");				/* Update data2 zone position. */				if (rlpos) {					ntfs_cluster_t tc;					ntfs_debug(DEBUG_OTHER, __FUNCTION__							"(): Before checks, "							"vol->data2_zone_pos = "							"0x%x.\n",							vol->data2_zone_pos);					tc = rl2[rlpos - 1].lcn +							rl2[rlpos - 1].len;					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, __FUNCTION__							"(): After checks, "							"vol->data2_zone_pos = "							"0x%x.\n",							vol->data2_zone_pos);				}				/* Switch from data2 zone to data1 zone. */				goto switch_to_data1_zone; /* See above. */			default:				BUG();			}			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After zone "					"switch, search_zone = %i, pass = %i, "					"initial_location = 0x%x, zone_start "					"= 0x%x, zone_end = 0x%x.\n",					search_zone, pass, initial_location,					zone_start, zone_end);			buf_pos = zone_start;			if (zone_start == zone_end) {				ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): "						"Empty zone, going to "						"done_zones_check.\n");				/* Empty zone. Don't bother searching it. */				goto done_zones_check;			}			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Continuing "					"outer while loop.\n");			continue;		} /* done_zones == 7 */		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): 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_debug(DEBUG_OTHER, __FUNCTION__ "(): vol->mft_zone_start "				"= 0x%x, vol->mft_zone_end = 0x%x, "				"mft_zone_size = 0x%x.\n", vol->mft_zone_start,				vol->mft_zone_end, mft_zone_size);		if (zone == MFT_ZONE || mft_zone_size <= (ntfs_cluster_t)0) {			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): No free "					"clusters left, returning -ENOSPC, "					"going to fail_ret.\n");			/* Really no more space left on device. */			err = -ENOSPC;			goto fail_ret;		} /* zone == DATA_ZONE && mft_zone_size > 0 */		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Shrinking mft "				"zone.\n");		zone_end = vol->mft_zone_end;		mft_zone_size >>= 1;		if (mft_zone_size > (ntfs_cluster_t)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 = (ntfs_cluster_t)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 = (ntfs_cluster_t)0;		}		buf_pos = zone_start = initial_location =				vol->data1_zone_pos = vol->mft_zone_end;		search_zone = 2;		pass = 2;		done_zones &= ~2;		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After shrinking mft "				"zone, mft_zone_size = 0x%x, "				"vol->mft_zone_start = 0x%x, vol->mft_zone_end "				"= 0x%x, vol->mft_zone_pos = 0x%x, search_zone "				"= 2, pass = 2, dones_zones = 0x%x, zone_start "				"= 0x%x, zone_end = 0x%x, vol->data1_zone_pos "				"= 0x%x, continuing outer while loop.\n",				mft_zone_size, vol->mft_zone_start,				vol->mft_zone_end, vol->mft_zone_pos,				search_zone, pass, done_zones, zone_start,				zone_end, vol->data1_zone_pos);	}	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After outer while loop.\n");done_ret:	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At done_ret.\n");	rl2[rlpos].lcn = (ntfs_cluster_t)-1;	rl2[rlpos].len = (ntfs_cluster_t)0;	*rl = rl2;	*rl_len = rlpos;	if (need_writeback) {		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Writing back.\n");		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(__FUNCTION__ "(): Bitmap writeback failed "					"in done code path with error code "					"%i.\n", -err);			goto err_ret;		}		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Wrote 0x%Lx bytes.\n",				io.size);	}done_fail_ret:	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At done_fail_ret (follows "			"done_ret).\n");	unlock_kernel();	free_page((unsigned long)buf);	if (err)		ntfs_debug(DEBUG_FILE3, __FUNCTION__ "(): Failed to allocate "				"clusters. Returning with error code %i.\n",				-err);	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Syncing $Bitmap inode.\n");	if (ntfs_update_inode(vol->bitmap))		ntfs_error(__FUNCTION__ "(): Failed to sync inode $Bitmap. "				"Continuing anyway.\n");	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Returning with code %i.\n",			err);	return err;fail_ret:	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At fail_ret.\n");	if (rl2) {		if (err == -ENOSPC) {			/* Return first free lcn and count of free clusters. */			*location = rl2[0].lcn;			*count -= clusters;			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): err = "					"-ENOSPC, *location = 0x%x, *count = "					"0x%x.\n", *location, *count);		}		/* Deallocate all allocated clusters. */		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Deallocating "				"allocated clusters.\n");		ntfs_deallocate_clusters(vol, rl2, rlpos);		/* Free the runlist. */		ntfs_vfree(rl2);	} else {		if (err == -ENOSPC) {			/* Nothing free at all. */			*location = vol->data1_zone_pos; /* Irrelevant... */			*count = 0;			ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): No space "					"left at all, err = -ENOSPC, *location "					"= 0x%x, *count = 0.\n", *location);		}	}	*rl = NULL;	*rl_len = 0;	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): *rl = NULL, *rl_len = 0, "			"going to done_fail_ret.\n");	goto done_fail_ret;wb_err_ret:	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At wb_err_ret.\n");	if (need_writeback) {		int __err;		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Writing back.\n");		io.param = buf;		io.do_read = 0;		__err = ntfs_readwrite_attr(vol->bitmap, data, last_read_pos,				&io);		if (__err)			ntfs_error(__FUNCTION__ "(): Bitmap writeback failed "					"in error code path with error code "					"%i.\n", -__err);		need_writeback = 0;	}err_ret:	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At err_ret, *location = -1, "			"*count = 0, going to fail_ret.\n");	*location = -1;	*count = 0;	goto fail_ret;}/* * IMPORTANT: Caller has to hold big kernel lock or the race monster will come * to get you! (-; * TODO: Need our own lock for bitmap accesses but BKL is more secure for now, * considering we might not have covered all places with a lock yet. In that * case the BKL offers a one way exclusion which is better than no exclusion * at all... (AIA) */static int ntfs_clear_bitrange(ntfs_inode *bitmap,		const ntfs_cluster_t start_bit, const ntfs_cluster_t count){	ntfs_cluster_t buf_size, bit, nr_bits = count;	unsigned char *buf, *byte;	int err;	ntfs_io io;	io.fn_put = ntfs_put;	io.fn_get = ntfs_get;	/* Calculate the required buffer size in bytes. */	buf_size = (ntfs_cluster_t)((start_bit & 7) + nr_bits + 7) >> 3;	if (buf_size <= (ntfs_cluster_t)(64 * 1024))		buf = ntfs_malloc(buf_size);	else		buf = ntfs_vmalloc(buf_size);	if (!buf)		return -ENOMEM;	/* Read the bitmap from the data attribute. */	io.param = byte = buf;	io.size = buf_size;	err = ntfs_read_attr(bitmap, bitmap->vol->at_data, 0, start_bit >> 3,			&io);	if (err || io.size != buf_size)		goto err_out;	/* Now clear the bits in the read bitmap. */	bit = start_bit & 7;	while (bit && nr_bits) { /* Process first partial byte, if present. */		*byte &= ~(1 << bit++);		nr_bits--;		bit &= 7;		if (!bit)			byte++;	}	while (nr_bits >= 8) { /* Process full bytes. */		*byte = 0;		nr_bits -= 8;		byte++;	}	bit = 0;	while (nr_bits) { /* Process last partial byte, if present. */		*byte &= ~(1 << bit);		nr_bits--;		bit++;	}	/* Write the modified bitmap back to disk. */	io.param = buf;	io.size = buf_size;	err = ntfs_write_attr(bitmap, bitmap->vol->at_data, 0, start_bit >> 3,			&io);err_out:	if (buf_size <= (ntfs_cluster_t)(64 * 1024))		ntfs_free(buf);	else		ntfs_vfree(buf);	if (!err && io.size != buf_size)		err = -EIO;	return err;}/* * See comments for lack of zone adjustments below in the description of the * function ntfs_deallocate_clusters(). */int ntfs_deallocate_cluster_run(const ntfs_volume *vol,		const ntfs_cluster_t lcn, const ntfs_cluster_t len){	int err;	lock_kernel();	err = ntfs_clear_bitrange(vol->bitmap, lcn, len);	unlock_kernel();	return err;}/* * This is inefficient, but logically trivial, so will do for now. Note, we * do not touch the mft nor the data zones here because we want to minimize * recycling of clusters to enhance the chances of data being undeleteable. * Also we don't want the overhead. Instead we do one additional sweep of the * current data zone during cluster allocation to check for freed clusters. */int ntfs_deallocate_clusters(const ntfs_volume *vol, const ntfs_runlist *rl,		const int rl_len){	int i, err;	lock_kernel();	for (i = err = 0; i < rl_len && !err; i++)		err = ntfs_clear_bitrange(vol->bitmap, rl[i].lcn, rl[i].len);	unlock_kernel();	return err;}

⌨️ 快捷键说明

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