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

📄 lvm.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef DEBUG_IOCTL		printk(KERN_DEBUG		       "%s -- lvm_blk_ioctl -- BLKFLSBUF\n", lvm_name);#endif		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;#ifdef DEBUG_IOCTL		printk(KERN_DEBUG		       "%s -- lvm_blk_ioctl -- BLKRASET: %d sectors for %02X:%02X\n",		       lvm_name, (long) arg, MAJOR(inode->i_rdev), minor);#endif		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 */#ifdef DEBUG_IOCTL		printk(KERN_DEBUG		       "%s -- lvm_blk_ioctl -- BLKRAGET\n", lvm_name);#endif		if (put_user(lv_ptr->lv_read_ahead, (long *)arg))			return -EFAULT;		break;	case HDIO_GETGEO:		/* get disk geometry */#ifdef DEBUG_IOCTL		printk(KERN_DEBUG		       "%s -- lvm_blk_ioctl -- HDIO_GETGEO\n", lvm_name);#endif		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;		}#ifdef DEBUG_IOCTL		printk(KERN_DEBUG		       "%s -- lvm_blk_ioctl -- cylinders: %d\n",		       lvm_name, lv_ptr->lv_size / heads / sectors);#endif		break;	case LV_SET_ACCESS:		/* set access flags of a logical volume */		if (!capable(CAP_SYS_ADMIN)) return -EACCES;		lv_ptr->lv_access = (ulong) arg;		if ( lv_ptr->lv_access & LV_WRITE)			set_device_ro(lv_ptr->lv_dev, 0);		else			set_device_ro(lv_ptr->lv_dev, 1);		break;	case LV_SET_STATUS:		/* set status flags of a logical volume */		if (!capable(CAP_SYS_ADMIN)) return -EACCES;		if (!((ulong) arg & LV_ACTIVE) && lv_ptr->lv_open > 1)			return -EPERM;		lv_ptr->lv_status = (ulong) arg;		break;	case LV_BMAP:		/* turn logical block into (dev_t, block). non privileged. */		return lvm_user_bmap(inode, (struct lv_bmap *) arg);		break;	case LV_SET_ALLOCATION:		/* set allocation flags of a logical volume */		if (!capable(CAP_SYS_ADMIN)) return -EACCES;		lv_ptr->lv_allocation = (ulong) arg;		break;	case LV_SNAPSHOT_USE_RATE:		if (!(lv_ptr->lv_access & LV_SNAPSHOT)) return -EPERM;		{			lv_snapshot_use_rate_req_t	lv_snapshot_use_rate_req;			if (copy_from_user(&lv_snapshot_use_rate_req, arg,					   sizeof(lv_snapshot_use_rate_req_t)))				return -EFAULT;			if (lv_snapshot_use_rate_req.rate < 0 ||			    lv_snapshot_use_rate_req.rate  > 100) return -EFAULT;			switch (lv_snapshot_use_rate_req.block)			{			case 0:				lv_ptr->lv_snapshot_use_rate = lv_snapshot_use_rate_req.rate;				if (lv_ptr->lv_remap_ptr * 100 / lv_ptr->lv_remap_end < lv_ptr->lv_snapshot_use_rate)					interruptible_sleep_on (&lv_ptr->lv_snapshot_wait);				break;			case O_NONBLOCK:				break;			default:				return -EFAULT;			}			lv_snapshot_use_rate_req.rate = lv_ptr->lv_remap_ptr * 100 / lv_ptr->lv_remap_end;			if (copy_to_user(arg, &lv_snapshot_use_rate_req,					 sizeof(lv_snapshot_use_rate_req_t)))				return -EFAULT;		}		break;	default:		printk(KERN_WARNING		       "%s -- lvm_blk_ioctl: unknown command %d\n",		       lvm_name, command);		return -EINVAL;	}	return 0;} /* lvm_blk_ioctl() *//* * block device close routine */static int lvm_blk_close(struct inode *inode, struct file *file){	int minor = MINOR(inode->i_rdev);	vg_t *vg_ptr = vg[VG_BLK(minor)];	lv_t *lv_ptr = vg_ptr->lv[LV_BLK(minor)];#ifdef DEBUG	printk(KERN_DEBUG	       "%s -- lvm_blk_close MINOR: %d  VG#: %d  LV#: %d\n",	       lvm_name, minor, VG_BLK(minor), LV_BLK(minor));#endif	sync_dev(inode->i_rdev);	if (lv_ptr->lv_open == 1) vg_ptr->lv_open--;	lv_ptr->lv_open--;	MOD_DEC_USE_COUNT;	return 0;} /* lvm_blk_close() */static int lvm_user_bmap(struct inode *inode, struct lv_bmap *user_result){	struct buffer_head bh;	unsigned long block;	int err;		if (get_user(block, &user_result->lv_block))	return -EFAULT;		memset(&bh,0,sizeof bh);	bh.b_rsector = block;	bh.b_dev = bh.b_rdev = inode->i_dev;	bh.b_size = lvm_get_blksize(bh.b_dev);	if ((err=lvm_map(&bh, READ)) < 0)  {	printk("lvm map failed: %d\n", err);	return -EINVAL;	}		return put_user(  kdev_t_to_nr(bh.b_rdev), &user_result->lv_dev) ||	put_user(bh.b_rsector, &user_result->lv_block) ? -EFAULT : 0;}     /* * provide VG info for proc filesystem use (global) */int lvm_vg_info(vg_t *vg_ptr, char *buf) {	int sz = 0;	char inactive_flag = ' ';	if (!(vg_ptr->vg_status & VG_ACTIVE)) inactive_flag = 'I';	sz = sprintf(buf,		     "\nVG: %c%s  [%d PV, %d LV/%d open] "		     " PE Size: %d KB\n"		     "  Usage [KB/PE]: %d /%d total  "		     "%d /%d used  %d /%d free",		     inactive_flag,		     vg_ptr->vg_name,		     vg_ptr->pv_cur,		     vg_ptr->lv_cur,		     vg_ptr->lv_open,	     	     vg_ptr->pe_size >> 1,		     vg_ptr->pe_size * vg_ptr->pe_total >> 1,		     vg_ptr->pe_total,		     vg_ptr->pe_allocated * vg_ptr->pe_size >> 1,	     	     vg_ptr->pe_allocated,		     (vg_ptr->pe_total - vg_ptr->pe_allocated) *		     	     vg_ptr->pe_size >> 1,		     vg_ptr->pe_total - vg_ptr->pe_allocated);	return sz;}/* * provide LV info for proc filesystem use (global) */int lvm_lv_info(vg_t *vg_ptr, lv_t *lv_ptr, char *buf) {	int sz = 0;	char inactive_flag = 'A', allocation_flag = ' ',	     stripes_flag = ' ', rw_flag = ' ';	if (!(lv_ptr->lv_status & LV_ACTIVE))		inactive_flag = 'I';	rw_flag = 'R';	if (lv_ptr->lv_access & LV_WRITE)		rw_flag = 'W';	allocation_flag = 'D';	if (lv_ptr->lv_allocation & LV_CONTIGUOUS)		allocation_flag = 'C';	stripes_flag = 'L';	if (lv_ptr->lv_stripes > 1)		stripes_flag = 'S';	sz += sprintf(buf+sz,		      "[%c%c%c%c",		      inactive_flag,	 rw_flag,		      allocation_flag,		      stripes_flag);	if (lv_ptr->lv_stripes > 1)		sz += sprintf(buf+sz, "%-2d",			      lv_ptr->lv_stripes);	else		sz += sprintf(buf+sz, "  ");	basename = strrchr(lv_ptr->lv_name, '/');	if ( basename == 0) basename = lv_ptr->lv_name;	else                basename++;	sz += sprintf(buf+sz, "] %-25s", basename);	if (strlen(basename) > 25)		sz += sprintf(buf+sz,			      "\n                              ");	sz += sprintf(buf+sz, "%9d /%-6d   ",		      lv_ptr->lv_size >> 1,		      lv_ptr->lv_size / vg_ptr->pe_size);	if (lv_ptr->lv_open == 0)		sz += sprintf(buf+sz, "close");	else		sz += sprintf(buf+sz, "%dx open",			      lv_ptr->lv_open);	return sz;}/* * provide PV info for proc filesystem use (global) */int lvm_pv_info(pv_t *pv_ptr, char *buf) {	int sz = 0;	char inactive_flag = 'A', allocation_flag = ' ';	char *pv_name = NULL;	if (!(pv_ptr->pv_status & PV_ACTIVE))		inactive_flag = 'I';	allocation_flag = 'A';	if (!(pv_ptr->pv_allocatable & PV_ALLOCATABLE))		allocation_flag = 'N';	pv_name = strrchr(pv_ptr->pv_name+1,'/');	if ( pv_name == 0) pv_name = pv_ptr->pv_name;	else               pv_name++;	sz = sprintf(buf,		     "[%c%c] %-21s %8d /%-6d  "		     "%8d /%-6d  %8d /%-6d",		     inactive_flag,		     allocation_flag,		     pv_name,		     pv_ptr->pe_total *		     pv_ptr->pe_size >> 1,		     pv_ptr->pe_total,		     pv_ptr->pe_allocated *		     pv_ptr->pe_size >> 1,		     pv_ptr->pe_allocated,		     (pv_ptr->pe_total -		      pv_ptr->pe_allocated) *		     pv_ptr->pe_size >> 1,		     pv_ptr->pe_total -		     pv_ptr->pe_allocated);	return sz;}#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS/* * Support functions /proc-Filesystem */#define  LVM_PROC_BUF   ( i == 0 ? dummy_buf : &buf[sz])/* * provide global LVM information */static int lvm_proc_get_global_info(char *page, char **start, off_t pos, int count, int *eof, void *data){	int c, i, l, p, v, vg_counter, pv_counter, lv_counter, lv_open_counter,	 lv_open_total, pe_t_bytes, hash_table_bytes, lv_block_exception_t_bytes, seconds;	static off_t sz;	off_t sz_last;	static char *buf = NULL;	static char dummy_buf[160];	/* sized for 2 lines */	vg_t *vg_ptr;	lv_t *lv_ptr;	pv_t *pv_ptr;#ifdef DEBUG_LVM_PROC_GET_INFO	printk(KERN_DEBUG	       "%s - lvm_proc_get_global_info CALLED  pos: %lu  count: %d  whence: %d\n",	       lvm_name, pos, count, whence);#endif	MOD_INC_USE_COUNT;	if (pos == 0 || buf == NULL) {		sz_last = vg_counter = pv_counter = lv_counter = lv_open_counter = \		lv_open_total = pe_t_bytes = hash_table_bytes = \		lv_block_exception_t_bytes = 0;		/* search for activity */		for (v = 0; v < ABS_MAX_VG; v++) {			if ((vg_ptr = vg[v]) != NULL) {				vg_counter++;				pv_counter += vg_ptr->pv_cur;				lv_counter += vg_ptr->lv_cur;				if (vg_ptr->lv_cur > 0) {					for (l = 0; l < vg[v]->lv_max; l++) {						if ((lv_ptr = vg_ptr->lv[l]) != NULL) {							pe_t_bytes += lv_ptr->lv_allocated_le;							hash_table_bytes += lv_ptr->lv_snapshot_hash_table_size;							if (lv_ptr->lv_block_exception != NULL)								lv_block_exception_t_bytes += lv_ptr->lv_remap_end;							if (lv_ptr->lv_open > 0) {								lv_open_counter++;								lv_open_total += lv_ptr->lv_open;							}						}					}				}			}		}		pe_t_bytes *= sizeof(pe_t);		lv_block_exception_t_bytes *= sizeof(lv_block_exception_t);		if (buf != NULL) {#ifdef DEBUG_KFREE			printk(KERN_DEBUG			       "%s -- vfree %d\n", lvm_name, __LINE__);#endif			lock_kernel();			vfree(buf);			unlock_kernel();			buf = NULL;		}		/* 2 times: first to get size to allocate buffer,		   2nd to fill the malloced buffer */		for (i = 0; i < 2; i++) {			sz = 0;			sz += sprintf(LVM_PROC_BUF,				      "LVM "#ifdef MODULE				      "module"#else				      "driver"#endif				      " %s\n\n"				    "Total:  %d VG%s  %d PV%s  %d LV%s ",				      lvm_short_version,				  vg_counter, vg_counter == 1 ? "" : "s",				  pv_counter, pv_counter == 1 ? "" : "s",				 lv_counter, lv_counter == 1 ? "" : "s");			sz += sprintf(LVM_PROC_BUF,				      "(%d LV%s open",				      lv_open_counter,				      lv_open_counter == 1 ? "" : "s");			if (lv_open_total > 0)				sz += sprintf(LVM_PROC_BUF,					      " %d times)\n",					      lv_open_total);			else				sz += sprintf(LVM_PROC_BUF, ")");			sz += sprintf(LVM_PROC_BUF,				      "\nGlobal: %lu bytes malloced   IOP version: %d   ",				      vg_counter * sizeof(vg_t) +				      pv_counter * sizeof(pv_t) +				      lv_counter * sizeof(lv_t) +				      pe_t_bytes + hash_table_bytes + lv_block_exception_t_bytes + sz_last,				      lvm_iop_version);			seconds = CURRENT_TIME - loadtime;			if (seconds < 0)				loadtime = CURRENT_TIME + seconds;			if (seconds / 86400 > 0) {				sz += sprintf(LVM_PROC_BUF, "%d day%s ",					      seconds / 86400,					      seconds / 86400 == 0 ||					 seconds / 86400 > 1 ? "s" : "");			}			sz += sprintf(LVM_PROC_BUF, "%d:%02d:%02d active\n",				      (seconds % 86400) / 3600,				      (seconds % 3600) / 60,				      seconds % 60);			if (vg_counter > 0) {				for (v = 0; v < ABS_MAX_VG; v++) {					/* volume group */					if ((vg_ptr = vg[v]) != NULL) {						sz += lvm_vg_info(vg_ptr, LVM_PROC_BUF);						/* physical volumes */						sz += sprintf(LVM_PROC_BUF,							      "\n  PV%s ",							      vg_ptr->pv_cur == 1 ? ": " : "s:");						c = 0;						for (p = 0; p < vg_ptr->pv_max; p++) {							if ((pv_ptr = vg_ptr->pv[p]) != NULL) {								sz += lvm_pv_info(pv_ptr, LVM_PROC_BUF);								c++;								if (c < vg_ptr->pv_cur)									sz += sprintf(LVM_PROC_BUF,										      "\n       ");							}						}						/* logical volumes */						sz += sprintf(LVM_PROC_BUF,							   "\n    LV%s ",							      vg_ptr->lv_cur == 1 ? ": " : "s:");						c = 0;						for (l = 0; l < vg_ptr->lv_max; l++) {							if ((lv_ptr = vg_ptr->lv[l]) != NULL) {								sz += lvm_lv_info(vg_ptr, lv_ptr, LVM_PROC_BUF);								c++;								if (c < vg_ptr->lv_cur)									sz += sprintf(LVM_PROC_BUF,										      "\n         ");							}						}						if (vg_ptr->lv_cur == 0) sz += sprintf(LVM_PROC_BUF, "none");						sz += sprintf(LVM_PROC_BUF, "\n");					}				}			}			if (buf == NULL) {				lock_kernel();				buf = vmalloc(sz);				unlock_kernel();				if (buf == NULL) {					sz = 0;					MOD_DEC_USE_COUNT;					return sprintf(page, "%s - vmalloc error at line %d\n",

⌨️ 快捷键说明

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