| Age | Commit message (Collapse) | Author |
|
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>
|
|
There is no need to export struct mb_cache outside mbcache.c. Move struct
mb_cache to fs/mbcache.c and remove the superfluous struct
mb_cache_entry_index declaration.
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
mb_cache_entry_takeout and mb_cache_entry_dup are totally unused.
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
|
Patch from Andreas Gruenbacher <agruen@suse.de>
Add a gfp_mask parameter to the free() callback so that the callback can
safely do I/O, etc. The free callback can now also fail. This will be
needed by reiserfs.
The order of entries on the cache entry lru is reversed so that
list_for_each_safe() can be used. Several helper functions that don't
make the code any better are removed. Finally, a couple of cosmetic
things.
|
|
(now uses struct block_device * to index devices, and uses hash.h for hash function)
This patch creates a meta block cache which is utilized by the ext3 and
ext2 extended attribute patch (patches 2 and 3, respectively). This
cache allows directory blocks to be indexed by multiple keys. In the
case of the extended attribute patches, it is used to look up blocks by
both the block number and by the hash of the extended attributes. This
is extremely important to allow the sharing of acl's when stored as
extended attributes. Otherwise every single file would require its own,
separate, one block overhead to store then ACL, even though there might
be a large number of files that have the same ACL.
|