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

📄 super.c

📁 ocfs1.4.1 oracle分布式文件系统
💻 C
📖 第 1 页 / 共 4 页
字号:
}static int ocfs2_sb_probe(struct super_block *sb,			  struct buffer_head **bh,			  int *sector_size){	int status, tmpstat;	struct ocfs1_vol_disk_hdr *hdr;	struct ocfs2_dinode *di;	int blksize;	*bh = NULL;	/* may be > 512 */	*sector_size = bdev_hardsect_size(sb->s_bdev);	if (*sector_size > OCFS2_MAX_BLOCKSIZE) {		mlog(ML_ERROR, "Hardware sector size too large: %d (max=%d)\n",		     *sector_size, OCFS2_MAX_BLOCKSIZE);		status = -EINVAL;		goto bail;	}	/* Can this really happen? */	if (*sector_size < OCFS2_MIN_BLOCKSIZE)		*sector_size = OCFS2_MIN_BLOCKSIZE;	/* check block zero for old format */	status = ocfs2_get_sector(sb, bh, 0, *sector_size);	if (status < 0) {		mlog_errno(status);		goto bail;	}	hdr = (struct ocfs1_vol_disk_hdr *) (*bh)->b_data;	if (hdr->major_version == OCFS1_MAJOR_VERSION) {		mlog(ML_ERROR, "incompatible version: %u.%u\n",		     hdr->major_version, hdr->minor_version);		status = -EINVAL;	}	if (memcmp(hdr->signature, OCFS1_VOLUME_SIGNATURE,		   strlen(OCFS1_VOLUME_SIGNATURE)) == 0) {		mlog(ML_ERROR, "incompatible volume signature: %8s\n",		     hdr->signature);		status = -EINVAL;	}	brelse(*bh);	*bh = NULL;	if (status < 0) {		mlog(ML_ERROR, "This is an ocfs v1 filesystem which must be "		     "upgraded before mounting with ocfs v2\n");		goto bail;	}	/*	 * Now check at magic offset for 512, 1024, 2048, 4096	 * blocksizes.  4096 is the maximum blocksize because it is	 * the minimum clustersize.	 */	status = -EINVAL;	for (blksize = *sector_size;	     blksize <= OCFS2_MAX_BLOCKSIZE;	     blksize <<= 1) {		tmpstat = ocfs2_get_sector(sb, bh,					   OCFS2_SUPER_BLOCK_BLKNO,					   blksize);		if (tmpstat < 0) {			status = tmpstat;			mlog_errno(status);			goto bail;		}		di = (struct ocfs2_dinode *) (*bh)->b_data;		status = ocfs2_verify_volume(di, *bh, blksize);		if (status >= 0)			goto bail;		brelse(*bh);		*bh = NULL;		if (status != -EAGAIN)			break;	}bail:	return status;}static int ocfs2_verify_heartbeat(struct ocfs2_super *osb){	if (ocfs2_mount_local(osb)) {		if (osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) {			mlog(ML_ERROR, "Cannot heartbeat on a locally "			     "mounted device.\n");			return -EINVAL;		}	}	if (!(osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL)) {		if (!ocfs2_mount_local(osb) && !ocfs2_is_hard_readonly(osb)) {			mlog(ML_ERROR, "Heartbeat has to be started to mount "			     "a read-write clustered device.\n");			return -EINVAL;		}	}	return 0;}static int ocfs2_fill_super(struct super_block *sb, void *data, int silent){	struct dentry *root;	int status, sector_size;	struct mount_options parsed_options;	struct inode *inode = NULL;	struct ocfs2_super *osb = NULL;	struct buffer_head *bh = NULL;	char nodestr[8];	mlog_entry("%p, %p, %i", sb, data, silent);	if (!ocfs2_parse_options(sb, data, &parsed_options, 0)) {		status = -EINVAL;		goto read_super_error;	}	/* for now we only have one cluster/node, make sure we see it	 * in the heartbeat universe */	if (parsed_options.mount_opt & OCFS2_MOUNT_HB_LOCAL) {		if (!o2hb_check_local_node_heartbeating()) {			status = -EINVAL;			goto read_super_error;		}	}	/* probe for superblock */	status = ocfs2_sb_probe(sb, &bh, &sector_size);	if (status < 0) {		mlog(ML_ERROR, "superblock probe failed!\n");		goto read_super_error;	}	status = ocfs2_initialize_super(sb, bh, sector_size);	osb = OCFS2_SB(sb);	if (status < 0) {		mlog_errno(status);		goto read_super_error;	}	brelse(bh);	bh = NULL;	osb->s_mount_opt = parsed_options.mount_opt;	osb->s_atime_quantum = parsed_options.atime_quantum;	osb->preferred_slot = parsed_options.slot;	osb->osb_commit_interval = parsed_options.commit_interval;	osb->local_alloc_size = parsed_options.localalloc_opt;#ifdef OCFS2_ORACORE_WORKAROUNDS	if (osb->s_mount_opt & OCFS2_MOUNT_COMPAT_OCFS)		sb->s_magic = OCFS_SUPER_MAGIC;	else#endif		sb->s_magic = OCFS2_SUPER_MAGIC;	/* Hard readonly mode only if: bdev_read_only, MS_RDONLY,	 * heartbeat=none */	if (bdev_read_only(sb->s_bdev)) {		if (!(sb->s_flags & MS_RDONLY)) {			status = -EACCES;			mlog(ML_ERROR, "Readonly device detected but readonly "			     "mount was not specified.\n");			goto read_super_error;		}		/* You should not be able to start a local heartbeat		 * on a readonly device. */		if (osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) {			status = -EROFS;			mlog(ML_ERROR, "Local heartbeat specified on readonly "			     "device.\n");			goto read_super_error;		}		status = ocfs2_check_journals_nolocks(osb);		if (status < 0) {			if (status == -EROFS)				mlog(ML_ERROR, "Recovery required on readonly "				     "file system, but write access is "				     "unavailable.\n");			else				mlog_errno(status);						goto read_super_error;		}		ocfs2_set_ro_flag(osb, 1);		printk(KERN_NOTICE "Readonly device detected. No cluster "		       "services will be utilized for this mount. Recovery "		       "will be skipped.\n");	}	if (!ocfs2_is_hard_readonly(osb)) {		if (sb->s_flags & MS_RDONLY)			ocfs2_set_ro_flag(osb, 0);	}	status = ocfs2_verify_heartbeat(osb);	if (status < 0) {		mlog_errno(status);		goto read_super_error;	}	osb->osb_debug_root = debugfs_create_dir(osb->uuid_str,						 ocfs2_debugfs_root);	if (!osb->osb_debug_root) {		status = -EINVAL;		mlog(ML_ERROR, "Unable to create per-mount debugfs root.\n");		goto read_super_error;	}	status = ocfs2_mount_volume(sb);	if (osb->root_inode)		inode = igrab(osb->root_inode);	if (status < 0)		goto read_super_error;	if (!inode) {		status = -EIO;		mlog_errno(status);		goto read_super_error;	}	root = d_alloc_root(inode);	if (!root) {		status = -ENOMEM;		mlog_errno(status);		goto read_super_error;	}	sb->s_root = root;	ocfs2_complete_mount_recovery(osb);	if (ocfs2_mount_local(osb))		snprintf(nodestr, sizeof(nodestr), "local");	else		snprintf(nodestr, sizeof(nodestr), "%d", osb->node_num);	printk(KERN_INFO "ocfs2: Mounting device (%s) on (node %s, slot %d) "	       "with %s data mode.\n",	       osb->dev_str, nodestr, osb->slot_num,	       osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK ? "writeback" :	       "ordered");	atomic_set(&osb->vol_state, VOLUME_MOUNTED);	wake_up(&osb->osb_mount_event);#ifdef HAS_MS_LOOP_NO_AOPS	/* OCFS2 1.4 doesn't provide prepare and commit write operations */	sb->s_flags |= MS_LOOP_NO_AOPS;#endif	mlog_exit(status);	return status;read_super_error:	if (bh != NULL)		brelse(bh);	if (inode)		iput(inode);	if (osb) {		atomic_set(&osb->vol_state, VOLUME_DISABLED);		wake_up(&osb->osb_mount_event);		ocfs2_dismount_volume(sb, 1);	}	mlog_exit(status);	return status;}#ifdef NO_VFSMOUNT_IN_GET_SB_BDEVstatic struct super_block *ocfs2_get_sb(struct file_system_type *fs_type,					int flags,					const char *dev_name,					void *data){	return get_sb_bdev(fs_type, flags, dev_name, data, ocfs2_fill_super);}#elsestatic int ocfs2_get_sb(struct file_system_type *fs_type,			int flags,			const char *dev_name,			void *data,			struct vfsmount *mnt){	return get_sb_bdev(fs_type, flags, dev_name, data, ocfs2_fill_super,			   mnt);}#endifstatic struct file_system_type ocfs2_fs_type = {	.owner          = THIS_MODULE,	.name           = "ocfs2",	.get_sb         = ocfs2_get_sb, /* is this called when we mount					* the fs? */	.kill_sb        = kill_block_super, /* set to the generic one					     * right now, but do we					     * need to change that? */	.fs_flags       = FS_REQUIRES_DEV|FS_RENAME_DOES_D_MOVE,	.next           = NULL};static int ocfs2_parse_options(struct super_block *sb,			       char *options,			       struct mount_options *mopt,			       int is_remount){	int status;	char *p;	mlog_entry("remount: %d, options: \"%s\"\n", is_remount,		   options ? options : "(none)");	mopt->commit_interval = 0;	mopt->mount_opt = 0;	mopt->atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM;	mopt->slot = OCFS2_INVALID_SLOT;	mopt->localalloc_opt = OCFS2_DEFAULT_LOCAL_ALLOC_SIZE;	if (!options) {		status = 1;		goto bail;	}	while ((p = strsep(&options, ",")) != NULL) {		int token, option;		substring_t args[MAX_OPT_ARGS];		if (!*p)			continue;		token = match_token(p, tokens, args);		switch (token) {		case Opt_hb_local:			mopt->mount_opt |= OCFS2_MOUNT_HB_LOCAL;			break;		case Opt_hb_none:			mopt->mount_opt &= ~OCFS2_MOUNT_HB_LOCAL;			break;		case Opt_barrier:			if (match_int(&args[0], &option)) {				status = 0;				goto bail;			}			if (option)				mopt->mount_opt |= OCFS2_MOUNT_BARRIER;			else				mopt->mount_opt &= ~OCFS2_MOUNT_BARRIER;			break;		case Opt_intr:			mopt->mount_opt &= ~OCFS2_MOUNT_NOINTR;			break;		case Opt_nointr:			mopt->mount_opt |= OCFS2_MOUNT_NOINTR;			break;		case Opt_err_panic:			mopt->mount_opt |= OCFS2_MOUNT_ERRORS_PANIC;			break;		case Opt_err_ro:			mopt->mount_opt &= ~OCFS2_MOUNT_ERRORS_PANIC;			break;		case Opt_data_ordered:			mopt->mount_opt &= ~OCFS2_MOUNT_DATA_WRITEBACK;			break;		case Opt_data_writeback:			mopt->mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK;			break;#ifdef OCFS2_ORACORE_WORKAROUNDS		case Opt_datavolume:			if (is_remount) {				mlog(ML_ERROR, "Cannot specify datavolume "				     "on remount.\n");				status = 0;				goto bail;			}			mopt->mount_opt |= OCFS2_MOUNT_COMPAT_OCFS;			break;#endif		case Opt_atime_quantum:			if (match_int(&args[0], &option)) {				status = 0;				goto bail;			}			if (option >= 0)				mopt->atime_quantum = option;			break;		case Opt_slot:			option = 0;			if (match_int(&args[0], &option)) {				status = 0;				goto bail;			}			if (option)				mopt->slot = (s16)option;			break;		case Opt_commit:			option = 0;			if (match_int(&args[0], &option)) {				status = 0;				goto bail;			}			if (option < 0)				return 0;			if (option == 0)				option = JBD_DEFAULT_MAX_COMMIT_AGE;			mopt->commit_interval = HZ * option;			break;		case Opt_localalloc:			option = 0;			if (match_int(&args[0], &option)) {				status = 0;				goto bail;			}			if (option >= 0 && (option <= ocfs2_local_alloc_size(sb) * 8))				mopt->localalloc_opt = option;			break;		case Opt_localflocks:			/*			 * Changing this during remount could race			 * flock() requests, or "unbalance" existing			 * ones (e.g., a lock is taken in one mode but			 * dropped in the other). If users care enough			 * to flip locking modes during remount, we			 * could add a "local" flag to individual			 * flock structures for proper tracking of			 * state.			 */			if (!is_remount)				mopt->mount_opt |= OCFS2_MOUNT_LOCALFLOCKS;			break;		default:			mlog(ML_ERROR,			     "Unrecognized mount option \"%s\" "			     "or missing value\n", p);			status = 0;			goto bail;		}	}	status = 1;bail:	mlog_exit(status);	return status;}static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt){	struct ocfs2_super *osb = OCFS2_SB(mnt->mnt_sb);	unsigned long opts = osb->s_mount_opt;	if (opts & OCFS2_MOUNT_HB_LOCAL)		seq_printf(s, ",_netdev,heartbeat=local");	else		seq_printf(s, ",heartbeat=none");	if (opts & OCFS2_MOUNT_NOINTR)		seq_printf(s, ",nointr");	if (opts & OCFS2_MOUNT_DATA_WRITEBACK)		seq_printf(s, ",data=writeback");	else		seq_printf(s, ",data=ordered");	if (opts & OCFS2_MOUNT_BARRIER)		seq_printf(s, ",barrier=1");	if (opts & OCFS2_MOUNT_ERRORS_PANIC)		seq_printf(s, ",errors=panic");	else		seq_printf(s, ",errors=remount-ro");

⌨️ 快捷键说明

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