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

📄 dm-target.c

📁 基于WINDOWS DDK 编写的文件型文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	mempool_free (bc, tc->bio_ctx_pool);}static void work_process (void *data){	struct bio_ctx *bc = (struct bio_ctx *) data;	struct target_ctx *tc = (struct target_ctx *) bc->target->private;	struct bio_vec *bv;	sector_t sec_no = bc->crypto_sector;	int seg_no;	unsigned long flags;	trace (3, "work_process (%p)\n", data);	// Decrypt queued data	bio_for_each_segment (bv, bc->orig_bio, seg_no)	{		unsigned int secs = bv->bv_len / SECTOR_SIZE;		char *data = bvec_kmap_irq (bv, &flags);		trace (2, "DecryptSectors (%Ld, %d)\n", sec_no, secs);		DecryptSectors ((unsigned __int32 *)data, sec_no, secs, tc->ci);		sec_no += secs;		flush_dcache_page (bv->bv_page);		bvec_kunmap_irq (data, &flags);	}	dereference_bio_ctx (bc);}static int truecrypt_endio (struct bio *bio, unsigned int bytes_done, int error){	struct bio_ctx *bc = (struct bio_ctx *) bio->bi_private;	struct target_ctx *tc = (struct target_ctx *) bc->target->private;	struct bio_vec *bv;	int seg_no;		trace (3, "truecrypt_endio (%p, %d, %d)\n", bio, bytes_done, error);	trace (1, "end: sc=" SECTOR_FORMAT " fl=%ld rw=%ld sz=%d ix=%hd vc=%hd dn=%d er=%d\n",		bio->bi_sector, bio->bi_flags, bio->bi_rw, bio->bi_size, bio->bi_idx, bio->bi_vcnt, bytes_done, error);	if (error != 0)		bc->error = error;	if (bio->bi_size)	{		trace (2, "Outstanding IO: %d\n", bio->bi_size);		return 1;	}	if (bio_data_dir (bio) == READ)	{		bio_put (bio);		// Queue decryption to leave completion interrupt ASAP		INIT_WORK (&bc->work, work_process, bc);		trace (3, "queue_work (%p)\n", work_queue);		queue_work (work_queue, &bc->work);		return error;	}	// Free pages allocated for encryption	bio_for_each_segment (bv, bio, seg_no)	{		trace (3, "mempool_free (%p, %p)\n", bv->bv_page, tc->pg_pool);		mempool_free (bv->bv_page, tc->pg_pool);  	}	bio_put (bio);	dereference_bio_ctx (bc);	return error;}static int truecrypt_map (struct dm_target *ti, struct bio *bio, union map_info *map_context){	struct target_ctx *tc = (struct target_ctx *) ti->private;	struct bio_ctx *bc;	struct bio *bion;	struct bio_vec *bv;	int seg_no;	trace (3, "truecrypt_map (%p, %p, %p)\n", ti, bio, map_context);	trace (1, "map: sc=" SECTOR_FORMAT " fl=%ld rw=%ld sz=%d ix=%hd vc=%hd\n",		bio->bi_sector, bio->bi_flags, bio->bi_rw, bio->bi_size, bio->bi_idx, bio->bi_vcnt);	// Write protection	if (bio_data_dir (bio) == WRITE && READ_ONLY (tc))		return -EPERM;	// Validate segment sizes	bio_for_each_segment (bv, bio, seg_no)	{		if (bv->bv_len & (SECTOR_SIZE - 1))		{			error ("unsupported segment size %d (%ld %d %hd %hd)\n",				bv->bv_len, bio->bi_rw, bio->bi_size, bio->bi_idx, bio->bi_vcnt);			return -EINVAL;		}	}	// Bio context	bc = mempool_alloc (tc->bio_ctx_pool, GFP_NOIO);	if (!bc)	{		error ("bio context allocation failed\n");		return -ENOMEM;	}	trace (3, "truecrypt_map: mempool_alloc bc: %p\n", bc);	atomic_set (&bc->ref_count, 1);	bc->orig_bio = bio;	bc->error = 0;	bc->target = ti;	bc->crypto_sector = tc->start + (bio->bi_sector - ti->begin);	// New bio for encrypted device	trace (3, "bio_alloc (%hd)\n", bio_segments (bio));	bion = bio_alloc (GFP_NOIO, bio_segments (bio));	if (!bion) 	{		error ("bio allocation failed\n");		bc->error = -ENOMEM;		dereference_bio_ctx (bc);		return 0;	}	bion->bi_bdev = tc->dev->bdev;	bion->bi_end_io = truecrypt_endio;	bion->bi_idx = 0;	bion->bi_private = bc;	bion->bi_rw = bio->bi_rw;	bion->bi_sector = bc->crypto_sector;	bion->bi_size = bio->bi_size;	bion->bi_vcnt = bio_segments (bio);	if (bio_data_dir (bio) == READ)	{		// Buffers of originating bio can be used for decryption		memcpy (bion->bi_io_vec,			bio_iovec (bio),			bion->bi_vcnt * sizeof (struct bio_vec));	}	else	{		// Encrypt data to be written		unsigned long flags, copyFlags;		char *data, *copy;		long long sec_no = bc->crypto_sector;		memset (bion->bi_io_vec, 0, sizeof (struct bio_vec) * bion->bi_vcnt);		bio_for_each_segment (bv, bio, seg_no)		{			struct bio_vec *cbv = bio_iovec_idx (bion, seg_no);			unsigned int secs = bv->bv_len / SECTOR_SIZE;			// Hidden volume protection			if (!READ_ONLY (tc) && HID_VOL_PROT (tc)				&& RegionsOverlap (sec_no, sec_no + secs - 1, tc->read_only_start, tc->read_only_end))			{				tc->flags |= FLAG_READ_ONLY | FLAG_PROTECTION_ACTIVATED;			}			if (!READ_ONLY (tc))			{				cbv->bv_page = mempool_alloc (tc->pg_pool, GFP_NOIO);				if (cbv->bv_page == NULL)					error ("page allocation failed during write\n");			}			if (READ_ONLY (tc) || cbv->bv_page == NULL)			{				// Write not permitted or no memory				bio_for_each_segment (cbv, bion, seg_no)				{					if (cbv->bv_page != NULL)						mempool_free (cbv->bv_page, tc->pg_pool);  				}				bio_put (bion);				bc->error = READ_ONLY (tc) ? -EPERM : -ENOMEM;				dereference_bio_ctx (bc);				return 0;			}			trace (3, "truecrypt_map: mempool_alloc pg: %p\n", cbv->bv_page);			cbv->bv_offset = 0;			cbv->bv_len = bv->bv_len;			data = bvec_kmap_irq (bv, &flags);			copy = bvec_kmap_irq (cbv, &copyFlags);			memcpy (copy, data, bv->bv_len);			flush_dcache_page (bv->bv_page);			bvec_kunmap_irq (data, &flags);			trace (2, "EncryptSectors (%Ld, %d)\n", sec_no, secs);			EncryptSectors ((unsigned __int32 *)copy, sec_no, secs, tc->ci);			sec_no += secs;			flush_dcache_page (cbv->bv_page);			bvec_kunmap_irq (copy, &copyFlags);		}	}	atomic_inc (&bc->ref_count);	trace (3, "generic_make_request (rw=%ld sc=" SECTOR_FORMAT ")\n", bion->bi_rw, bion->bi_sector);	generic_make_request (bion);	dereference_bio_ctx (bc);	return 0;}static int truecrypt_status (struct dm_target *ti, status_type_t type, char *result, unsigned int maxlen){	struct target_ctx *tc = (struct target_ctx *) ti->private;	switch (type)	{	case STATUSTYPE_INFO:		result[0] = 0;		break;	case STATUSTYPE_TABLE:		{			char name[32];			format_dev_t (name, tc->dev->bdev->bd_dev);			snprintf (result, maxlen, "%d %d 0 0 %s " SECTOR_FORMAT " " SECTOR_FORMAT " " SECTOR_FORMAT " %Ld %Ld %d %s",				tc->ci->ea,				tc->ci->mode,				name,				tc->start,				tc->read_only_start,				tc->read_only_end,				tc->mtime,				tc->atime,				tc->flags,				tc->volume_path);		}		break;	}	return 0;}static struct target_type truecrypt_target = {	.name   = "truecrypt",	.version= {VERSION_NUM1, VERSION_NUM2, VERSION_NUM3},	.module = THIS_MODULE,	.ctr    = truecrypt_ctr,	.dtr    = truecrypt_dtr,	.map    = truecrypt_map,	.status = truecrypt_status};int __init dm_truecrypt_init(void){	int r;	trace (3, "dm_truecrypt_init (trace_level=%d)\n", trace_level);	if (!AutoTestAlgorithms ())	{		DMERR ("truecrypt: self-test of algorithms failed");		return -ERANGE;	}	work_queue = create_workqueue ("truecryptq");	if (!work_queue)	{		DMERR ("truecrypt: create_workqueue creation failed");		goto err;	}	bio_ctx_cache = kmem_cache_create ("truecrypt-bioctx", sizeof (struct bio_ctx), 0, 0, NULL, NULL);	if (!bio_ctx_cache)	{		DMERR ("truecrypt: kmem_cache_create failed");		goto err;	}	r = dm_register_target (&truecrypt_target);	if (r < 0)	{		DMERR ("truecrypt: register failed %d", r);		goto err;	}	return r;err:	if (work_queue)		destroy_workqueue (work_queue);	if (bio_ctx_cache)		kmem_cache_destroy (bio_ctx_cache);	return -ENOMEM;}void __exit dm_truecrypt_exit(void){	int r;	trace (3, "dm_truecrypt_exit ()\n");	r = dm_unregister_target (&truecrypt_target);	if (r < 0)		DMERR ("truecrypt: unregister failed %d", r);	destroy_workqueue (work_queue);	kmem_cache_destroy (bio_ctx_cache);}module_init(dm_truecrypt_init);module_exit(dm_truecrypt_exit);module_param_named(trace, trace_level, int, 0);MODULE_AUTHOR("TrueCrypt Foundation");MODULE_DESCRIPTION(DM_NAME " target for encryption and decryption of TrueCrypt volumes");MODULE_PARM_DESC(trace, "Trace level");MODULE_LICENSE("GPL and additional rights"); // Kernel thinks only GPL/BSD/MPL != closed-source code

⌨️ 快捷键说明

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