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