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

📄 md.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
		 */		if (mddev->pers->stop_resync)			if (mddev->pers->stop_resync(mddev))				resync_interrupted = 1;		if (mddev->recovery_running)			md_interrupt_thread(md_recovery_thread);		/*		 * This synchronizes with signal delivery to the		 * resync or reconstruction thread. It also nicely		 * hangs the process if some reconstruction has not		 * finished.		 */		down(&mddev->recovery_sem);		up(&mddev->recovery_sem);		invalidate_device(dev, 1);		if (ro) {			if (mddev->ro)				OUT(-ENXIO);			mddev->ro = 1;		} else {			if (mddev->ro)				set_device_ro(dev, 0);			if (mddev->pers->stop(mddev)) {				if (mddev->ro)					set_device_ro(dev, 1);				OUT(-EBUSY);			}			if (mddev->ro)				mddev->ro = 0;		}		if (mddev->sb) {			/*			 * mark it clean only if there was no resync			 * interrupted.			 */			if (!mddev->recovery_running && !resync_interrupted) {				printk(KERN_INFO "md: marking sb clean...\n");				mddev->sb->state |= 1 << MD_SB_CLEAN;			}			mddev->sb_dirty = 1;			md_update_sb(mddev);		}		if (ro)			set_device_ro(dev, 1);	}	/*	 * Free resources if final stop	 */	if (!ro) {		printk(KERN_INFO "md: md%d stopped.\n", mdidx(mddev));		free_mddev(mddev);	} else		printk(KERN_INFO "md: md%d switched to read-only mode.\n", mdidx(mddev));out:	return err;}#undef OUT/* * We have to safely support old arrays too. */int detect_old_array(mdp_super_t *sb){	if (sb->major_version > 0)		return 0;	if (sb->minor_version >= 90)		return 0;	return -EINVAL;}static void autorun_array(mddev_t *mddev){	mdk_rdev_t *rdev;	struct md_list_head *tmp;	int err;	if (mddev->disks.prev == &mddev->disks) {		MD_BUG();		return;	}	printk(KERN_INFO "md: running: ");	ITERATE_RDEV(mddev,rdev,tmp) {		printk("<%s>", partition_name(rdev->dev));	}	printk("\n");	err = do_md_run (mddev);	if (err) {		printk(KERN_WARNING "md :do_md_run() returned %d\n", err);		/*		 * prevent the writeback of an unrunnable array		 */		mddev->sb_dirty = 0;		do_md_stop (mddev, 0);	}}/* * lets try to run arrays based on all disks that have arrived * until now. (those are in the ->pending list) * * the method: pick the first pending disk, collect all disks with * the same UUID, remove all from the pending list and put them into * the 'same_array' list. Then order this list based on superblock * update time (freshest comes first), kick out 'old' disks and * compare superblocks. If everything's fine then run it. * * If "unit" is allocated, then bump its reference count */static void autorun_devices(kdev_t countdev){	struct md_list_head candidates;	struct md_list_head *tmp;	mdk_rdev_t *rdev0, *rdev;	mddev_t *mddev;	kdev_t md_kdev;	printk(KERN_INFO "md: autorun ...\n");	while (pending_raid_disks.next != &pending_raid_disks) {		rdev0 = md_list_entry(pending_raid_disks.next,					 mdk_rdev_t, pending);		printk(KERN_INFO "md: considering %s ...\n", partition_name(rdev0->dev));		MD_INIT_LIST_HEAD(&candidates);		ITERATE_RDEV_PENDING(rdev,tmp) {			if (uuid_equal(rdev0, rdev)) {				if (!sb_equal(rdev0->sb, rdev->sb)) {					printk(KERN_WARNING					       "md: %s has same UUID as %s, but superblocks differ ...\n",					       partition_name(rdev->dev), partition_name(rdev0->dev));					continue;				}				printk(KERN_INFO "md:  adding %s ...\n", partition_name(rdev->dev));				md_list_del(&rdev->pending);				md_list_add(&rdev->pending, &candidates);			}		}		/*		 * now we have a set of devices, with all of them having		 * mostly sane superblocks. It's time to allocate the		 * mddev.		 */		md_kdev = MKDEV(MD_MAJOR, rdev0->sb->md_minor);		mddev = kdev_to_mddev(md_kdev);		if (mddev) {			printk(KERN_WARNING "md: md%d already running, cannot run %s\n",			       mdidx(mddev), partition_name(rdev0->dev));			ITERATE_RDEV_GENERIC(candidates,pending,rdev,tmp)				export_rdev(rdev);			continue;		}		mddev = alloc_mddev(md_kdev);		if (!mddev) {			printk(KERN_ERR "md: cannot allocate memory for md drive.\n");			break;		}		if (md_kdev == countdev)			atomic_inc(&mddev->active);		printk(KERN_INFO "md: created md%d\n", mdidx(mddev));		ITERATE_RDEV_GENERIC(candidates,pending,rdev,tmp) {			bind_rdev_to_array(rdev, mddev);			md_list_del(&rdev->pending);			MD_INIT_LIST_HEAD(&rdev->pending);		}		autorun_array(mddev);	}	printk(KERN_INFO "md: ... autorun DONE.\n");}/* * import RAID devices based on one partition * if possible, the array gets run as well. */#define BAD_VERSION KERN_ERR \"md: %s has RAID superblock version 0.%d, autodetect needs v0.90 or higher\n"#define OUT_OF_MEM KERN_ALERT \"md: out of memory.\n"#define NO_DEVICE KERN_ERR \"md: disabled device %s\n"#define AUTOADD_FAILED KERN_ERR \"md: auto-adding devices to md%d FAILED (error %d).\n"#define AUTOADD_FAILED_USED KERN_ERR \"md: cannot auto-add device %s to md%d, already used.\n"#define AUTORUN_FAILED KERN_ERR \"md: auto-running md%d FAILED (error %d).\n"#define MDDEV_BUSY KERN_ERR \"md: cannot auto-add to md%d, already running.\n"#define AUTOADDING KERN_INFO \"md: auto-adding devices to md%d, based on %s's superblock.\n"#define AUTORUNNING KERN_INFO \"md: auto-running md%d.\n"static int autostart_array(kdev_t startdev, kdev_t countdev){	int err = -EINVAL, i;	mdp_super_t *sb = NULL;	mdk_rdev_t *start_rdev = NULL, *rdev;	if (md_import_device(startdev, 1)) {		printk(KERN_WARNING "md: could not import %s!\n", partition_name(startdev));		goto abort;	}	start_rdev = find_rdev_all(startdev);	if (!start_rdev) {		MD_BUG();		goto abort;	}	if (start_rdev->faulty) {		printk(KERN_WARNING "md: can not autostart based on faulty %s!\n",						partition_name(startdev));		goto abort;	}	md_list_add(&start_rdev->pending, &pending_raid_disks);	sb = start_rdev->sb;	err = detect_old_array(sb);	if (err) {		printk(KERN_WARNING "md: array version is too old to be autostarted ,"		       "use raidtools 0.90 mkraid --upgrade to upgrade the array "		       "without data loss!\n");		goto abort;	}	for (i = 0; i < MD_SB_DISKS; i++) {		mdp_disk_t *desc;		kdev_t dev;		desc = sb->disks + i;		dev = MKDEV(desc->major, desc->minor);		if (dev == MKDEV(0,0))			continue;		if (dev == startdev)			continue;		if (md_import_device(dev, 1)) {			printk(KERN_WARNING "md: could not import %s, trying to run array nevertheless.\n",			       partition_name(dev));			continue;		}		rdev = find_rdev_all(dev);		if (!rdev) {			MD_BUG();			goto abort;		}		md_list_add(&rdev->pending, &pending_raid_disks);	}	/*	 * possibly return codes	 */	autorun_devices(countdev);	return 0;abort:	if (start_rdev)		export_rdev(start_rdev);	return err;}#undef BAD_VERSION#undef OUT_OF_MEM#undef NO_DEVICE#undef AUTOADD_FAILED_USED#undef AUTOADD_FAILED#undef AUTORUN_FAILED#undef AUTOADDING#undef AUTORUNNINGstatic int get_version(void * arg){	mdu_version_t ver;	ver.major = MD_MAJOR_VERSION;	ver.minor = MD_MINOR_VERSION;	ver.patchlevel = MD_PATCHLEVEL_VERSION;	if (md_copy_to_user(arg, &ver, sizeof(ver)))		return -EFAULT;	return 0;}#define SET_FROM_SB(x) info.x = mddev->sb->xstatic int get_array_info(mddev_t * mddev, void * arg){	mdu_array_info_t info;	if (!mddev->sb) {		MD_BUG();		return -EINVAL;	}	SET_FROM_SB(major_version);	SET_FROM_SB(minor_version);	SET_FROM_SB(patch_version);	SET_FROM_SB(ctime);	SET_FROM_SB(level);	SET_FROM_SB(size);	SET_FROM_SB(nr_disks);	SET_FROM_SB(raid_disks);	SET_FROM_SB(md_minor);	SET_FROM_SB(not_persistent);	SET_FROM_SB(utime);	SET_FROM_SB(state);	SET_FROM_SB(active_disks);	SET_FROM_SB(working_disks);	SET_FROM_SB(failed_disks);	SET_FROM_SB(spare_disks);	SET_FROM_SB(layout);	SET_FROM_SB(chunk_size);	if (md_copy_to_user(arg, &info, sizeof(info)))		return -EFAULT;	return 0;}#undef SET_FROM_SB#define SET_FROM_SB(x) info.x = mddev->sb->disks[nr].xstatic int get_disk_info(mddev_t * mddev, void * arg){	mdu_disk_info_t info;	unsigned int nr;	if (!mddev->sb)		return -EINVAL;	if (md_copy_from_user(&info, arg, sizeof(info)))		return -EFAULT;	nr = info.number;	if (nr >= MD_SB_DISKS)		return -EINVAL;	SET_FROM_SB(major);	SET_FROM_SB(minor);	SET_FROM_SB(raid_disk);	SET_FROM_SB(state);	if (md_copy_to_user(arg, &info, sizeof(info)))		return -EFAULT;	return 0;}#undef SET_FROM_SB#define SET_SB(x) mddev->sb->disks[nr].x = info->xstatic int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info){	int err, size, persistent;	mdk_rdev_t *rdev;	unsigned int nr;	kdev_t dev;	dev = MKDEV(info->major,info->minor);	if (find_rdev_all(dev)) {		printk(KERN_WARNING "md: device %s already used in a RAID array!\n",		       partition_name(dev));		return -EBUSY;	}	if (!mddev->sb) {		/* expecting a device which has a superblock */		err = md_import_device(dev, 1);		if (err) {			printk(KERN_WARNING "md: md_import_device returned %d\n", err);			return -EINVAL;		}		rdev = find_rdev_all(dev);		if (!rdev) {			MD_BUG();			return -EINVAL;		}		if (mddev->nb_dev) {			mdk_rdev_t *rdev0 = md_list_entry(mddev->disks.next,							mdk_rdev_t, same_set);			if (!uuid_equal(rdev0, rdev)) {				printk(KERN_WARNING "md: %s has different UUID to %s\n",				       partition_name(rdev->dev), partition_name(rdev0->dev));				export_rdev(rdev);				return -EINVAL;			}			if (!sb_equal(rdev0->sb, rdev->sb)) {				printk(KERN_WARNING "md: %s has same UUID but different superblock to %s\n",				       partition_name(rdev->dev), partition_name(rdev0->dev));				export_rdev(rdev);				return -EINVAL;			}		}		bind_rdev_to_array(rdev, mddev);		return 0;	}	nr = info->number;	if (nr >= mddev->sb->nr_disks) {		MD_BUG();		return -EINVAL;	}	SET_SB(number);	SET_SB(major);	SET_SB(minor);	SET_SB(raid_disk);	SET_SB(state);	if ((info->state & (1<<MD_DISK_FAULTY))==0) {		err = md_import_device (dev, 0);		if (err) {			printk(KERN_WARNING "md: error, md_import_device() returned %d\n", err);			return -EINVAL;		}		rdev = find_rdev_all(dev);		if (!rdev) {			MD_BUG();			return -EINVAL;		}		rdev->old_dev = dev;		rdev->desc_nr = info->number;		bind_rdev_to_array(rdev, mddev);		persistent = !mddev->sb->not_persistent;		if (!persistent)			printk(KERN_INFO "md: nonpersistent superblock ...\n");		size = calc_dev_size(dev, mddev, persistent);		rdev->sb_offset = calc_dev_sboffset(dev, mddev, persistent);		if (!mddev->sb->size || (mddev->sb->size > size))			mddev->sb->size = size;	}	/*	 * sync all other superblocks with the main superblock	 */	sync_sbs(mddev);	return 0;}#undef SET_SBstatic int hot_generate_error(mddev_t * mddev, kdev_t dev){	struct request_queue *q;	mdk_rdev_t *rdev;	mdp_disk_t *disk;	if (!mddev->pers)		return -ENODEV;	printk(KERN_INFO "md: trying to generate %s error in md%d ... \n",		partition_name(dev), mdidx(mddev));	rdev = find_rdev(mddev, dev);	if (!rdev) {		MD_BUG();		return -ENXIO;	}	if (rdev->desc_nr == -1) {		MD_BUG();		return -EINVAL;	}	disk = &mddev->sb->disks[rdev->desc_nr];	if (!disk_active(disk))		return -ENODEV;	q = blk_get_queue(rdev->dev);	if (!q) {		MD_BUG();		return -ENODEV;	}	printk(KERN_INFO "md: okay, generating error!\n");//	q->oneshot_error = 1; // disabled for now	return 0;}static int hot_remove_disk(mddev_t * mddev, kdev_t dev){	int err;	mdk_rdev_t *rdev;	mdp_disk_t *disk;	if (!mddev->pers)		return -ENODEV;	printk(KERN_INFO "md: trying to remove %s from md%d ... \n",		partition_name(dev), mdidx(mddev));	if (!mddev->pers->diskop) {		printk(KERN_WARNING "md%d: personality does not support diskops!\n",		       mdidx(mddev));		return -EINVAL;	}	rdev = find_rdev(mddev, dev);	if (!rdev)		return -ENXIO;	if (rdev->desc_nr == -1) {		MD_BUG();		return -EINVAL;	}	disk = &mddev->sb->disks[rdev->desc_nr];	if (disk_active(disk)) {		MD_BUG();		goto busy;	}	if (disk_removed(disk)) {		MD_BUG();		return -EINVAL;	}	err = mddev->pers->diskop(mddev, &disk, DISKOP_HOT_REMOVE_DISK);	if (err == -EBUSY) {		MD_BUG();		goto busy;	}	if (err) {		MD_BUG();		return -EINVAL;	}	remove_descriptor(disk, mddev->sb);	kick_rdev_from_array(rdev);	mddev->sb_dirty = 1;	md_update_sb(mddev);	return 0;busy:	printk(KERN_WARNING "md: cannot remove active disk %s from md%d ... \n",		partition_name(dev), mdidx(mddev));	return -EBUSY;}static int hot_add_disk(mddev_t * mddev, kdev_t dev){	int i, err, persistent;	unsigned int size;	mdk_rdev_t *rdev;	mdp_disk_t *disk;	if (!mddev->pers)		return -ENODEV;	printk(KERN_INFO "md: trying to hot-add %s to md%d ... \n",		partition_name(dev), mdidx(mddev));	if (!mddev->pers->diskop) {		printk(KERN_WARNING "md%d: personality does not support diskops!\n",		       mdidx(mddev));		return -EINVAL;	}	persistent = !mddev->sb->not_persistent;	size = calc_dev_size(dev, mddev, persistent);	if (size < mddev->sb->size) {		printk(KERN_WARNING "md%d: disk size %d blocks < array size %d\n",				mdidx(mddev), size, mddev->sb->size);		return -ENOSPC;	}	rdev = find_rdev(mddev, dev);	if (rdev)		return -EBUSY;	err = md_import_device (dev, 0);	if (err) {		printk(KERN_WARNING "md: error, md_import_device() returned %d\n", err);		return -EINVAL;	}	rdev = find_rdev_all(dev);

⌨️ 快捷键说明

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