Message ID | 1fd8f27289a8608c77f66c065d6fda87a7d89628.1706183427.git.fdmanana@suse.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs: some directory fixes for stable 5.15 | expand |
On Thu, Jan 25, 2024 at 11:59:38AM +0000, fdmanana@kernel.org wrote: > From: Filipe Manana <fdmanana@suse.com> > > commit 8e7f82deb0c0386a03b62e30082574347f8b57d5 upstream. > > When opening a directory (opendir(3)) or rewinding it (rewinddir(3)), we > are not holding the directory's inode locked, and this can result in later > attempting to add two entries to the directory with the same index number, > resulting in a transaction abort, with -EEXIST (-17), when inserting the > second delayed dir index. This results in a trace like the following: [..] > Fixes: 9b378f6ad48c ("btrfs: fix infinite directory reads") > CC: stable@vger.kernel.org # 6.5+ > Signed-off-by: Filipe Manana <fdmanana@suse.com> > Reviewed-by: David Sterba <dsterba@suse.com> > Signed-off-by: David Sterba <dsterba@suse.com> Based on https://lore.kernel.org/stable/20240126185534.GA2668448@lxhi-087: Reviewed-by: Eugeniu Rosca <eugeniu.rosca@bosch.com>
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b7047604d255..2d2caa978d80 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6173,21 +6173,24 @@ static int btrfs_set_inode_index_count(struct btrfs_inode *inode) static int btrfs_get_dir_last_index(struct btrfs_inode *dir, u64 *index) { - if (dir->index_cnt == (u64)-1) { - int ret; + int ret = 0; + btrfs_inode_lock(&dir->vfs_inode, 0); + if (dir->index_cnt == (u64)-1) { ret = btrfs_inode_delayed_dir_index_count(dir); if (ret) { ret = btrfs_set_inode_index_count(dir); if (ret) - return ret; + goto out; } } /* index_cnt is the index number of next new entry, so decrement it. */ *index = dir->index_cnt - 1; +out: + btrfs_inode_unlock(&dir->vfs_inode, 0); - return 0; + return ret; } /*