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

📄 lvm.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
	return;}	/* lvm_cleanup() *//* * support function to initialize lvm variables */static void __init lvm_init_vars(void){	int v;	loadtime = CURRENT_TIME;	lvm_lock = lvm_snapshot_lock = SPIN_LOCK_UNLOCKED;	pe_lock_req.lock = UNLOCK_PE;	pe_lock_req.data.lv_dev = 0;	pe_lock_req.data.pv_dev = 0;	pe_lock_req.data.pv_offset = 0;	/* Initialize VG pointers */	for (v = 0; v < ABS_MAX_VG; v++) vg[v] = NULL;	/* Initialize LV -> VG association */	for (v = 0; v < ABS_MAX_LV; v++) {		/* index ABS_MAX_VG never used for real VG */		vg_lv_map[v].vg_number = ABS_MAX_VG;		vg_lv_map[v].lv_number = -1;	}	return;} /* lvm_init_vars() *//******************************************************************** * * Character device functions * ********************************************************************/#define MODE_TO_STR(mode) (mode) & FMODE_READ ? "READ" : "", \			  (mode) & FMODE_WRITE ? "WRITE" : ""/* * character device open routine */static int lvm_chr_open(struct inode *inode, struct file *file){	unsigned int minor = MINOR(inode->i_rdev);	P_DEV("chr_open MINOR: %d  VG#: %d  mode: %s%s  lock: %d\n",	      minor, VG_CHR(minor), MODE_TO_STR(file->f_mode), lock);	/* super user validation */	if (!capable(CAP_SYS_ADMIN)) return -EACCES;	/* Group special file open */	if (VG_CHR(minor) > MAX_VG) return -ENXIO;       spin_lock(&lvm_lock);       if(lock == current->pid)               _lock_open_count++;       spin_unlock(&lvm_lock);	lvm_chr_open_count++;	MOD_INC_USE_COUNT;	return 0;} /* lvm_chr_open() *//* * character device i/o-control routine * * Only one changing process can do changing ioctl at one time, * others will block. * */static int lvm_chr_ioctl(struct inode *inode, struct file *file,		  uint command, ulong a){	int minor = MINOR(inode->i_rdev);	uint extendable, l, v;	void *arg = (void *) a;	lv_t lv;	vg_t* vg_ptr = vg[VG_CHR(minor)];	/* otherwise cc will complain about unused variables */	(void) lvm_lock;	P_IOCTL("chr MINOR: %d  command: 0x%X  arg: %p  VG#: %d  mode: %s%s\n",		minor, command, arg, VG_CHR(minor), MODE_TO_STR(file->f_mode));#ifdef LVM_TOTAL_RESET	if (lvm_reset_spindown > 0) return -EACCES;#endif	/* Main command switch */	switch (command) {	case LVM_LOCK_LVM:		/* lock the LVM */		return lvm_do_lock_lvm();	case LVM_GET_IOP_VERSION:		/* check lvm version to ensure driver/tools+lib		   interoperability */		if (copy_to_user(arg, &lvm_iop_version, sizeof(ushort)) != 0)			return -EFAULT;		return 0;#ifdef LVM_TOTAL_RESET	case LVM_RESET:		/* lock reset function */		lvm_reset_spindown = 1;		for (v = 0; v < ABS_MAX_VG; v++) {			if (vg[v] != NULL) lvm_do_vg_remove(v);		}#ifdef MODULE		while (GET_USE_COUNT(&__this_module) < 1)			MOD_INC_USE_COUNT;		while (GET_USE_COUNT(&__this_module) > 1)			MOD_DEC_USE_COUNT;#endif /* MODULE */		lock = 0;	/* release lock */		wake_up_interruptible(&lvm_wait);		return 0;#endif /* LVM_TOTAL_RESET */	case LE_REMAP:		/* remap a logical extent (after moving the physical extent) */		return lvm_do_le_remap(vg_ptr,arg);	case PE_LOCK_UNLOCK:		/* lock/unlock i/o to a physical extent to move it to another		   physical volume (move's done in user space's pvmove) */		return lvm_do_pe_lock_unlock(vg_ptr,arg);	case VG_CREATE_OLD:		/* create a VGDA */		return lvm_do_vg_create(arg, minor);       case VG_CREATE:               /* create a VGDA, assume VG number is filled in */		return lvm_do_vg_create(arg, -1);	case VG_EXTEND:		/* extend a volume group */		return lvm_do_vg_extend(vg_ptr, arg);	case VG_REDUCE:		/* reduce a volume group */		return lvm_do_vg_reduce(vg_ptr, arg);	case VG_RENAME:		/* rename a volume group */		return lvm_do_vg_rename(vg_ptr, arg);	case VG_REMOVE:		/* remove an inactive VGDA */		return lvm_do_vg_remove(minor);	case VG_SET_EXTENDABLE:		/* set/clear extendability flag of volume group */		if (vg_ptr == NULL) return -ENXIO;		if (copy_from_user(&extendable, arg, sizeof(extendable)) != 0)			return -EFAULT;		if (extendable == VG_EXTENDABLE ||		    extendable == ~VG_EXTENDABLE) {			if (extendable == VG_EXTENDABLE)				vg_ptr->vg_status |= VG_EXTENDABLE;			else				vg_ptr->vg_status &= ~VG_EXTENDABLE;		} else return -EINVAL;		return 0;	case VG_STATUS:		/* get volume group data (only the vg_t struct) */		if (vg_ptr == NULL) return -ENXIO;		if (copy_to_user(arg, vg_ptr, sizeof(vg_t)) != 0)			return -EFAULT;		return 0;	case VG_STATUS_GET_COUNT:		/* get volume group count */		if (copy_to_user(arg, &vg_count, sizeof(vg_count)) != 0)			return -EFAULT;		return 0;	case VG_STATUS_GET_NAMELIST:		/* get volume group names */		for (l = v = 0; v < ABS_MAX_VG; v++) {			if (vg[v] != NULL) {				if (copy_to_user(arg + l * NAME_LEN,						 vg[v]->vg_name,						 NAME_LEN) != 0)					return -EFAULT;				l++;			}		}		return 0;	case LV_CREATE:	case LV_EXTEND:	case LV_REDUCE:	case LV_REMOVE:	case LV_RENAME:		/* create, extend, reduce, remove or rename a logical volume */		if (vg_ptr == NULL) return -ENXIO;		if (copy_from_user(&lv_req, arg, sizeof(lv_req)) != 0)			return -EFAULT;		if (command != LV_REMOVE) {			if (copy_from_user(&lv, lv_req.lv, sizeof(lv_t)) != 0)				return -EFAULT;		}		switch (command) {		case LV_CREATE:			return lvm_do_lv_create(minor, lv_req.lv_name, &lv);		case LV_EXTEND:		case LV_REDUCE:			return lvm_do_lv_extend_reduce(minor, lv_req.lv_name, &lv);		case LV_REMOVE:			return lvm_do_lv_remove(minor, lv_req.lv_name, -1);		case LV_RENAME:			return lvm_do_lv_rename(vg_ptr, &lv_req, &lv);		}	case LV_STATUS_BYNAME:		/* get status of a logical volume by name */		return lvm_do_lv_status_byname(vg_ptr, arg);	case LV_STATUS_BYINDEX:		/* get status of a logical volume by index */		return lvm_do_lv_status_byindex(vg_ptr, arg);	case LV_STATUS_BYDEV:		/* get status of a logical volume by device */		return lvm_do_lv_status_bydev(vg_ptr, arg);	case PV_CHANGE:		/* change a physical volume */		return lvm_do_pv_change(vg_ptr,arg);	case PV_STATUS:		/* get physical volume data (pv_t structure only) */		return lvm_do_pv_status(vg_ptr,arg);	case PV_FLUSH:		/* physical volume buffer flush/invalidate */               return lvm_do_pv_flush(arg);	default:		printk(KERN_WARNING		       "%s -- lvm_chr_ioctl: unknown command 0x%x\n",		       lvm_name, command);		return -EINVAL;	}	return 0;} /* lvm_chr_ioctl *//* * character device close routine */static int lvm_chr_close(struct inode *inode, struct file *file){	P_DEV("chr_close MINOR: %d  VG#: %d\n",	      MINOR(inode->i_rdev), VG_CHR(MINOR(inode->i_rdev)));#ifdef LVM_TOTAL_RESET	if (lvm_reset_spindown > 0) {		lvm_reset_spindown = 0;		lvm_chr_open_count = 0;	}#endif	if (lvm_chr_open_count > 0) lvm_chr_open_count--;       spin_lock(&lvm_lock);       if(lock == current->pid) {               if(!_lock_open_count) {			P_DEV("chr_close: unlocking LVM for pid %d\n", lock);                       lock = 0;                       wake_up_interruptible(&lvm_wait);               } else                       _lock_open_count--;	}       spin_unlock(&lvm_lock);	MOD_DEC_USE_COUNT;	return 0;} /* lvm_chr_close() *//******************************************************************** * * Block device functions * ********************************************************************//* * block device open routine */static int lvm_blk_open(struct inode *inode, struct file *file){	int minor = MINOR(inode->i_rdev);	lv_t *lv_ptr;	vg_t *vg_ptr = vg[VG_BLK(minor)];	P_DEV("blk_open MINOR: %d  VG#: %d  LV#: %d  mode: %s%s\n",	      minor, VG_BLK(minor), LV_BLK(minor), MODE_TO_STR(file->f_mode));#ifdef LVM_TOTAL_RESET	if (lvm_reset_spindown > 0)		return -EPERM;#endif	if (vg_ptr != NULL &&	    (vg_ptr->vg_status & VG_ACTIVE) &&	    (lv_ptr = vg_ptr->lv[LV_BLK(minor)]) != NULL &&	    LV_BLK(minor) >= 0 &&	    LV_BLK(minor) < vg_ptr->lv_max) {		/* Check parallel LV spindown (LV remove) */		if (lv_ptr->lv_status & LV_SPINDOWN) return -EPERM;		/* Check inactive LV and open for read/write */		/* We need to be able to "read" an inactive LV		   to re-activate it again */		if ((file->f_mode & FMODE_WRITE) &&		    (!(lv_ptr->lv_status & LV_ACTIVE)))		    return -EPERM;		if (!(lv_ptr->lv_access & LV_WRITE) &&		    (file->f_mode & FMODE_WRITE))			return -EACCES;                /* be sure to increment VG counter */		if (lv_ptr->lv_open == 0) vg_ptr->lv_open++;		lv_ptr->lv_open++;		MOD_INC_USE_COUNT;		P_DEV("blk_open OK, LV size %d\n", lv_ptr->lv_size);		return 0;	}	return -ENXIO;} /* lvm_blk_open() *//* * block device i/o-control routine */static int lvm_blk_ioctl(struct inode *inode, struct file *file,			 uint command, ulong a){	int minor = MINOR(inode->i_rdev);	vg_t *vg_ptr = vg[VG_BLK(minor)];	lv_t *lv_ptr = vg_ptr->lv[LV_BLK(minor)];	void *arg = (void *) a;	struct hd_geometry *hd = (struct hd_geometry *) a;	P_IOCTL("blk MINOR: %d  command: 0x%X  arg: %p  VG#: %d  LV#: %d  "		"mode: %s%s\n", minor, command, arg, VG_BLK(minor),		LV_BLK(minor), MODE_TO_STR(file->f_mode));	switch (command) {	case BLKSSZGET:		/* get block device sector size as needed e.g. by fdisk */		return put_user(get_hardsect_size(inode->i_rdev), (int *) arg);	case BLKGETSIZE:		/* return device size */		P_IOCTL("BLKGETSIZE: %u\n", lv_ptr->lv_size);		if (put_user(lv_ptr->lv_size, (unsigned long *)arg))			return -EFAULT;		break;	case BLKGETSIZE64:		if (put_user((u64)lv_ptr->lv_size << 9, (u64 *)arg))			return -EFAULT;		break;	case BLKFLSBUF:		/* flush buffer cache */		if (!capable(CAP_SYS_ADMIN)) return -EACCES;		P_IOCTL("BLKFLSBUF\n");		fsync_dev(inode->i_rdev);		invalidate_buffers(inode->i_rdev);		break;	case BLKRASET:		/* set read ahead for block device */		if (!capable(CAP_SYS_ADMIN)) return -EACCES;		P_IOCTL("BLKRASET: %ld sectors for %s\n",			(long) arg, kdevname(inode->i_rdev));		if ((long) arg < LVM_MIN_READ_AHEAD ||		    (long) arg > LVM_MAX_READ_AHEAD)			return -EINVAL;		lv_ptr->lv_read_ahead = (long) arg;		break;	case BLKRAGET:		/* get current read ahead setting */		P_IOCTL("BLKRAGET %d\n", lv_ptr->lv_read_ahead);		if (put_user(lv_ptr->lv_read_ahead, (long *)arg))			return -EFAULT;		break;	case HDIO_GETGEO:		/* get disk geometry */		P_IOCTL("%s -- lvm_blk_ioctl -- HDIO_GETGEO\n", lvm_name);		if (hd == NULL)			return -EINVAL;		{			unsigned char heads = 64;			unsigned char sectors = 32;			long start = 0;			short cylinders = lv_ptr->lv_size / heads / sectors;			if (copy_to_user((char *) &hd->heads, &heads,					 sizeof(heads)) != 0 ||			    copy_to_user((char *) &hd->sectors, &sectors,					 sizeof(sectors)) != 0 ||			    copy_to_user((short *) &hd->cylinders,				   &cylinders, sizeof(cylinders)) != 0 ||			    copy_to_user((long *) &hd->start, &start,					 sizeof(start)) != 0)				return -EFAULT;			P_IOCTL("%s -- lvm_blk_ioctl -- cylinders: %d\n",				lvm_name, cylinders);		}		break;

⌨️ 快捷键说明

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