• Al Viro's avatar
    ufs: don't use lock_ufs() for block pointers tree protection · 724bb09f
    Al Viro authored
    * stores to block pointers are under per-inode seqlock (meta_lock) and
    mutex (truncate_mutex)
    * fetches of block pointers are either under truncate_mutex, or wrapped
    into seqretry loop on meta_lock
    * all changes of ->i_size are under truncate_mutex and i_mutex
    * all changes of ->i_lastfrag are under truncate_mutex
    
    It's similar to what ext2 is doing; the main difference is that unlike
    ext2 we can't rely upon the atomicity of stores into block pointers -
    on UFS2 they are 64bit.  So we can't cut the corner when switching
    a pointer from NULL to non-NULL as we could in ext2_splice_branch()
    and need to use meta_lock on all modifications.
    
    We use seqlock where ext2 uses rwlock; ext2 could probably also benefit
    from such change...
    
    Another non-trivial difference is that with UFS we *cannot* have reader
    grab truncate_mutex in case of race - it has to keep retrying.  That
    might be possible to change, but not until we lift tail unpacking
    several levels up in call chain.
    
    After that commit we do *NOT* hold fs-wide serialization on accesses
    to block pointers anymore.  Moreover, lock_ufs() can become a normal
    mutex now - it's only used on statfs, remount and sync_fs and none
    of those uses are recursive.  As the matter of fact, *now* it can be
    collapsed with ->s_lock, and be eventually replaced with saner
    per-cylinder-group spinlocks, but that's a separate story.
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    724bb09f
balloc.c 27.1 KB