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

📄 bc_dev22.c

📁 BestCrypt开源加密原代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		}		atomic_inc(&bc_buffers[i].count);	}	uptodate = 1;error_out:	        if (!end_that_request_first(req, uptodate, DEVICE_NAME))		end_that_request_last(req);		goto repeat;}/*-- end of strategy routine --------------------------------*//*-- fops functions -----------------------------------------*/static int bc_open(struct inode *inode, struct file *file){	struct bc_device *bc;	if (!inode)			return -EINVAL;	bc = get_bcdev(inode->i_rdev);	if (NULL == bc)		return save_fops.open(inode, file);	MOD_INC_USE_COUNT;	while (1) {		down(&bc->bc_control);		if (!bc->bc_flags.busy)			break;		up(&bc->bc_control);		sleep_on(&wait_open);	}	bc->bc_refcnt++;	up(&bc->bc_control);	if (capable(CAP_SYS_ADMIN))		bc_add_pid(current->pid);		return 0;}static int bc_release(struct inode *inode, struct file *file){	struct bc_device *bc;		if (!inode)		return 0;	bc = get_bcdev(inode->i_rdev);	if (NULL == bc)		return save_fops.release(inode, file);	down(&bc->bc_control);	if (bc->bc_refcnt <= 0)			printk(KERN_WARNING "bc_release: refcount (%d) <= 0\n", bc->bc_refcnt);	else  {		bc->bc_refcnt--;		MOD_DEC_USE_COUNT;	}	up(&bc->bc_control);	return 0;}static ssize_t bc_read (struct file *file, char *buf, size_t count, loff_t *ppos){	struct bc_disk	*bd;	struct inode	*inode;		if (!file)			return -EINVAL;		inode = file->f_dentry->d_inode;		bd = get_bcdsk(inode->i_rdev);	if (NULL == bd)		return save_fops.read(file, buf, count, ppos);	if (bd->bd_flags.mounted) {		printk("bc_read: device busy\n");		return -EBUSY;	}	return block_read(file, buf, count, ppos);}static ssize_t bc_write(struct file *file, const char *buf, size_t count, loff_t *ppos){	struct bc_disk	*bd;	struct inode	*inode;			if (!file)		return -EINVAL;			inode = file->f_dentry->d_inode;	bd = get_bcdsk(inode->i_rdev);	if (NULL == bd)		return save_fops.write(file, buf, count, ppos);/*	if (!bd->bd_flags.configured) { 		printk("bc_write: device not configured\n");		return -ENXIO;	}*/	if (bd->bd_flags.mounted) {		printk("bc_write: device busy\n");		return -EBUSY;	}	return block_write(file, buf, count, ppos);}/*-- end of fops functions ----------------------------------*/static int bc_get_info(struct bc_disk *bd, struct bc_device *bc, struct bc_info *arg){	struct bc_info	query;	long		busy;		BC_GET_ARG(arg, query)	put_user(BC_VERSION_MAJOR, (long *)&arg->ver_major);	put_user(BC_VERSION_MINOR, (long *)&arg->ver_minor);	busy = bd->bd_flags.configured || bc->bc_refcnt > 1 ? 1 : 0;	put_user(busy,  (long *)&arg->busy);	return 0;}static int bc_check(struct bc_check *arg){	struct bc_check	query;	struct file	*file;	int             i, max_devices;		if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;			BC_GET_ARG(arg, query)	if (!(file = fget(query.fd)))		return -EBADF;	max_devices = bc_devices*bc_partitions;	for (i = 0; i < max_devices; i++) {		if (!bc_dsk[i].bd_flags.configured)			continue;		if (file == bc_dev[i>>bc_minor_shift].bc_file)			break;	}	if (max_devices <= i)		i = BC_CONTAINER_UNUSED;	else if (bc_dsk[i].bd_flags.mounted)		i = BC_CONTAINER_MOUNTED;	else		i = BC_CONTAINER_USED;	put_user(i, (long *)&arg->busy);	return 0;}#define MAX_DISK_SIZE 1024*1024*1024static int scan_device(struct bc_disk *bd, struct bc_device *bc){	int	i, part, size;	kdev_t	dev;	struct super_block *sb = NULL;		if (!is_parent(bd))		return -EPERM;	if (NULL == bc->bc_dentry)		return -ENXIO;			if (bc->bc_refcnt > 1)		return -EBUSY;	bc->bc_flags.busy = 1;		if (S_ISREG(bc->bc_dentry->d_inode->i_mode)) {		size = (bc->bc_dentry->d_inode->i_size - bc->bc_offset) >> BLOCK_SIZE_BITS;	} else {	/* special inode */		kdev_t bcdev = bc->bc_dev;		if (blk_size[MAJOR(bcdev)])			size = blk_size[MAJOR(bcdev)][MINOR(bcdev)] - (bc->bc_offset >> BLOCK_SIZE_BITS);		else			size = MAX_DISK_SIZE;	}	bc_sizes[bd->bd_number] = size;	bd->bd_offset = bc->bc_offset;	bd->bd_flags.configured = 1;	if (!bc->bc_flags.multpart || !bc_minor_shift) {		bd->bd_flags.configured = 1;		bc->bc_flags.busy = 0;		wake_up(&wait_open);		return 0;	}			for (i = bc_gendisk.max_p - 1; i >= 0; i--) {		part = bd->bd_number + i;		dev  = MKDEV(MAJOR_NR, part);		sb   = get_super(dev);		sync_dev(dev);		if (sb)			invalidate_inodes(sb);		invalidate_buffers(dev);		bc_gendisk.part[part].start_sect = 0;		bc_gendisk.part[part].nr_sects   = 0;				bc_dsk[part-bc_start_minor].bd_flags.configured = 0;		bc_dsk[part-bc_start_minor].bd_offset = bc->bc_offset;	}	bc_gendisk.part[bd->bd_number].nr_sects = size << 1; 	resetup_one_dev(&bc_gendisk, bd->bd_number >> bc_gendisk.minor_shift);		for (i = bc_gendisk.max_p - 1; i >= 0; i--) {		part = bd->bd_number + i;		if (0 < bc_gendisk.part[part].nr_sects) {			bc_dsk[part-bc_start_minor].bd_flags.configured = 1;			bc_dsk[part-bc_start_minor].bd_offset =	bc->bc_offset + 				(((loff_t)bc_gendisk.part[part].start_sect) << 9);		}	}		bc->bc_flags.busy = 0;	wake_up(&wait_open);	return 0;}static int bc_set_fd(struct bc_disk *bd, struct bc_device *bc, kdev_t dev, struct bc_file64 *arg)/* key must be ready */{	struct file		*file = NULL;	struct inode		*inode = NULL;	struct bc_algorithm	*bc_alg = NULL;	struct bc_file64	query; 	int 			error;	if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;			MOD_INC_USE_COUNT;		BC_GET_ARG(arg, query)	if (!is_parent(bd)) {		error = -EPERM;		goto error_out;	}	if (bc->bc_dentry) {		error = -EBUSY;		goto error_out;	}			bc_alg = get_bc_algo(query.alg_id, NULL);	if (!bc_alg || bc_alg->test_key(query.key_handle) != 0) {		error = -EINVAL;		goto error_out;	}	if (!(file = fget(query.fd))) {		error = -EBADF;		goto error_out;	}	inode = file->f_dentry->d_inode;	error = -EINVAL;	if (!inode) {		printk(KERN_ERR "bc_set_fd: NULL inode.\n");		goto error_out;	}	if (!file->f_op) {		printk(KERN_ERR "bc_set_fd: NULL file_operations.\n");		goto error_out;	}	if (!file->f_op->read) {		printk(KERN_ERR "bc_set_fd: Can't perform reads.\n");		goto error_out;	}		reset_dev(bc);	if (S_ISBLK(inode->i_mode)) {		error = blkdev_open(inode, file);		if (error) 			goto error_out;		bc->bc_dev   = inode->i_rdev;	} else if (S_ISREG(inode->i_mode)) {		bc->bc_dev   = inode->i_dev;	} else 		goto error_out;	bc->bc_flags.iv_64bit = query.flags & BC_FLAGS_IV_64BIT || 0;	bc->bc_flags.multpart = query.flags & BC_FLAGS_MULTPART || 0;	bc->bc_flags.readonly = IS_RDONLY (inode) || 				is_read_only(bc->bc_dev) || 				(NULL == file->f_op->write) ||				query.flags & BC_FLAGS_READONLY;	if (!bc->bc_flags.readonly) 		invalidate_inode_pages (inode);	set_device_ro(dev, bc->bc_flags.readonly);		bc->bc_key	= query.key_handle;	bc->bc_alg	= bc_alg;	bc->bc_file	= file; 	bc->bc_dentry	= dget(file->f_dentry);	bc->bc_offset	= (loff_t)query.offset;	bc->bc_start_sector	= (loff_t)query.start_sector;	bc->bc_num_sectors	= (loff_t)query.num_sectors;	bc_alg->lock_key(query.key_handle, 1);	scan_device(bd, bc);	return 0;error_out:	if (file)		fput(file);			MOD_DEC_USE_COUNT;	return error;}static int bc_clr_fd(struct bc_disk *bd, struct bc_device *bc){	int		i, minor;	size_t		ret;	loff_t		pos;	unsigned char	magic;	mm_segment_t	fs;						if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;			if (!is_parent(bd))		return -EPERM;	if (NULL == bc->bc_dentry)		return -ENXIO;	if (NULL == bc->bc_file)		return -ENXIO;	if (bc->bc_refcnt > 1)	/* we needed one fd for the ioctl */		return -EBUSY;	for (i = 0; i < 1 << bc_minor_shift; i++) {		minor = bd->bd_number + i;		sync_dev(MKDEV(MAJOR_NR, minor));		invalidate_buffers(MKDEV(MAJOR_NR, minor));		bc_sizes[minor] = 0;	}	if (!bc->bc_flags.readonly && bc->bc_offset) {		pos = 0;		magic = 0xEB;		fs = get_fs();		set_fs(KERNEL_DS);		ret = bc->bc_file->f_op->write(bc->bc_file, &magic, 1, &pos);		set_fs(fs);		if (ret != 1)		        printk(KERN_ERR "bc: error %ld writing magic\n",		        (unsigned long)ret);	}																								if (S_ISBLK(bc->bc_dentry->d_inode->i_mode))			blkdev_release(bc->bc_dentry->d_inode);	dput(bc->bc_dentry);	/* release inode */	fput(bc->bc_file);//	bc->bc_alg->lock_key(bc->bc_key, 0);	bc->bc_alg->free_key(bc->bc_key);	reset_dev(bc);		MOD_DEC_USE_COUNT;	return 0;}static int bc_lock_dev(struct bc_disk *bd, struct bc_device *bc, kdev_t dev, int lock){	struct super_block * sb;	if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;		//	if (!capable(CAP_SYS_ADMIN))//		return -EPERM;	if (!bd->bd_flags.configured) {		if (!lock) 			return 0;		printk(KERN_ERR "bc: attempt to lock free device.\n");		return -EINVAL;	}	sb = get_super(dev);	if (!sb || !sb->s_root) {		if (!lock)			return 0;		printk(KERN_ERR "bc: attempt to lock unmounted device.\n");		return -EINVAL;	}	if (lock && !bd->bd_flags.mounted) {	    sb->s_root->d_count++;	    bd->bd_flags.mounted = 1;	    bc->bc_refcnt++;	} else if (!lock && bd->bd_flags.mounted) {	    sb->s_root->d_count--;	    bd->bd_flags.mounted = 0;	    bc->bc_refcnt--;	}	return 0;}static int bc_force_unlock(struct bc_disk *bd, struct bc_device *bc, kdev_t dev){	struct super_block * sb;	if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;	if (!bd->bd_flags.configured)		return 0;		sb = get_super(dev);	if (!sb || !sb->s_root) {		return 0;	}	if (bd->bd_flags.mounted) {	    while (sb->s_root->d_count-- > 2);	    bd->bd_flags.mounted = 0;	    bc->bc_refcnt--;	}	return 0;}static int bc_get_priv(u_long arg) {	if (bc_find_pid_safe(current->pid) >= 0) {		current->cap_effective |= (1<<CAP_SYS_ADMIN)|(1<<CAP_CHOWN)|(1<<CAP_DAC_OVERRIDE)|(1<<CAP_FOWNER);		current->euid = 0;	} else {		return -EPERM;		}		if (arg)	    bc_del_pid(current->pid);	return 0;}static int bc_check_activity(struct bc_device *bc, kdev_t dev, long *arg){	if (bc_find_pid_safe(current->pid) < 0)		return -EPERM;			if (NULL == arg)		return -EINVAL;			fsync_dev(dev);	put_user(bc->bc_activity, arg);	bc->bc_activity = 0;	return 0;}									

⌨️ 快捷键说明

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