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

📄 super.c

📁 ocfs1.4.1 oracle分布式文件系统
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifdef OCFS2_ORACORE_WORKAROUNDS	if (opts & OCFS2_MOUNT_COMPAT_OCFS)		seq_printf(s, ",datavolume");#endif	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);	if (osb->osb_commit_interval)		seq_printf(s, ",commit=%u",			   (unsigned) (osb->osb_commit_interval / HZ));	if (osb->local_alloc_size != OCFS2_DEFAULT_LOCAL_ALLOC_SIZE)		seq_printf(s, ",localalloc=%d", osb->local_alloc_size);	if (opts & OCFS2_MOUNT_LOCALFLOCKS)		seq_printf(s, ",localflocks,");	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 inline 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_inode_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);#ifdef OCFS2_ORACORE_WORKAROUNDS	if (osb->s_mount_opt & OCFS2_MOUNT_COMPAT_OCFS)		buf->f_type = OCFS_SUPER_MAGIC;	else#endif		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_inode_unlock(inode, 0);	status = 0;bail:	if (inode)		iput(inode);	mlog_exit(status);	return status;}#ifdef STATFS_TAKES_SBstatic int ocfs2_statfs(struct super_block *sb, struct kstatfs *buf){	return _ocfs2_statfs(sb->s_root, buf);}#elsestatic int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf){	return _ocfs2_statfs(dentry, buf);}#endifstatic void ocfs2_inode_init_once(void *data,				  struct kmem_cache *cachep,				  unsigned long flags){	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_inode_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 = kapi_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_dlm_init(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;	}	/* 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;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);	ocfs2_truncate_log_shutdown(osb);	/* disable any new recovery threads and wait for any currently	 * running ones to exit. Do this before setting the vol_state. */	mutex_lock(&osb->recovery_lock);	osb->disable_recovery = 1;	mutex_unlock(&osb->recovery_lock);	wait_event(osb->recovery_event, !ocfs2_recovery_thread_running(osb));	/* At this point, we know that no more recovery threads can be	 * launched, so wait for any recovery completion work to	 * complete. */	flush_workqueue(ocfs2_wq);	ocfs2_journal_shutdown(osb);	ocfs2_sync_blockdev(sb);	/* No dlm means we've failed during mount, so skip all the	 * steps which depended on that to complete. */	if (osb->dlm) {		tmp = ocfs2_super_lock(osb, 1);		if (tmp < 0) {			mlog_errno(tmp);			return;		}	}	if (osb->slot_num != OCFS2_INVALID_SLOT)		ocfs2_put_slot(osb);	if (osb->dlm)		ocfs2_super_unlock(osb, 1);	ocfs2_release_system_inodes(osb);	if (osb->dlm)		ocfs2_dlm_shutdown(osb);	debugfs_remove(osb->osb_debug_root);	if (!mnt_err)		ocfs2_stop_heartbeat(osb);	atomic_set(&osb->vol_state, VOLUME_DISMOUNTED);	if (ocfs2_mount_local(osb))		snprintf(nodestr, sizeof(nodestr), "local");	else		snprintf(nodestr, sizeof(nodestr), "%d", osb->node_num);	printk(KERN_INFO "ocfs2: Unmounting device (%s) on (node %s)\n",	       osb->dev_str, nodestr);	ocfs2_delete_osb(osb);	kfree(osb);	sb->s_dev = 0;	sb->s_fs_info = NULL;}static int ocfs2_setup_osb_uuid(struct ocfs2_super *osb, const unsigned char *uuid,				unsigned uuid_bytes){	int i, ret;	char *ptr;	BUG_ON(uuid_bytes != OCFS2_VOL_UUID_LEN);	osb->uuid_str = kzalloc(OCFS2_VOL_UUID_LEN * 2 + 1, GFP_KERNEL);	if (osb->uuid_str == NULL)		return -ENOMEM;	for (i = 0, ptr = osb->uuid_str; i < OCFS2_VOL_UUID_LEN; i++) {		/* print with null */		ret = snprintf(ptr, 3, "%02X", uuid[i]);		if (ret != 2) /* drop super cleans up */			return -EINVAL;		/* then only advance past the last char */		ptr += 2;	}	return 0;}static int ocfs2_initialize_super(struct super_block *sb,				  struct buffer_head *bh,				  int sector_size){	int status;	int i, cbits, bbits;	struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;	struct inode *inode = NULL;	struct ocfs2_journal *journal;	__le32 uuid_net_key;	struct ocfs2_super *osb;	mlog_entry_void();	osb = kzalloc(sizeof(struct ocfs2_super), GFP_KERNEL);	if (!osb) {		status = -ENOMEM;		mlog_errno(status);		goto bail;	}	sb->s_fs_info = osb;	sb->s_op = &ocfs2_sops;	sb->s_export_op = &ocfs2_export_ops;	osb->osb_locking_proto = ocfs2_locking_protocol;	sb->s_time_gran = 1;	sb->s_flags |= MS_NOATIME;	/* this is needed to support O_LARGEFILE */	cbits = le32_to_cpu(di->id2.i_super.s_clustersize_bits);

⌨️ 快捷键说明

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