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

📄 inode.c

📁 上一个上传的有问题,这个是好的。visopsys包括系统内核和GUI的全部SOURCE code ,还包括一些基本的docs文档。里面src子目录对应所有SOURCE code.对于想研究操作系统的朋
💻 C
📖 第 1 页 / 共 3 页
字号:
			goto rollback;		}	}	/* Add $ATTRIBUTE_LIST to mft record. */	if (ntfs_resident_attr_record_add(ni,				AT_ATTRIBUTE_LIST, NULL, 0, NULL, 0, 0) < 0) {		err = errno;		ntfs_log_trace("Couldn't add $ATTRIBUTE_LIST to MFT record.\n");		goto rollback;	}	/* Resize it. */	na = ntfs_attr_open(ni, AT_ATTRIBUTE_LIST, AT_UNNAMED, 0);	if (!na) {		err = errno;		ntfs_log_trace("Failed to open just added $ATTRIBUTE_LIST.\n");		goto remove_attrlist_record;	}	if (ntfs_attr_truncate(na, al_len)) {		err = errno;		ntfs_log_trace("Failed to resize just added $ATTRIBUTE_LIST.\n");		ntfs_attr_close(na);		goto remove_attrlist_record;;	}	/* Done! */	ntfs_attr_close(na);	return 0;remove_attrlist_record:	/* Prevent ntfs_attr_recorm_rm from freeing attribute list. */	ni->attr_list = NULL;	NInoClearAttrList(ni);	/* Remove $ATTRIBUTE_LIST record. */	ntfs_attr_reinit_search_ctx(ctx);	if (!ntfs_attr_lookup(AT_ATTRIBUTE_LIST, NULL, 0,				CASE_SENSITIVE, 0, NULL, 0, ctx)) {		if (ntfs_attr_record_rm(ctx))			ntfs_log_trace("Rollback failed. Failed to remove attribute "					"list record.\n");	} else		ntfs_log_trace("Rollback failed. Couldn't find attribute list "				"record.\n");	/* Setup back in-memory runlist. */	ni->attr_list = al;	ni->attr_list_size = al_len;	NInoSetAttrList(ni);rollback:	/*	 * Scan attribute list for attributes that placed not in the base MFT	 * record and move them to it.	 */	ntfs_attr_reinit_search_ctx(ctx);	ale = (ATTR_LIST_ENTRY*)al;	while ((u8*)ale < al + al_len) {		if (MREF_LE(ale->mft_reference) != ni->mft_no) {			if (!ntfs_attr_lookup(ale->type, ale->name,						ale->name_length,						CASE_SENSITIVE,						sle64_to_cpu(ale->lowest_vcn),						NULL, 0, ctx)) {				if (ntfs_attr_record_move_to(ctx, ni))					ntfs_log_trace("Rollback failed. Couldn't "						"back attribute to base MFT record.\n");			} else				ntfs_log_trace("Rollback failed. ntfs_attr_lookup "						"failed.\n");			ntfs_attr_reinit_search_ctx(ctx);		}		ale = (ATTR_LIST_ENTRY*)((u8*)ale + le16_to_cpu(ale->length));	}	/* Remove in-memory attribute list. */	ni->attr_list = NULL;	ni->attr_list_size = 0;	NInoClearAttrList(ni);	NInoAttrListClearDirty(ni);put_err_out:	ntfs_attr_put_search_ctx(ctx);err_out:	free(al);	errno = err;	return -1;}/** * ntfs_inode_free_space - free space in the MFT record of inode * @ni:		ntfs inode in which MFT record free space * @size:	amount of space needed to free * * Return 0 on success or -1 on error with errno set to the error code. */int ntfs_inode_free_space(ntfs_inode *ni, int size){	ntfs_attr_search_ctx *ctx;	int freed, err;	if (!ni || size < 0) {		ntfs_log_trace("Invalid arguments.\n");		errno = EINVAL;		return -1;	}	ntfs_log_trace("Entering for inode 0x%llx, size %d.\n",			(long long) ni->mft_no, size);	freed = (le32_to_cpu(ni->mrec->bytes_allocated) -				le32_to_cpu(ni->mrec->bytes_in_use));	if (size <= freed)		return 0;	ctx = ntfs_attr_get_search_ctx(ni, NULL);	if (!ctx) {		err = errno;		ntfs_log_trace("Failed to get attribute search context.\n");		errno = err;		return -1;	}	/*	 * Chkdsk complain if $STANDARD_INFORMATION is not in the base MFT	 * record. FIXME: I'm not sure in this, need to recheck. For now simply	 * do not move $STANDARD_INFORMATION at all.	 *	 * Also we can't move $ATTRIBUTE_LIST from base MFT_RECORD, so position	 * search context on first attribute after $STANDARD_INFORMATION and	 * $ATTRIBUTE_LIST.	 *	 * Why we reposition instead of simply skip this attributes during	 * enumeration? Because in case we have got only in-memory attribute	 * list ntfs_attr_lookup will fail when it will try to find	 * $ATTRIBUTE_LIST.	 */	if (ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, CASE_SENSITIVE, 0, NULL,				0, ctx)) {		if (errno != ENOENT) {			err = errno;			ntfs_log_trace("Attribute lookup failed.\n");			goto put_err_out;		}		if (ctx->attr->type == AT_END) {			err = ENOSPC;			goto put_err_out;		}	}	while (1) {		int record_size;		/*		 * Check whether attribute is from different MFT record. If so,		 * find next, because we don't need such.		 */		while (ctx->ntfs_ino->mft_no != ni->mft_no) {			if (ntfs_attr_lookup(AT_UNUSED, NULL, 0, CASE_SENSITIVE,						0, NULL, 0, ctx)) {				err = errno;				if (errno != ENOENT) {					ntfs_log_trace("Attribute lookup failed.\n");				} else					err = ENOSPC;				goto put_err_out;			}		}		record_size = le32_to_cpu(ctx->attr->length);		/* Move away attribute. */		if (ntfs_attr_record_move_away(ctx, 0)) {			err = errno;			ntfs_log_trace("Failed to move out attribute.\n");			break;		}		freed += record_size;		/* Check whether we done. */		if (size <= freed) {			ntfs_attr_put_search_ctx(ctx);			return 0;		}		/*		 * Reposition to first attribute after $STANDARD_INFORMATION and		 * $ATTRIBUTE_LIST (see comments upwards).		 */		ntfs_attr_reinit_search_ctx(ctx);		if (ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, CASE_SENSITIVE, 0,				NULL, 0, ctx)) {			if (errno != ENOENT) {				err = errno;				ntfs_log_trace("Attribute lookup failed.\n");				break;			}			if (ctx->attr->type == AT_END) {				err = ENOSPC;				break;			}		}	}put_err_out:	ntfs_attr_put_search_ctx(ctx);	if (err == ENOSPC)		ntfs_log_trace("No attributes left that can be moved out.\n");	errno = err;	return -1;}/** * ntfs_inode_update_atime - update access time for ntfs inode * @ni:		ntfs inode for which update access time * * This function usually get called when user read not metadata from inode. * Do not update time for system files. */void ntfs_inode_update_atime(ntfs_inode *ni){	if (!NVolReadOnly(ni->vol) && !NVolNoATime(ni->vol) && (ni->mft_no >=			FILE_first_user || ni->mft_no == FILE_root)) {		ni->last_access_time = time(NULL);		NInoFileNameSetDirty(ni);		NInoSetDirty(ni);	}}/** * ntfs_inode_update_time - update all times for ntfs inode * @ni:		ntfs inode for which update times * * This function updates last access, mft and data change times. Usually * get called when user write not metadata to inode. Do not update time for * system files. */void ntfs_inode_update_time(ntfs_inode *ni){	if (!NVolReadOnly(ni->vol) && !NVolNoATime(ni->vol) && (ni->mft_no >=			FILE_first_user || ni->mft_no == FILE_root)) {		time_t now;		now = time(NULL);		ni->last_access_time = now;		ni->last_data_change_time = now;		ni->last_mft_change_time = now;		NInoFileNameSetDirty(ni);		NInoSetDirty(ni);	}}/** * ntfs_inode_badclus_bad - check for $Badclus:$Bad data attribute * @mft_no:		mft record number where @attr is present * @attr:		attribute record used to check for the $Bad attribute * * Check if the mft record given by @mft_no and @attr contains the bad sector * list. Please note that mft record numbers describing $Badclus extent inodes * will not match the current $Badclus:$Bad check. *  * On success return 1 if the file is $Badclus:$Bad, otherwise return 0. * On error return -1 with errno set to the error code. */int ntfs_inode_badclus_bad(u64 mft_no, ATTR_RECORD *attr){	int len, ret = 0;	ntfschar *ustr;	if (!attr) {		ntfs_log_error("Invalid argument.\n");		errno = EINVAL;		return -1;	}		if (mft_no != FILE_BadClus)	       	return 0;	if (attr->type != AT_DATA)	       	return 0;	if ((ustr = ntfs_str2ucs("$Bad", &len)) == NULL) {		ntfs_log_perror("Couldn't convert '$Bad' to Unicode");		return -1;	}	if (ustr && ntfs_names_are_equal(ustr, len,			(ntfschar *)((u8 *)attr + le16_to_cpu(attr->name_offset)),			attr->name_length, 0, NULL, 0))		ret = 1;	ntfs_ucsfree(ustr);	return ret;}#ifndef __VISOPSYS__#ifdef NTFS_RICH#include "rich.h"/** * ntfs_inode_close2 - Close an inode, freeing any resources * @ni: * * Description... * * Returns: */int ntfs_inode_close2(ntfs_inode *ni){	if (!ni)		return 0;	ntfs_log_trace ("inode %p, mft %lld, refcount %d\n", ni, MREF(ni->mft_no), ni->ref_count);	ni->ref_count--;	if (ni->ref_count > 0)		return 0;	// unlink	//   ino->private_data	// XXX temporary until we have commit/rollback	NInoClearDirty(ni);	return ntfs_inode_close(ni);}/** * ntfs_inode_open2 - Open an inode and initialise it * @vol: * @mref: * * Description... * * Returns: */ntfs_inode * ntfs_inode_open2(ntfs_volume *vol, const MFT_REF mref){	ntfs_inode *ino = NULL;	struct ntfs_dir *dir;	if (!vol)		return NULL;	ntfs_log_trace ("\n");	switch (mref) {		case FILE_Bitmap:  ino = vol->lcnbmp_ni;  break;		case FILE_MFT:     ino = vol->mft_ni;     break;		case FILE_MFTMirr: ino = vol->mftmirr_ni; break;		case FILE_Volume:  ino = vol->vol_ni;     break;		case FILE_root:			dir = vol->private_data;			if (dir)				ino = dir->inode;			break;	}	if (ino) {		ntfs_log_debug("inode reuse %lld\n", mref);		ino->ref_count++;		return ino;	}	ino = ntfs_inode_open(vol, mref);	if (!ino)		return NULL;	/*	if (mref != FILE_root)		ntfs_inode_dir_map (ino);	*/	// link	//   ino->private_data	ino->private_data = NULL;	ino->ref_count = 1;	ntfs_log_debug("inode open %lld, 0x%llx\n", MREF(mref), mref);	return ino;}/** * ntfs_inode_open3 - Open an inode and initialise it * @vol: * @mref: * * Description... * * Returns: */ntfs_inode * ntfs_inode_open3(ntfs_volume *vol, const MFT_REF mref){	ntfs_inode *ino = NULL;	if (!vol)		return NULL;	ntfs_log_trace ("\n");	ino = calloc(1, sizeof(*ino));	if (!ino)		return NULL;	ino->mrec = malloc(vol->mft_record_size);	if (!ino->mrec) {		free(ino);		return NULL;	}	ino->mft_no = mref;	ino->vol = vol;	ino->data_size = -1;	ino->allocated_size = -1;	ino->private_data = NULL;	ino->ref_count = 1;	if (1 != ntfs_attr_mst_pread(vol->mft_na, MREF(mref) * vol->mft_record_size, 1, vol->mft_record_size, ino->mrec)) {		//ntfs_inode_close2(ino); ???		free(ino->mrec);		free(ino);		return NULL;	}	NInoSetDirty(ino);	return ino;}#endif /* NTFS_RICH */#endif /* __VISOPSYS__ */

⌨️ 快捷键说明

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