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

📄 super.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
					 " with non-standard journal");		else {			reiserfs_warning(s,					 "sh-2012: read_super_block: found unknown "					 "format \"%u\" of reiserfs with non-standard magic",					 sb_version(rs));			return 1;		}	} else		/* s_version of standard format may contain incorrect information,		   so we just look at the magic string */		reiserfs_info(s,			      "found reiserfs format \"%s\" with standard journal\n",			      is_reiserfs_3_5(rs) ? "3.5" : "3.6");	s->s_op = &reiserfs_sops;	s->s_export_op = &reiserfs_export_ops;#ifdef CONFIG_QUOTA	s->s_qcop = &reiserfs_qctl_operations;	s->dq_op = &reiserfs_quota_operations;#endif	/* new format is limited by the 32 bit wide i_blocks field, want to	 ** be one full block below that.	 */	s->s_maxbytes = (512LL << 32) - s->s_blocksize;	return 0;}/* after journal replay, reread all bitmap and super blocks */static int reread_meta_blocks(struct super_block *s){	ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s)));	wait_on_buffer(SB_BUFFER_WITH_SB(s));	if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) {		reiserfs_warning(s,				 "reread_meta_blocks, error reading the super");		return 1;	}	return 0;}/////////////////////////////////////////////////////// hash detection stuff// if root directory is empty - we set default - Yura's - hash and// warn about it// FIXME: we look for only one name in a directory. If tea and yura// bith have the same value - we ask user to send report to the// mailing liststatic __u32 find_hash_out(struct super_block *s){	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;	do {			// Some serious "goto"-hater was there ;)		u32 teahash, r5hash, yurahash;		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(s, "FS seems to be empty, autodetect "					 "is using the default hash");			break;		}		r5hash = GET_HASH_VALUE(r5_hash(de.de_name, de.de_namelen));		teahash = GET_HASH_VALUE(keyed_hash(de.de_name, de.de_namelen));		yurahash = GET_HASH_VALUE(yura_hash(de.de_name, de.de_namelen));		if (((teahash == r5hash)		     &&		     (GET_HASH_VALUE(deh_offset(&(de.de_deh[de.de_entry_num])))		      == r5hash)) || ((teahash == yurahash)				      && (yurahash ==					  GET_HASH_VALUE(deh_offset							 (&							  (de.							   de_deh[de.								  de_entry_num])))))		    || ((r5hash == yurahash)			&& (yurahash ==			    GET_HASH_VALUE(deh_offset					   (&(de.de_deh[de.de_entry_num])))))) {			reiserfs_warning(s,					 "Unable to automatically detect hash function. "					 "Please mount with -o hash={tea,rupasov,r5}",					 reiserfs_bdevname(s));			hash = UNSET_HASH;			break;		}		if (GET_HASH_VALUE(deh_offset(&(de.de_deh[de.de_entry_num]))) ==		    yurahash)			hash = YURA_HASH;		else if (GET_HASH_VALUE			 (deh_offset(&(de.de_deh[de.de_entry_num]))) == teahash)			hash = TEA_HASH;		else if (GET_HASH_VALUE			 (deh_offset(&(de.de_deh[de.de_entry_num]))) == r5hash)			hash = R5_HASH;		else {			reiserfs_warning(s, "Unrecognised hash function");			hash = UNSET_HASH;		}	} while (0);	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) {			reiserfs_warning(s, "Error, %s hash detected, "					 "unable to force rupasov hash",					 reiserfs_hashname(code));			code = UNSET_HASH;		} else if (reiserfs_tea_hash(s) && code != TEA_HASH) {			reiserfs_warning(s, "Error, %s hash detected, "					 "unable to force tea hash",					 reiserfs_hashname(code));			code = UNSET_HASH;		} else if (reiserfs_r5_hash(s) && code != R5_HASH) {			reiserfs_warning(s, "Error, %s hash detected, "					 "unable to force r5 hash",					 reiserfs_hashname(code));			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_info(s, "Using tea hash to sort names\n");		return keyed_hash;	case YURA_HASH:		reiserfs_info(s, "Using rupasov hash to sort names\n");		return yura_hash;	case R5_HASH:		reiserfs_info(s, "Using r5 hash to sort names\n");		return r5_hash;	}	return NULL;}// this is used to set up correct value for old partitionsstatic int 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;}#define SWARN(silent, s, ...)			\	if (!(silent))				\		reiserfs_warning (s, __VA_ARGS__)static int reiserfs_fill_super(struct super_block *s, void *data, int silent){	struct inode *root_inode;	struct reiserfs_transaction_handle th;	int old_format = 0;	unsigned long blocks;	unsigned int commit_max_age = 0;	int jinit_done = 0;	struct reiserfs_iget_args args;	struct reiserfs_super_block *rs;	char *jdev_name;	struct reiserfs_sb_info *sbi;	int errval = -EINVAL;	sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL);	if (!sbi) {		errval = -ENOMEM;		goto error;	}	s->s_fs_info = sbi;	/* Set default values for options: non-aggressive tails, RO on errors */	REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL);	REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ERROR_RO);	/* no preallocation minimum, be smart in	   reiserfs_file_write instead */	REISERFS_SB(s)->s_alloc_options.preallocmin = 0;	/* Preallocate by 16 blocks (17-1) at once */	REISERFS_SB(s)->s_alloc_options.preallocsize = 17;#ifdef CONFIG_REISERFS_FS_XATTR	/* Initialize the rwsem for xattr dir */	init_rwsem(&REISERFS_SB(s)->xattr_dir_sem);#endif	/* setup default block allocator options */	reiserfs_init_alloc_options(s);	jdev_name = NULL;	if (reiserfs_parse_options	    (s, (char *)data, &(sbi->s_mount_opt), &blocks, &jdev_name,	     &commit_max_age) == 0) {		goto error;	}	if (blocks) {		SWARN(silent, s, "jmacd-7: reiserfs_fill_super: resize option "		      "for remount only");		goto error;	}	/* try old format (undistributed bitmap, super block in 8-th 1k block of a device) */	if (!read_super_block(s, REISERFS_OLD_DISK_OFFSET_IN_BYTES))		old_format = 1;	/* try new format (64-th 1k block), which can contain reiserfs super block */	else if (read_super_block(s, REISERFS_DISK_OFFSET_IN_BYTES)) {		SWARN(silent, s,		      "sh-2021: reiserfs_fill_super: can not find reiserfs on %s",		      reiserfs_bdevname(s));		goto error;	}	rs = SB_DISK_SUPER_BLOCK(s);	/* Let's do basic sanity check to verify that underlying device is not	   smaller than the filesystem. If the check fails then abort and scream,	   because bad stuff will happen otherwise. */	if (s->s_bdev && s->s_bdev->bd_inode	    && i_size_read(s->s_bdev->bd_inode) <	    sb_block_count(rs) * sb_blocksize(rs)) {		SWARN(silent, s,		      "Filesystem on %s cannot be mounted because it is bigger than the device",		      reiserfs_bdevname(s));		SWARN(silent, s,		      "You may need to run fsck or increase size of your LVM partition");		SWARN(silent, s,		      "Or may be you forgot to reboot after fdisk when it told you to");		goto error;	}	sbi->s_mount_state = SB_REISERFS_STATE(s);	sbi->s_mount_state = REISERFS_VALID_FS;	if ((errval = reiserfs_init_bitmap_cache(s))) {		SWARN(silent, s,		      "jmacd-8: reiserfs_fill_super: unable to read bitmap");		goto error;	}	errval = -EINVAL;#ifdef CONFIG_REISERFS_CHECK	SWARN(silent, s, "CONFIG_REISERFS_CHECK is set ON");	SWARN(silent, s, "- it is slow mode for debugging.");#endif	/* make data=ordered the default */	if (!reiserfs_data_log(s) && !reiserfs_data_ordered(s) &&	    !reiserfs_data_writeback(s)) {		REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_DATA_ORDERED);	}	if (reiserfs_data_log(s)) {		reiserfs_info(s, "using journaled data mode\n");	} else if (reiserfs_data_ordered(s)) {		reiserfs_info(s, "using ordered data mode\n");	} else {		reiserfs_info(s, "using writeback data mode\n");	}	if (reiserfs_barrier_flush(s)) {		printk("reiserfs: using flush barriers\n");	}	// set_device_ro(s->s_dev, 1) ;	if (journal_init(s, jdev_name, old_format, commit_max_age)) {		SWARN(silent, s,		      "sh-2022: reiserfs_fill_super: unable to initialize journal space");		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)) {		SWARN(silent, s,		      "jmacd-9: reiserfs_fill_super: unable to reread meta blocks after journal init");		goto error;	}	if (replay_only(s))		goto error;	if (bdev_read_only(s->s_bdev) && !(s->s_flags & MS_RDONLY)) {		SWARN(silent, s,		      "clm-7000: Detected readonly device, marking FS readonly");		s->s_flags |= MS_RDONLY;	}	args.objectid = REISERFS_ROOT_OBJECTID;	args.dirid = REISERFS_ROOT_PARENT_OBJECTID;	root_inode =	    iget5_locked(s, REISERFS_ROOT_OBJECTID, reiserfs_find_actor,			 reiserfs_init_locked_inode, (void *)(&args));	if (!root_inode) {		SWARN(silent, s,		      "jmacd-10: reiserfs_fill_super: get root inode failed");		goto error;	}	if (root_inode->i_state & I_NEW) {		reiserfs_read_locked_inode(root_inode, &args);		unlock_new_inode(root_inode);	}	s->s_root = d_alloc_root(root_inode);	if (!s->s_root) {		iput(root_inode);		goto error;	}	// define and initialize hash function	sbi->s_hash_function = hash_function(s);	if (sbi->s_hash_function == NULL) {		dput(s->s_root);		s->s_root = NULL;		goto error;	}	if (is_reiserfs_3_5(rs)	    || (is_reiserfs_jr(rs) && SB_VERSION(s) == REISERFS_VERSION_1))		set_bit(REISERFS_3_5, &(sbi->s_properties));	else if (old_format)		set_bit(REISERFS_OLD_FORMAT, &(sbi->s_properties));	else		set_bit(REISERFS_3_6, &(sbi->s_properties));	if (!(s->s_flags & MS_RDONLY)) {		errval = journal_begin(&th, s, 1);		if (errval) {			dput(s->s_root);			s->s_root = NULL;			goto error;		}		reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);		set_sb_umount_state(rs, REISERFS_ERROR_FS);		set_sb_fs_state(rs, 0);		/* Clear out s_bmap_nr if it would wrap. We can handle this		 * case, but older revisions can't. This will cause the		 * file system to fail mount on those older implementations,		 * avoiding corruption. -jeffm */		if (bmap_would_wrap(reiserfs_bmap_count(s)) &&		    sb_bmap_nr(rs) != 0) {			reiserfs_warning(s, "super-2030: This file system "					"claims to use %u bitmap blocks in "					"its super block, but requires %u. "					"Clearing to zero.", sb_bmap_nr(rs),					reiserfs_bmap_count(s));			set_sb_bmap_nr(rs, 0);		}		if (old_format_only(s)) {			/* filesystem of format 3.5 either with standard or non-standard			   journal */			if (convert_reiserfs(s)) {				/* and -o conv is given */				if (!silent)					reiserfs_info(s,						      "converting 3.5 filesystem to the 3.6 format");				if (is_reiserfs_3_5(rs))					/* put magic string of 3.6 format. 2.2 will not be able to					   mount this filesystem anymore */					memcpy(rs->s_v1.s_magic,					       reiserfs_3_6_magic_string,					       sizeof					       (reiserfs_3_6_magic_string));				set_sb_version(rs, REISERFS_VERSION_2);				reiserfs_convert_objectid_map_v1(s);				set_bit(REISERFS_3_6, &(sbi->s_properties));				clear_bit(REISERFS_3_5, &(sbi->s_properties));			} else if (!silent) {				reiserfs_info(s, "using 3.5.x disk format\n");			}		}		journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));		errval = journal_end(&th, s, 1);		if (errval) {			dput(s->s_root);

⌨️ 快捷键说明

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