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

📄 ioctl32.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	uint32_t pv_cur;	uint32_t pv_act;	uint32_t dummy;	uint32_t vgda;	uint32_t pe_size;	uint32_t pe_total;	uint32_t pe_allocated;	uint32_t pvg_total;	u32 proc;	u32 pv[ABS_MAX_PV + 1];	u32 lv[ABS_MAX_LV + 1];    	uint8_t vg_uuid[UUID_LEN+1];	/* volume group UUID */	uint8_t dummy1[200];} vg32_t;typedef struct {	uint8_t id[2];	uint16_t version;	lvm_disk_data_t pv_on_disk;	lvm_disk_data_t vg_on_disk;	lvm_disk_data_t pv_namelist_on_disk;	lvm_disk_data_t lv_on_disk;	lvm_disk_data_t pe_on_disk;	uint8_t pv_name[NAME_LEN];	uint8_t vg_name[NAME_LEN];	uint8_t system_id[NAME_LEN];	kdev_t pv_dev;	uint32_t pv_number;	uint32_t pv_status;	uint32_t pv_allocatable;	uint32_t pv_size;	uint32_t lv_cur;	uint32_t pe_size;	uint32_t pe_total;	uint32_t pe_allocated;	uint32_t pe_stale;	u32 pe;	u32 inode;	uint8_t pv_uuid[UUID_LEN+1];} pv32_t;typedef struct {	char lv_name[NAME_LEN];	u32 lv;} lv_req32_t;typedef struct {	u32 lv_index;	u32 lv;	/* Transfer size because user space and kernel space differ */	uint16_t size;} lv_status_byindex_req32_t;typedef struct {	__kernel_dev_t32 dev;	u32   lv;} lv_status_bydev_req32_t;typedef struct {	uint8_t lv_name[NAME_LEN];	kdev_t old_dev;	kdev_t new_dev;	u32 old_pe;	u32 new_pe;} le_remap_req32_t;typedef struct {	char pv_name[NAME_LEN];	u32 pv;} pv_status_req32_t;typedef struct {	uint8_t lv_name[NAME_LEN];	uint8_t vg_name[NAME_LEN];	uint32_t lv_access;	uint32_t lv_status;	uint32_t lv_open;	kdev_t lv_dev;	uint32_t lv_number;	uint32_t lv_mirror_copies;	uint32_t lv_recovery;	uint32_t lv_schedule;	uint32_t lv_size;	u32 lv_current_pe;	uint32_t lv_current_le;	uint32_t lv_allocated_le;	uint32_t lv_stripes;	uint32_t lv_stripesize;	uint32_t lv_badblock;	uint32_t lv_allocation;	uint32_t lv_io_timeout;	uint32_t lv_read_ahead;	/* delta to version 1 starts here */	u32 lv_snapshot_org;	u32 lv_snapshot_prev;	u32 lv_snapshot_next;	u32 lv_block_exception;	uint32_t lv_remap_ptr;	uint32_t lv_remap_end;	uint32_t lv_chunk_size;	uint32_t lv_snapshot_minor;	char dummy[200];} lv32_t;typedef struct {	u32 hash[2];	u32 rsector_org;	kdev_t rdev_org;	u32 rsector_new;	kdev_t rdev_new;} lv_block_exception32_t;static void put_lv_t(lv_t *l){	if (l->lv_current_pe) vfree(l->lv_current_pe);	if (l->lv_block_exception) vfree(l->lv_block_exception);	kfree(l);}static lv_t *get_lv_t(u32 p, int *errp){	int err, i;	u32 ptr1, ptr2;	size_t size;	lv_block_exception32_t *lbe32;	lv_block_exception_t *lbe;	lv32_t *ul = (lv32_t *)A(p);	lv_t *l = (lv_t *) kmalloc(sizeof(lv_t), GFP_KERNEL);	if (!l) {		*errp = -ENOMEM;		return NULL;	}	memset(l, 0, sizeof(lv_t));	err = copy_from_user(l, ul, (long)&((lv32_t *)0)->lv_current_pe);	err |= __copy_from_user(&l->lv_current_le, &ul->lv_current_le,				((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le));	err |= __copy_from_user(&l->lv_remap_ptr, &ul->lv_remap_ptr,				((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));	err |= __get_user(ptr1, &ul->lv_current_pe);	err |= __get_user(ptr2, &ul->lv_block_exception);	if (err) {		kfree(l);		*errp = -EFAULT;		return NULL;	}	if (ptr1) {		size = l->lv_allocated_le * sizeof(pe_t);		l->lv_current_pe = vmalloc(size);		if (l->lv_current_pe)			err = copy_from_user(l->lv_current_pe, (void *)A(ptr1), size);	}	if (!err && ptr2) {		size = l->lv_remap_end * sizeof(lv_block_exception_t);		l->lv_block_exception = lbe = vmalloc(size);		if (l->lv_block_exception) {			lbe32 = (lv_block_exception32_t *)A(ptr2);			memset(lbe, 0, size);			for (i = 0; i < l->lv_remap_end; i++, lbe++, lbe32++) {				err |= get_user(lbe->rsector_org, &lbe32->rsector_org);				err |= __get_user(lbe->rdev_org, &lbe32->rdev_org);				err |= __get_user(lbe->rsector_new, &lbe32->rsector_new);				err |= __get_user(lbe->rdev_new, &lbe32->rdev_new);			}		}	}	if (err || (ptr1 && !l->lv_current_pe) || (ptr2 && !l->lv_block_exception)) {		if (!err)			*errp = -ENOMEM;		else			*errp = -EFAULT;		put_lv_t(l);		return NULL;	}	return l;}static int copy_lv_t(u32 ptr, lv_t *l){	int err;	lv32_t *ul = (lv32_t *)A(ptr);	u32 ptr1;	size_t size;	err = get_user(ptr1, &ul->lv_current_pe);	if (err)		return -EFAULT;	err = copy_to_user(ul, l, (long)&((lv32_t *)0)->lv_current_pe);	err |= __copy_to_user(&ul->lv_current_le, &l->lv_current_le,				((long)&ul->lv_snapshot_org) - ((long)&ul->lv_current_le));	err |= __copy_to_user(&ul->lv_remap_ptr, &l->lv_remap_ptr,				((long)&ul->dummy[0]) - ((long)&ul->lv_remap_ptr));	size = l->lv_allocated_le * sizeof(pe_t);	if (ptr1)		err |= __copy_to_user((void *)A(ptr1), l->lv_current_pe, size);	return err ? -EFAULT : 0;}static int do_lvm_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg){	vg_t *v = NULL;	union {		lv_req_t lv_req;		le_remap_req_t le_remap;		lv_status_byindex_req_t lv_byindex;	        lv_status_bydev_req_t lv_bydev;		pv_status_req_t pv_status;	} u;	pv_t p;	int err;	u32 ptr = 0;	int i;	mm_segment_t old_fs;	void *karg = &u;	switch (cmd) {	case VG_STATUS:		v = kmalloc(sizeof(vg_t), GFP_KERNEL);		if (!v)			return -ENOMEM;		karg = v;		break;	case VG_CREATE_OLD:	case VG_CREATE:		v = kmalloc(sizeof(vg_t), GFP_KERNEL);		if (!v)			return -ENOMEM;		if (copy_from_user(v, (void *)arg, (long)&((vg32_t *)0)->proc)) {			kfree(v);			return -EFAULT;		}		/* 'proc' field is unused, just NULL it out. */		v->proc = NULL;		if (copy_from_user(v->vg_uuid, ((vg32_t *)arg)->vg_uuid, UUID_LEN+1)) {			kfree(v);			return -EFAULT;		}		    		karg = v;		memset(v->pv, 0, sizeof(v->pv) + sizeof(v->lv));		if (v->pv_max > ABS_MAX_PV || v->lv_max > ABS_MAX_LV)			return -EPERM;		for (i = 0; i < v->pv_max; i++) {			err = __get_user(ptr, &((vg32_t *)arg)->pv[i]);			if (err)				break;			if (ptr) {				v->pv[i] = kmalloc(sizeof(pv_t), GFP_KERNEL);				if (!v->pv[i]) {					err = -ENOMEM;					break;				}				err = copy_from_user(v->pv[i], (void *)A(ptr),						     sizeof(pv32_t) - 8 - UUID_LEN+1);				if (err) {					err = -EFAULT;					break;				}				err = copy_from_user(v->pv[i]->pv_uuid,						     ((pv32_t *)A(ptr))->pv_uuid,						     UUID_LEN+1);				if (err) {				        err = -EFAULT;					break;				}				v->pv[i]->pe = NULL;				v->pv[i]->bd = NULL;			}		}		if (!err) {			for (i = 0; i < v->lv_max; i++) {				err = __get_user(ptr, &((vg32_t *)arg)->lv[i]);				if (err)					break;				if (ptr) {					v->lv[i] = get_lv_t(ptr, &err);					if (err)						break;				}			}		}		break;	case LV_CREATE:	case LV_EXTEND:	case LV_REDUCE:	case LV_REMOVE:	case LV_RENAME:	case LV_STATUS_BYNAME:	        err = copy_from_user(&u.pv_status, arg, sizeof(u.pv_status.pv_name));		if (err)			return -EFAULT;		if (cmd != LV_REMOVE) {			err = __get_user(ptr, &((lv_req32_t *)arg)->lv);			if (err)				return err;			u.lv_req.lv = get_lv_t(ptr, &err);		} else			u.lv_req.lv = NULL;		break;	case LV_STATUS_BYINDEX:		err = get_user(u.lv_byindex.lv_index,			       &((lv_status_byindex_req32_t *)arg)->lv_index);		err |= __get_user(ptr, &((lv_status_byindex_req32_t *)arg)->lv);		if (err)			return err;		u.lv_byindex.lv = get_lv_t(ptr, &err);		break;	case LV_STATUS_BYDEV:	        err = get_user(u.lv_bydev.dev, &((lv_status_bydev_req32_t *)arg)->dev);		err |= __get_user(ptr, &((lv_status_bydev_req32_t *)arg)->lv);		if (err)			return err;		u.lv_bydev.lv = get_lv_t(ptr, &err);		break;	case VG_EXTEND:		err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8 - UUID_LEN+1);		if (err)			return -EFAULT;		err = copy_from_user(p.pv_uuid, ((pv32_t *)arg)->pv_uuid, UUID_LEN+1);		if (err)			return -EFAULT;		p.pe = NULL;		p.bd = NULL;		karg = &p;		break;	case PV_CHANGE:	case PV_STATUS:		err = copy_from_user(&u.pv_status, arg, sizeof(u.lv_req.lv_name));		if (err)			return -EFAULT;		err = __get_user(ptr, &((pv_status_req32_t *)arg)->pv);		if (err)			return err;		u.pv_status.pv = &p;		if (cmd == PV_CHANGE) {			err = copy_from_user(&p, (void *)A(ptr),					     sizeof(pv32_t) - 8 - UUID_LEN+1);			if (err)				return -EFAULT;			p.pe = NULL;			p.bd = NULL;		}		break;	};        old_fs = get_fs(); set_fs (KERNEL_DS);        err = sys_ioctl (fd, cmd, (unsigned long)karg);        set_fs (old_fs);	switch (cmd) {	case VG_STATUS:		if (!err) {			if (copy_to_user((void *)arg, v, (long)&((vg32_t *)0)->proc) ||			    clear_user(&((vg32_t *)arg)->proc, sizeof(vg32_t) - (long)&((vg32_t *)0)->proc))				err = -EFAULT;		}		if (copy_to_user(((vg32_t *)arg)->vg_uuid, v->vg_uuid, UUID_LEN+1)) {		        err = -EFAULT;		}		kfree(v);		break;	case VG_CREATE_OLD:	case VG_CREATE:		for (i = 0; i < v->pv_max; i++) {			if (v->pv[i])				kfree(v->pv[i]);		}		for (i = 0; i < v->lv_max; i++) {			if (v->lv[i])				put_lv_t(v->lv[i]);		}		kfree(v);		break;	case LV_STATUS_BYNAME:		if (!err && u.lv_req.lv)			err = copy_lv_t(ptr, u.lv_req.lv);		/* Fall through */        case LV_CREATE:	case LV_EXTEND:	case LV_REDUCE:		if (u.lv_req.lv)			put_lv_t(u.lv_req.lv);		break;	case LV_STATUS_BYINDEX:		if (u.lv_byindex.lv) {			if (!err)				err = copy_lv_t(ptr, u.lv_byindex.lv);			put_lv_t(u.lv_byindex.lv);		}		break;	case LV_STATUS_BYDEV:	        if (u.lv_bydev.lv) {			if (!err)				err = copy_lv_t(ptr, u.lv_bydev.lv);			put_lv_t(u.lv_byindex.lv);	        }	        break;	case PV_STATUS:		if (!err) {			err = copy_to_user((void *)A(ptr), &p, sizeof(pv32_t) - 8 - UUID_LEN+1);			if (err)				return -EFAULT;			err = copy_to_user(((pv_t *)A(ptr))->pv_uuid, p.pv_uuid, UUID_LEN + 1);			if (err)				return -EFAULT;		}		break;	};	return err;}#endif#ifdef CONFIG_GENRTC#endif#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)/* This really belongs in include/linux/drm.h -DaveM */#include "../../../drivers/char/drm/drm.h"typedef struct drm32_version {	int    version_major;	  /* Major version			    */	int    version_minor;	  /* Minor version			    */	int    version_patchlevel;/* Patch level			    */	int    name_len;	  /* Length of name buffer		    */	u32    name;		  /* Name of driver			    */	int    date_len;	  /* Length of date buffer		    */	u32    date;		  /* User-space buffer to hold date	    */	int    desc_len;	  /* Length of desc buffer		    */	u32    desc;		  /* User-space buffer to hold desc	    */} drm32_version_t;#define DRM32_IOCTL_VERSION    

⌨️ 快捷键说明

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