Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1243564
  • 博文数量: 298
  • 博客积分: 10050
  • 博客等级: 上将
  • 技术积分: 3277
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-14 13:36
文章分类
文章存档

2015年(7)

2012年(1)

2010年(5)

2009年(55)

2008年(73)

2007年(160)

我的朋友

分类: LINUX

2007-07-11 00:30:09

对于磁盘读写加解密实现,现在不得不摒弃前面的一些想法。

但总体思路仍然是:高速缓存中保证是明文,写入设备时,数据加密存储。

 

对于修改generic_make_request这个函数。

读操作中,如果要从设备读的话 readpage->block_read_full_page->submit_bh->generic_make_request

       写操作中,(除开一些进程强制刷新调用sync方法等)都是用

bdflush->write_locked_buffers->submit_bh->generic_make_request

 

        两者都用到了generic_make_request

        开始希望在generic_make_request分按传入的参数是写or读的方法分别进行加解密。那么也可以省去readwrite需要从设备读这些情况下的解密操作了。

可是事实上我忽略了一个问题。generic_make_request只是将buffers读写请求提交给驱程,如果是写,可以先加密再提交。而读,这时是还没有从设备上读出来的。所以这个思路不对。

 

还是回到了原来的一个想法,在b_end_io上做文章,很感谢suoguang特意发邮件给我一些建议,并且很肯定地也提到了这个方法:即调用buffer_head结构进行读写,bhb_end_io成员函数如果被设置,那么操作系统接收到磁盘读完成的中断后,会调用b_end_io, 进行后期处理.那么我们可以在这里做一些修改。

 

读操作需要从设备读的时候解密:

方法1:利用b_end_io方法

block_read_full_page   

for (i = 0; i < nr; i++) {

    struct buffer_head * bh = arr[i];

    lock_buffer(bh);

    set_buffer_async_io(bh);

}

 

/* Stage 3: start the IO */

for (i = 0; i < nr; i++) {

    struct buffer_head * bh = arr[i];

...

        submit_bh(READ, bh);

}

 

调用了set_buffer_async_io(bh)为提交给submit_bh(READ, bh)bh设置b_end_io的方法:设置了bh->b_end_io = end_buffer_io_async(异步读)

我们可以把这里的b_end_io改成包含有解密功能I/O操作完毕对bh操作的自定义方法

需要修改block_read_full_pag函数(不知道还有没有其他机制会调用这个函数?)

 

    方法2:修改do_generic_file_read中的readpage代码段

 

readpage:

    /* ... and start the actual read. The read will unlock the page. */

    error = mapping->a_ops->readpage(filp, page);

 

    if (!error) {

        if (Page_Uptodate(page))

            goto page_ok;

 

        /* Again, try some read-ahead while waiting for the page to finish.. */

        generic_file_readahead(reada_ok, filp, inode, page);

        wait_on_page(page);

        if (Page_Uptodate(page))

            goto page_ok;

        error = -EIO;

    }

 

     在我理解是调用了readpage(filp, page)方法后,而readpage并没有等到读完就返回了,实际上它只是发出读取请求,真正读完要到下面的:

if (!error) {

...

                          wait_on_page(page);

...

                 }

 

wait_on_page,会等到该页面被真正读入完成后才返回,在这期间会睡眠,将cpu让给其它进程。 那么是否可以wait_on_page后,再来解密page->buffers(但是不确定这里buffers是否都已经读完毕了,和异步读是否有冲突,值得考虑一下。)

 

 

写操作需要考虑两个方面:

.写中有读,欲写先读

prepare_write中,当需要写的块没有被缓存的时候,会先调用ll_rw_block(READ, 1, &bh)来从磁盘读入块的内容

if (!buffer_uptodate(bh) &&

         (block_start < from || block_end > to)) {

        ll_rw_block(READ, 1, &bh);

        *wait_bh++=bh;

但是这里的bh->b_end_io是在ll_rw_block函数中定义的,为end_buffer_io_sync(同步读)那么这里我们也可以模仿read操作,自定义b_end_io方法来达到解密功能

1.       重新自定义一个ll_rw_block()

与原ll_rw_block()均相同,除了在其中自定义个b_end_io方法

2.       修改成

ll_rw_block(READ, 1, &bh);

bh->b_end_io = 自定义IO方法;

因为ll_rw_block也只是调用函数将bh提交给驱程,是否这里后面对b_end_io的定义可以覆盖ll_rw_block中定义的?(还在悬疑中)

 

.写操作加密

加密后写入设备不是很难做到,可以修改generic_make_request函数bh没有提交给驱程之前,将其加密

可是加密后刷新到块设备的同时,buffers里的数据也变成密文了。而我们需要保证高速缓存中的应当为明文。这里如何把buffers中的密文改回来呢?

 

    解密-〉加密后的buffers数据

1.       利用b_end_io方法

bdflush中调用write_locked_buffers

 

        bh->b_end_io = end_buffer_io_sync;

        submit_bh(WRITE, bh);

 

自定义bh ->b_end_io方法中去做解密,修改generic_make_request完成加密功能,在加密写入设备完成后,便会调用自定义b_end_io方法解密buffers中的数据。

 

    2. 分配新buffers(参考create_bounce)

在写入设备前,在generic_make_request中分配new_buffer,和new_bh.new_bh指向原bhnew_bh和原来的bh几乎相同,让原bh所指的数据区内容填充new_bh的数据区内容,再new_bh的数据区加密后将new_bh传给__make_request提交给驱程,且需要自定义new_bhb_end_io方法.这样写入设备的便是加密后的数据,而高速缓存中仍然是明文。

 

因为我们最终实现加解密功能都是调用加解密设备

这里2种方法的利弊是:

对于方法1

1. generic_make_request做加密时需要调用一次fpga设备进行加密

2. 把加密的数据写入sd

3. b_end_io方法中解密时再次调用fpga设备进行解密

共访问外设3次,速度大大降低

 

需要修改write_locked_buffers函数(不知道还有没有其他机制会调用这个函数?)

 

对于方法2

1. 对于原bh,本来是需要加密写入设备的。可是利用了new_bh,那么原bh就不应该加密且写入设备了。在传入generic_make_request前,原bh的状态为BH_Locked = 1,BH_Dirty = 0.且设置了b_end_io方法。那么应该将其在加密传入__make_request之前就直接执行b_end_io方法,将其状态锁释放,并从链表中移除,使其不用写入设备。可是这里一旦释放了锁,是否会有别的进程会写它?而与写入设备的new_bh的数据不一致了?

2. 对于new_bhb_end_io方法是否和原bh同样就可以了,还是需要自定义一个新的end_io方法来实现一些细节。有待详细考虑。

需要处理细节太多。对原bhnew_bh需要不同特殊处理。可是只需要访问外设2次。

并且b_end_io我们要确定这个函数可以调用驱动来实现硬件机制加解密

 

阅读(1867) | 评论(2) | 转发(0) |
0

上一篇:笔记7.9

下一篇:姐妹出嫁

给主人留下些什么吧!~~