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

📄 dir.c

📁 上一个上传的有问题,这个是好的。visopsys包括系统内核和GUI的全部SOURCE code ,还包括一些基本的docs文档。里面src子目录对应所有SOURCE code.对于想研究操作系统的朋
💻 C
📖 第 1 页 / 共 4 页
字号:
 * @name:	unicode name of the new link * @name_len:	length of the name in unicode characters * * NOTE: At present we allow creating hardlinks to directories, we use them * in a temporary state during rename. But it's defenitely bad idea to have * hard links to directories as a result of operation. * FIXME: Create internal  __ntfs_link that allows hard links to a directories * and external ntfs_link that do not. Write ntfs_rename that uses __ntfs_link. * * Return 0 on success or -1 on error with errno set to the error code. */int ntfs_link(ntfs_inode *ni, ntfs_inode *dir_ni, ntfschar *name, u8 name_len){	FILE_NAME_ATTR *fn = NULL;	int fn_len, err;	ntfs_log_trace("Entering.\n");	if (!ni || !dir_ni || !name || !name_len ||			ni->mft_no == dir_ni->mft_no) {		err = errno;		ntfs_log_error("Invalid arguments.\n");		goto err_out;	}	/* Create FILE_NAME attribute. */	fn_len = sizeof(FILE_NAME_ATTR) + name_len * sizeof(ntfschar);	fn = calloc(1, fn_len);	if (!fn) {		err = errno;		ntfs_log_error("Not enough memory.\n");		goto err_out;	}	fn->parent_directory = MK_LE_MREF(dir_ni->mft_no,			le16_to_cpu(dir_ni->mrec->sequence_number));	fn->file_name_length = name_len;	fn->file_name_type = FILE_NAME_POSIX;	fn->file_attributes = ni->flags;	if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)		fn->file_attributes |= FILE_ATTR_I30_INDEX_PRESENT;	fn->allocated_size = cpu_to_sle64(ni->allocated_size);	fn->data_size = cpu_to_sle64(ni->data_size);	fn->creation_time = utc2ntfs(ni->creation_time);	fn->last_data_change_time = utc2ntfs(ni->last_data_change_time);	fn->last_mft_change_time = utc2ntfs(ni->last_mft_change_time);	fn->last_access_time = utc2ntfs(ni->last_access_time);	memcpy(fn->file_name, name, name_len * sizeof(ntfschar));	/* Add FILE_NAME attribute to index. */	if (ntfs_index_add_filename(dir_ni, fn, MK_MREF(ni->mft_no,			le16_to_cpu(ni->mrec->sequence_number)))) {		err = errno;		ntfs_log_error("Failed to add entry to the index.\n");		goto err_out;	}	/* Add FILE_NAME attribute to inode. */	if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) {		ntfs_index_context *ictx;		err = errno;		ntfs_log_error("Failed to add FILE_NAME attribute.\n");		/* Try to remove just added attribute from index. */		ictx = ntfs_index_ctx_get(dir_ni, NTFS_INDEX_I30, 4);		if (!ictx)			goto rollback_failed;		if (ntfs_index_lookup(fn, fn_len, ictx)) {			ntfs_index_ctx_put(ictx);			goto rollback_failed;		}		if (ntfs_index_rm(ictx)) {			ntfs_index_ctx_put(ictx);			goto rollback_failed;		}		goto err_out;	}	/* Increment hard links count. */	ni->mrec->link_count = cpu_to_le16(le16_to_cpu(			ni->mrec->link_count) + 1);	/* Done! */	ntfs_inode_mark_dirty(ni);	free(fn);	ntfs_log_trace("Done.\n");	return 0;rollback_failed:	ntfs_log_error("Rollback failed. Leaving inconsistent metadata.\n");err_out:	ntfs_log_error("Failed.\n");	free(fn);	errno = err;	return -1;}#ifdef NTFS_RICH#include "layout.h"#include "tree.h"#include "bitmap.h"#include "rich.h"/** * ntfs_dir_rollback - Discard the in-memory directory changes * @dir: * * Description... * * Returns: */int ntfs_dir_rollback(struct ntfs_dir *dir){	int i;	if (!dir)		return -1;	ntfs_log_trace ("dir %p, inode %lld, children %d\n", dir,		dir ? MREF(dir->mft_num) : 0, dir ? dir->child_count : 0);	if (ntfs_dt_rollback(dir->index) < 0)		return -1;	if (ntfs_bmp_rollback(dir->bitmap) < 0)		return -1;	for (i = 0; i < dir->child_count; i++) {		if (ntfs_dir_rollback(dir->children[i]) < 0)			return -1;	}	return 0;}/** * ntfs_dir_truncate - Shrink an index allocation * @vol: * @dir: * * Description... * * Returns: */int ntfs_dir_truncate(ntfs_volume *vol, struct ntfs_dir *dir){	//int i;	//u8 *buffer;	//int buf_count;	s64 last_bit;	INDEX_ENTRY *ie;	if (!vol || !dir)		return -1;	ntfs_log_trace ("dir %p, inode %lld, children %d\n", dir,		dir ? MREF(dir->mft_num) : 0, dir ? dir->child_count : 0);	if ((dir->ialloc == NULL) || (dir->bitmap == NULL))		return 0;#if 0	buf_count = ROUND_UP(dir->bitmap->attr->allocated_size, vol->cluster_size) >> vol->cluster_size_bits;	ntfs_log_debug("alloc = %lld bytes\n", dir->ialloc->allocated_size);	ntfs_log_debug("alloc = %lld clusters\n", dir->ialloc->allocated_size >> vol->cluster_size_bits);	ntfs_log_debug("bitmap bytes 0 to %lld\n", ((dir->ialloc->allocated_size >> vol->cluster_size_bits)-1)>>3);	ntfs_log_debug("bitmap = %p\n", dir->bitmap);	ntfs_log_debug("bitmap = %lld bytes\n", dir->bitmap->attr->allocated_size);	ntfs_log_debug("bitmap = %d buffers\n", buf_count);#endif	last_bit = ntfs_bmp_find_last_set(dir->bitmap);	if (dir->ialloc->allocated_size == (dir->index_size * (last_bit + 1))) {		//ntfs_log_debug("nothing to do\n");		return 0;	}	ntfs_log_debug("Truncation needed\n");#if 0	ntfs_log_debug("\tlast bit = %lld\n", last_bit);	ntfs_log_debug("\tactual IALLOC size = %lld\n", dir->ialloc->allocated_size);	ntfs_log_debug("\tshould IALLOC size = %lld\n", dir->index_size * (last_bit + 1));#endif	if ((dir->index_size * (last_bit + 1)) == 0) {		ntfs_log_debug("root dt %d, vcn = %lld\n", dir->index->changed, dir->index->vcn);		//rollback all dts		//ntfs_dt_rollback(dir->index);		//dir->index = NULL;		// What about the ROOT dt?		ie = ntfs_ie_copy(dir->index->children[0]);		if (!ie) {			ntfs_log_warning("IE copy failed\n");			return -1;		}		ie = ntfs_ie_remove_vcn(ie);		if (!ie) {			ntfs_log_warning("IE remove vcn failed\n");			return -1;		}		//utils_dump_mem(dir->index->data, 0, dir->index->data_len, DM_DEFAULTS); ntfs_log_debug("\n");		//utils_dump_mem(ie, 0, ie->length, DM_DEFAULTS); ntfs_log_debug("\n");		ntfs_dt_root_replace(dir->index, 0, dir->index->children[0], ie);		//utils_dump_mem(dir->index->data, 0, dir->index->data_len, DM_DEFAULTS); ntfs_log_debug("\n");		//ntfs_log_debug("root dt %d, vcn = %lld\n", dir->index->changed, dir->index->vcn);		ntfs_ie_free(ie);		ie = NULL;		//index flags remove LARGE_INDEX		dir->index->header->flags = 0;		//rollback dir's bmp		ntfs_bmp_free(dir->bitmap);		dir->bitmap = NULL;		/*		for (i = 0; i < dir->index->child_count; i++) {			ntfs_dt_rollback(dir->index->sub_nodes[i]);			dir->index->sub_nodes[i] = NULL;		}		*/		//ntfs_log_debug("dir->index->inodes[0] = %p\n", dir->index->inodes[0]);		//remove 0xA0 attribute		ntfs_mft_remove_attr(vol->private_bmp2, dir->inode, AT_INDEX_ALLOCATION);		//remove 0xB0 attribute		ntfs_mft_remove_attr(vol->private_bmp2, dir->inode, AT_BITMAP);	} else {		ntfs_log_warning("Cannot shrink directory\n");		//ntfs_dir_shrink_alloc		//ntfs_dir_shrink_bitmap		//make bitmap resident?	}	/*	 * Remove	 *   dt -> dead	 *   bitmap updated	 *   rollback dead dts	 *   commit bitmap	 *   commit dts	 *   commit dir	 */	/*	 * Reuse	 *   search for lowest dead	 *   update bitmap	 *   init dt	 *   remove from dead	 *   insert into tree	 *   init INDX	 */#if 0	buffer = ntfs_bmp_get_data(dir->bitmap, 0);	if (!buffer)		return -1;	utils_dump_mem(buffer, 0, 8, DM_NO_ASCII);	for (i = buf_count-1; i >= 0; i--) {		if (buffer[i]) {			ntfs_log_debug("alloc in use\n");			return 0;		}	}#endif	// <dir>/$BITMAP($I30)	// <dir>/$INDEX_ALLOCATION($I30)	// $Bitmap	// Find the highest set bit in the directory bitmap	// can we free any clusters of the alloc?	// if yes, resize attribute	// Are *any* bits set?	// If not remove ialloc	return 0;}/** * ntfs_dir_commit - Write to disk the in-memory directory changes * @dir: * * Description... * * Returns: */int ntfs_dir_commit(struct ntfs_dir *dir){	int i;	if (!dir)		return 0;	ntfs_log_trace ("dir %p, inode %lld, children %d\n", dir,		dir ? MREF(dir->mft_num) : 0, dir ? dir->child_count : 0);	if (NInoDirty(dir->inode)) {		ntfs_inode_sync(dir->inode);		ntfs_log_warning("\tntfs_inode_sync %llu\n", dir->inode->mft_no);	}	if (ntfs_dt_commit(dir->index) < 0)		return -1;	if (ntfs_bmp_commit(dir->bitmap) < 0)		return -1;	for (i = 0; i < dir->child_count; i++) {		if (ntfs_dir_commit(dir->children[i]) < 0)			return -1;	}	return 0;}/** * ntfs_dir_free - Destroy a directory object * @dir: * * Description... * * Returns: */void ntfs_dir_free(struct ntfs_dir *dir){	struct ntfs_dir *parent;	int i;	if (!dir)		return;	ntfs_log_trace ("dir %p, inode %lld, children %d\n", dir,		dir ? MREF(dir->mft_num) : 0, dir ? dir->child_count : 0);	ntfs_dir_rollback(dir);	parent = dir->parent;	if (parent) {		for (i = 0; i < parent->child_count; i++) {			if (parent->children[i] == dir) {				parent->children[i] = NULL;			}		}	}	ntfs_attr_close(dir->iroot);	ntfs_attr_close(dir->ialloc);	ntfs_inode_close2(dir->inode);	ntfs_dt_free  (dir->index);	ntfs_bmp_free(dir->bitmap);	for (i = 0; i < dir->child_count; i++)		ntfs_dir_free(dir->children[i]);	free(dir->name);	free(dir->children);	free(dir);}/** * ntfs_dir_create - Create a representation of a directory * @vol: * @mft_num: * * Description... * * Returns: */struct ntfs_dir * ntfs_dir_create(ntfs_volume *vol, MFT_REF mft_num){	struct ntfs_dir *dir   = NULL;	ntfs_inode      *inode = NULL;	ATTR_RECORD     *rec   = NULL;	INDEX_ROOT      *ir    = NULL;	FILE_NAME_ATTR  *name  = NULL;	if (!vol)		return NULL;	ntfs_log_trace ("inode %lld\n", MREF(mft_num));	inode = ntfs_inode_open2(vol, mft_num);	if (!inode)		return NULL;	dir = calloc(1, sizeof(*dir));	if (!dir) {		ntfs_inode_close2(inode);		return NULL;	}	dir->inode  = inode;	dir->iroot  = ntfs_attr_open(inode, AT_INDEX_ROOT,       NTFS_INDEX_I30, 4);	dir->ialloc = ntfs_attr_open(inode, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4);	if (!dir->iroot) {		ntfs_dir_free(dir);		return NULL;	}	dir->vol	  = vol;	dir->parent	  = NULL;	dir->name	  = NULL;	dir->name_len	  = 0;	dir->index	  = NULL;	dir->children	  = NULL;	dir->child_count  = 0;	dir->mft_num	  = mft_num;	// This may not exist	dir->bitmap = ntfs_bmp_create(inode, AT_BITMAP, NTFS_INDEX_I30, 4);	if (dir->iroot) {		rec = find_first_attribute(AT_INDEX_ROOT, inode->mrec);		ir  = (INDEX_ROOT*) ((u8*)rec + rec->value_offset);		dir->index_size = ir->index_block_size;		ntfs_log_debug("dir size = %d\n", dir->index_size);	} else {		// XXX !iroot?		dir->index_size = 0;	}	// Finally, find the dir's name	rec = find_first_attribute(AT_FILE_NAME, inode->mrec);	name = (FILE_NAME_ATTR*) ((u8*)rec + rec->value_offset);	dir->name_len = name->file_name_length;	dir->name = malloc(sizeof(ntfschar) * dir->name_len);	memcpy(dir->name, name->file_name, sizeof(ntfschar) * dir->name_len);	return dir;}/** * ntfs_dir_add - Add a directory to another as a child * @parent: * @child: * * Description... * * Returns: */void ntfs_dir_add(struct ntfs_dir *parent, struct ntfs_dir *child){	if (!parent || !child)		return;	ntfs_log_trace ("parent %p, inode %lld, children %d\n", parent,		parent ? MREF(parent->mft_num) : 0, parent ? parent->child_count : 0);	ntfs_log_trace ("child %p, inode %lld, children %d\n", child,		child ? MREF(child->mft_num) : 0, child ? child->child_count : 0);	parent->child_count++;	//ntfs_log_debug("child count = %d\n", parent->child_count);	parent->children = realloc(parent->children, parent->child_count * sizeof(struct ntfs_dir*));	child->parent = parent;	parent->children[parent->child_count-1] = child;}/** * ntfs_dir_find2 - Find a directory by name * @dir: * @name: * @name_len: * * Description... * * Returns: */struct ntfs_dir * ntfs_dir_find2(struct ntfs_dir *dir, ntfschar *name, int name_len){	int i;	struct ntfs_dir *child = NULL;	struct ntfs_dt *dt = NULL;	int dt_num = 0;	INDEX_ENTRY *ie;	MFT_REF mft_num;	if (!dir || !name)		return NULL;	ntfs_log_trace ("dir %p, inode %lld, children %d\n", dir,		dir ? MREF(dir->mft_num) : 0, dir ? dir->child_count : 0);	if (!dir->index) {	// XXX when will this happen?		ntfs_log_debug("ntfs_dir_find2 - directory has no index\n");		return NULL;	}	for (i = 0; i < dir->child_count; i++) {		if (0 == ntfs_names_collate(name, name_len,					dir->children[i]->name,					dir->children[i]->name_len,					2, IGNORE_CASE,					dir->vol->upcase,					dir->vol->upcase_len))			return dir->children[i];	}	dt = ntfs_dt_find2(dir->index, name, name_len, &dt_num);	if (!dt) {		ntfs_log_debug("can't find name in dir\n");		return NULL;	}	ie = dt->children[dt_num];	mft_num = ie->indexed_file;	child = ntfs_dir_create(dir->vol, mft_num);	if (!child)		return NULL;	child->index = ntfs_dt_create(child, NULL, -1);	ntfs_dir_add(dir, child);	return child;}#endif /* NTFS_RICH */#endif /* __VISOPSYS__ */

⌨️ 快捷键说明

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