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

📄 super.c

📁 ARM 嵌入式 系统 设计与实例开发 实验教材 二源码
💻 C
📖 第 1 页 / 共 3 页
字号:
{    int retval;    struct inode * inode;    struct cpu_key key;    INITIALIZE_PATH (path);    struct reiserfs_dir_entry de;    __u32 hash = DEFAULT_HASH;    inode = s->s_root->d_inode;    while (1) {	make_cpu_key (&key, inode, ~0, TYPE_DIRENTRY, 3);	retval = search_by_entry_key (s, &key, &path, &de);	if (retval == IO_ERROR) {	    pathrelse (&path);	    return UNSET_HASH ;	}	if (retval == NAME_NOT_FOUND)	    de.de_entry_num --;	set_de_name_and_namelen (&de);	if (deh_offset( &(de.de_deh[de.de_entry_num]) ) == DOT_DOT_OFFSET) {	    /* allow override in this case */	    if (reiserfs_rupasov_hash(s)) {		hash = YURA_HASH ;	    }	    reiserfs_warning("reiserfs: FS seems to be empty, autodetect "	                     "is using the default hash\n");	    break;	}	if (GET_HASH_VALUE(yura_hash (de.de_name, de.de_namelen)) == 	    GET_HASH_VALUE(keyed_hash (de.de_name, de.de_namelen))) {	    reiserfs_warning ("reiserfs: Could not detect hash function "			      "please mount with -o hash={tea,rupasov,r5}\n") ;	    hash = UNSET_HASH ;	    break;	}	if (GET_HASH_VALUE( deh_offset(&(de.de_deh[de.de_entry_num])) ) ==	    GET_HASH_VALUE (yura_hash (de.de_name, de.de_namelen)))	    hash = YURA_HASH;	else	    hash = TEA_HASH;	break;    }    pathrelse (&path);    return hash;}// finds out which hash names are sorted withstatic int what_hash (struct super_block * s){    __u32 code;    code = sb_hash_function_code(SB_DISK_SUPER_BLOCK(s));    /* reiserfs_hash_detect() == true if any of the hash mount options    ** were used.  We must check them to make sure the user isn't    ** using a bad hash value    */    if (code == UNSET_HASH || reiserfs_hash_detect(s))	code = find_hash_out (s);    if (code != UNSET_HASH && reiserfs_hash_detect(s)) {	/* detection has found the hash, and we must check against the 	** mount options 	*/	if (reiserfs_rupasov_hash(s) && code != YURA_HASH) {	    printk("REISERFS: Error, tea hash detected, "		   "unable to force rupasov hash\n") ;	    code = UNSET_HASH ;	} else if (reiserfs_tea_hash(s) && code != TEA_HASH) {	    printk("REISERFS: Error, rupasov hash detected, "		   "unable to force tea hash\n") ;	    code = UNSET_HASH ;	} else if (reiserfs_r5_hash(s) && code != R5_HASH) {	    printk("REISERFS: Error, r5 hash detected, "		   "unable to force r5 hash\n") ;	    code = UNSET_HASH ;	}     } else {         /* find_hash_out was not called or could not determine the hash */	if (reiserfs_rupasov_hash(s)) {	    code = YURA_HASH ;	} else if (reiserfs_tea_hash(s)) {	    code = TEA_HASH ;	} else if (reiserfs_r5_hash(s)) {	    code = R5_HASH ;	}     }    /* if we are mounted RW, and we have a new valid hash code, update     ** the super    */    if (code != UNSET_HASH && 	!(s->s_flags & MS_RDONLY) &&         code != sb_hash_function_code(SB_DISK_SUPER_BLOCK(s))) {        set_sb_hash_function_code(SB_DISK_SUPER_BLOCK(s), code);    }    return code;}// return pointer to appropriate functionstatic hashf_t hash_function (struct super_block * s){    switch (what_hash (s)) {    case TEA_HASH:	reiserfs_warning ("Using tea hash to sort names\n");	return keyed_hash;    case YURA_HASH:	reiserfs_warning ("Using rupasov hash to sort names\n");	return yura_hash;    case R5_HASH:	reiserfs_warning ("Using r5 hash to sort names\n");	return r5_hash;    }    return NULL;}// this is used to set up correct value for old partitionsint function2code (hashf_t func){    if (func == keyed_hash)	return TEA_HASH;    if (func == yura_hash)	return YURA_HASH;    if (func == r5_hash)	return R5_HASH;    BUG() ; // should never happen     return 0;}//// a portion of this function, particularly the VFS interface portion,// was derived from minix or ext2's analog and evolved as the// prototype did. You should be able to tell which portion by looking// at the ext2 code and comparing. It's subfunctions contain no code// used as a template unless they are so labeled.//static struct super_block * reiserfs_read_super (struct super_block * s, void * data, int silent){    int size;    struct inode *root_inode;    kdev_t dev = s->s_dev;    int j;    extern int *blksize_size[];    struct reiserfs_transaction_handle th ;    int old_format = 0;    unsigned long blocks;    int jinit_done = 0 ;    struct reiserfs_iget4_args args ;    int old_magic;    struct reiserfs_super_block * rs;    memset (&s->u.reiserfs_sb, 0, sizeof (struct reiserfs_sb_info));    if (parse_options ((char *) data, &(s->u.reiserfs_sb.s_mount_opt), &blocks) == 0) {	return NULL;    }    if (blocks) {  	printk("reserfs: resize option for remount only\n");	return NULL;    }	    if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)] != 0) {	/* as blocksize is set for partition we use it */	size = blksize_size[MAJOR(dev)][MINOR(dev)];    } else {	size = BLOCK_SIZE;	set_blocksize (s->s_dev, BLOCK_SIZE);    }    /* read block (64-th 1k block), which can contain reiserfs super block */    if (read_super_block (s, size, REISERFS_DISK_OFFSET_IN_BYTES)) {	// try old format (undistributed bitmap, super block in 8-th 1k block of a device)	if (read_super_block (s, size, REISERFS_OLD_DISK_OFFSET_IN_BYTES)) 	    goto error;	else	    old_format = 1;    }    s->u.reiserfs_sb.s_mount_state = SB_REISERFS_STATE(s);    s->u.reiserfs_sb.s_mount_state = REISERFS_VALID_FS ;    if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) { 	printk ("reiserfs_read_super: unable to read bitmap\n");	goto error;    }#ifdef CONFIG_REISERFS_CHECK    printk("reiserfs:warning: CONFIG_REISERFS_CHECK is set ON\n");    printk("reiserfs:warning: - it is slow mode for debugging.\n");#endif    // set_device_ro(s->s_dev, 1) ;    if (journal_init(s)) {	printk("reiserfs_read_super: unable to initialize journal space\n") ;	goto error ;    } else {	jinit_done = 1 ; /* once this is set, journal_release must be called			 ** if we error out of the mount 			 */    }    if (reread_meta_blocks(s)) {	printk("reiserfs_read_super: unable to reread meta blocks after journal init\n") ;	goto error ;    }    if (replay_only (s))	goto error;    if (is_read_only(s->s_dev) && !(s->s_flags & MS_RDONLY)) {        printk("clm-7000: Detected readonly device, marking FS readonly\n") ;	s->s_flags |= MS_RDONLY ;    }    args.objectid = REISERFS_ROOT_PARENT_OBJECTID ;    root_inode = iget4 (s, REISERFS_ROOT_OBJECTID, 0, (void *)(&args));    if (!root_inode) {	printk ("reiserfs_read_super: get root inode failed\n");	goto error;    }    s->s_root = d_alloc_root(root_inode);      if (!s->s_root) {	iput(root_inode);	goto error;    }    // define and initialize hash function    s->u.reiserfs_sb.s_hash_function = hash_function (s);    if (s->u.reiserfs_sb.s_hash_function == NULL) {      dput(s->s_root) ;      s->s_root = NULL ;      goto error ;    }    rs = SB_DISK_SUPER_BLOCK (s);    old_magic = strncmp (rs->s_magic,  REISER2FS_SUPER_MAGIC_STRING,                           strlen ( REISER2FS_SUPER_MAGIC_STRING));    if (!old_magic)	set_bit(REISERFS_3_6, &(s->u.reiserfs_sb.s_properties));    else	set_bit(REISERFS_3_5, &(s->u.reiserfs_sb.s_properties));    if (!(s->s_flags & MS_RDONLY)) {	journal_begin(&th, s, 1) ;	reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;        set_sb_state( rs, REISERFS_ERROR_FS );        if ( old_magic ) {	    // filesystem created under 3.5.x found	    if (convert_reiserfs (s)) {		reiserfs_warning("reiserfs: converting 3.5.x filesystem to the new format\n") ;		// after this 3.5.x will not be able to mount this partition		memcpy (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING, 			sizeof (REISER2FS_SUPER_MAGIC_STRING));		reiserfs_convert_objectid_map_v1(s) ;		set_bit(REISERFS_3_6, &(s->u.reiserfs_sb.s_properties));		clear_bit(REISERFS_3_5, &(s->u.reiserfs_sb.s_properties));	    } else {		reiserfs_warning("reiserfs: using 3.5.x disk format\n") ;	    }	}	journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));	journal_end(&th, s, 1) ;		/* look for files which were to be removed in previous session */	finish_unfinished (s);	s->s_dirt = 0;    } else {	if ( old_magic ) {	    reiserfs_warning("reiserfs: using 3.5.x disk format\n") ;	}    }    // mark hash in super block: it could be unset. overwrite should be ok    set_sb_hash_function_code( rs, function2code(s->u.reiserfs_sb.s_hash_function ) );    reiserfs_proc_info_init( s );    reiserfs_proc_register( s, "version", reiserfs_version_in_proc );    reiserfs_proc_register( s, "super", reiserfs_super_in_proc );    reiserfs_proc_register( s, "per-level", reiserfs_per_level_in_proc );    reiserfs_proc_register( s, "bitmap", reiserfs_bitmap_in_proc );    reiserfs_proc_register( s, "on-disk-super", reiserfs_on_disk_super_in_proc );    reiserfs_proc_register( s, "oidmap", reiserfs_oidmap_in_proc );    reiserfs_proc_register( s, "journal", reiserfs_journal_in_proc );    init_waitqueue_head (&(s->u.reiserfs_sb.s_wait));    printk("%s\n", reiserfs_get_version_string()) ;    return s; error:    if (jinit_done) { /* kill the commit thread, free journal ram */	journal_release_error(NULL, s) ;    }    if (SB_DISK_SUPER_BLOCK (s)) {	for (j = 0; j < SB_BMAP_NR (s); j ++) {	    if (SB_AP_BITMAP (s))		brelse (SB_AP_BITMAP (s)[j]);	}	if (SB_AP_BITMAP (s))	    reiserfs_kfree (SB_AP_BITMAP (s), sizeof (struct buffer_head *) * SB_BMAP_NR (s), s);    }    if (SB_BUFFER_WITH_SB (s))	brelse(SB_BUFFER_WITH_SB (s));    return NULL;}//// a portion of this function, particularly the VFS interface portion,// was derived from minix or ext2's analog and evolved as the// prototype did. You should be able to tell which portion by looking// at the ext2 code and comparing. It's subfunctions contain no code// used as a template unless they are so labeled.//static int reiserfs_statfs (struct super_block * s, struct statfs * buf){  struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s);  				/* changed to accomodate gcc folks.*/  buf->f_type    =  REISERFS_SUPER_MAGIC;  buf->f_bsize   = s->s_blocksize;  buf->f_blocks  = sb_block_count(rs) - sb_bmap_nr(rs) - 1;  buf->f_bfree   = sb_free_blocks(rs);  buf->f_bavail  = buf->f_bfree;  buf->f_files   = -1;  buf->f_ffree   = -1;  buf->f_namelen = (REISERFS_MAX_NAME_LEN (s->s_blocksize));  return 0;}static DECLARE_FSTYPE_DEV(reiserfs_fs_type,"reiserfs",reiserfs_read_super);//// this is exactly what 2.3.99-pre9's init_ext2_fs is//static int __init init_reiserfs_fs (void){	reiserfs_proc_info_global_init();	reiserfs_proc_register_global( "version", 				       reiserfs_global_version_in_proc );        return register_filesystem(&reiserfs_fs_type);}MODULE_DESCRIPTION("ReiserFS journaled filesystem");MODULE_AUTHOR("Hans Reiser <reiser@namesys.com>");MODULE_LICENSE("GPL");EXPORT_NO_SYMBOLS;//// this is exactly what 2.3.99-pre9's init_ext2_fs is//static void __exit exit_reiserfs_fs(void){	reiserfs_proc_unregister_global( "version" );	reiserfs_proc_info_global_done();        unregister_filesystem(&reiserfs_fs_type);}module_init(init_reiserfs_fs) ;module_exit(exit_reiserfs_fs) ;

⌨️ 快捷键说明

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