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

📄 super.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		 (1 << REISERFS_LARGETAIL) | (1 << REISERFS_SMALLTAIL)},		{"conv",.setmask = 1 << REISERFS_CONVERT},		{"attrs",.setmask = 1 << REISERFS_ATTRS},		{"noattrs",.clrmask = 1 << REISERFS_ATTRS},#ifdef CONFIG_REISERFS_FS_XATTR		{"user_xattr",.setmask = 1 << REISERFS_XATTRS_USER},		{"nouser_xattr",.clrmask = 1 << REISERFS_XATTRS_USER},#else		{"user_xattr",.setmask = 1 << REISERFS_UNSUPPORTED_OPT},		{"nouser_xattr",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT},#endif#ifdef CONFIG_REISERFS_FS_POSIX_ACL		{"acl",.setmask = 1 << REISERFS_POSIXACL},		{"noacl",.clrmask = 1 << REISERFS_POSIXACL},#else		{"acl",.setmask = 1 << REISERFS_UNSUPPORTED_OPT},		{"noacl",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT},#endif		{.option_name = "nolog"},		{"replayonly",.setmask = 1 << REPLAYONLY},		{"block-allocator",.arg_required = 'a',.values = balloc},		{"data",.arg_required = 'd',.values = logging_mode},		{"barrier",.arg_required = 'b',.values = barrier_mode},		{"resize",.arg_required = 'r',.values = NULL},		{"jdev",.arg_required = 'j',.values = NULL},		{"nolargeio",.arg_required = 'w',.values = NULL},		{"commit",.arg_required = 'c',.values = NULL},		{"usrquota",.setmask = 1 << REISERFS_QUOTA},		{"grpquota",.setmask = 1 << REISERFS_QUOTA},		{"noquota",.clrmask = 1 << REISERFS_QUOTA},		{"errors",.arg_required = 'e',.values = error_actions},		{"usrjquota",.arg_required =		 'u' | (1 << REISERFS_OPT_ALLOWEMPTY),.values = NULL},		{"grpjquota",.arg_required =		 'g' | (1 << REISERFS_OPT_ALLOWEMPTY),.values = NULL},		{"jqfmt",.arg_required = 'f',.values = NULL},		{.option_name = NULL}	};	*blocks = 0;	if (!options || !*options)		/* use default configuration: create tails, journaling on, no		   conversion to newest format */		return 1;	for (pos = options; pos;) {		c = reiserfs_getopt(s, &pos, opts, &arg, mount_options);		if (c == -1)			/* wrong option is given */			return 0;		if (c == 'r') {			char *p;			p = NULL;			/* "resize=NNN" or "resize=auto" */			if (!strcmp(arg, "auto")) {				/* From JFS code, to auto-get the size. */				*blocks =				    s->s_bdev->bd_inode->i_size >> s->				    s_blocksize_bits;			} else {				*blocks = simple_strtoul(arg, &p, 0);				if (*p != '\0') {					/* NNN does not look like a number */					reiserfs_warning(s,							 "reiserfs_parse_options: bad value %s",							 arg);					return 0;				}			}		}		if (c == 'c') {			char *p = NULL;			unsigned long val = simple_strtoul(arg, &p, 0);			/* commit=NNN (time in seconds) */			if (*p != '\0' || val >= (unsigned int)-1) {				reiserfs_warning(s,						 "reiserfs_parse_options: bad value %s",						 arg);				return 0;			}			*commit_max_age = (unsigned int)val;		}		if (c == 'w') {			reiserfs_warning(s, "reiserfs: nolargeio option is no longer supported");			return 0;		}		if (c == 'j') {			if (arg && *arg && jdev_name) {				if (*jdev_name) {	//Hm, already assigned?					reiserfs_warning(s,							 "reiserfs_parse_options: journal device was already  specified to be %s",							 *jdev_name);					return 0;				}				*jdev_name = arg;			}		}#ifdef CONFIG_QUOTA		if (c == 'u' || c == 'g') {			int qtype = c == 'u' ? USRQUOTA : GRPQUOTA;			if (sb_any_quota_enabled(s)) {				reiserfs_warning(s,						 "reiserfs_parse_options: cannot change journalled quota options when quota turned on.");				return 0;			}			if (*arg) {	/* Some filename specified? */				if (REISERFS_SB(s)->s_qf_names[qtype]				    && strcmp(REISERFS_SB(s)->s_qf_names[qtype],					      arg)) {					reiserfs_warning(s,							 "reiserfs_parse_options: %s quota file already specified.",							 QTYPE2NAME(qtype));					return 0;				}				if (strchr(arg, '/')) {					reiserfs_warning(s,							 "reiserfs_parse_options: quotafile must be on filesystem root.");					return 0;				}				REISERFS_SB(s)->s_qf_names[qtype] =				    kmalloc(strlen(arg) + 1, GFP_KERNEL);				if (!REISERFS_SB(s)->s_qf_names[qtype]) {					reiserfs_warning(s,							 "reiserfs_parse_options: not enough memory for storing quotafile name.");					return 0;				}				strcpy(REISERFS_SB(s)->s_qf_names[qtype], arg);				*mount_options |= 1 << REISERFS_QUOTA;			} else {				kfree(REISERFS_SB(s)->s_qf_names[qtype]);				REISERFS_SB(s)->s_qf_names[qtype] = NULL;			}		}		if (c == 'f') {			if (!strcmp(arg, "vfsold"))				REISERFS_SB(s)->s_jquota_fmt = QFMT_VFS_OLD;			else if (!strcmp(arg, "vfsv0"))				REISERFS_SB(s)->s_jquota_fmt = QFMT_VFS_V0;			else {				reiserfs_warning(s,						 "reiserfs_parse_options: unknown quota format specified.");				return 0;			}		}#else		if (c == 'u' || c == 'g' || c == 'f') {			reiserfs_warning(s,					 "reiserfs_parse_options: journalled quota options not supported.");			return 0;		}#endif	}#ifdef CONFIG_QUOTA	if (!REISERFS_SB(s)->s_jquota_fmt	    && (REISERFS_SB(s)->s_qf_names[USRQUOTA]		|| REISERFS_SB(s)->s_qf_names[GRPQUOTA])) {		reiserfs_warning(s,				 "reiserfs_parse_options: journalled quota format not specified.");		return 0;	}	/* This checking is not precise wrt the quota type but for our purposes it is sufficient */	if (!(*mount_options & (1 << REISERFS_QUOTA))	    && sb_any_quota_enabled(s)) {		reiserfs_warning(s,				 "reiserfs_parse_options: quota options must be present when quota is turned on.");		return 0;	}#endif	return 1;}static void switch_data_mode(struct super_block *s, unsigned long mode){	REISERFS_SB(s)->s_mount_opt &= ~((1 << REISERFS_DATA_LOG) |					 (1 << REISERFS_DATA_ORDERED) |					 (1 << REISERFS_DATA_WRITEBACK));	REISERFS_SB(s)->s_mount_opt |= (1 << mode);}static void handle_data_mode(struct super_block *s, unsigned long mount_options){	if (mount_options & (1 << REISERFS_DATA_LOG)) {		if (!reiserfs_data_log(s)) {			switch_data_mode(s, REISERFS_DATA_LOG);			reiserfs_info(s, "switching to journaled data mode\n");		}	} else if (mount_options & (1 << REISERFS_DATA_ORDERED)) {		if (!reiserfs_data_ordered(s)) {			switch_data_mode(s, REISERFS_DATA_ORDERED);			reiserfs_info(s, "switching to ordered data mode\n");		}	} else if (mount_options & (1 << REISERFS_DATA_WRITEBACK)) {		if (!reiserfs_data_writeback(s)) {			switch_data_mode(s, REISERFS_DATA_WRITEBACK);			reiserfs_info(s, "switching to writeback data mode\n");		}	}}static void handle_barrier_mode(struct super_block *s, unsigned long bits){	int flush = (1 << REISERFS_BARRIER_FLUSH);	int none = (1 << REISERFS_BARRIER_NONE);	int all_barrier = flush | none;	if (bits & all_barrier) {		REISERFS_SB(s)->s_mount_opt &= ~all_barrier;		if (bits & flush) {			REISERFS_SB(s)->s_mount_opt |= flush;			printk("reiserfs: enabling write barrier flush mode\n");		} else if (bits & none) {			REISERFS_SB(s)->s_mount_opt |= none;			printk("reiserfs: write barriers turned off\n");		}	}}static void handle_attrs(struct super_block *s){	struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s);	if (reiserfs_attrs(s)) {		if (old_format_only(s)) {			reiserfs_warning(s,					 "reiserfs: cannot support attributes on 3.5.x disk format");			REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS);			return;		}		if (!(le32_to_cpu(rs->s_flags) & reiserfs_attrs_cleared)) {			reiserfs_warning(s,					 "reiserfs: cannot support attributes until flag is set in super-block");			REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS);		}	}}static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg){	struct reiserfs_super_block *rs;	struct reiserfs_transaction_handle th;	unsigned long blocks;	unsigned long mount_options = REISERFS_SB(s)->s_mount_opt;	unsigned long safe_mask = 0;	unsigned int commit_max_age = (unsigned int)-1;	struct reiserfs_journal *journal = SB_JOURNAL(s);	int err;#ifdef CONFIG_QUOTA	int i;#endif	rs = SB_DISK_SUPER_BLOCK(s);	if (!reiserfs_parse_options	    (s, arg, &mount_options, &blocks, NULL, &commit_max_age)) {#ifdef CONFIG_QUOTA		for (i = 0; i < MAXQUOTAS; i++) {			kfree(REISERFS_SB(s)->s_qf_names[i]);			REISERFS_SB(s)->s_qf_names[i] = NULL;		}#endif		return -EINVAL;	}	handle_attrs(s);	/* Add options that are safe here */	safe_mask |= 1 << REISERFS_SMALLTAIL;	safe_mask |= 1 << REISERFS_LARGETAIL;	safe_mask |= 1 << REISERFS_NO_BORDER;	safe_mask |= 1 << REISERFS_NO_UNHASHED_RELOCATION;	safe_mask |= 1 << REISERFS_HASHED_RELOCATION;	safe_mask |= 1 << REISERFS_TEST4;	safe_mask |= 1 << REISERFS_ATTRS;	safe_mask |= 1 << REISERFS_XATTRS_USER;	safe_mask |= 1 << REISERFS_POSIXACL;	safe_mask |= 1 << REISERFS_BARRIER_FLUSH;	safe_mask |= 1 << REISERFS_BARRIER_NONE;	safe_mask |= 1 << REISERFS_ERROR_RO;	safe_mask |= 1 << REISERFS_ERROR_CONTINUE;	safe_mask |= 1 << REISERFS_ERROR_PANIC;	safe_mask |= 1 << REISERFS_QUOTA;	/* Update the bitmask, taking care to keep	 * the bits we're not allowed to change here */	REISERFS_SB(s)->s_mount_opt =	    (REISERFS_SB(s)->	     s_mount_opt & ~safe_mask) | (mount_options & safe_mask);	if (commit_max_age != 0 && commit_max_age != (unsigned int)-1) {		journal->j_max_commit_age = commit_max_age;		journal->j_max_trans_age = commit_max_age;	} else if (commit_max_age == 0) {		/* 0 means restore defaults. */		journal->j_max_commit_age = journal->j_default_max_commit_age;		journal->j_max_trans_age = JOURNAL_MAX_TRANS_AGE;	}	if (blocks) {		int rc = reiserfs_resize(s, blocks);		if (rc != 0)			return rc;	}	if (*mount_flags & MS_RDONLY) {		reiserfs_xattr_init(s, *mount_flags);		/* remount read-only */		if (s->s_flags & MS_RDONLY)			/* it is read-only already */			return 0;		/* try to remount file system with read-only permissions */		if (sb_umount_state(rs) == REISERFS_VALID_FS		    || REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) {			return 0;		}		err = journal_begin(&th, s, 10);		if (err)			return err;		/* Mounting a rw partition read-only. */		reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);		set_sb_umount_state(rs, REISERFS_SB(s)->s_mount_state);		journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));	} else {		/* remount read-write */		if (!(s->s_flags & MS_RDONLY)) {			reiserfs_xattr_init(s, *mount_flags);			return 0;	/* We are read-write already */		}		if (reiserfs_is_journal_aborted(journal))			return journal->j_errno;		handle_data_mode(s, mount_options);		handle_barrier_mode(s, mount_options);		REISERFS_SB(s)->s_mount_state = sb_umount_state(rs);		s->s_flags &= ~MS_RDONLY;	/* now it is safe to call journal_begin */		err = journal_begin(&th, s, 10);		if (err)			return err;		/* Mount a partition which is read-only, read-write */		reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);		REISERFS_SB(s)->s_mount_state = sb_umount_state(rs);		s->s_flags &= ~MS_RDONLY;		set_sb_umount_state(rs, REISERFS_ERROR_FS);		/* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1); */		journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));		REISERFS_SB(s)->s_mount_state = REISERFS_VALID_FS;	}	/* this will force a full flush of all journal lists */	SB_JOURNAL(s)->j_must_wait = 1;	err = journal_end(&th, s, 10);	if (err)		return err;	s->s_dirt = 0;	if (!(*mount_flags & MS_RDONLY)) {		finish_unfinished(s);		reiserfs_xattr_init(s, *mount_flags);	}	return 0;}static int read_super_block(struct super_block *s, int offset){	struct buffer_head *bh;	struct reiserfs_super_block *rs;	int fs_blocksize;	bh = sb_bread(s, offset / s->s_blocksize);	if (!bh) {		reiserfs_warning(s, "sh-2006: read_super_block: "				 "bread failed (dev %s, block %lu, size %lu)",				 reiserfs_bdevname(s), offset / s->s_blocksize,				 s->s_blocksize);		return 1;	}	rs = (struct reiserfs_super_block *)bh->b_data;	if (!is_any_reiserfs_magic_string(rs)) {		brelse(bh);		return 1;	}	//	// ok, reiserfs signature (old or new) found in at the given offset	//    	fs_blocksize = sb_blocksize(rs);	brelse(bh);	sb_set_blocksize(s, fs_blocksize);	bh = sb_bread(s, offset / s->s_blocksize);	if (!bh) {		reiserfs_warning(s, "sh-2007: read_super_block: "				 "bread failed (dev %s, block %lu, size %lu)\n",				 reiserfs_bdevname(s), offset / s->s_blocksize,				 s->s_blocksize);		return 1;	}	rs = (struct reiserfs_super_block *)bh->b_data;	if (sb_blocksize(rs) != s->s_blocksize) {		reiserfs_warning(s, "sh-2011: read_super_block: "				 "can't find a reiserfs filesystem on (dev %s, block %Lu, size %lu)\n",				 reiserfs_bdevname(s),				 (unsigned long long)bh->b_blocknr,				 s->s_blocksize);		brelse(bh);		return 1;	}	if (rs->s_v1.s_root_block == cpu_to_le32(-1)) {		brelse(bh);		reiserfs_warning(s,				 "Unfinished reiserfsck --rebuild-tree run detected. Please run\n"				 "reiserfsck --rebuild-tree and wait for a completion. If that fails\n"				 "get newer reiserfsprogs package");		return 1;	}	SB_BUFFER_WITH_SB(s) = bh;	SB_DISK_SUPER_BLOCK(s) = rs;	if (is_reiserfs_jr(rs)) {		/* magic is of non-standard journal filesystem, look at s_version to		   find which format is in use */		if (sb_version(rs) == REISERFS_VERSION_2)			reiserfs_warning(s,					 "read_super_block: found reiserfs format \"3.6\""					 " with non-standard journal");		else if (sb_version(rs) == REISERFS_VERSION_1)			reiserfs_warning(s,					 "read_super_block: found reiserfs format \"3.5\""

⌨️ 快捷键说明

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