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

📄 loop.c-2.2.original

📁 Fast and transparent file system and swap encryption package for linux. No source code changes to li
💻 ORIGINAL
📖 第 1 页 / 共 2 页
字号:
		lo->lo_device = inode->i_rdev;		lo->lo_flags = 0;		/* Backed by a block device - don't need to hold onto		   a file structure */		lo->lo_backing_file = NULL;	} else if (S_ISREG(inode->i_mode)) {		if (!inode->i_op->bmap) { 			printk(KERN_ERR "loop: device has no block access/not implemented\n");			goto out_putf;		}		/* Backed by a regular file - we need to hold onto		   a file structure for this file.  We'll use it to		   write to blocks that are not already present in 		   a sparse file.  We create a new file structure		   based on the one passed to us via 'arg'.  This is		   to avoid changing the file structure that the		   caller is using */		lo->lo_device = inode->i_dev;		lo->lo_flags = LO_FLAGS_DO_BMAP;		error = -ENFILE;		lo->lo_backing_file = get_empty_filp();		if (lo->lo_backing_file) {			lo->lo_backing_file->f_mode = file->f_mode;			lo->lo_backing_file->f_pos = file->f_pos;			lo->lo_backing_file->f_flags = file->f_flags;			lo->lo_backing_file->f_owner = file->f_owner;			lo->lo_backing_file->f_dentry = file->f_dentry;			lo->lo_backing_file->f_op = file->f_op;			lo->lo_backing_file->private_data = file->private_data;			error = get_write_access(inode);			if (error) {				put_filp(lo->lo_backing_file);				lo->lo_backing_file = NULL;			}		}	}	if (error)		goto out_putf;	if (IS_RDONLY (inode) || is_read_only(lo->lo_device)) {		lo->lo_flags |= LO_FLAGS_READ_ONLY;		set_device_ro(dev, 1);	} else {		invalidate_inode_pages (inode);		set_device_ro(dev, 0);	}	lo->lo_dentry = dget(file->f_dentry);	lo->transfer = NULL;	lo->ioctl = NULL;	figure_loop_size(lo);out_putf:	fput(file);out:	if (error)		MOD_DEC_USE_COUNT;	return error;}static int loop_release_xfer(struct loop_device *lo){	int err = 0; 	if (lo->lo_encrypt_type) {		struct loop_func_table *xfer= xfer_funcs[lo->lo_encrypt_type]; 		if (xfer && xfer->release)			err = xfer->release(lo); 		if (xfer && xfer->unlock)			xfer->unlock(lo); 		lo->lo_encrypt_type = 0;	}	return err;}static int loop_init_xfer(struct loop_device *lo, int type,struct loop_info *i){	int err = 0; 	if (type) {		struct loop_func_table *xfer = xfer_funcs[type]; 		if (xfer->init)			err = xfer->init(lo, i);		if (!err) { 			lo->lo_encrypt_type = type;			if (xfer->lock)				xfer->lock(lo);		}	}	return err;}  static int loop_clr_fd(struct loop_device *lo, kdev_t dev){	struct dentry *dentry = lo->lo_dentry;	if (!dentry)		return -ENXIO;	if (lo->lo_refcnt > 1)	/* we needed one fd for the ioctl */		return -EBUSY;	if (S_ISBLK(dentry->d_inode->i_mode))		blkdev_release (dentry->d_inode);	lo->lo_dentry = NULL;	if (lo->lo_backing_file != NULL) {		fput(lo->lo_backing_file);		lo->lo_backing_file = NULL;	} else {		dput(dentry);	}	loop_release_xfer(lo);	lo->transfer = NULL;	lo->ioctl = NULL;	lo->lo_device = 0;	lo->lo_encrypt_type = 0;	lo->lo_offset = 0;	lo->lo_encrypt_key_size = 0;	memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE);	memset(lo->lo_name, 0, LO_NAME_SIZE);	loop_sizes[lo->lo_number] = 0;	invalidate_buffers(dev);	MOD_DEC_USE_COUNT;	return 0;}static int loop_set_status(struct loop_device *lo, struct loop_info *arg){	struct loop_info info; 	int err;	unsigned int type;	if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid && 	    !capable(CAP_SYS_ADMIN))		return -EPERM;	if (!lo->lo_dentry)		return -ENXIO;	if (copy_from_user(&info, arg, sizeof (struct loop_info)))		return -EFAULT; 	if ((unsigned int) info.lo_encrypt_key_size > LO_KEY_SIZE)		return -EINVAL;	type = info.lo_encrypt_type; 	if (type >= MAX_LO_CRYPT || xfer_funcs[type] == NULL)		return -EINVAL;	err = loop_release_xfer(lo);	if (!err) 		err = loop_init_xfer(lo, type, &info);	if (err)		return err;		lo->lo_offset = info.lo_offset;	strncpy(lo->lo_name, info.lo_name, LO_NAME_SIZE);	lo->transfer = xfer_funcs[type]->transfer;	lo->ioctl = xfer_funcs[type]->ioctl;	lo->lo_encrypt_key_size = info.lo_encrypt_key_size;	lo->lo_init[0] = info.lo_init[0];	lo->lo_init[1] = info.lo_init[1];	if (info.lo_encrypt_key_size) {		memcpy(lo->lo_encrypt_key, info.lo_encrypt_key, 		       info.lo_encrypt_key_size);		lo->lo_key_owner = current->uid; 	}		figure_loop_size(lo);	return 0;}static int loop_get_status(struct loop_device *lo, struct loop_info *arg){	struct loop_info	info;	if (!lo->lo_dentry)		return -ENXIO;	if (!arg)		return -EINVAL;	memset(&info, 0, sizeof(info));	info.lo_number = lo->lo_number;	info.lo_device = kdev_t_to_nr(lo->lo_dentry->d_inode->i_dev);	info.lo_inode = lo->lo_dentry->d_inode->i_ino;	info.lo_rdevice = kdev_t_to_nr(lo->lo_device);	info.lo_offset = lo->lo_offset;	info.lo_flags = lo->lo_flags;	strncpy(info.lo_name, lo->lo_name, LO_NAME_SIZE);	info.lo_encrypt_type = lo->lo_encrypt_type;	if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {		info.lo_encrypt_key_size = lo->lo_encrypt_key_size;		memcpy(info.lo_encrypt_key, lo->lo_encrypt_key,		       lo->lo_encrypt_key_size);	}	return copy_to_user(arg, &info, sizeof(info)) ? -EFAULT : 0;}static int lo_ioctl(struct inode * inode, struct file * file,	unsigned int cmd, unsigned long arg){	struct loop_device *lo;	int dev;	if (!inode)		return -EINVAL;	if (MAJOR(inode->i_rdev) != MAJOR_NR) {		printk(KERN_WARNING "lo_ioctl: pseudo-major != %d\n", MAJOR_NR);		return -ENODEV;	}	dev = MINOR(inode->i_rdev);	if (dev >= MAX_LOOP)		return -ENODEV;	lo = &loop_dev[dev];	switch (cmd) {	case LOOP_SET_FD:		return loop_set_fd(lo, inode->i_rdev, arg);	case LOOP_CLR_FD:		return loop_clr_fd(lo, inode->i_rdev);	case LOOP_SET_STATUS:		return loop_set_status(lo, (struct loop_info *) arg);	case LOOP_GET_STATUS:		return loop_get_status(lo, (struct loop_info *) arg);	case BLKGETSIZE:   /* Return device size */		if (!lo->lo_dentry)			return -ENXIO;		if (!arg)			return -EINVAL;		return put_user(loop_sizes[lo->lo_number] << 1, (long *) arg);	default:		return lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;	}	return 0;}static int lo_open(struct inode *inode, struct file *file){	struct loop_device *lo;	int	dev, type;	if (!inode)		return -EINVAL;	if (MAJOR(inode->i_rdev) != MAJOR_NR) {		printk(KERN_WARNING "lo_open: pseudo-major != %d\n", MAJOR_NR);		return -ENODEV;	}	dev = MINOR(inode->i_rdev);	if (dev >= MAX_LOOP) {		return -ENODEV;	}	lo = &loop_dev[dev];	type = lo->lo_encrypt_type; 	if (type && xfer_funcs[type] && xfer_funcs[type]->lock)		xfer_funcs[type]->lock(lo);	lo->lo_refcnt++;	MOD_INC_USE_COUNT;	return 0;}static int lo_release(struct inode *inode, struct file *file){	struct loop_device *lo;	int	dev, err;	if (!inode)		return 0;	if (MAJOR(inode->i_rdev) != MAJOR_NR) {		printk(KERN_WARNING "lo_release: pseudo-major != %d\n", MAJOR_NR);		return 0;	}	dev = MINOR(inode->i_rdev);	if (dev >= MAX_LOOP)		return 0;	err = fsync_dev(inode->i_rdev);	lo = &loop_dev[dev];	if (lo->lo_refcnt <= 0)		printk(KERN_ERR "lo_release: refcount(%d) <= 0\n", lo->lo_refcnt);	else  {		int type  = lo->lo_encrypt_type;		--lo->lo_refcnt;		if (xfer_funcs[type] && xfer_funcs[type]->unlock)			xfer_funcs[type]->unlock(lo);		MOD_DEC_USE_COUNT;	}	return err;}static struct file_operations lo_fops = {	NULL,			/* lseek - default */	block_read,		/* read - general block-dev read */	block_write,		/* write - general block-dev write */	NULL,			/* readdir - bad */	NULL,			/* poll */	lo_ioctl,		/* ioctl */	NULL,			/* mmap */	lo_open,		/* open */	NULL,			/* flush */	lo_release		/* release */};/* * And now the modules code and kernel interface. */#ifdef MODULE#define loop_init init_module#endifint loop_register_transfer(struct loop_func_table *funcs){	if ((unsigned)funcs->number > MAX_LO_CRYPT || xfer_funcs[funcs->number])		return -EINVAL;	xfer_funcs[funcs->number] = funcs;	return 0; }int loop_unregister_transfer(int number){	struct loop_device *lo; 	if ((unsigned)number >= MAX_LO_CRYPT)		return -EINVAL; 	for (lo = &loop_dev[0]; lo < &loop_dev[MAX_LOOP]; lo++) { 		int type = lo->lo_encrypt_type;		if (type == number) { 			xfer_funcs[type]->release(lo);			lo->transfer = NULL; 			lo->lo_encrypt_type = 0; 		}	}	xfer_funcs[number] = NULL; 	return 0; }EXPORT_SYMBOL(loop_register_transfer);EXPORT_SYMBOL(loop_unregister_transfer);int __init loop_init(void) {	int	i;	if (register_blkdev(MAJOR_NR, "loop", &lo_fops)) {		printk(KERN_WARNING "Unable to get major number %d for loop device\n",		       MAJOR_NR);		return -EIO;	}#ifndef MODULE	printk(KERN_INFO "loop: registered device at major %d\n", MAJOR_NR);#endif	blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;	for (i=0; i < MAX_LOOP; i++) {		memset(&loop_dev[i], 0, sizeof(struct loop_device));		loop_dev[i].lo_number = i;	}	memset(&loop_sizes, 0, sizeof(loop_sizes));	memset(&loop_blksizes, 0, sizeof(loop_blksizes));	blk_size[MAJOR_NR] = loop_sizes;	blksize_size[MAJOR_NR] = loop_blksizes;	return 0;}#ifdef MODULEvoid cleanup_module(void) {	if (unregister_blkdev(MAJOR_NR, "loop") != 0)		printk(KERN_WARNING "loop: cannot unregister blkdev\n");}#endif

⌨️ 快捷键说明

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