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

📄 inode.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 5 页
字号:
			 * 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, __FUNCTION__ "(): Found free "					"record bit (#1) = 0x%lx.\n", bit);			goto found_free_rec;		}		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Done pass 2.\n");		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before: "				"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "				"bmp->initialized = 0x%Lx.\n", 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, __FUNCTION__ "(): Initialized "					"> allocated.\n");			/* 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, __FUNCTION__ "(): Read %lu "					"bytes.\n", (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, __FUNCTION__							"(): Appending one "							"cluster to mftbmp.\n");				}			}			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(__FUNCTION__							"(): Cluster "							"deallocation in error "							"code path failed! You "							"should run chkdsk.\n");					}					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, __FUNCTION__ "(): "						"Adding run to mftbmp. "						"LCN = %i, len = %i\n", 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, __FUNCTION__ "(): After: "				"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "				"bmp->initialized = 0x%Lx.\n", bmp->allocated,				bmp->size, bmp->initialized);		/* We now have sufficient allocated space. */		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Now have sufficient "				"allocated space in mftbmp.\n");		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before: "				"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "				"bmp->initialized = 0x%Lx.\n", 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, __FUNCTION__ "(): After: "				"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "				"bmp->initialized = 0x%Lx.\n", 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, __FUNCTION__ "(): Wrote extended "				"mftbmp bytes %lu.\n", (unsigned long)io.size);		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After write: "				"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "				"bmp->initialized = 0x%Lx.\n", bmp->allocated,				bmp->size, bmp->initialized);		bit = buf_pos << 3;		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Found free record "				"bit (#2) = 0x%lx.\n", 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, __FUNCTION__ "(): At found_free_rec.\n");	io.param = buf;	io.size = 1;	io.do_read = 1;	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Before update: "			"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "			"bmp->initialized = 0x%Lx.\n", 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, __FUNCTION__ "(): Read %lu bytes.\n",			(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, __FUNCTION__ "(): Wrote %lu bytes.\n",			(unsigned long)io.size);	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After update: "			"bmp->allocated = 0x%Lx, bmp->size = 0x%Lx, "			"bmp->initialized = 0x%Lx.\n", 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, __FUNCTION__ "(): Allocated mft record "				"already initialized!\n");		goto done_ret;	}	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Allocated mft record needs "			"to be initialized.\n");	/* 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, __FUNCTION__ "(): Extending mft "				"data allocation, data->allocated = 0x%Lx, "				"data->size = 0x%Lx, data->initialized = "				"0x%Lx.\n", 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, __FUNCTION__ "(): min_nr = %i.\n",				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, __FUNCTION__ "(): nr = %i.\n", nr);		rl2 = data->d.r.runlist;		r2len = data->d.r.len;		lcn2 = rl2[r2len - 1].lcn + rl2[r2len - 1].len;		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): rl2[r2len - 1].lcn "				"= %i, .len = %i.\n", rl2[r2len - 1].lcn,				rl2[r2len - 1].len);		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): lcn2 = %i, r2len = "				"%i.\n", 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, __FUNCTION__ "(): "						"Retrying mft data "						"allocation, nr = min_nr = %i"						".\n", nr);				goto retry_mft_data_allocation;			}			goto undo_mftbmp_alloc_err_ret;		}		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Allocated %i "				"clusters starting at LCN %i.\n", nr_lcn2,				lcn2);		ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Allocated "				"runlist:\n");		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, __FUNCTION__ "(): "					"splice_runlists failed with error "					"code %i.\n", -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, __FUNCTION__ "(): After extending mft "				"data allocation, data->allocated = 0x%Lx, "				"data->size = 0x%Lx, data->initialized = "				"0x%Lx.\n", 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, __FUNCTION__ "(): Initializing mft "				"record 0x%Lx.\n",				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, __FUNCTION__ "(): Wrote %i bytes to "				"mft data.\n", io.size);	}	/* Update the VFS inode size as well. */	VFS_I(vol->mft_ino)->i_size = data->size;#ifdef DEBUG	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): After mft record "			"initialization: data->allocated = 0x%Lx, data->size "			"= 0x%Lx, data->initialized = 0x%Lx.\n",			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, __FUNCTION__ "(): At done_ret. *result = bit = "			"0x%lx.\n", bit);	*result = bit;	vol->mft_data_pos = bit + 1;err_ret:	unlock_kernel();	free_page((unsigned long)buf);	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): Syncing inode $MFT.\n");	if (ntfs_update_inode(vol->mft_ino))		ntfs_error(__FUNCTION__ "(): Failed to sync inode $MFT. "				"Continuing anyway.\n");	if (!err) {		ntfs_debug(DEBUG_FILE3, __FUNCTION__ "(): Done. Allocated mft "				"record number *result = 0x%lx.\n", *result);		return 0;	}	if (err != -ENOSPC)		ntfs_error(__FUNCTION__ "(): Failed to allocate an mft "				"record. Returning error code %i.\n", -err);	else		ntfs_debug(DEBUG_FILE3, __FUNCTION__ "(): Failed to allocate "				"an mft record due to lack of free space.\n");	return err;undo_data_init_err_ret:	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At "			"undo_data_init_err_ret.\n");	data->initialized = old_data_initialized;	data->size = old_data_size;undo_data_alloc_err_ret:	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At undo_data_alloc_err_ret."			"\n");	data->allocated = old_data_allocated;undo_partial_data_alloc_err_ret:	ntfs_debug(DEBUG_OTHER, __FUNCTION__ "(): At "			"undo_partial_data_alloc_err_ret.\n");	/* Deallocate the clusters. */	if (ntfs_deallocate_clusters(vol, rl2, r2len))		ntfs_error(__FUNCTION__ "(): Error deallocating clusters in "				"error code path. You should run chkdsk.\n");	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_vfree(data->d.r.runlist);			data->d.r.runlist = rl2;		} else			ntfs_error(__FUNCTION__ "(): Error reallocating "					"memory in error code path. This "					"should be harmless.\n");	}	undo_mft

⌨️ 快捷键说明

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