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

📄 fs.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
{	int error;	struct inode *r = 0;	ntfs_volume *vol;	ntfs_inode *ino;	ntfs_attribute *si;	ntfs_debug (DEBUG_DIR1, "mkdir %s in %x\n",d->d_name.name, dir->i_ino);	error = ENAMETOOLONG;	if (d->d_name.len > /* FIXME */255)		goto out;	error = EIO;	r = new_inode(dir->i_sb);	if (!r)		goto out;		vol = NTFS_INO2VOL(dir);#ifdef NTFS_IN_LINUX_KERNEL	ino = NTFS_LINO2NINO(r);#else	ino = ntfs_malloc(sizeof(ntfs_inode));	error = ENOMEM;	if(!ino)		goto out;	r->u.generic_ip = ino;#endif	error = ntfs_mkdir(NTFS_LINO2NINO(dir), 			   d->d_name.name, d->d_name.len, ino);	if(error)		goto out;	r->i_uid = vol->uid;	r->i_gid = vol->gid;	si = ntfs_find_attr(ino,vol->at_standard_information,NULL);	if(si){		char *attr = si->d.data;		r->i_atime = ntfs_ntutc2unixutc(NTFS_GETU64(attr+0x18));		r->i_ctime = ntfs_ntutc2unixutc(NTFS_GETU64(attr));		r->i_mtime = ntfs_ntutc2unixutc(NTFS_GETU64(attr+8));	}	/* It's a directory */	r->i_op = &ntfs_dir_inode_operations;	r->i_fop = &ntfs_dir_operations;	r->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;#ifdef CONFIG_NTFS_RW	r->i_mode|=S_IWUGO;#endif	r->i_mode &= ~vol->umask;			insert_inode_hash(r);	d_instantiate(d, r);	error = 0; out: 	ntfs_debug (DEBUG_DIR1, "mkdir returns %d\n", -error);	return -error;}#endif#if 0static int ntfs_bmap(struct inode *ino,int block){	int ret=ntfs_vcn_to_lcn(NTFS_LINO2NINO(ino),block);	ntfs_debug(DEBUG_OTHER, "bmap of %lx,block %x is %x\n",	       ino->i_ino,block,ret);	return (ret==-1) ? 0:ret;}#endif/* It's fscking broken. *//* FIXME: [bm]map code is disabled until ntfs_get_block gets sorted! *//*static int ntfs_get_block(struct inode *inode, long block, struct buffer_head *bh, int create){	BUG();	return -1;}static struct file_operations ntfs_file_operations = {	read:		ntfs_read,	mmap:		generic_file_mmap,#ifdef CONFIG_NTFS_RW	write:		ntfs_write,#endif};static struct inode_operations ntfs_inode_operations;*/static struct file_operations ntfs_dir_operations = {	read:		generic_read_dir,	readdir:	ntfs_readdir,};static struct inode_operations ntfs_dir_inode_operations = {	lookup:		ntfs_lookup,#ifdef CONFIG_NTFS_RW	create:		ntfs_create,	mkdir:		_linux_ntfs_mkdir,#endif};/*static int ntfs_writepage(struct page *page){	return block_write_full_page(page,ntfs_get_block);}static int ntfs_readpage(struct file *file, struct page *page){	return block_read_full_page(page,ntfs_get_block);}static int ntfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to){	return cont_prepare_write(page,from,to,ntfs_get_block,		&page->mapping->host->u.ntfs_i.mmu_private);}static int _ntfs_bmap(struct address_space *mapping, long block){	return generic_block_bmap(mapping,block,ntfs_get_block);}struct address_space_operations ntfs_aops = {	readpage: ntfs_readpage,	writepage: ntfs_writepage,	sync_page: block_sync_page,	prepare_write: ntfs_prepare_write,	commit_write: generic_commit_write,	bmap: _ntfs_bmap};*//* ntfs_read_inode is called by the Virtual File System (the kernel layer that * deals with filesystems) when iget is called requesting an inode not already * present in the inode table. Typically filesystems have separate * inode_operations for directories, files and symlinks. */static void ntfs_read_inode(struct inode* inode){	ntfs_volume *vol;	int can_mmap=0;	ntfs_inode *ino;	ntfs_attribute *data;	ntfs_attribute *si;	vol=NTFS_INO2VOL(inode);	inode->i_mode=0;	ntfs_debug(DEBUG_OTHER, "ntfs_read_inode %x\n",(unsigned)inode->i_ino);	switch(inode->i_ino)	{		/* those are loaded special files */	case FILE_MFT:		ntfs_error("Trying to open MFT\n");return;	default:		#ifdef NTFS_IN_LINUX_KERNEL		ino=&inode->u.ntfs_i;		#else		/* FIXME: check for ntfs_malloc failure */		ino=(ntfs_inode*)ntfs_malloc(sizeof(ntfs_inode));		inode->u.generic_ip=ino;		#endif		if(!ino || ntfs_init_inode(ino,					   NTFS_INO2VOL(inode),inode->i_ino))		{			ntfs_debug(DEBUG_OTHER, "NTFS:Error loading inode %x\n",			       (unsigned int)inode->i_ino);			return;		}	}	/* Set uid/gid from mount options */	inode->i_uid=vol->uid;	inode->i_gid=vol->gid;	inode->i_nlink=1;	/* Use the size of the data attribute as file size */	data = ntfs_find_attr(ino,vol->at_data,NULL);	if(!data)	{		inode->i_size=0;		can_mmap=0;	}	else	{		inode->i_size=data->size;		/* FIXME: once ntfs_get_block is implemented, uncomment the		 * next line and remove the can_mmap = 0; */		/* can_mmap=!data->resident && !data->compressed;*/		can_mmap = 0;	}	/* get the file modification times from the standard information */	si=ntfs_find_attr(ino,vol->at_standard_information,NULL);	if(si){		char *attr=si->d.data;		inode->i_atime=ntfs_ntutc2unixutc(NTFS_GETU64(attr+0x18));		inode->i_ctime=ntfs_ntutc2unixutc(NTFS_GETU64(attr));		inode->i_mtime=ntfs_ntutc2unixutc(NTFS_GETU64(attr+8));	}	/* if it has an index root, it's a directory */	if(ntfs_find_attr(ino,vol->at_index_root,"$I30"))	{		ntfs_attribute *at;		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	{		/* As long as ntfs_get_block() is just a call to BUG() do not	 	 * define any [bm]map ops or we get the BUG() whenever someone		 * runs mc or mpg123 on an ntfs partition!		 * FIXME: Uncomment the below code when ntfs_get_block is		 * implemented. */		/* if (can_mmap) {			inode->i_op = &ntfs_inode_operations;			inode->i_fop = &ntfs_file_operations;			inode->i_mapping->a_ops = &ntfs_aops;			inode->u.ntfs_i.mmu_private = inode->i_size;		} else */ {			inode->i_op=&ntfs_inode_operations_nobmap;			inode->i_fop=&ntfs_file_operations_nommap;		}		inode->i_mode=S_IFREG|S_IRUGO;	}#ifdef CONFIG_NTFS_RW	if(!data || !data->compressed)		inode->i_mode|=S_IWUGO;#endif	inode->i_mode &= ~vol->umask;}#ifdef CONFIG_NTFS_RWstatic void ntfs_write_inode (struct inode *ino, int unused){	lock_kernel();	ntfs_debug (DEBUG_LINUX, "ntfs:write inode %x\n", ino->i_ino);	ntfs_update_inode (NTFS_LINO2NINO (ino));	unlock_kernel();}#endifstatic void _ntfs_clear_inode(struct inode *ino){	lock_kernel();	ntfs_debug(DEBUG_OTHER, "ntfs_clear_inode %lx\n",ino->i_ino);#ifdef NTFS_IN_LINUX_KERNEL	if(ino->i_ino!=FILE_MFT)		ntfs_clear_inode(&ino->u.ntfs_i);#else	if(ino->i_ino!=FILE_MFT && ino->u.generic_ip)	{		ntfs_clear_inode(ino->u.generic_ip);		ntfs_free(ino->u.generic_ip);		ino->u.generic_ip=0;	}#endif	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);#ifndef NTFS_IN_LINUX_KERNEL	ntfs_free(vol);#endif	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;	ntfs_u64 size;	int error;	ntfs_debug(DEBUG_OTHER, "ntfs_statfs\n");	vol=NTFS_SB2VOL(sb);	sf->f_type=NTFS_SUPER_MAGIC;	sf->f_bsize=vol->clustersize;	error = ntfs_get_volumesize( NTFS_SB2VOL( sb ), &size );	if( error )		return -error;	sf->f_blocks = size;	/* volumesize is in clusters */	sf->f_bfree=ntfs_get_free_cluster_count(vol->bitmap);	sf->f_bavail=sf->f_bfree;	mft=iget(sb,FILE_MFT);	if (!mft)		return -EIO;	/* So ... we lie... thus this following cast of loff_t value	   is ok here.. */	sf->f_files = (unsigned long)mft->i_size / vol->mft_recordsize;	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,};/* 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;	ntfs_debug(DEBUG_OTHER, "ntfs_read_super\n");#ifdef NTFS_IN_LINUX_KERNEL	vol = NTFS_SB2VOL(sb);#else	if(!(vol = ntfs_malloc(sizeof(ntfs_volume))))		goto ntfs_read_super_dec;	NTFS_SB2VOL(sb)=vol;#endif		if(!parse_options(vol,(char*)options))		goto ntfs_read_super_vol;#if 0	/* Set to read only, user option might reset it */	sb->s_flags |= MS_RDONLY;#endif	/* Assume a 512 bytes block device for now */	set_blocksize(sb->s_dev, 512);	/* Read the super block (boot block) */	if(!(bh=bread(sb->s_dev,0,512))) {		ntfs_error("Reading super block failed\n");		goto ntfs_read_super_unl;	}	ntfs_debug(DEBUG_OTHER, "Done reading boot block\n");	/* Check for 'NTFS' magic number */	if(!IS_NTFS_VOLUME(bh->b_data)){		ntfs_debug(DEBUG_OTHER, "Not a NTFS volume\n");		brelse(bh);		goto ntfs_read_super_unl;	}	ntfs_debug(DEBUG_OTHER, "Going to init volume\n");	ntfs_init_volume(vol,bh->b_data);	ntfs_debug(DEBUG_OTHER, "MFT record at cluster 0x%X\n",vol->mft_cluster);	brelse(bh);	NTFS_SB(vol)=sb;	ntfs_debug(DEBUG_OTHER, "Done to init volume\n");	/* Inform the kernel that a device block is a NTFS cluster */	sb->s_blocksize=vol->clustersize;	for(i=sb->s_blocksize,sb->s_blocksize_bits=0;i != 1;i>>=1)		sb->s_blocksize_bits++;	set_blocksize(sb->s_dev,sb->s_blocksize);	ntfs_debug(DEBUG_OTHER, "set_blocksize\n");	/* Allocate a MFT record (MFT record can be smaller than a cluster) */	if(!(vol->mft=ntfs_malloc(max(vol->mft_recordsize,vol->clustersize))))		goto ntfs_read_super_unl;	/* Read at least the MFT record for $MFT */	for(i=0;i<max(vol->mft_clusters_per_record,1);i++){		if(!(bh=bread(sb->s_dev,vol->mft_cluster+i,vol->clustersize))) {			ntfs_error("Could not read MFT record 0\n");			goto ntfs_read_super_mft;		}		ntfs_memcpy(vol->mft+i*vol->clustersize,bh->b_data,vol->clustersize);		brelse(bh);		ntfs_debug(DEBUG_OTHER, "Read cluster %x\n",vol->mft_cluster+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;		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_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:	#ifndef NTFS_IN_LINUX_KERNEL	ntfs_free(vol);ntfs_read_super_dec:	#endif	ntfs_debug(DEBUG_OTHER, "read_super: done\n");	return NULL;}/* 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 version " NTFS_VERSION "\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;MODULE_AUTHOR("Martin von L鰓is");MODULE_DESCRIPTION("NTFS driver");#ifdef DEBUGMODULE_PARM(ntdebug, "i");MODULE_PARM_DESC(ntdebug, "Debug level");#endifmodule_init(init_ntfs_fs)module_exit(exit_ntfs_fs)/* * Local variables: *  c-file-style: "linux" * End: */

⌨️ 快捷键说明

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