diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 561d7308b393a0347dea3b1344f409bf5fed0139..5d00bf0602545f9e60e7b27790df2bd868285dbc 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -266,7 +266,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx) ctx->pos += ext4_rec_len_from_disk(de->rec_len, sb->s_blocksize); } - if ((ctx->pos < inode->i_size) && !dir_relax(inode)) + if ((ctx->pos < inode->i_size) && !dir_relax_shared(inode)) goto done; brelse(bh); bh = NULL; @@ -644,7 +644,7 @@ int ext4_check_all_de(struct inode *dir, struct buffer_head *bh, void *buf, const struct file_operations ext4_dir_operations = { .llseek = ext4_dir_llseek, .read = generic_read_dir, - .iterate = ext4_readdir, + .iterate_shared = ext4_readdir, .unlocked_ioctl = ext4_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = ext4_compat_ioctl, diff --git a/include/linux/fs.h b/include/linux/fs.h index 3dc0258a2b640c525d7d95588c29ccd452809a10..e87245ac6941a5e796b3d4a410e230ec135433b7 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3134,6 +3134,13 @@ static inline bool dir_relax(struct inode *inode) return !IS_DEADDIR(inode); } +static inline bool dir_relax_shared(struct inode *inode) +{ + inode_unlock_shared(inode); + inode_lock_shared(inode); + return !IS_DEADDIR(inode); +} + extern bool path_noexec(const struct path *path); extern void inode_nohighmem(struct inode *inode);