Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 041388b5 authored by Lachlan McIlroy's avatar Lachlan McIlroy
Browse files

[XFS] Put the correct offset in dirent d_off



The recent filldir regression fix was not putting the correct d_off in
each dirent. This was resulting in incorrect cookies being passed to dmapi
ioctls and the wrong offset appearing in the dirents. readdir was
unaffected as the filp->f_pos was being updated with the correct offset
and this was being written into the last dirent in each buffer. Fix the
XFS code to do the right thing.

SGI-PV: 973746
SGI-Modid: xfs-linux-melb:xfs-kern:30240a

Signed-off-by: default avatarDavid Chinner <dgc@sgi.com>
Signed-off-by: default avatarChristoph Hellwig <hch@infradead.org>
Signed-off-by: default avatarLachlan McIlroy <lachlan@sgi.com>
parent c734c79b
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -356,8 +356,8 @@ xfs_file_readdir(


			reclen = sizeof(struct hack_dirent) + de->namlen;
			reclen = sizeof(struct hack_dirent) + de->namlen;
			size -= reclen;
			size -= reclen;
			curr_offset = de->offset /* & 0x7fffffff */;
			de = (struct hack_dirent *)((char *)de + reclen);
			de = (struct hack_dirent *)((char *)de + reclen);
			curr_offset = de->offset /* & 0x7fffffff */;
		}
		}
	}
	}


+2 −4
Original line number Original line Diff line number Diff line
@@ -508,7 +508,7 @@ xfs_dir2_block_getdents(
			continue;
			continue;


		cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
		cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
						    ptr - (char *)block);
					    (char *)dep - (char *)block);
		ino = be64_to_cpu(dep->inumber);
		ino = be64_to_cpu(dep->inumber);
#if XFS_BIG_INUMS
#if XFS_BIG_INUMS
		ino += mp->m_inoadd;
		ino += mp->m_inoadd;
@@ -519,9 +519,7 @@ xfs_dir2_block_getdents(
		 */
		 */
		if (filldir(dirent, dep->name, dep->namelen, cook,
		if (filldir(dirent, dep->name, dep->namelen, cook,
			    ino, DT_UNKNOWN)) {
			    ino, DT_UNKNOWN)) {
			*offset = xfs_dir2_db_off_to_dataptr(mp,
			*offset = cook;
					mp->m_dirdatablk,
					(char *)dep - (char *)block);
			xfs_da_brelse(NULL, bp);
			xfs_da_brelse(NULL, bp);
			return 0;
			return 0;
		}
		}
+1 −1
Original line number Original line Diff line number Diff line
@@ -1091,7 +1091,7 @@ xfs_dir2_leaf_getdents(
		 * Won't fit.  Return to caller.
		 * Won't fit.  Return to caller.
		 */
		 */
		if (filldir(dirent, dep->name, dep->namelen,
		if (filldir(dirent, dep->name, dep->namelen,
			    xfs_dir2_byte_to_dataptr(mp, curoff + length),
			    xfs_dir2_byte_to_dataptr(mp, curoff),
			    ino, DT_UNKNOWN))
			    ino, DT_UNKNOWN))
			break;
			break;


+3 −6
Original line number Original line Diff line number Diff line
@@ -752,7 +752,7 @@ xfs_dir2_sf_getdents(
#if XFS_BIG_INUMS
#if XFS_BIG_INUMS
		ino += mp->m_inoadd;
		ino += mp->m_inoadd;
#endif
#endif
		if (filldir(dirent, ".", 1, dotdot_offset, ino, DT_DIR)) {
		if (filldir(dirent, ".", 1, dot_offset, ino, DT_DIR)) {
			*offset = dot_offset;
			*offset = dot_offset;
			return 0;
			return 0;
		}
		}
@@ -762,13 +762,11 @@ xfs_dir2_sf_getdents(
	 * Put .. entry unless we're starting past it.
	 * Put .. entry unless we're starting past it.
	 */
	 */
	if (*offset <= dotdot_offset) {
	if (*offset <= dotdot_offset) {
		off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
						  XFS_DIR2_DATA_FIRST_OFFSET);
		ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent);
		ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent);
#if XFS_BIG_INUMS
#if XFS_BIG_INUMS
		ino += mp->m_inoadd;
		ino += mp->m_inoadd;
#endif
#endif
		if (filldir(dirent, "..", 2, off, ino, DT_DIR)) {
		if (filldir(dirent, "..", 2, dotdot_offset, ino, DT_DIR)) {
			*offset = dotdot_offset;
			*offset = dotdot_offset;
			return 0;
			return 0;
		}
		}
@@ -793,8 +791,7 @@ xfs_dir2_sf_getdents(
#endif
#endif


		if (filldir(dirent, sfep->name, sfep->namelen,
		if (filldir(dirent, sfep->name, sfep->namelen,
			    off + xfs_dir2_data_entsize(sfep->namelen),
					    off, ino, DT_UNKNOWN)) {
			    ino, DT_UNKNOWN)) {
			*offset = off;
			*offset = off;
			return 0;
			return 0;
		}
		}