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