ckrm_E16
[linux-2.6.git] / include / linux / blockgroup_lock.h
1 /*
2  * Per-blockgroup locking for ext2 and ext3.
3  *
4  * Simple hashed spinlocking.
5  */
6
7 #include <linux/config.h>
8 #include <linux/spinlock.h>
9 #include <linux/cache.h>
10
11 #ifdef CONFIG_SMP
12
13 /*
14  * We want a power-of-two.  Is there a better way than this?
15  */
16
17 #if NR_CPUS >= 32
18 #define NR_BG_LOCKS     128
19 #elif NR_CPUS >= 16
20 #define NR_BG_LOCKS     64
21 #elif NR_CPUS >= 8
22 #define NR_BG_LOCKS     32
23 #elif NR_CPUS >= 4
24 #define NR_BG_LOCKS     16
25 #elif NR_CPUS >= 2
26 #define NR_BG_LOCKS     8
27 #else
28 #define NR_BG_LOCKS     4
29 #endif
30
31 #else   /* CONFIG_SMP */
32 #define NR_BG_LOCKS     1
33 #endif  /* CONFIG_SMP */
34
35 struct bgl_lock {
36         spinlock_t lock;
37 } ____cacheline_aligned_in_smp;
38
39 struct blockgroup_lock {
40         struct bgl_lock locks[NR_BG_LOCKS];
41 };
42
43 static inline void bgl_lock_init(struct blockgroup_lock *bgl)
44 {
45         int i;
46
47         for (i = 0; i < NR_BG_LOCKS; i++)
48                 spin_lock_init(&bgl->locks[i].lock);
49 }
50
51 /*
52  * The accessor is a macro so we can embed a blockgroup_lock into different
53  * superblock types
54  */
55 #define sb_bgl_lock(sb, block_group) \
56         (&(sb)->s_blockgroup_lock.locks[(block_group) & (NR_BG_LOCKS-1)].lock)
57
58