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

📄 inode.c

📁 EM85XX读NTFS修正代码包
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (bmp->initialized << 3 > nr_mft_records &&				bmp->initialized > 3) {			/*			 * The mft bitmap is already bigger but the space is			 * not covered by mft records, this implies that the			 * next records are all free, so we already have found			 * a free record.			 */			bit = nr_mft_records;			if (bit < 24UL)				bit = 24UL;			ntfs_debug(DEBUG_OTHER, "%s(): Found free record bit "					"(#1) = 0x%lx.\n", __FUNCTION__, bit);			goto found_free_rec;		}		ntfs_debug(DEBUG_OTHER, "%s(): Done pass 2.\n", __FUNCTION__);		ntfs_debug(DEBUG_OTHER, "%s(): Before: bmp->allocated = 0x%Lx, "				"bmp->size = 0x%Lx, bmp->initialized = "				"0x%Lx.\n", __FUNCTION__, bmp->allocated,				bmp->size, bmp->initialized);		/* Need to extend the mft bitmap. */		if (bmp->initialized + 8LL > bmp->allocated) {			ntfs_io io2;			ntfs_debug(DEBUG_OTHER, "%s(): Initialized "					"> allocated.\n", __FUNCTION__);			/* Need to extend bitmap by one more cluster. */			rl = bmp->d.r.runlist;			rlen = bmp->d.r.len - 1;			lcn = rl[rlen].lcn + rl[rlen].len;			io2.fn_put = ntfs_put;			io2.fn_get = ntfs_get;			io2.param = &b;			io2.size = 1;			io2.do_read = 1;			err = ntfs_readwrite_attr(vol->bitmap, data, lcn >> 3,					&io2);			if (err)				goto err_ret;			ntfs_debug(DEBUG_OTHER, "%s(): Read %lu bytes.\n",					__FUNCTION__, (unsigned long)io2.size);			if (io2.size == 1 && b != 0xff) {				__u8 tb = 1 << (lcn & (ntfs_cluster_t)7);				if (!(b & tb)) {					/* Next cluster is free. Allocate it. */					b |= tb;					io2.param = &b;					io2.do_read = 0;					err = ntfs_readwrite_attr(vol->bitmap,							data, lcn >> 3, &io2);					if (err || io.size != 1) {						if (!err)							err = -EIO;						goto err_ret;					}append_mftbmp_simple:			rl[rlen].len++;					have_allocated_mftbmp |= 1;					ntfs_debug(DEBUG_OTHER, "%s(): "							"Appending one cluster "							"to mftbmp.\n",							__FUNCTION__);				}			}			if (!have_allocated_mftbmp) {				/* Allocate a cluster from the DATA_ZONE. */				ntfs_cluster_t lcn2 = lcn;				ntfs_cluster_t count = 1;				err = ntfs_allocate_clusters(vol, &lcn2,						&count, &rl2, &r2len,						DATA_ZONE);				if (err)					goto err_ret;				if (count != 1 || lcn2 <= 0) {					if (count > 0) {rl2_dealloc_err_out:				if (ntfs_deallocate_clusters(							vol, rl2, r2len))							ntfs_error("%s(): "							"Cluster "							"deallocation in error "							"code path failed! You "							"should run chkdsk.\n",							__FUNCTION__);					}					ntfs_vfree(rl2);					if (!err)						err = -EINVAL;					goto err_ret;				}				if (lcn2 == lcn) {					ntfs_vfree(rl2);					goto append_mftbmp_simple;				}				/* We need to append a new run. */				rl_size = (rlen * sizeof(ntfs_runlist) +						PAGE_SIZE - 1) & PAGE_MASK;				/* Reallocate memory if necessary. */				if ((rlen + 2) * sizeof(ntfs_runlist) >=						rl_size) {					ntfs_runlist *rlt;					rl_size += PAGE_SIZE;					rlt = ntfs_vmalloc(rl_size);					if (!rlt) {						err = -ENOMEM;						goto rl2_dealloc_err_out;					}					ntfs_memcpy(rlt, rl, rl_size -							PAGE_SIZE);					ntfs_vfree(rl);					bmp->d.r.runlist = rl = rlt;				}				ntfs_vfree(rl2);				rl[rlen].lcn = lcn = lcn2;				rl[rlen].len = count;				bmp->d.r.len = ++rlen;				have_allocated_mftbmp |= 2;				ntfs_debug(DEBUG_OTHER, "%s(): Adding run to "						"mftbmp. LCN = %i, len = %i\n",						__FUNCTION__, lcn, count);			}			/*			 * We now have extended the mft bitmap allocated size			 * by one cluster. Reflect this in the attribute.			 */			bmp->allocated += (__s64)vol->cluster_size;		}		ntfs_debug(DEBUG_OTHER, "%s(): After: bmp->allocated = 0x%Lx, "				"bmp->size = 0x%Lx, bmp->initialized = "				"0x%Lx.\n", __FUNCTION__, bmp->allocated,				bmp->size, bmp->initialized);		/* We now have sufficient allocated space. */		ntfs_debug(DEBUG_OTHER, "%s(): Now have sufficient allocated "				"space in mftbmp.\n", __FUNCTION__);		ntfs_debug(DEBUG_OTHER, "%s(): Before: bmp->allocated = 0x%Lx, "				"bmp->size = 0x%Lx, bmp->initialized = "				"0x%Lx.\n", __FUNCTION__, bmp->allocated,				bmp->size, bmp->initialized);		buf_pos = bmp->initialized;		bmp->initialized += 8LL;		if (bmp->initialized > bmp->size)			bmp->size = bmp->initialized;		ntfs_debug(DEBUG_OTHER, "%s(): After: bmp->allocated = 0x%Lx, "				"bmp->size = 0x%Lx, bmp->initialized = "				"0x%Lx.\n", __FUNCTION__, bmp->allocated,				bmp->size, bmp->initialized);		have_allocated_mftbmp |= 4;		/* Update the mft bitmap attribute value. */		memset(buf, 0, 8);		io.param = buf;		io.size = 8;		io.do_read = 0;		err = ntfs_readwrite_attr(vol->mft_ino, bmp, buf_pos, &io);		if (err || io.size != 8) {			if (!err)				err = -EIO;			goto shrink_mftbmp_err_ret;		}		ntfs_debug(DEBUG_OTHER, "%s(): Wrote extended mftbmp bytes "				"%lu.\n", __FUNCTION__, (unsigned long)io.size);		ntfs_debug(DEBUG_OTHER, "%s(): After write: bmp->allocated = "				"0x%Lx, bmp->size = 0x%Lx, bmp->initialized = "				"0x%Lx.\n", __FUNCTION__, bmp->allocated,				bmp->size, bmp->initialized);		bit = buf_pos << 3;		ntfs_debug(DEBUG_OTHER, "%s(): Found free record bit (#2) = "				"0x%lx.\n", __FUNCTION__, bit);		goto found_free_rec;	}found_free_rec:	/* bit is the found free mft record. Allocate it in the mft bitmap. */	vol->mft_data_pos = bit;	ntfs_debug(DEBUG_OTHER, "%s(): At found_free_rec.\n", __FUNCTION__);	io.param = buf;	io.size = 1;	io.do_read = 1;	ntfs_debug(DEBUG_OTHER, "%s(): Before update: bmp->allocated = 0x%Lx, "			"bmp->size = 0x%Lx, bmp->initialized = 0x%Lx.\n",			__FUNCTION__, bmp->allocated,			bmp->size, bmp->initialized);	err = ntfs_readwrite_attr(vol->mft_ino, bmp, bit >> 3, &io);	if (err || io.size != 1) {		if (!err)			err = -EIO;		goto shrink_mftbmp_err_ret;	}	ntfs_debug(DEBUG_OTHER, "%s(): Read %lu bytes.\n", __FUNCTION__,			(unsigned long)io.size);#ifdef DEBUG	/* Check our bit is really zero! */	if (*buf & (1 << (bit & 7)))		BUG();#endif	*buf |= 1 << (bit & 7);	io.param = buf;	io.do_read = 0;	err = ntfs_readwrite_attr(vol->mft_ino, bmp, bit >> 3, &io);	if (err || io.size != 1) {		if (!err)			err = -EIO;		goto shrink_mftbmp_err_ret;	}	ntfs_debug(DEBUG_OTHER, "%s(): Wrote %lu bytes.\n", __FUNCTION__,			(unsigned long)io.size);	ntfs_debug(DEBUG_OTHER, "%s(): After update: bmp->allocated = 0x%Lx, "			"bmp->size = 0x%Lx, bmp->initialized = 0x%Lx.\n",			__FUNCTION__, bmp->allocated,			bmp->size, bmp->initialized);	/* The mft bitmap is now uptodate. Deal with mft data attribute now. */	ll = (__s64)(bit + 1) << vol->mft_record_size_bits;	if (ll <= data->initialized) {		/* The allocated record is already initialized. We are done! */		ntfs_debug(DEBUG_OTHER, "%s(): Allocated mft record "				"already initialized!\n", __FUNCTION__);		goto done_ret;	}	ntfs_debug(DEBUG_OTHER, "%s(): Allocated mft record needs "			"to be initialized.\n", __FUNCTION__);	/* The mft record is outside the initialized data. */	mft_rec_size = (unsigned long)vol->mft_record_size;	/* Preserve old values for undo purposes. */	old_data_allocated = data->allocated;	old_data_rlen = data->d.r.len - 1;	old_data_len = data->d.r.runlist[old_data_rlen].len;	/*	 * If necessary, extend the mft until it covers the allocated record.	 * The loop is only actually used when a freshly formatted volume is	 * first written to. But it optimizes away nicely in the common case.	 */	while (ll > data->allocated) {		ntfs_cluster_t lcn2, nr_lcn2, nr, min_nr;		ntfs_debug(DEBUG_OTHER, "%s(): Extending mft data allocation, "				"data->allocated = 0x%Lx, data->size = 0x%Lx, "				"data->initialized = 0x%Lx.\n", __FUNCTION__,				data->allocated, data->size, data->initialized);		/* Minimum allocation is one mft record worth of clusters. */		if (mft_rec_size <= vol->cluster_size)			min_nr = (ntfs_cluster_t)1;		else			min_nr = mft_rec_size >> vol->cluster_size_bits;		ntfs_debug(DEBUG_OTHER, "%s(): min_nr = %i.\n", __FUNCTION__,				min_nr);		/* Allocate 16 mft records worth of clusters. */		nr = mft_rec_size << 4 >> vol->cluster_size_bits;		if (!nr)			nr = (ntfs_cluster_t)1;		/* Determine the preferred allocation location. */		ntfs_debug(DEBUG_OTHER, "%s(): nr = %i.\n", __FUNCTION__, nr);		rl2 = data->d.r.runlist;		r2len = data->d.r.len;		lcn2 = rl2[r2len - 1].lcn + rl2[r2len - 1].len;		ntfs_debug(DEBUG_OTHER, "%s(): rl2[r2len - 1].lcn = %i, .len = "				"%i.\n", __FUNCTION__, rl2[r2len - 1].lcn,				rl2[r2len - 1].len);		ntfs_debug(DEBUG_OTHER, "%s(): lcn2 = %i, r2len = %i.\n",				__FUNCTION__, lcn2, r2len);retry_mft_data_allocation:		nr_lcn2 = nr;		err = ntfs_allocate_clusters(vol, &lcn2, &nr_lcn2, &rl2,				&r2len, MFT_ZONE);#ifdef DEBUG		if (!err && nr_lcn2 < min_nr)			/* Allocated less than minimum needed. Weird! */			BUG();#endif		if (err) {			/*			 * If there isn't enough space to do the wanted			 * allocation, but there is enough space to do a			 * minimal allocation, then try that, unless the wanted			 * allocation was already the minimal allocation.			 */			if (err == -ENOSPC && nr > min_nr &&					nr_lcn2 >= min_nr) {				nr = min_nr;				ntfs_debug(DEBUG_OTHER, "%s(): Retrying mft "						"data allocation, nr = min_nr "						"= %i.\n", __FUNCTION__, nr);				goto retry_mft_data_allocation;			}			goto undo_mftbmp_alloc_err_ret;		}		ntfs_debug(DEBUG_OTHER, "%s(): Allocated %i clusters starting "				"at LCN %i.\n", __FUNCTION__, nr_lcn2, lcn2);		ntfs_debug(DEBUG_OTHER, "%s(): Allocated runlist:\n",				__FUNCTION__);		dump_runlist(rl2, r2len);		/* Append rl2 to the mft data attribute's run list. */		err = splice_runlists(&data->d.r.runlist, (int*)&data->d.r.len,				rl2, r2len);		if (err) {			ntfs_debug(DEBUG_OTHER, "%s(): splice_runlists failed "					"with error code %i.\n", __FUNCTION__,					-err);			goto undo_partial_data_alloc_err_ret;		}		/* Reflect the allocated clusters in the mft allocated data. */		data->allocated += nr_lcn2 << vol->cluster_size_bits;		ntfs_debug(DEBUG_OTHER, "%s(): After extending mft data "				"allocation, data->allocated = 0x%Lx, "				"data->size = 0x%Lx, data->initialized = "				"0x%Lx.\n", __FUNCTION__, data->allocated,				data->size, data->initialized);	}	/* Prepare a formatted (empty) mft record. */	memset(buf, 0, mft_rec_size);	ntfs_fill_mft_header(buf, mft_rec_size, 0, 0, 0);	err = ntfs_insert_fixups(buf, mft_rec_size);	if (err)		goto undo_data_alloc_err_ret;	/*	 * Extend mft data initialized size to reach the allocated mft record	 * and write the formatted mft record buffer to each mft record being	 * initialized. Note, that ntfs_readwrite_attr extends both	 * data->initialized and data->size, so no need for us to touch them.	 */	old_data_initialized = data->initialized;	old_data_size = data->size;	while (ll > data->initialized) {		ntfs_debug(DEBUG_OTHER, "%s(): Initializing mft record "				"0x%Lx.\n", __FUNCTION__, 				data->initialized >> vol->mft_record_size_bits);		io.param = buf;		io.size = mft_rec_size;		io.do_read = 0;		err = ntfs_readwrite_attr(vol->mft_ino, data,				data->initialized, &io);		if (err || io.size != mft_rec_size) {			if (!err)				err = -EIO;			goto undo_data_init_err_ret;		}		ntfs_debug(DEBUG_OTHER, "%s(): Wrote %i bytes to mft data.\n",				__FUNCTION__, io.size);	}	/* Update the VFS inode size as well. */	VFS_I(vol->mft_ino)->i_size = data->size;#ifdef DEBUG	ntfs_debug(DEBUG_OTHER, "%s(): After mft record "			"initialization: data->allocated = 0x%Lx, data->size "			"= 0x%Lx, data->initialized = 0x%Lx.\n", __FUNCTION__,			data->allocated, data->size, data->initialized);	/* Sanity checks. */	if (data->size > data->allocated || data->size < data->initialized ||			data->initialized > data->allocated)		BUG();#endifdone_ret:	/* Return the number of the allocated mft record. */	ntfs_debug(DEBUG_OTHER, "%s(): At done_ret. *result = bit = 0x%lx.\n",			__FUNCTION__, bit);	*result = bit;	vol->mft_data_pos = bit + 1;err_ret:	unlock_kernel();	free_page((unsigned long)buf);	ntfs_debug(DEBUG_OTHER, "%s(): Syncing inode $MFT.\n", __FUNCTION__);	if (ntfs_update_inode(vol->mft_ino))		ntfs_error("%s(): Failed to sync inode $MFT. "				"Continuing anyway.\n",__FUNCTION__);	if (!err) {		ntfs_debug(DEBUG_FILE3, "%s(): Done. Allocated mft record "				"number *result = 0x%lx.\n", __FUNCTION__,				*result);		return 0;	}	if (err != -ENOSPC)		ntfs_error("%s(): Failed to allocate an mft record. Returning "				"error code %i.\n", __FUNCTION__, -err);	else		ntfs_debug(DEBUG_FILE3, "%s(): Failed to allocate an mft "				"record due to lack of free space.\n",				__FUNCTION__);	return err;undo_data_init_err_ret:	ntfs_debug(DEBUG_OTHER, "%s(): At undo_data_init_err_ret.\n",			__FUNCTION__);	data->initialized = old_data_initialized;	data->size = old_data_size;undo_data_alloc_err_ret:	ntfs_debug(DEBUG_OTHER, "%s(): At undo_data_alloc_err_ret.\n",			__FUNCTION__);	data->allocated = old_data_allocated;undo_partial_data_alloc_err_ret:	ntfs_debug(DEBUG_OTHER, "%s(): At undo_partial_data_alloc_err_ret.\n",			__FUNCTION__);	/* Deallocate the clusters. */	if (ntfs_deallocate_clusters(vol, rl2, r2len))		ntfs_error("%s(): Error deallocating clusters in error code "			"path. You should run chkdsk.\n", __FUNCTION__);	ntfs_vfree(rl2);	/* Revert the run list back to what it was before. */	r2len = data->d.r.len;	rl2 = data->d.r.runlist;	rl2[old_data_rlen++].len = old_data_len;	rl2[old_data_rlen].lcn = (ntfs_cluster_t)-1;	rl2[old_data_rlen].len = (ntfs_cluster_t)0;	data->d.r.len = old_data_rlen;	rl2_size = ((old_data_rlen + 1) * sizeof(ntfs_runlist) + PAGE_SIZE -			1) & PAGE_MASK;	/* Reallocate memory freeing any extra memory allocated. */	if (rl2_size < ((r2len * sizeof(ntfs_runlist) + PAGE_SIZE - 1) &			PAGE_MASK)) {		rl2 = ntfs_vmalloc(rl2_size);		if (rl2) {			ntfs_memcpy(rl2, data->d.r.runlist, rl2_size);			ntfs_vfre

⌨️ 快捷键说明

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