summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@suse.de>2005-01-14 23:35:57 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-14 23:35:57 -0800
commitfd1ea9abe35beaa2402b90b83a4c47135b086613 (patch)
treefae65165516b9faed78100cd3e9bb532a01c43d4 /include/linux
parent401494b1615efb1922a380226b0bea3eccb22ff3 (diff)
[PATCH] ext3/EA: Race in ext[23] xattr sharing code
Andrew Tridgell and Stephen C. Tweedie have reported two different Oopses caused by a race condition in the mbcache, which is responsible for extended attribute sharing in ext2 and ext3. Stephen tracked down the bug; I did the fix. Explanation: The mbcache caches the locations and content hashes of xattr blocks. There are two access strategies: [1] xattr block disposal via mb_cache_entry_get(), [2] xattr block reuse (sharing) via mb_cache_entry_find_{first,next}(). There is no locking between the two methods, so between one mb_cache_entry_find_x and the next, a mb_cache_entry_get might come in, unhash the cache entry, and change the journaling state of the xattr buffer. Subsequently, two things can happen: [a] the next mb_cache_entry_find_x may try to follow the mbcache hash chain starting from the entry that has become unhashed, which now is a stale pointer, [b] the block may have become deallocated, and then we try to reuse it. Fix this by converting the mbcache into a readers-writer style lock, and protect all block accesses in ext2/ext3 by the mbcache entry lock. This ensures that destroying blocks is an exclusive operation that may not overlap xattr block reuse, while allowing multiple "re-users". Write access to the xattr block's buffer is protected by the buffer lock. Signed-off-by: Andreas Gruenbacher <agruen@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/mbcache.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/include/linux/mbcache.h b/include/linux/mbcache.h
index 4c941af6225c..8e5a10410a30 100644
--- a/include/linux/mbcache.h
+++ b/include/linux/mbcache.h
@@ -10,7 +10,8 @@
struct mb_cache_entry {
struct list_head e_lru_list;
struct mb_cache *e_cache;
- atomic_t e_used;
+ unsigned short e_used;
+ unsigned short e_queued;
struct block_device *e_bdev;
sector_t e_block;
struct list_head e_block_list;