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

📄 ntfs_fs.c

📁 NTFS 磁盘系统 加载源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		MOD_DEC_USE_COUNT;		return 0;	}	/* Read the superblock assuming 512 byte blocks for now */	set_blocksize(dev,512);	/* Read the boot block to get the location of the MFT */	if(!(bh=bread(dev,0,512)))	{		printk("Reading super block failed\n");		sb->s_dev=0;		ntfs_free(vol);		unlock_super(sb);		MOD_DEC_USE_COUNT;		return NULL;	}	NTFS_DEBUG("Done reading boot block\n");	/* Check for 'NTFS' magic at offset 3 */	if(!IS_NTFS_VOLUME(bh->b_data)){		NTFS_DEBUG("Not a NTFS volume\n");		ntfs_free(vol);		sb->s_dev=0;		brelse(bh);		unlock_super(sb);		MOD_DEC_USE_COUNT;		return NULL;	}	NTFS_DEBUG("Going to init volume\n");	ntfs_init_volume(vol,bh->b_data);	NTFS_SB(vol)=sb;	NTFS_SB2VOL(sb)=vol;	NTFS_DEBUG("Done to init volume\n");	sb->s_blocksize=vol->clustersize;	for(i=sb->s_blocksize,sb->s_blocksize_bits=0;i;i>>=1)		sb->s_blocksize_bits++;	/* inform the kernel that a device block is a NTFS cluster */	set_blocksize(dev,sb->s_blocksize);	NTFS_DEBUG("set_blocksize\n");	NTFS_DEBUG("MFT record at cluster 0x%X\n",vol->mft_cluster);	brelse(bh);	/* Allocate a MFT record */	/* Handle cases where mft record is smaller than a cluster */	vol->mft=ntfs_malloc(max(vol->mft_recordsize,vol->clustersize));	/* read the MFT record 0 */	/* If there is more than one MFT record per cluster, 	   read just one cluster */	for(i=0;i<max(vol->mft_clusters_per_record,1);i++){		if(!(bh=bread(dev,vol->mft_cluster+i,vol->clustersize)))		{			NTFS_DEBUG("Could not read MFT record 0\n");			sb->s_dev=0;			unlock_super(sb);			MOD_DEC_USE_COUNT;			return NULL;		}		ntfs_memcpy(vol->mft+i*vol->clustersize,bh->b_data,vol->clustersize);		brelse(bh);		NTFS_DEBUG("Read cluster %x\n",vol->mft_cluster+i);	}	/* Check and fixup MFT record 0 */	if(!ntfs_check_mft_record(vol,vol->mft)){		NTFS_DEBUG("Invalid MFT record 0\n");		sb->s_dev=0;		unlock_super(sb);		MOD_DEC_USE_COUNT;		return NULL;	}	/* inform the kernel about which super operations are available */	sb->s_op = &ntfs_super_operations;	sb->s_magic = NTFS_SUPER_MAGIC;		NTFS_DEBUG("Reading master and upcase files\n");	ntfs_load_special_files(vol);	unlock_super(sb);	NTFS_DEBUG("Getting RootDir\n");	/* get the root directory */	if(!(sb->s_mounted=iget(sb,FILE_ROOT))){		sb->s_dev=0;		NTFS_DEBUG("Could not get root dir inode\n");		MOD_DEC_USE_COUNT;		return NULL;	}	NTFS_DEBUG("read_super: done\n");	return sb;}static void ntfs_put_super(struct super_block *sb){	ntfs_volume *vol=NTFS_SB2VOL(sb);	NTFS_DEBUG("ntfs_put_super\n");	lock_super(sb);	if(vol->mft_ino){		ntfs_clear_inode(vol->mft_ino);		ntfs_free(vol->mft_ino);		vol->mft_ino=0;	}	sb->s_dev=0;	ntfs_free(vol->mft);	ntfs_free(vol->upcase);	ntfs_free(sb->u.generic_sbp);	sb->u.generic_sbp=0;	unlock_super(sb);	MOD_DEC_USE_COUNT;}static int ntfs_remount_fs(struct super_block *sb, int* flags, char* options){	if(parse_options(sb,(ntfs_volume*)sb->u.generic_sbp, options))	{		if((*flags & MS_RDONLY) && (sb->s_flags && MS_RDONLY))			return 0;		if(*flags & MS_RDONLY)			/* changing from rw to ro */			sb->s_flags |= MS_RDONLY;		else if(sb->s_flags & MS_RDONLY)			/* changing from rw to rw */			sb->s_flags &= ~MS_RDONLY;		return 0;	}	else		return -EINVAL;}static int ntfs_lookup(struct inode *dir, const char *name, int len,	struct inode **result){	struct inode *res=0;	unsigned long ino;	char *item=0;	ntfs_iterate_s walk;	int error;	NTFS_DEBUG("Looking up %s in %x\n",name,(unsigned)dir->i_ino);	if(strncmp(name,".",len)==0){		*result=dir;		return 0;	}	if(dcache_lookup(dir,name,len,&ino))	{		if(!(*result = iget(dir->i_sb,ino)))		{			iput(dir);			return -EACCES;		}		iput(dir);		return 0;	}	if(strncmp(name,"..",len)==0)	{		/*NTFS_DEBUG(".. not supported\n");*/		/* What if a directory has more than one name? */		/* FIXME: support for segments */		ntfs_attribute *attr=ntfs_find_attr((ntfs_inode*)dir->u.generic_ip,						    AT_FILE_NAME,NULL);		if(!attr){			NTFS_DEBUG(".. not found\n");			iput(dir);			return -ENOENT;		}		if(!(*result = iget(dir->i_sb,NTFS_GETU32(attr->d.data))))		{			iput(dir);			return -EACCES;		}		iput(dir);		return 0;	}	/* convert to wide string */	error=ntfs_decodeuni(NTFS_INO2VOL(dir),name,len,			     &walk.name,&walk.namelen);	if(error)		return error;	item=ntfs_malloc(ITEM_SIZE);	/* ntfs_getdir will place the directory entry into item,	   and the first long long is the MFT record number */	walk.type=BY_NAME;	walk.dir=(ntfs_inode*)dir->u.generic_ip;	walk.result=item;	if(ntfs_getdir_byname(&walk))	{		res=iget(dir->i_sb,NTFS_GETU32(item));		dcache_add(dir, name, len, NTFS_GETU32(item));	}	iput(dir);	*result=res;	ntfs_free(item);	ntfs_free(walk.name);	return res?0:-ENOENT;}static int ntfs_bmap(struct inode *ino,int block){	int ret=ntfs_vcn_to_lcn((ntfs_inode*)ino->u.generic_ip,block);	NTFS_DEBUG("bmap of %lx,block %x is %x\n",	       ino->i_ino,block,ret);	return (ret==-1) ? 0:ret;}struct file_operations ntfs_file_operations = {	NULL, /* lseek */	ntfs_read,	ntfs_write,	NULL, /* readdir */	NULL, /* select */	NULL, /* ioctl */	generic_file_mmap,	NULL, /* open */	NULL, /* release */	NULL, /* fsync */	NULL, /* fasync */	NULL, /* check_media_change */	NULL  /* revalidate */};struct inode_operations ntfs_inode_operations = {	&ntfs_file_operations,	NULL, /* create */	NULL, /* lookup */	NULL, /* link */	NULL, /* unlink */	NULL, /* symlink */	NULL, /* mkdir */	NULL, /* rmdir */	NULL, /* mknod */	NULL, /* rename */	NULL, /* readlink */	NULL, /* follow_link */	NULL, /* readpage */	NULL, /* writepage */	ntfs_bmap,	NULL, /* truncate */	NULL, /* permission */	NULL, /* smap */};struct file_operations ntfs_file_operations_nommap = {	NULL, /* lseek */	ntfs_read,	ntfs_write,	NULL, /* readdir */	NULL, /* select */	NULL, /* ioctl */	NULL, /* mmap */	NULL, /* open */	NULL, /* release */	NULL, /* fsync */	NULL, /* fasync */	NULL, /* check_media_change */	NULL  /* revalidate */};struct inode_operations ntfs_inode_operations_nobmap = {	&ntfs_file_operations_nommap,	NULL, /* create */	NULL, /* lookup */	NULL, /* link */	NULL, /* unlink */	NULL, /* symlink */	NULL, /* mkdir */	NULL, /* rmdir */	NULL, /* mknod */	NULL, /* rename */	NULL, /* readlink */	NULL, /* follow_link */	NULL, /* readpage */	NULL, /* writepage */	NULL, /* bmap */	NULL, /* truncate */	NULL, /* permission */	NULL, /* smap */};struct file_operations ntfs_dir_operations = {	NULL, /* lseek */	NULL, /* read */	NULL, /* write */	ntfs_readdir, /* readdir */	NULL, /* select */	NULL, /* ioctl */	NULL, /* mmap */	NULL, /* open */	NULL, /* release */	NULL, /* fsync */	NULL, /* fasync */	NULL, /* check_media_change */	NULL  /* revalidate */};struct inode_operations ntfs_dir_inode_operations = {	&ntfs_dir_operations,	NULL, /* create */	ntfs_lookup, /* lookup */	NULL, /* link */	NULL, /* unlink */	NULL, /* symlink */	NULL, /* mkdir */	NULL, /* rmdir */	NULL, /* mknod */	NULL, /* rename */	NULL, /* readlink */	NULL, /* follow_link */	NULL, /* readpage */	NULL, /* writepage */	NULL, /* bmap */	NULL, /* truncate */	NULL, /* permission */	NULL, /* smap */};struct super_operations ntfs_super_operations = {	ntfs_read_inode,	NULL, /* notify_change */	NULL, /* write_inode */	ntfs_put_inode,	ntfs_put_super,	NULL, /* write_super */	ntfs_statfs,	ntfs_remount_fs, /* remount */};/* This structure defines the filesystem * * Define SECOND if you cannot unload ntfs, and want to avoid rebooting * for just one more test */struct file_system_type ntfs_fs_type = {	ntfs_read_super,/* Entry point of the filesystem */#ifndef SECOND	"ntfs", /* Name of the filesystem, as used in mount -t ntfs */#else	"ntfs2",#endif	1,      /* The filesystem requires a block device to be mounted on */	NULL    /* Will point to the next filesystem in the kernel table */};int init_ntfs_fs(void){	/* Uncomment this if you don't trust klogd. There are reasons	   not to trust it. */#if 0	extern int console_loglevel;	console_loglevel=15;#endif	NTFS_DEBUG("registering %s\n",ntfs_fs_type.name);	printk(KERN_NOTICE "NTFS version " NTFS_VERSION "\n");	/* add this filesystem to the kernel table of filesystems */	return register_filesystem(&ntfs_fs_type);}#ifdef MODULE/* Every module must contain 2 particular functions whose names are predefined : * . init_module() is called by the kernel when kerneld loads the module in *     memory. Here is the real beginning of the code. * . cleanup_module() is called by the kernel when kerneld removes the module */#if (LINUX_VERSION_CODE > (2*65536 + 256 + 17))EXPORT_NO_SYMBOLS;MODULE_AUTHOR("Martin von L鰓is");/* no supported device *//* no parameters */#endifint init_module(void){	int error = init_ntfs_fs();#if (LINUX_VERSION_CODE < (2*65536 + 256 + 18))	if(!error)		register_symtab(0);#endif	return error;}void cleanup_module(void){	NTFS_DEBUG("unregistering %s\n",ntfs_fs_type.name);	unregister_filesystem(&ntfs_fs_type);}#endif/* These functions allow the rest of the ntfs code some generic interface   to the operating system */static char print_buf[1024];void ntfs_error(const char *fmt,...){	va_list ap;	va_start(ap,fmt);	strcpy(print_buf,KERN_ERR);	vsprintf(print_buf+3,fmt,ap);	printk(print_buf);	va_end(ap);}void ntfs_debug(const char *fmt,...){#ifdef DEBUG	va_list ap;	if(ntdebug & DEBUG_OTHER){		va_start(ap,fmt);		strcpy(print_buf,KERN_DEBUG);		vsprintf(print_buf+3,fmt,ap);		printk(print_buf);		va_end(ap);	}#endif}void *ntfs_malloc(int size){	void *ret=kmalloc(size,GFP_KERNEL);	if(ntdebug & DEBUG_MALLOC){		NTFS_DEBUG("Allocating %x at %x\n",size,(unsigned)ret);	}	return ret;}void ntfs_free(void *block){	if(ntdebug & DEBUG_MALLOC){		NTFS_DEBUG("Releasing memory at %x\n",(unsigned)block);	}	kfree(block);}int ntfs_getput_clusters(ntfs_volume *vol,int cluster,			 ntfs_size_t start_offs,			 ntfs_size_t length,ntfs_io *buf){	struct super_block *sb=NTFS_SB(vol);	struct buffer_head *bh;	ntfs_size_t to_copy;	if(buf->do_read)		NTFS_DEBUG("get_clusters %d %d %d\n",cluster,start_offs,length);	else		NTFS_DEBUG("put_clusters %d %d %d\n",cluster,start_offs,length);	while(length)	{		if(!(bh=bread(sb->s_dev,cluster,vol->clustersize)))		{			NTFS_DEBUG("%s failed\n", buf->do_read?"Reading":"Writing");			return 0;		}		to_copy=min(vol->clustersize-start_offs,length);		lock_buffer(bh);		if(buf->do_read)			buf->fn_put(buf,bh->b_data+start_offs,to_copy);		else		{			buf->fn_get(bh->b_data+start_offs,buf,to_copy);			mark_buffer_dirty(bh,1);		}		unlock_buffer(bh);		length-=to_copy;		start_offs=0;		cluster++;		brelse(bh);	}	return 1;}int ntfs_read_mft_record(ntfs_volume *vol,int mftno,char *buf){	ntfs_io io;	NTFS_DEBUG("read_mft_record %x\n",mftno);	if(mftno==FILE_MFT)	{		memcpy(buf,vol->mft,vol->mft_recordsize);		return 0;	}	if(!vol->mft_ino)	{		printk("ntfs:something is terribly wrong here\n");		return -1;	} 	io.fn_put=ntfs_put;	io.fn_get=0;	io.param=buf;	if(ntfs_read_attr(vol->mft_ino,AT_DATA,NULL,mftno*vol->mft_recordsize,			  &io,vol->mft_recordsize)!=vol->mft_recordsize)	{		NTFS_DEBUG("read_mft_record: read %x failed\n",mftno);		return -1;	}	NTFS_DEBUG("read_mft_record: finished read %x\n",mftno);	if(!ntfs_check_mft_record(vol,buf))	{		printk("Invalid MFT record for %x\n",mftno);		return -1;	}	NTFS_DEBUG("read_mft_record: Done %x\n",mftno);	return 0;}ntfs_time64_t ntfs_now(){	return ntfs_unixutc2ntutc(CURRENT_TIME);}/* * Local variables: *  c-file-style: "linux" * End: */

⌨️ 快捷键说明

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