From: Tao Ma <boyu.mt@xxxxxxxxxx> Zach reported a problem that if inline data is enabled, we don't tell the difference between the offset of '.' and '..'. And a getdents will fail if the user only want to get '.'. This patch adds a new offset EXT4_INLINE_DOTDOT_OFFSET which indicates the offset of inline "..", and now 0 is for the "." and EXT4_INLINE_DOTDOT_OFFSET is for "..". Reported-by: Zach Brown <zab@xxxxxxxxxx> Signed-off-by: Tao Ma <boyu.mt@xxxxxxxxxx> --- fs/ext4/inline.c | 18 +++++++++++++++--- 1 files changed, 15 insertions(+), 3 deletions(-) diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index c0fd1a1..9c09dd5 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -19,7 +19,8 @@ #define EXT4_XATTR_SYSTEM_DATA "data" #define EXT4_MIN_INLINE_DATA_SIZE ((sizeof(__le32) * EXT4_N_BLOCKS)) -#define EXT4_INLINE_DOTDOT_SIZE 4 +#define EXT4_INLINE_DOTDOT_SIZE 4 +#define EXT4_INLINE_DOTDOT_OFFSET 2 int ext4_get_inline_size(struct inode *inode) { @@ -1330,6 +1331,7 @@ int ext4_read_inline_dir(struct file *filp, sb = inode->i_sb; stored = 0; parent_ino = le32_to_cpu(((struct ext4_dir_entry_2 *)dir_buf)->inode); + offset = filp->f_pos; while (!error && !stored && filp->f_pos < inode->i_size) { revalidate: @@ -1342,9 +1344,15 @@ revalidate: if (filp->f_version != inode->i_version) { for (i = 0; i < inode->i_size && i < offset;) { + /* + * "." is with offset 0 and + * ".." is EXT4_INLINE_DOTDOT_OFFSET. + */ if (!i) { - /* skip "." and ".." if needed. */ - i += EXT4_INLINE_DOTDOT_SIZE; + i = EXT4_INLINE_DOTDOT_OFFSET; + continue; + } else if (i == EXT4_INLINE_DOTDOT_OFFSET) { + i = EXT4_INLINE_DOTDOT_SIZE; continue; } de = (struct ext4_dir_entry_2 *) @@ -1373,7 +1381,11 @@ revalidate: if (error) break; stored++; + filp->f_pos = EXT4_INLINE_DOTDOT_OFFSET; + continue; + } + if (filp->f_pos == EXT4_INLINE_DOTDOT_OFFSET) { error = filldir(dirent, "..", 2, 0, parent_ino, DT_DIR); if (error) -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html