dmc->size表示flashcache中block的数目,而在flashcache_ctr中:
dmc->assoc_shift = ffs(dmc->assoc) - 1;
因为dmc->assoc表示一个set中块的数目,那么dmc->assoc_shift则表示dmc->assoc二进制形式中0的个数。这样可以使用位运算加快除法速度。也就是说: num_cache_sets = dmc->size >> dmc->assoc_shift;是flashcache中的set数目。
因为我使用的版本是flashcache 3.1.1,所以来看else子句
value = (unsigned long) (dbn >> dmc->disk_assoc_shift);
value = jhash_1word(value, 0xbeef);
这里的value = (unsigned long) (dbn >> dmc->disk_assoc_shift);相当于
value = (unsigned long) (dbn / dmc->disk_assoc);所以来看看jhash_1word做了啥:
170 static inline u32 jhash_1word(u32 a, u32 initval)
171 {
172 return __jhash_nwords(a, 0, 0, initval + JHASH_INITVAL + (1 << 2));
173 }
其中调用了__jhash_nwords(value, 0, 0, 0xbeef + JHASH_INITVAL + (1 << 2)); 其中JHASH_INITVAL被初始化为任意值:
57
58 #define JHASH_INITVAL 0xdeadbeef
而在__jhash_nwords函数中,
149 static inline u32 __jhash_nwords(u32 a, u32 b, u32 c, u32 initval)
150 {
151 a += initval;
152 b += initval;
153 c += initval;
154
155 __jhash_final(a, b, c);
156
157 return c;
158 }
又调用了 __jhash_final(value+initval, initval, initval); 在该函数中,进行了奇怪的运算:
45
46 #define __jhash_final(a, b, c) \
47 { \
48 c ^= b; c -= rol32(b, 14); \
49 a ^= c; a -= rol32(c, 11); \
50 b ^= a; b -= rol32(a, 25); \
51 c ^= b; c -= rol32(b, 16); \
52 a ^= c; a -= rol32(c, 4); \
53 b ^= a; b -= rol32(a, 14); \
54 c ^= b; c -= rol32(b, 24); \
55 }
好吧,来看看rol32函数,应该是不会用到随机函数,不然以后每次相同的dbn找的cache block岂不是不相同:
103
108 static inline __u32 rol32(__u32 word, unsigned int shift)
109 {
110 return (word << shift) | (word >> ((-shift) & 31));
111 }
112
113
果然不是什么随机函数,只是一些位运算罢了,从这里可以印证出每次相同的dbn找的cache block是相同的。
注意hash_block末尾的这句话set_number = value % num_cache_sets; 加上前面的value = (unsigned long) (dbn >> dmc->disk_assoc_shift);印证了flashcache-doc.txt的这句话:
target set = (dbn / block size / set size) mod (number of sets),但是好像这句话有点老,因为在if语句里面才是完全符合这句话:value = (unsigned long)
(dbn >> (dmc->block_shift + dmc->assoc_shift));