radix_tree_gang_lookup()函数虽然不是我们理想中的遍历函数,但也有了八九不离十的功能。 就像在酒吧里找不到D Cup,带回去个C Cup也总比看A片强。 通过radix_tree_gang_lookup()函数,我们可以一次从基树中获取多个节点的信息: unsigned
int radix_tree_gang_lookup(struct radix_tree_root *root, void
**results, unsigned long first_index, unsigned int max_items); 具体的参数嘛,RTFSC吧。
这是我们注意到使用这个函数时顾此失彼的一面,虽然我们获得了一组需要释放的指针,但却无法获得这些指针的索引。 而执行释放基树中节点的操作时却恰恰需要使用索引作参数。 然后就是一个技巧了,我们借用page结构的index成员来存储这一索引。 之所以可以这样用,是因为page结构的index成员在该页用作页高速缓存时存储相对文件起始处的以页大小为单位的偏移, 而我们所使用的页面不会被同时用作页高速缓存,因此这里可以借用page.index成员。 按照以上思路,我们写出了修改后的代码: void free_diskmem(void) { unsigned long long next_seg; struct page *seglist[64]; int listcnt; int i;
改过的simp_blkdev_trans()函数变成了这个样子: static int simp_blkdev_trans(unsigned long long dsk_offset, void *buf, unsigned int len, int dir) { unsigned int done_cnt; struct page *this_first_page; unsigned int this_off; unsigned int this_cnt;
done_cnt = 0; while (done_cnt < len) { /* iterate each data segment */ this_off = (dsk_offset + done_cnt) & ~SIMP_BLKDEV_DATASEGMASK; this_cnt = min(len - done_cnt, (unsigned int)SIMP_BLKDEV_DATASEGSIZE - this_off);