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

📄 super.c

📁 ocfs1.4.1 oracle分布式文件系统
💻 C
📖 第 1 页 / 共 4 页
字号:
	bbits = le32_to_cpu(di->id2.i_super.s_blocksize_bits);	sb->s_maxbytes = ocfs2_max_file_offset(bbits, cbits);	osb->sb = sb;	/* Save off for ocfs2_rw_direct */	osb->s_sectsize_bits = blksize_bits(sector_size);	BUG_ON(!osb->s_sectsize_bits);	init_waitqueue_head(&osb->recovery_event);	spin_lock_init(&osb->dc_task_lock);	init_waitqueue_head(&osb->dc_event);	osb->dc_work_sequence = 0;	osb->dc_wake_sequence = 0;	INIT_LIST_HEAD(&osb->blocked_lock_list);	osb->blocked_lock_count = 0;	spin_lock_init(&osb->osb_lock);	ocfs2_init_inode_steal_slot(osb);	atomic_set(&osb->alloc_stats.moves, 0);	atomic_set(&osb->alloc_stats.local_data, 0);	atomic_set(&osb->alloc_stats.bitmap_data, 0);	atomic_set(&osb->alloc_stats.bg_allocs, 0);	atomic_set(&osb->alloc_stats.bg_extends, 0);	ocfs2_init_node_maps(osb);	snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u",		 MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));	mutex_init(&osb->recovery_lock);	osb->disable_recovery = 0;	osb->recovery_thread_task = NULL;	init_waitqueue_head(&osb->checkpoint_event);	atomic_set(&osb->needs_checkpoint, 0);	osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM;	osb->node_num = O2NM_INVALID_NODE_NUM;	osb->slot_num = OCFS2_INVALID_SLOT;	osb->local_alloc_state = OCFS2_LA_UNUSED;	osb->local_alloc_bh = NULL;	ocfs2_setup_hb_callbacks(osb);	init_waitqueue_head(&osb->osb_mount_event);	osb->vol_label = kmalloc(OCFS2_MAX_VOL_LABEL_LEN, GFP_KERNEL);	if (!osb->vol_label) {		mlog(ML_ERROR, "unable to alloc vol label\n");		status = -ENOMEM;		goto bail;	}	osb->max_slots = le16_to_cpu(di->id2.i_super.s_max_slots);	if (osb->max_slots > OCFS2_MAX_SLOTS || osb->max_slots == 0) {		mlog(ML_ERROR, "Invalid number of node slots (%u)\n",		     osb->max_slots);		status = -EINVAL;		goto bail;	}	mlog(0, "max_slots for this device: %u\n", osb->max_slots);	osb->slot_recovery_generations =		kcalloc(osb->max_slots, sizeof(*osb->slot_recovery_generations),			GFP_KERNEL);	if (!osb->slot_recovery_generations) {		status = -ENOMEM;		mlog_errno(status);		goto bail;	}	init_waitqueue_head(&osb->osb_wipe_event);	osb->osb_orphan_wipes = kcalloc(osb->max_slots,					sizeof(*osb->osb_orphan_wipes),					GFP_KERNEL);	if (!osb->osb_orphan_wipes) {		status = -ENOMEM;		mlog_errno(status);		goto bail;	}	osb->s_feature_compat =		le32_to_cpu(OCFS2_RAW_SB(di)->s_feature_compat);	osb->s_feature_ro_compat =		le32_to_cpu(OCFS2_RAW_SB(di)->s_feature_ro_compat);	osb->s_feature_incompat =		le32_to_cpu(OCFS2_RAW_SB(di)->s_feature_incompat);	if ((i = OCFS2_HAS_INCOMPAT_FEATURE(osb->sb, ~OCFS2_FEATURE_INCOMPAT_SUPP))) {		mlog(ML_ERROR, "couldn't mount because of unsupported "		     "optional features (%x).\n", i);		status = -EINVAL;		goto bail;	}	if (!(osb->sb->s_flags & MS_RDONLY) &&	    (i = OCFS2_HAS_RO_COMPAT_FEATURE(osb->sb, ~OCFS2_FEATURE_RO_COMPAT_SUPP))) {		mlog(ML_ERROR, "couldn't mount RDWR because of "		     "unsupported optional features (%x).\n", i);		status = -EINVAL;		goto bail;	}	get_random_bytes(&osb->s_next_generation, sizeof(u32));	/* FIXME	 * This should be done in ocfs2_journal_init(), but unknown	 * ordering issues will cause the filesystem to crash.	 * If anyone wants to figure out what part of the code	 * refers to osb->journal before ocfs2_journal_init() is run,	 * be my guest.	 */	/* initialize our journal structure */	journal = kzalloc(sizeof(struct ocfs2_journal), GFP_KERNEL);	if (!journal) {		mlog(ML_ERROR, "unable to alloc journal\n");		status = -ENOMEM;		goto bail;	}	osb->journal = journal;	journal->j_osb = osb;	atomic_set(&journal->j_num_trans, 0);	init_rwsem(&journal->j_trans_barrier);	init_waitqueue_head(&journal->j_checkpointed);	spin_lock_init(&journal->j_lock);	journal->j_trans_id = (unsigned long) 1;	INIT_LIST_HEAD(&journal->j_la_cleanups);	KAPI_INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery, journal);	journal->j_state = OCFS2_JOURNAL_FREE;	/* get some pseudo constants for clustersize bits */	osb->s_clustersize_bits =		le32_to_cpu(di->id2.i_super.s_clustersize_bits);	osb->s_clustersize = 1 << osb->s_clustersize_bits;	mlog(0, "clusterbits=%d\n", osb->s_clustersize_bits);	if (osb->s_clustersize < OCFS2_MIN_CLUSTERSIZE ||	    osb->s_clustersize > OCFS2_MAX_CLUSTERSIZE) {		mlog(ML_ERROR, "Volume has invalid cluster size (%d)\n",		     osb->s_clustersize);		status = -EINVAL;		goto bail;	}	if (ocfs2_clusters_to_blocks(osb->sb, le32_to_cpu(di->i_clusters) - 1)	    > (u32)~0UL) {		mlog(ML_ERROR, "Volume might try to write to blocks beyond "		     "what jbd can address in 32 bits.\n");		status = -EINVAL;		goto bail;	}	if (ocfs2_setup_osb_uuid(osb, di->id2.i_super.s_uuid,				 sizeof(di->id2.i_super.s_uuid))) {		mlog(ML_ERROR, "Out of memory trying to setup our uuid.\n");		status = -ENOMEM;		goto bail;	}	memcpy(&uuid_net_key, di->id2.i_super.s_uuid, sizeof(uuid_net_key));	strncpy(osb->vol_label, di->id2.i_super.s_label, 63);	osb->vol_label[63] = '\0';	osb->root_blkno = le64_to_cpu(di->id2.i_super.s_root_blkno);	osb->system_dir_blkno = le64_to_cpu(di->id2.i_super.s_system_dir_blkno);	osb->first_cluster_group_blkno =		le64_to_cpu(di->id2.i_super.s_first_cluster_group);	osb->fs_generation = le32_to_cpu(di->i_fs_generation);	mlog(0, "vol_label: %s\n", osb->vol_label);	mlog(0, "uuid: %s\n", osb->uuid_str);	mlog(0, "root_blkno=%llu, system_dir_blkno=%llu\n",	     (unsigned long long)osb->root_blkno,	     (unsigned long long)osb->system_dir_blkno);	osb->osb_dlm_debug = ocfs2_new_dlm_debug();	if (!osb->osb_dlm_debug) {		status = -ENOMEM;		mlog_errno(status);		goto bail;	}	atomic_set(&osb->vol_state, VOLUME_INIT);	/* load root, system_dir, and all global system inodes */	status = ocfs2_init_global_system_inodes(osb);	if (status < 0) {		mlog_errno(status);		goto bail;	}	/*	 * global bitmap	 */	inode = ocfs2_get_system_file_inode(osb, GLOBAL_BITMAP_SYSTEM_INODE,					    OCFS2_INVALID_SLOT);	if (!inode) {		status = -EINVAL;		mlog_errno(status);		goto bail;	}	osb->bitmap_blkno = OCFS2_I(inode)->ip_blkno;	iput(inode);	osb->bitmap_cpg = ocfs2_group_bitmap_size(sb) * 8;	status = ocfs2_init_slot_info(osb);	if (status < 0) {		mlog_errno(status);		goto bail;	}bail:	mlog_exit(status);	return status;}/* * will return: -EAGAIN if it is ok to keep searching for superblocks *              -EINVAL if there is a bad superblock *              0 on success */static int ocfs2_verify_volume(struct ocfs2_dinode *di,			       struct buffer_head *bh,			       u32 blksz){	int status = -EAGAIN;	mlog_entry_void();	if (memcmp(di->i_signature, OCFS2_SUPER_BLOCK_SIGNATURE,		   strlen(OCFS2_SUPER_BLOCK_SIGNATURE)) == 0) {		status = -EINVAL;		if ((1 << le32_to_cpu(di->id2.i_super.s_blocksize_bits)) != blksz) {			mlog(ML_ERROR, "found superblock with incorrect block "			     "size: found %u, should be %u\n",			     1 << le32_to_cpu(di->id2.i_super.s_blocksize_bits),			       blksz);		} else if (le16_to_cpu(di->id2.i_super.s_major_rev_level) !=			   OCFS2_MAJOR_REV_LEVEL ||			   le16_to_cpu(di->id2.i_super.s_minor_rev_level) !=			   OCFS2_MINOR_REV_LEVEL) {			mlog(ML_ERROR, "found superblock with bad version: "			     "found %u.%u, should be %u.%u\n",			     le16_to_cpu(di->id2.i_super.s_major_rev_level),			     le16_to_cpu(di->id2.i_super.s_minor_rev_level),			     OCFS2_MAJOR_REV_LEVEL,			     OCFS2_MINOR_REV_LEVEL);		} else if (bh->b_blocknr != le64_to_cpu(di->i_blkno)) {			mlog(ML_ERROR, "bad block number on superblock: "			     "found %llu, should be %llu\n",			     (unsigned long long)le64_to_cpu(di->i_blkno),			     (unsigned long long)bh->b_blocknr);		} else if (le32_to_cpu(di->id2.i_super.s_clustersize_bits) < 12 ||			    le32_to_cpu(di->id2.i_super.s_clustersize_bits) > 20) {			mlog(ML_ERROR, "bad cluster size found: %u\n",			     1 << le32_to_cpu(di->id2.i_super.s_clustersize_bits));		} else if (!le64_to_cpu(di->id2.i_super.s_root_blkno)) {			mlog(ML_ERROR, "bad root_blkno: 0\n");		} else if (!le64_to_cpu(di->id2.i_super.s_system_dir_blkno)) {			mlog(ML_ERROR, "bad system_dir_blkno: 0\n");		} else if (le16_to_cpu(di->id2.i_super.s_max_slots) > OCFS2_MAX_SLOTS) {			mlog(ML_ERROR,			     "Superblock slots found greater than file system "			     "maximum: found %u, max %u\n",			     le16_to_cpu(di->id2.i_super.s_max_slots),			     OCFS2_MAX_SLOTS);		} else {			/* found it! */			status = 0;		}	}	mlog_exit(status);	return status;}static int ocfs2_check_volume(struct ocfs2_super *osb){	int status;	int dirty;	int local;	struct ocfs2_dinode *local_alloc = NULL; /* only used if we						  * recover						  * ourselves. */	mlog_entry_void();	/* Init our journal object. */	status = ocfs2_journal_init(osb->journal, &dirty);	if (status < 0) {		mlog(ML_ERROR, "Could not initialize journal!\n");		goto finally;	}	/* If the journal was unmounted cleanly then we don't want to	 * recover anything. Otherwise, journal_load will do that	 * dirty work for us :) */	if (!dirty) {		status = ocfs2_journal_wipe(osb->journal, 0);		if (status < 0) {			mlog_errno(status);			goto finally;		}	} else {		mlog(ML_NOTICE, "File system was not unmounted cleanly, "		     "recovering volume.\n");	}	local = ocfs2_mount_local(osb);	/* will play back anything left in the journal. */	status = ocfs2_journal_load(osb->journal, local, dirty);	if (status < 0) {		mlog(ML_ERROR, "ocfs2 journal load failed! %d\n", status);		goto finally;	}	if (dirty) {		/* recover my local alloc if we didn't unmount cleanly. */		status = ocfs2_begin_local_alloc_recovery(osb,							  osb->slot_num,							  &local_alloc);		if (status < 0) {			mlog_errno(status);			goto finally;		}		/* we complete the recovery process after we've marked		 * ourselves as mounted. */	}	mlog(0, "Journal loaded.\n");	status = ocfs2_load_local_alloc(osb);	if (status < 0) {		mlog_errno(status);		goto finally;	}	if (dirty) {		/* Recovery will be completed after we've mounted the		 * rest of the volume. */		osb->dirty = 1;		osb->local_alloc_copy = local_alloc;		local_alloc = NULL;	}	/* go through each journal, trylock it and if you get the	 * lock, and it's marked as dirty, set the bit in the recover	 * map and launch a recovery thread for it. */	status = ocfs2_mark_dead_nodes(osb);	if (status < 0)		mlog_errno(status);finally:	if (local_alloc)		kfree(local_alloc);	mlog_exit(status);	return status;}/* * The routine gets called from dismount or close whenever a dismount on * volume is requested and the osb open count becomes 1. * It will remove the osb from the global list and also free up all the * initialized resources and fileobject. */static void ocfs2_delete_osb(struct ocfs2_super *osb){	mlog_entry_void();	/* This function assumes that the caller has the main osb resource */	if (osb->slot_info)		ocfs2_free_slot_info(osb->slot_info);	kfree(osb->osb_orphan_wipes);	kfree(osb->slot_recovery_generations);	/* FIXME	 * This belongs in journal shutdown, but because we have to	 * allocate osb->journal at the start of ocfs2_initalize_osb(),	 * we free it here.	 */	kfree(osb->journal);	if (osb->local_alloc_copy)		kfree(osb->local_alloc_copy);	kfree(osb->uuid_str);	ocfs2_put_dlm_debug(osb->osb_dlm_debug);	memset(osb, 0, sizeof(struct ocfs2_super));	mlog_exit_void();}/* Put OCFS2 into a readonly state, or (if the user specifies it), * panic(). We do not support continue-on-error operation. */static void ocfs2_handle_error(struct super_block *sb){	struct ocfs2_super *osb = OCFS2_SB(sb);	if (osb->s_mount_opt & OCFS2_MOUNT_ERRORS_PANIC)		panic("OCFS2: (device %s): panic forced after error\n",		      sb->s_id);	ocfs2_set_osb_flag(osb, OCFS2_OSB_ERROR_FS);	if (sb->s_flags & MS_RDONLY &&	    (ocfs2_is_soft_readonly(osb) ||	     ocfs2_is_hard_readonly(osb)))		return;	printk(KERN_CRIT "File system is now read-only due to the potential "	       "of on-disk corruption. Please run fsck.ocfs2 once the file "	       "system is unmounted.\n");	sb->s_flags |= MS_RDONLY;	ocfs2_set_ro_flag(osb, 0);}static char error_buf[1024];void __ocfs2_error(struct super_block *sb,		   const char *function,		   const char *fmt, ...){	va_list args;	va_start(args, fmt);	vsnprintf(error_buf, sizeof(error_buf), fmt, args);	va_end(args);	/* Not using mlog here because we want to show the actual	 * function the error came from. */	printk(KERN_CRIT "OCFS2: ERROR (device %s): %s: %s\n",	       sb->s_id, function, error_buf);	ocfs2_handle_error(sb);}/* Handle critical errors. This is intentionally more drastic than * ocfs2_handle_error, so we only use for things like journal errors, * etc. */void __ocfs2_abort(struct super_block* sb,		   const char *function,		   const char *fmt, ...){	va_list args;	va_start(args, fmt);	vsnprintf(error_buf, sizeof(error_buf), fmt, args);	va_end(args);	printk(KERN_CRIT "OCFS2: abort (device %s): %s: %s\n",	       sb->s_id, function, error_buf);	/* We don't have the cluster support yet to go straight to	 * hard readonly in here. Until then, we want to keep	 * ocfs2_abort() so that we can at least mark critical	 * errors.	 *	 * TODO: This should abort the journal and alert other nodes	 * that our slot needs recovery. */	/* Force a panic(). This stinks, but it's better than letting	 * things continue without having a proper hard readonly	 * here. */	OCFS2_SB(sb)->s_mount_opt |= OCFS2_MOUNT_ERRORS_PANIC;	ocfs2_handle_error(sb);}module_init(ocfs2_init);module_exit(ocfs2_exit);

⌨️ 快捷键说明

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