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

Commit b8227554 authored by Al Viro's avatar Al Viro
Browse files

[readdir] convert xfs



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 9cdda8d3
Loading
Loading
Loading
Loading
+5 −8
Original line number Diff line number Diff line
@@ -368,10 +368,8 @@ xfs_dir_removename(
int
xfs_readdir(
	xfs_inode_t	*dp,
	void		*dirent,
	size_t		bufsize,
	xfs_off_t	*offset,
	filldir_t	filldir)
	struct dir_context *ctx,
	size_t		bufsize)
{
	int		rval;		/* return value */
	int		v;		/* type-checking value */
@@ -385,14 +383,13 @@ xfs_readdir(
	XFS_STATS_INC(xs_dir_getdents);

	if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
		rval = xfs_dir2_sf_getdents(dp, dirent, offset, filldir);
		rval = xfs_dir2_sf_getdents(dp, ctx);
	else if ((rval = xfs_dir2_isblock(NULL, dp, &v)))
		;
	else if (v)
		rval = xfs_dir2_block_getdents(dp, dirent, offset, filldir);
		rval = xfs_dir2_block_getdents(dp, ctx);
	else
		rval = xfs_dir2_leaf_getdents(dp, dirent, bufsize, offset,
					      filldir);
		rval = xfs_dir2_leaf_getdents(dp, ctx, bufsize);
	return rval;
}

+7 −10
Original line number Diff line number Diff line
@@ -569,9 +569,7 @@ xfs_dir2_block_addname(
int						/* error */
xfs_dir2_block_getdents(
	xfs_inode_t		*dp,		/* incore inode */
	void			*dirent,
	xfs_off_t		*offset,
	filldir_t		filldir)
	struct dir_context	*ctx)
{
	xfs_dir2_data_hdr_t	*hdr;		/* block header */
	struct xfs_buf		*bp;		/* buffer for block */
@@ -589,7 +587,7 @@ xfs_dir2_block_getdents(
	/*
	 * If the block number in the offset is out of range, we're done.
	 */
	if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk)
	if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk)
		return 0;

	error = xfs_dir3_block_read(NULL, dp, &bp);
@@ -600,7 +598,7 @@ xfs_dir2_block_getdents(
	 * Extract the byte offset we start at from the seek pointer.
	 * We'll skip entries before this.
	 */
	wantoff = xfs_dir2_dataptr_to_off(mp, *offset);
	wantoff = xfs_dir2_dataptr_to_off(mp, ctx->pos);
	hdr = bp->b_addr;
	xfs_dir3_data_check(dp, bp);
	/*
@@ -639,13 +637,12 @@ xfs_dir2_block_getdents(
		cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
					    (char *)dep - (char *)hdr);

		ctx->pos = cook & 0x7fffffff;
		/*
		 * If it didn't fit, set the final offset to here & return.
		 */
		if (filldir(dirent, (char *)dep->name, dep->namelen,
			    cook & 0x7fffffff, be64_to_cpu(dep->inumber),
			    DT_UNKNOWN)) {
			*offset = cook & 0x7fffffff;
		if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
			    be64_to_cpu(dep->inumber), DT_UNKNOWN)) {
			xfs_trans_brelse(NULL, bp);
			return 0;
		}
@@ -655,7 +652,7 @@ xfs_dir2_block_getdents(
	 * Reached the end of the block.
	 * Set the offset to a non-existent block 1 and return.
	 */
	*offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) &
	ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) &
			0x7fffffff;
	xfs_trans_brelse(NULL, bp);
	return 0;
+8 −10
Original line number Diff line number Diff line
@@ -1300,10 +1300,8 @@ out:
int						/* error */
xfs_dir2_leaf_getdents(
	xfs_inode_t		*dp,		/* incore directory inode */
	void			*dirent,
	size_t			bufsize,
	xfs_off_t		*offset,
	filldir_t		filldir)
	struct dir_context	*ctx,
	size_t			bufsize)
{
	struct xfs_buf		*bp = NULL;	/* data block buffer */
	xfs_dir2_data_hdr_t	*hdr;		/* data block header */
@@ -1322,7 +1320,7 @@ xfs_dir2_leaf_getdents(
	 * If the offset is at or past the largest allowed value,
	 * give up right away.
	 */
	if (*offset >= XFS_DIR2_MAX_DATAPTR)
	if (ctx->pos >= XFS_DIR2_MAX_DATAPTR)
		return 0;

	mp = dp->i_mount;
@@ -1343,7 +1341,7 @@ xfs_dir2_leaf_getdents(
	 * Inside the loop we keep the main offset value as a byte offset
	 * in the directory file.
	 */
	curoff = xfs_dir2_dataptr_to_byte(mp, *offset);
	curoff = xfs_dir2_dataptr_to_byte(mp, ctx->pos);

	/*
	 * Force this conversion through db so we truncate the offset
@@ -1444,8 +1442,8 @@ xfs_dir2_leaf_getdents(
		dep = (xfs_dir2_data_entry_t *)ptr;
		length = xfs_dir2_data_entsize(dep->namelen);

		if (filldir(dirent, (char *)dep->name, dep->namelen,
			    xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff,
		ctx->pos = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff;
		if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
			    be64_to_cpu(dep->inumber), DT_UNKNOWN))
			break;

@@ -1462,9 +1460,9 @@ xfs_dir2_leaf_getdents(
	 * All done.  Set output offset value to current offset.
	 */
	if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR))
		*offset = XFS_DIR2_MAX_DATAPTR & 0x7fffffff;
		ctx->pos = XFS_DIR2_MAX_DATAPTR & 0x7fffffff;
	else
		*offset = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff;
		ctx->pos = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff;
	kmem_free(map_info);
	if (bp)
		xfs_trans_brelse(NULL, bp);
+5 −6
Original line number Diff line number Diff line
@@ -33,8 +33,8 @@ extern int xfs_dir_cilookup_result(struct xfs_da_args *args,
extern const struct xfs_buf_ops xfs_dir3_block_buf_ops;

extern int xfs_dir2_block_addname(struct xfs_da_args *args);
extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent,
		xfs_off_t *offset, filldir_t filldir);
extern int xfs_dir2_block_getdents(struct xfs_inode *dp,
		struct dir_context *ctx);
extern int xfs_dir2_block_lookup(struct xfs_da_args *args);
extern int xfs_dir2_block_removename(struct xfs_da_args *args);
extern int xfs_dir2_block_replace(struct xfs_da_args *args);
@@ -91,8 +91,8 @@ extern void xfs_dir3_leaf_compact(struct xfs_da_args *args,
extern void xfs_dir3_leaf_compact_x1(struct xfs_dir3_icleaf_hdr *leafhdr,
		struct xfs_dir2_leaf_entry *ents, int *indexp,
		int *lowstalep, int *highstalep, int *lowlogp, int *highlogp);
extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, void *dirent,
		size_t bufsize, xfs_off_t *offset, filldir_t filldir);
extern int xfs_dir2_leaf_getdents(struct xfs_inode *dp, struct dir_context *ctx,
		size_t bufsize);
extern int xfs_dir3_leaf_get_buf(struct xfs_da_args *args, xfs_dir2_db_t bno,
		struct xfs_buf **bpp, __uint16_t magic);
extern void xfs_dir3_leaf_log_ents(struct xfs_trans *tp, struct xfs_buf *bp,
@@ -153,8 +153,7 @@ extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_buf *bp,
		int size, xfs_dir2_sf_hdr_t *sfhp);
extern int xfs_dir2_sf_addname(struct xfs_da_args *args);
extern int xfs_dir2_sf_create(struct xfs_da_args *args, xfs_ino_t pino);
extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, void *dirent,
		xfs_off_t *offset, filldir_t filldir);
extern int xfs_dir2_sf_getdents(struct xfs_inode *dp, struct dir_context *ctx);
extern int xfs_dir2_sf_lookup(struct xfs_da_args *args);
extern int xfs_dir2_sf_removename(struct xfs_da_args *args);
extern int xfs_dir2_sf_replace(struct xfs_da_args *args);
+13 −18
Original line number Diff line number Diff line
@@ -768,9 +768,7 @@ xfs_dir2_sf_create(
int						/* error */
xfs_dir2_sf_getdents(
	xfs_inode_t		*dp,		/* incore directory inode */
	void			*dirent,
	xfs_off_t		*offset,
	filldir_t		filldir)
	struct dir_context	*ctx)
{
	int			i;		/* shortform entry number */
	xfs_mount_t		*mp;		/* filesystem mount point */
@@ -802,7 +800,7 @@ xfs_dir2_sf_getdents(
	/*
	 * If the block number in the offset is out of range, we're done.
	 */
	if (xfs_dir2_dataptr_to_db(mp, *offset) > mp->m_dirdatablk)
	if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk)
		return 0;

	/*
@@ -819,23 +817,21 @@ xfs_dir2_sf_getdents(
	/*
	 * Put . entry unless we're starting past it.
	 */
	if (*offset <= dot_offset) {
		if (filldir(dirent, ".", 1, dot_offset & 0x7fffffff, dp->i_ino, DT_DIR)) {
			*offset = dot_offset & 0x7fffffff;
	if (ctx->pos <= dot_offset) {
		ctx->pos = dot_offset & 0x7fffffff;
		if (!dir_emit(ctx, ".", 1, dp->i_ino, DT_DIR))
			return 0;
	}
	}

	/*
	 * Put .. entry unless we're starting past it.
	 */
	if (*offset <= dotdot_offset) {
	if (ctx->pos <= dotdot_offset) {
		ino = xfs_dir2_sf_get_parent_ino(sfp);
		if (filldir(dirent, "..", 2, dotdot_offset & 0x7fffffff, ino, DT_DIR)) {
			*offset = dotdot_offset & 0x7fffffff;
		ctx->pos = dotdot_offset & 0x7fffffff;
		if (!dir_emit(ctx, "..", 2, ino, DT_DIR))
			return 0;
	}
	}

	/*
	 * Loop while there are more entries and put'ing works.
@@ -845,21 +841,20 @@ xfs_dir2_sf_getdents(
		off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
				xfs_dir2_sf_get_offset(sfep));

		if (*offset > off) {
		if (ctx->pos > off) {
			sfep = xfs_dir2_sf_nextentry(sfp, sfep);
			continue;
		}

		ino = xfs_dir2_sfe_get_ino(sfp, sfep);
		if (filldir(dirent, (char *)sfep->name, sfep->namelen,
			    off & 0x7fffffff, ino, DT_UNKNOWN)) {
			*offset = off & 0x7fffffff;
		ctx->pos = off & 0x7fffffff;
		if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen,
			    ino, DT_UNKNOWN))
			return 0;
		}
		sfep = xfs_dir2_sf_nextentry(sfp, sfep);
	}

	*offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) &
	ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) &
			0x7fffffff;
	return 0;
}
Loading