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

📄 super.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
			     "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);	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;}static 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);}static 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->mount_opt = 0;	mopt->atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM;	mopt->slot = OCFS2_INVALID_SLOT;	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;		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;		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");	if (osb->preferred_slot != OCFS2_INVALID_SLOT)		seq_printf(s, ",preferred_slot=%d", osb->preferred_slot);	if (osb->s_atime_quantum != OCFS2_DEFAULT_ATIME_QUANTUM)		seq_printf(s, ",atime_quantum=%u", osb->s_atime_quantum);	return 0;}static int __init ocfs2_init(void){	int status;	mlog_entry_void();	ocfs2_print_version();	status = init_ocfs2_uptodate_cache();	if (status < 0) {		mlog_errno(status);		goto leave;	}	status = ocfs2_initialize_mem_caches();	if (status < 0) {		mlog_errno(status);		goto leave;	}	ocfs2_wq = create_singlethread_workqueue("ocfs2_wq");	if (!ocfs2_wq) {		status = -ENOMEM;		goto leave;	}	ocfs2_debugfs_root = debugfs_create_dir("ocfs2", NULL);	if (!ocfs2_debugfs_root) {		status = -EFAULT;		mlog(ML_ERROR, "Unable to create ocfs2 debugfs root.\n");	}leave:	if (status < 0) {		ocfs2_free_mem_caches();		exit_ocfs2_uptodate_cache();	}	mlog_exit(status);	if (status >= 0) {		return register_filesystem(&ocfs2_fs_type);	} else		return -1;}static void __exit ocfs2_exit(void){	mlog_entry_void();	if (ocfs2_wq) {		flush_workqueue(ocfs2_wq);		destroy_workqueue(ocfs2_wq);	}	debugfs_remove(ocfs2_debugfs_root);	ocfs2_free_mem_caches();	unregister_filesystem(&ocfs2_fs_type);	exit_ocfs2_uptodate_cache();	mlog_exit_void();}static void ocfs2_put_super(struct super_block *sb){	mlog_entry("(0x%p)\n", sb);	ocfs2_sync_blockdev(sb);	ocfs2_dismount_volume(sb, 0);	mlog_exit_void();}static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf){	struct ocfs2_super *osb;	u32 numbits, freebits;	int status;	struct ocfs2_dinode *bm_lock;	struct buffer_head *bh = NULL;	struct inode *inode = NULL;	mlog_entry("(%p, %p)\n", dentry->d_sb, buf);	osb = OCFS2_SB(dentry->d_sb);	inode = ocfs2_get_system_file_inode(osb,					    GLOBAL_BITMAP_SYSTEM_INODE,					    OCFS2_INVALID_SLOT);	if (!inode) {		mlog(ML_ERROR, "failed to get bitmap inode\n");		status = -EIO;		goto bail;	}	status = ocfs2_meta_lock(inode, &bh, 0);	if (status < 0) {		mlog_errno(status);		goto bail;	}	bm_lock = (struct ocfs2_dinode *) bh->b_data;	numbits = le32_to_cpu(bm_lock->id1.bitmap1.i_total);	freebits = numbits - le32_to_cpu(bm_lock->id1.bitmap1.i_used);	buf->f_type = OCFS2_SUPER_MAGIC;	buf->f_bsize = dentry->d_sb->s_blocksize;	buf->f_namelen = OCFS2_MAX_FILENAME_LEN;	buf->f_blocks = ((sector_t) numbits) *			(osb->s_clustersize >> osb->sb->s_blocksize_bits);	buf->f_bfree = ((sector_t) freebits) *		       (osb->s_clustersize >> osb->sb->s_blocksize_bits);	buf->f_bavail = buf->f_bfree;	buf->f_files = numbits;	buf->f_ffree = freebits;	brelse(bh);	ocfs2_meta_unlock(inode, 0);	status = 0;bail:	if (inode)		iput(inode);	mlog_exit(status);	return status;}static void ocfs2_inode_init_once(struct kmem_cache *cachep, void *data){	struct ocfs2_inode_info *oi = data;	oi->ip_flags = 0;	oi->ip_open_count = 0;	spin_lock_init(&oi->ip_lock);	ocfs2_extent_map_init(&oi->vfs_inode);	INIT_LIST_HEAD(&oi->ip_io_markers);	oi->ip_created_trans = 0;	oi->ip_last_trans = 0;	oi->ip_dir_start_lookup = 0;	init_rwsem(&oi->ip_alloc_sem);	mutex_init(&oi->ip_io_mutex);	oi->ip_blkno = 0ULL;	oi->ip_clusters = 0;	ocfs2_lock_res_init_once(&oi->ip_rw_lockres);	ocfs2_lock_res_init_once(&oi->ip_meta_lockres);	ocfs2_lock_res_init_once(&oi->ip_data_lockres);	ocfs2_lock_res_init_once(&oi->ip_open_lockres);	ocfs2_metadata_cache_init(&oi->vfs_inode);	inode_init_once(&oi->vfs_inode);}static int ocfs2_initialize_mem_caches(void){	ocfs2_inode_cachep = kmem_cache_create("ocfs2_inode_cache",				       sizeof(struct ocfs2_inode_info),				       0,				       (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|						SLAB_MEM_SPREAD),				       ocfs2_inode_init_once);	if (!ocfs2_inode_cachep)		return -ENOMEM;	return 0;}static void ocfs2_free_mem_caches(void){	if (ocfs2_inode_cachep)		kmem_cache_destroy(ocfs2_inode_cachep);	ocfs2_inode_cachep = NULL;}static int ocfs2_get_sector(struct super_block *sb,			    struct buffer_head **bh,			    int block,			    int sect_size){	if (!sb_set_blocksize(sb, sect_size)) {		mlog(ML_ERROR, "unable to set blocksize\n");		return -EIO;	}	*bh = sb_getblk(sb, block);	if (!*bh) {		mlog_errno(-EIO);		return -EIO;	}	lock_buffer(*bh);	if (!buffer_dirty(*bh))		clear_buffer_uptodate(*bh);	unlock_buffer(*bh);	ll_rw_block(READ, 1, bh);	wait_on_buffer(*bh);	return 0;}/* ocfs2 1.0 only allows one cluster and node identity per kernel image. */static int ocfs2_fill_local_node_info(struct ocfs2_super *osb){	int status;	/* XXX hold a ref on the node while mounte?  easy enough, if	 * desirable. */	if (ocfs2_mount_local(osb))		osb->node_num = 0;	else		osb->node_num = o2nm_this_node();	if (osb->node_num == O2NM_MAX_NODES) {		mlog(ML_ERROR, "could not find this host's node number\n");		status = -ENOENT;		goto bail;	}	mlog(0, "I am node %d\n", osb->node_num);	status = 0;bail:	return status;}static int ocfs2_mount_volume(struct super_block *sb){	int status = 0;	int unlock_super = 0;	struct ocfs2_super *osb = OCFS2_SB(sb);	mlog_entry_void();	if (ocfs2_is_hard_readonly(osb))		goto leave;	status = ocfs2_fill_local_node_info(osb);	if (status < 0) {		mlog_errno(status);		goto leave;	}	status = ocfs2_register_hb_callbacks(osb);	if (status < 0) {		mlog_errno(status);		goto leave;	}	status = ocfs2_dlm_init(osb);	if (status < 0) {		mlog_errno(status);		goto leave;	}	/* requires vote_thread to be running. */	status = ocfs2_register_net_handlers(osb);	if (status < 0) {		mlog_errno(status);		goto leave;	}	status = ocfs2_super_lock(osb, 1);	if (status < 0) {		mlog_errno(status);		goto leave;	}	unlock_super = 1;	/* This will load up the node map and add ourselves to it. */	status = ocfs2_find_slot(osb);	if (status < 0) {		mlog_errno(status);		goto leave;	}	ocfs2_populate_mounted_map(osb);	/* load all node-local system inodes */	status = ocfs2_init_local_system_inodes(osb);	if (status < 0) {		mlog_errno(status);		goto leave;	}	status = ocfs2_check_volume(osb);	if (status < 0) {		mlog_errno(status);		goto leave;	}	status = ocfs2_truncate_log_init(osb);	if (status < 0) {		mlog_errno(status);		goto leave;	}	if (ocfs2_mount_local(osb))		goto leave;	/* This should be sent *after* we recovered our journal as it	 * will cause other nodes to unmark us as needing	 * recovery. However, we need to send it *before* dropping the	 * super block lock as otherwise their recovery threads might	 * try to clean us up while we're live! */	status = ocfs2_request_mount_vote(osb);	if (status < 0)		mlog_errno(status);leave:	if (unlock_super)		ocfs2_super_unlock(osb, 1);	mlog_exit(status);	return status;}/* we can't grab the goofy sem lock from inside wait_event, so we use * memory barriers to make sure that we'll see the null task before * being woken up */static int ocfs2_recovery_thread_running(struct ocfs2_super *osb){	mb();	return osb->recovery_thread_task != NULL;}static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err){	int tmp;	struct ocfs2_super *osb = NULL;	char nodestr[8];	mlog_entry("(0x%p)\n", sb);	BUG_ON(!sb);	osb = OCFS2_SB(sb);	BUG_ON(!osb);	ocfs2_shutdown_local_alloc(osb);

⌨️ 快捷键说明

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