• T
    ext4: fix races in ext4_sync_parent() · d59729f4
    Theodore Ts'o 提交于
    Fix problems if fsync() races against a rename of a parent directory
    as pointed out by Al Viro in his own inimitable way:
    
    >While we are at it, could somebody please explain what the hell is ext4
    >doing in
    >static int ext4_sync_parent(struct inode *inode)
    >{
    >        struct writeback_control wbc;
    >        struct dentry *dentry = NULL;
    >        int ret = 0;
    >
    >        while (inode && ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) {
    >                ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY);
    >                dentry = list_entry(inode->i_dentry.next,
    >                                    struct dentry, d_alias);
    >                if (!dentry || !dentry->d_parent || !dentry->d_parent->d_inode)
    >                        break;
    >                inode = dentry->d_parent->d_inode;
    >                ret = sync_mapping_buffers(inode->i_mapping);
    >                ...
    >Note that dentry obviously can't be NULL there.  dentry->d_parent is never
    >NULL.  And dentry->d_parent would better not be negative, for crying out
    >loud!  What's worse, there's no guarantees that dentry->d_parent will
    >remain our parent over that sync_mapping_buffers() *and* that inode won't
    >just be freed under us (after rename() and memory pressure leading to
    >eviction of what used to be our dentry->d_parent)......
    Reported-by: NAl Viro <viro@ZenIV.linux.org.uk>
    Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
    d59729f4
fsync.c 7.1 KB