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

📄 fs.c

📁 《嵌入式系统设计与实例开发实验教材二源码》Linux内核移植与编译实验
💻 C
📖 第 1 页 / 共 3 页
字号:
		at = ntfs_find_attr(ino, vol->at_index_allocation, "$I30");		inode->i_size = at ? at->size : 0;		inode->i_op = &ntfs_dir_inode_operations;		inode->i_fop = &ntfs_dir_operations;		inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;	} else {		inode->i_op = &ntfs_inode_operations;		inode->i_fop = &ntfs_file_operations;		inode->i_mode = S_IFREG | S_IRUGO;	}#ifdef CONFIG_NTFS_RW	if (!data || !(data->flags & (ATTR_IS_COMPRESSED | ATTR_IS_ENCRYPTED)))		inode->i_mode |= S_IWUGO;#endif	inode->i_mode &= ~vol->umask;	return;sys_file_error:	ntfs_error("Critical error. Tried to call ntfs_read_inode() before we "		"have completed read_super() or VFS error.\n");	// FIXME: Should we panic() at this stage?}#ifdef CONFIG_NTFS_RWstatic void ntfs_write_inode(struct inode *ino, int unused){	lock_kernel();	ntfs_debug(DEBUG_LINUX, "ntfs_write_inode 0x%x\n", ino->i_ino);	ntfs_update_inode(NTFS_LINO2NINO(ino));	unlock_kernel();}#endifstatic void _ntfs_clear_inode(struct inode *inode){	ntfs_inode *ino;	ntfs_volume *vol;		lock_kernel();	ntfs_debug(DEBUG_OTHER, "_ntfs_clear_inode 0x%x\n", inode->i_ino);	vol = NTFS_INO2VOL(inode);	if (!vol)		ntfs_error("_ntfs_clear_inode: vol = NTFS_INO2VOL(inode) is "				"NULL.\n");	switch (inode->i_ino) {	case FILE_Mft:		if (vol->mft_ino && ((vol->ino_flags & 1) == 0)) {			ino = (ntfs_inode*)ntfs_malloc(sizeof(ntfs_inode));			ntfs_memcpy(ino, &inode->u.ntfs_i, sizeof(ntfs_inode));			vol->mft_ino = ino;			vol->ino_flags |= 1;			goto unl_out;		}		break;	case FILE_MftMirr:		if (vol->mftmirr && ((vol->ino_flags & 2) == 0)) {			ino = (ntfs_inode*)ntfs_malloc(sizeof(ntfs_inode));			ntfs_memcpy(ino, &inode->u.ntfs_i, sizeof(ntfs_inode));			vol->mftmirr = ino;			vol->ino_flags |= 2;			goto unl_out;		}		break;	case FILE_BitMap:		if (vol->bitmap && ((vol->ino_flags & 4) == 0)) {			ino = (ntfs_inode*)ntfs_malloc(sizeof(ntfs_inode));			ntfs_memcpy(ino, &inode->u.ntfs_i, sizeof(ntfs_inode));			vol->bitmap = ino;			vol->ino_flags |= 4;			goto unl_out;		}		break;	default:		/* Nothing. Just clear the inode and exit. */	}	ntfs_clear_inode(&inode->u.ntfs_i);unl_out:	unlock_kernel();	return;}/* Called when umounting a filesystem by do_umount() in fs/super.c. */static void ntfs_put_super(struct super_block *sb){	ntfs_volume *vol;	ntfs_debug(DEBUG_OTHER, "ntfs_put_super\n");	vol = NTFS_SB2VOL(sb);	ntfs_release_volume(vol);	if (vol->nls_map)		unload_nls(vol->nls_map);	ntfs_debug(DEBUG_OTHER, "ntfs_put_super: done\n");}/* Called by the kernel when asking for stats. */static int ntfs_statfs(struct super_block *sb, struct statfs *sf){	struct inode *mft;	ntfs_volume *vol;	__s64 size;	int error;	ntfs_debug(DEBUG_OTHER, "ntfs_statfs\n");	vol = NTFS_SB2VOL(sb);	sf->f_type = NTFS_SUPER_MAGIC;	sf->f_bsize = vol->cluster_size;	error = ntfs_get_volumesize(NTFS_SB2VOL(sb), &size);	if (error)		return error;	sf->f_blocks = size;	/* Volumesize is in clusters. */	size = (__s64)ntfs_get_free_cluster_count(vol->bitmap);	/* Just say zero if the call failed. */	if (size < 0LL)		size = 0;	sf->f_bfree = sf->f_bavail = size;	ntfs_debug(DEBUG_OTHER, "ntfs_statfs: calling mft = iget(sb, "			"FILE_Mft)\n");	mft = iget(sb, FILE_Mft);	ntfs_debug(DEBUG_OTHER, "ntfs_statfs: iget(sb, FILE_Mft) returned "			"0x%x\n", mft);	if (!mft)		return -EIO;	sf->f_files = mft->i_size >> vol->mft_record_size_bits;	ntfs_debug(DEBUG_OTHER, "ntfs_statfs: calling iput(mft)\n");	iput(mft);	/* Should be read from volume. */	sf->f_namelen = 255;	return 0;}/* Called when remounting a filesystem by do_remount_sb() in fs/super.c. */static int ntfs_remount_fs(struct super_block *sb, int *flags, char *options){	if (!parse_options(NTFS_SB2VOL(sb), options))		return -EINVAL;	return 0;}/* Define the super block operation that are implemented */static struct super_operations ntfs_super_operations = {	read_inode:	ntfs_read_inode,#ifdef CONFIG_NTFS_RW	write_inode:	ntfs_write_inode,#endif	put_super:	ntfs_put_super,	statfs:		ntfs_statfs,	remount_fs:	ntfs_remount_fs,	clear_inode:	_ntfs_clear_inode,};/** * is_boot_sector_ntfs - check an NTFS boot sector for validity * @b:		buffer containing bootsector to check *  * Check whether @b contains a valid NTFS boot sector. * Return 1 if @b is a valid NTFS bootsector or 0 if not. */static int is_boot_sector_ntfs(ntfs_u8 *b){	ntfs_u32 i;	/* FIXME: We don't use checksumming yet as NT4(SP6a) doesn't either...	 * But we might as well have the code ready to do it. (AIA) */#if 0	/* Calculate the checksum. */	if (b < b + 0x50) {		ntfs_u32 *u;		ntfs_u32 *bi = (ntfs_u32 *)(b + 0x50);				for (u = bi, i = 0; u < bi; ++u)			i += NTFS_GETU32(*u);	}#endif	/* Check magic is "NTFS    " */	if (b[3] != 0x4e) goto not_ntfs;	if (b[4] != 0x54) goto not_ntfs;	if (b[5] != 0x46) goto not_ntfs;	if (b[6] != 0x53) goto not_ntfs;	for (i = 7; i < 0xb; ++i)		if (b[i] != 0x20) goto not_ntfs;	/* Check bytes per sector value is between 512 and 4096. */	if (b[0xb] != 0) goto not_ntfs;	if (b[0xc] > 0x10) goto not_ntfs;	/* Check sectors per cluster value is valid. */	switch (b[0xd]) {	case 1: case 2: case 4: case 8: case 16:	case 32: case 64: case 128:		break;	default:		goto not_ntfs;	}	/* Check reserved sectors value and four other fields are zero. */	for (i = 0xe; i < 0x15; ++i) 		if (b[i] != 0) goto not_ntfs;	if (b[0x16] != 0) goto not_ntfs;	if (b[0x17] != 0) goto not_ntfs;	for (i = 0x20; i < 0x24; ++i)		if (b[i] != 0) goto not_ntfs;	/* Check clusters per file record segment value is valid. */	if (b[0x40] < 0xe1 || b[0x40] > 0xf7) {		switch (b[0x40]) {		case 1: case 2: case 4: case 8: case 16: case 32: case 64:			break;		default:			goto not_ntfs;		}	}	/* Check clusters per index block value is valid. */	if (b[0x44] < 0xe1 || b[0x44] > 0xf7) {		switch (b[0x44]) {		case 1: case 2: case 4: case 8: case 16: case 32: case 64:			break;		default:			goto not_ntfs;		}	}	return 1;not_ntfs:	return 0;}/* Called to mount a filesystem by read_super() in fs/super.c. * Return a super block, the main structure of a filesystem. * * NOTE : Don't store a pointer to an option, as the page containing the * options is freed after ntfs_read_super() returns. * * NOTE : A context switch can happen in kernel code only if the code blocks * (= calls schedule() in kernel/sched.c). */struct super_block *ntfs_read_super(struct super_block *sb, void *options,		int silent){	ntfs_volume *vol;	struct buffer_head *bh;	int i, to_read, blocksize;	ntfs_debug(DEBUG_OTHER, "ntfs_read_super\n");	vol = NTFS_SB2VOL(sb);	init_ntfs_super_block(vol);	if (!parse_options(vol, (char*)options))		goto ntfs_read_super_vol;	blocksize = get_hardsect_size(sb->s_dev);	if (blocksize < 512)		blocksize = 512;	if (set_blocksize(sb->s_dev, blocksize) < 0) {		ntfs_error("Unable to set blocksize %d.\n", blocksize);		goto ntfs_read_super_vol;	}	sb->s_blocksize = blocksize;	/* Read the super block (boot block). */	if (!(bh = sb_bread(sb, 0))) {		ntfs_error("Reading super block failed\n");		goto ntfs_read_super_unl;	}	ntfs_debug(DEBUG_OTHER, "Done reading boot block\n");	/* Check for valid 'NTFS' boot sector. */	if (!is_boot_sector_ntfs(bh->b_data)) {		ntfs_debug(DEBUG_OTHER, "Not a NTFS volume\n");		bforget(bh);		goto ntfs_read_super_unl;	}	ntfs_debug(DEBUG_OTHER, "Going to init volume\n");	if (ntfs_init_volume(vol, bh->b_data) < 0) {		ntfs_debug(DEBUG_OTHER, "Init volume failed.\n");		bforget(bh);		goto ntfs_read_super_unl;	}	ntfs_debug(DEBUG_OTHER, "$Mft at cluster 0x%lx\n", vol->mft_lcn);	brelse(bh);	NTFS_SB(vol) = sb;	if (vol->cluster_size > PAGE_SIZE) {		ntfs_error("Partition cluster size is not supported yet (it "			   "is > max kernel blocksize).\n");		goto ntfs_read_super_unl;	}	ntfs_debug(DEBUG_OTHER, "Done to init volume\n");	/* Inform the kernel that a device block is a NTFS cluster. */	sb->s_blocksize = vol->cluster_size;	sb->s_blocksize_bits = vol->cluster_size_bits;	if (blocksize != vol->cluster_size &&			set_blocksize(sb->s_dev, sb->s_blocksize) < 0) {		ntfs_error("Cluster size too small for device.\n");		goto ntfs_read_super_unl;	}	ntfs_debug(DEBUG_OTHER, "set_blocksize\n");	/* Allocate an MFT record (MFT record can be smaller than a cluster). */	i = vol->cluster_size;	if (i < vol->mft_record_size)		i = vol->mft_record_size;	if (!(vol->mft = ntfs_malloc(i)))		goto ntfs_read_super_unl;	/* Read at least the MFT record for $Mft. */	to_read = vol->mft_clusters_per_record;	if (to_read < 1)		to_read = 1;	for (i = 0; i < to_read; i++) {		if (!(bh = sb_bread(sb, vol->mft_lcn + i))) {			ntfs_error("Could not read $Mft record 0\n");			goto ntfs_read_super_mft;		}		ntfs_memcpy(vol->mft + ((__s64)i << vol->cluster_size_bits),						bh->b_data, vol->cluster_size);		brelse(bh);		ntfs_debug(DEBUG_OTHER, "Read cluster 0x%x\n",							 vol->mft_lcn + i);	}	/* Check and fixup this MFT record */	if (!ntfs_check_mft_record(vol, vol->mft)){		ntfs_error("Invalid $Mft record 0\n");		goto ntfs_read_super_mft;	}	/* Inform the kernel about which super operations are available. */	sb->s_op = &ntfs_super_operations;	sb->s_magic = NTFS_SUPER_MAGIC;	sb->s_maxbytes = ~0ULL >> 1;	ntfs_debug(DEBUG_OTHER, "Reading special files\n");	if (ntfs_load_special_files(vol)) {		ntfs_error("Error loading special files\n");		goto ntfs_read_super_mft;	}	ntfs_debug(DEBUG_OTHER, "Getting RootDir\n");	/* Get the root directory. */	if (!(sb->s_root = d_alloc_root(iget(sb, FILE_root)))) {		ntfs_error("Could not get root dir inode\n");		goto ntfs_read_super_mft;	}ntfs_read_super_ret:	ntfs_debug(DEBUG_OTHER, "read_super: done\n");	return sb;ntfs_read_super_mft:	ntfs_free(vol->mft);ntfs_read_super_unl:ntfs_read_super_vol:	sb = NULL;	goto ntfs_read_super_ret;}/* Define the filesystem */static DECLARE_FSTYPE_DEV(ntfs_fs_type, "ntfs", ntfs_read_super);static int __init init_ntfs_fs(void){	/* Comment this if you trust klogd. There are reasons not to trust it */#if defined(DEBUG) && !defined(MODULE)	console_verbose();#endif	printk(KERN_NOTICE "NTFS driver v" NTFS_VERSION " [Flags: R/"#ifdef CONFIG_NTFS_RW			"W"#else			"O"#endif#ifdef DEBUG			" DEBUG"#endif#ifdef MODULE			" MODULE"#endif			"]\n");	SYSCTL(1);	ntfs_debug(DEBUG_OTHER, "registering %s\n", ntfs_fs_type.name);	/* Add this filesystem to the kernel table of filesystems. */	return register_filesystem(&ntfs_fs_type);}static void __exit exit_ntfs_fs(void){	SYSCTL(0);	ntfs_debug(DEBUG_OTHER, "unregistering %s\n", ntfs_fs_type.name);	unregister_filesystem(&ntfs_fs_type);}EXPORT_NO_SYMBOLS;/* * Not strictly true. The driver was written originally by Martin von L鰓is. * I am just maintaining and rewriting it. */MODULE_AUTHOR("Anton Altaparmakov <aia21@cus.cam.ac.uk>");MODULE_DESCRIPTION("Linux NTFS driver");MODULE_LICENSE("GPL");#ifdef DEBUGMODULE_PARM(ntdebug, "i");MODULE_PARM_DESC(ntdebug, "Debug level");#endifmodule_init(init_ntfs_fs)module_exit(exit_ntfs_fs)

⌨️ 快捷键说明

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