Message ID | acbd885da4e8e7076c11bbcc31e0f6090cc10201.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:37AM +0000, fdmanana@kernel.org wrote: > From: Filipe Manana <fdmanana@suse.com> > > commit e60aa5da14d01fed8411202dbe4adf6c44bd2a57 upstream. > > When opening a directory we find what's the index of its last entry and > then store it in the directory's file handle private data (struct > btrfs_file_private::last_index), so that in the case new directory entries > are added to a directory after an opendir(3) call we don't end up in an > infinite loop (see commit 9b378f6ad48c ("btrfs: fix infinite directory > reads")) when calling readdir(3). [..] > Fixes: 9b378f6ad48c ("btrfs: fix infinite directory reads") > CC: stable@vger.kernel.org # 6.5+ > Signed-off-by: Filipe Manana <fdmanana@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 b144e346f24c..b7047604d255 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6222,6 +6222,19 @@ static int btrfs_opendir(struct inode *inode, struct file *file) return 0; } +static loff_t btrfs_dir_llseek(struct file *file, loff_t offset, int whence) +{ + struct btrfs_file_private *private = file->private_data; + int ret; + + ret = btrfs_get_dir_last_index(BTRFS_I(file_inode(file)), + &private->last_index); + if (ret) + return ret; + + return generic_file_llseek(file, offset, whence); +} + struct dir_entry { u64 ino; u64 offset; @@ -11087,7 +11100,7 @@ static const struct inode_operations btrfs_dir_inode_operations = { }; static const struct file_operations btrfs_dir_file_operations = { - .llseek = generic_file_llseek, + .llseek = btrfs_dir_llseek, .read = generic_read_dir, .iterate_shared = btrfs_real_readdir, .open = btrfs_opendir,