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

📄 lvm.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (copy_from_user(&le_remap_req, arg,			   sizeof(le_remap_req_t)) != 0)		return -EFAULT;	for (l = 0; l < vg_ptr->lv_max; l++) {		lv_ptr = vg_ptr->lv[l];		if (lv_ptr != NULL &&		    strcmp(lv_ptr->lv_name,			       le_remap_req.lv_name) == 0) {			for (le = 0; le < lv_ptr->lv_allocated_le; le++) {				if (lv_ptr->lv_current_pe[le].dev ==				    le_remap_req.old_dev &&				    lv_ptr->lv_current_pe[le].pe ==				    le_remap_req.old_pe) {					lv_ptr->lv_current_pe[le].dev =					    le_remap_req.new_dev;					lv_ptr->lv_current_pe[le].pe =					    le_remap_req.new_pe;					__update_hardsectsize(lv_ptr);					return 0;				}			}			return -EINVAL;		}	}	return -ENXIO;} /* lvm_do_le_remap() *//* * character device support function VGDA create */static int lvm_do_vg_create(void *arg, int minor){	int ret = 0;	ulong l, ls = 0, p, size;	lv_t lv;	vg_t *vg_ptr;	lv_t **snap_lv_ptr;	if ((vg_ptr = kmalloc(sizeof(vg_t),GFP_KERNEL)) == NULL) {		printk(KERN_CRIT		       "%s -- VG_CREATE: kmalloc error VG at line %d\n",		       lvm_name, __LINE__);		return -ENOMEM;	}	/* get the volume group structure */	if (copy_from_user(vg_ptr, arg, sizeof(vg_t)) != 0) {		P_IOCTL("lvm_do_vg_create ERROR: copy VG ptr %p (%d bytes)\n",			arg, sizeof(vg_t));		kfree(vg_ptr);		return -EFAULT;	}        /* VG_CREATE now uses minor number in VG structure */        if (minor == -1) minor = vg_ptr->vg_number;	/* Validate it */        if (vg[VG_CHR(minor)] != NULL) {		P_IOCTL("lvm_do_vg_create ERROR: VG %d in use\n", minor);		kfree(vg_ptr);  	     	return -EPERM;	}	/* we are not that active so far... */	vg_ptr->vg_status &= ~VG_ACTIVE;	vg_ptr->pe_allocated = 0;	if (vg_ptr->pv_max > ABS_MAX_PV) {		printk(KERN_WARNING		       "%s -- Can't activate VG: ABS_MAX_PV too small\n",		       lvm_name);		kfree(vg_ptr);		return -EPERM;	}	if (vg_ptr->lv_max > ABS_MAX_LV) {		printk(KERN_WARNING		"%s -- Can't activate VG: ABS_MAX_LV too small for %u\n",		       lvm_name, vg_ptr->lv_max);		kfree(vg_ptr);		return -EPERM;	}	/* create devfs and procfs entries */	lvm_fs_create_vg(vg_ptr);	vg[VG_CHR(minor)] = vg_ptr;	/* get the physical volume structures */	vg_ptr->pv_act = vg_ptr->pv_cur = 0;	for (p = 0; p < vg_ptr->pv_max; p++) {		pv_t *pvp;		/* user space address */		if ((pvp = vg_ptr->pv[p]) != NULL) {			ret = lvm_do_pv_create(pvp, vg_ptr, p);			if ( ret != 0) {				lvm_do_vg_remove(minor);				return ret;			}		}	}	size = vg_ptr->lv_max * sizeof(lv_t *);	if ((snap_lv_ptr = vmalloc ( size)) == NULL) {		printk(KERN_CRIT		       "%s -- VG_CREATE: vmalloc error snapshot LVs at line %d\n",		       lvm_name, __LINE__);		lvm_do_vg_remove(minor);		return -EFAULT;	}	memset(snap_lv_ptr, 0, size);	/* get the logical volume structures */	vg_ptr->lv_cur = 0;	for (l = 0; l < vg_ptr->lv_max; l++) {		lv_t *lvp;		/* user space address */		if ((lvp = vg_ptr->lv[l]) != NULL) {			if (copy_from_user(&lv, lvp, sizeof(lv_t)) != 0) {				P_IOCTL("ERROR: copying LV ptr %p (%d bytes)\n",					lvp, sizeof(lv_t));				lvm_do_vg_remove(minor);				return -EFAULT;			}			if ( lv.lv_access & LV_SNAPSHOT) {				snap_lv_ptr[ls] = lvp;				vg_ptr->lv[l] = NULL;				ls++;				continue;			}			vg_ptr->lv[l] = NULL;			/* only create original logical volumes for now */			if (lvm_do_lv_create(minor, lv.lv_name, &lv) != 0) {				lvm_do_vg_remove(minor);				return -EFAULT;			}		}	}	/* Second path to correct snapshot logical volumes which are not	   in place during first path above */	for (l = 0; l < ls; l++) {		lv_t *lvp = snap_lv_ptr[l];		if (copy_from_user(&lv, lvp, sizeof(lv_t)) != 0) {			lvm_do_vg_remove(minor);			return -EFAULT;		}		if (lvm_do_lv_create(minor, lv.lv_name, &lv) != 0) {			lvm_do_vg_remove(minor);			return -EFAULT;		}	}	vfree(snap_lv_ptr);	vg_count++;	MOD_INC_USE_COUNT;	/* let's go active */	vg_ptr->vg_status |= VG_ACTIVE;	return 0;} /* lvm_do_vg_create() *//* * character device support function VGDA extend */static int lvm_do_vg_extend(vg_t *vg_ptr, void *arg){	int ret = 0;	uint p;	pv_t *pv_ptr;	if (vg_ptr == NULL) return -ENXIO;	if (vg_ptr->pv_cur < vg_ptr->pv_max) {		for (p = 0; p < vg_ptr->pv_max; p++) {			if ( ( pv_ptr = vg_ptr->pv[p]) == NULL) {				ret = lvm_do_pv_create(arg, vg_ptr, p);				if ( ret != 0) return ret;				pv_ptr = vg_ptr->pv[p];				vg_ptr->pe_total += pv_ptr->pe_total;				return 0;			}		}	}	return -EPERM;} /* lvm_do_vg_extend() *//* * character device support function VGDA reduce */static int lvm_do_vg_reduce(vg_t *vg_ptr, void *arg) {	uint p;	pv_t *pv_ptr;	if (vg_ptr == NULL) return -ENXIO;	if (copy_from_user(pv_name, arg, sizeof(pv_name)) != 0)		return -EFAULT;	for (p = 0; p < vg_ptr->pv_max; p++) {		pv_ptr = vg_ptr->pv[p];		if (pv_ptr != NULL &&		    strcmp(pv_ptr->pv_name,			       pv_name) == 0) {			if (pv_ptr->lv_cur > 0) return -EPERM;			lvm_do_pv_remove(vg_ptr, p);			/* Make PV pointer array contiguous */			for (; p < vg_ptr->pv_max - 1; p++)				vg_ptr->pv[p] = vg_ptr->pv[p + 1];			vg_ptr->pv[p + 1] = NULL;			return 0;		}	}	return -ENXIO;} /* lvm_do_vg_reduce *//* * character device support function VG rename */static int lvm_do_vg_rename(vg_t *vg_ptr, void *arg){	int l = 0, p = 0, len = 0;	char vg_name[NAME_LEN] = { 0,};	char lv_name[NAME_LEN] = { 0,};	char *ptr = NULL;	lv_t *lv_ptr = NULL;	pv_t *pv_ptr = NULL;	if (vg_ptr == NULL) return -ENXIO;	if (copy_from_user(vg_name, arg, sizeof(vg_name)) != 0)		return -EFAULT;	lvm_fs_remove_vg(vg_ptr);	strncpy ( vg_ptr->vg_name, vg_name, sizeof ( vg_name)-1);	for ( l = 0; l < vg_ptr->lv_max; l++)	{		if ((lv_ptr = vg_ptr->lv[l]) == NULL) continue;		strncpy(lv_ptr->vg_name, vg_name, sizeof ( vg_name));		ptr = strrchr(lv_ptr->lv_name, '/');		if (ptr == NULL) ptr = lv_ptr->lv_name;		strncpy(lv_name, ptr, sizeof ( lv_name));		len = sizeof(LVM_DIR_PREFIX);		strcpy(lv_ptr->lv_name, LVM_DIR_PREFIX);		strncat(lv_ptr->lv_name, vg_name, NAME_LEN - len);		len += strlen ( vg_name);		strncat(lv_ptr->lv_name, lv_name, NAME_LEN - len);	}	for ( p = 0; p < vg_ptr->pv_max; p++)	{		if ( (pv_ptr = vg_ptr->pv[p]) == NULL) continue;		strncpy(pv_ptr->vg_name, vg_name, NAME_LEN);	}	lvm_fs_create_vg(vg_ptr);	return 0;} /* lvm_do_vg_rename *//* * character device support function VGDA remove */static int lvm_do_vg_remove(int minor){	int i;	vg_t *vg_ptr = vg[VG_CHR(minor)];	pv_t *pv_ptr;	if (vg_ptr == NULL) return -ENXIO;#ifdef LVM_TOTAL_RESET	if (vg_ptr->lv_open > 0 && lvm_reset_spindown == 0)#else	if (vg_ptr->lv_open > 0)#endif		return -EPERM;	/* let's go inactive */	vg_ptr->vg_status &= ~VG_ACTIVE;	/* remove from procfs and devfs */	lvm_fs_remove_vg(vg_ptr);	/* free LVs */	/* first free snapshot logical volumes */	for (i = 0; i < vg_ptr->lv_max; i++) {		if (vg_ptr->lv[i] != NULL &&		    vg_ptr->lv[i]->lv_access & LV_SNAPSHOT) {			lvm_do_lv_remove(minor, NULL, i);			current->state = TASK_UNINTERRUPTIBLE;			schedule_timeout(1);		}	}	/* then free the rest of the LVs */	for (i = 0; i < vg_ptr->lv_max; i++) {		if (vg_ptr->lv[i] != NULL) {			lvm_do_lv_remove(minor, NULL, i);			current->state = TASK_UNINTERRUPTIBLE;			schedule_timeout(1);		}	}	/* free PVs */	for (i = 0; i < vg_ptr->pv_max; i++) {		if ((pv_ptr = vg_ptr->pv[i]) != NULL) {			P_KFREE("%s -- kfree %d\n", lvm_name, __LINE__);			lvm_do_pv_remove(vg_ptr, i);		}	}	P_KFREE("%s -- kfree %d\n", lvm_name, __LINE__);	kfree(vg_ptr);	vg[VG_CHR(minor)] = NULL;	vg_count--;	MOD_DEC_USE_COUNT;	return 0;} /* lvm_do_vg_remove() *//* * character device support function physical volume create */static int lvm_do_pv_create(pv_t *pvp, vg_t *vg_ptr, ulong p) {	pv_t *pv;	int err;	pv = kmalloc(sizeof(pv_t),GFP_KERNEL);	if (pv == NULL) {		printk(KERN_CRIT		       "%s -- PV_CREATE: kmalloc error PV at line %d\n",		       lvm_name, __LINE__);		return -ENOMEM;	}	memset(pv, 0, sizeof(*pv));	if (copy_from_user(pv, pvp, sizeof(pv_t)) != 0) {		P_IOCTL("lvm_do_pv_create ERROR: copy PV ptr %p (%d bytes)\n",			pvp, sizeof(pv_t));		kfree(pv);		return -EFAULT;	}	if ((err = _open_pv(pv))) {		kfree(pv);		return err;	}	/* We don't need the PE list	   in kernel space as with LVs pe_t list (see below) */	pv->pe = NULL;	pv->pe_allocated = 0;	pv->pv_status = PV_ACTIVE;	vg_ptr->pv_act++;	vg_ptr->pv_cur++;	lvm_fs_create_pv(vg_ptr, pv);	vg_ptr->pv[p] = pv;	return 0;} /* lvm_do_pv_create() *//* * character device support function physical volume remove */static int lvm_do_pv_remove(vg_t *vg_ptr, ulong p) {	pv_t *pv = vg_ptr->pv[p];	lvm_fs_remove_pv(vg_ptr, pv);	vg_ptr->pe_total -= pv->pe_total;	vg_ptr->pv_cur--;	vg_ptr->pv_act--;	_close_pv(pv);	kfree(pv);	vg_ptr->pv[p] = NULL;	return 0;}static void __update_hardsectsize(lv_t *lv) {	int le, e;	int max_hardsectsize = 0, hardsectsize;	for (le = 0; le < lv->lv_allocated_le; le++) {		hardsectsize = get_hardsect_size(lv->lv_current_pe[le].dev);		if (hardsectsize == 0)			hardsectsize = 512;		if (hardsectsize > max_hardsectsize)			max_hardsectsize = hardsectsize;	}	/* only perform this operation on active snapshots */	if ((lv->lv_access & LV_SNAPSHOT) &&	    (lv->lv_status & LV_ACTIVE)) {		for (e = 0; e < lv->lv_remap_end; e++) {			hardsectsize = get_hardsect_size( lv->lv_block_exception[e].rdev_new);			if (hardsectsize == 0)				hardsectsize = 512;			if (hardsectsize > max_hardsectsize)				max_hardsectsize = hardsectsize;		}	}	lvm_hardsectsizes[MINOR(lv->lv_dev)] = max_hardsectsize;}/* * character device support function logical volume create */static int lvm_do_lv_create(int minor, char *lv_name, lv_t *lv){	int e, ret, l, le, l_new, p, size, activate = 1;	ulong lv_status_save;	lv_block_exception_t *lvbe = lv->lv_block_exception;	vg_t *vg_ptr = vg[VG_CHR(minor)];	lv_t *lv_ptr = NULL;	pe_t *pep;	if (!(pep = lv->lv_current_pe))		return -EINVAL;	if (_sectors_to_k(lv->lv_chunk_size) > LVM_SNAPSHOT_MAX_CHUNK)		return -EINVAL;	for (l = 0; l < vg_ptr->lv_cur; l++) {		if (vg_ptr->lv[l] != NULL &&		    strcmp(vg_ptr->lv[l]->lv_name, lv_name) == 0)			return -EEXIST;	}	/* in case of lv_remove(), lv_create() pair */	l_new = -1;	if (vg_ptr->lv[lv->lv_number] == NULL)		l_new = lv->lv_number;	else {		for (l = 0; l < vg_ptr->lv_max; l++) {			if (vg_ptr->lv[l] == NULL)				if (l_new == -1) l_new = l;		}	}	if (l_new == -1) return -EPERM;	else             l = l_new;	if ((lv_ptr = kmalloc(sizeof(lv_t),GFP_KERNEL)) == NULL) {;		printk(KERN_CRIT "%s -- LV_CREATE: kmalloc error LV at line %d\n",		       lvm_name, __LINE__);		return -ENOMEM;	}	/* copy preloaded LV */	memcpy((char *) lv_ptr, (char *) lv, sizeof(lv_t));	lv_status_save = lv_ptr->lv_status;

⌨️ 快捷键说明

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