Commit c9db333a authored by Andrew Morton's avatar Andrew Morton Committed by James Bottomley

[PATCH] blockgroup_lock: hashed spinlocks for ext2 and ext3

ext2 and ext3 per-blockgroup metadata needs locking.  An fs-wide lock is
expensive, and a per-blockgroup lock consumes too much storage (up to 32768
blockgroups per filesystem).  We need something in-between.

blockgroup_locks are very simple hashed spinlocks which provide this
compromise.  The size of the lock is scaled by NR_CPUS to implement an
additional speed/space tradeoff.

These locks are actually fairly generic.  However I presented it as something
which is specific to ext2 and ext3 so that people wouldn't go using them all
over the place.  They consume a lot of storage.
parent ba8e8755
/*
* Per-blockgroup locking for ext2 and ext3.
*
* Simple hashed spinlocking.
*/
#include <linux/config.h>
#include <linux/spinlock.h>
#include <linux/cache.h>
#ifdef CONFIG_SMP
/*
* We want a power-of-two. Is there a better way than this?
*/
#if NR_CPUS >= 32
#define NR_BG_LOCKS 128
#elif NR_CPUS >= 16
#define NR_BG_LOCKS 64
#elif NR_CPUS >= 8
#define NR_BG_LOCKS 32
#elif NR_CPUS >= 4
#define NR_BG_LOCKS 16
#elif NR_CPUS >= 2
#define NR_BG_LOCKS 8
#else
#define NR_BG_LOCKS 4
#endif
#else /* CONFIG_SMP */
#define NR_BG_LOCKS 1
#endif /* CONFIG_SMP */
struct bgl_lock {
spinlock_t lock;
} ____cacheline_aligned_in_smp;
struct blockgroup_lock {
struct bgl_lock locks[NR_BG_LOCKS];
};
static inline void bgl_lock_init(struct blockgroup_lock *bgl)
{
int i;
for (i = 0; i < NR_BG_LOCKS; i++)
spin_lock_init(&bgl->locks[i].lock);
}
/*
* The accessor is a macro so we can embed a blockgroup_lock into different
* superblock types
*/
#define sb_bgl_lock(sb, block_group) \
(&(sb)->s_blockgroup_lock.locks[(block_group) & (NR_BG_LOCKS-1)].lock)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment