[Devel] [PATCH RH9 2/4] xfs: Never show balloon in readdir results

Kirill Tkhai ktkhai at virtuozzo.com
Fri Oct 22 19:40:34 MSK 2021


Note, that xfs_readdir() may be called from many
places. To underline the case, when it's called
from normal readdir syscalls (not from xfs service
functionality), and to avoid to add a new argument
to xfs_readdir(), we introduce a special value:
XFS_FAKE_TRANS_IGNORE_BALLOON.

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 fs/xfs/libxfs/xfs_da_btree.h  |    1 +
 fs/xfs/libxfs/xfs_dir2_priv.h |    1 +
 fs/xfs/xfs_dir2_readdir.c     |   23 ++++++++++++++++++++++-
 fs/xfs/xfs_file.c             |    2 +-
 4 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index ad5dd324631a..3aa2dfd533ed 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -55,6 +55,7 @@ enum xfs_dacmp {
 typedef struct xfs_da_args {
 	struct xfs_da_geometry *geo;	/* da block geometry */
 	const uint8_t		*name;		/* string (maybe not NULL terminated) */
+	uint8_t		ignore_balloon:1;
 	int		namelen;	/* length of string (maybe no NULL) */
 	uint8_t		filetype;	/* filetype of inode for directories */
 	void		*value;		/* set of bytes (maybe contain NULLs) */
diff --git a/fs/xfs/libxfs/xfs_dir2_priv.h b/fs/xfs/libxfs/xfs_dir2_priv.h
index 94943ce49cab..e78fc1667836 100644
--- a/fs/xfs/libxfs/xfs_dir2_priv.h
+++ b/fs/xfs/libxfs/xfs_dir2_priv.h
@@ -184,6 +184,7 @@ void xfs_dir2_sf_put_ftype(struct xfs_mount *mp,
 		struct xfs_dir2_sf_entry *sfep, uint8_t ftype);
 
 /* xfs_dir2_readdir.c */
+#define XFS_FAKE_TRANS_IGNORE_BALLOON ((void *)1)
 extern int xfs_readdir(struct xfs_trans *tp, struct xfs_inode *dp,
 		       struct dir_context *ctx, size_t bufsize);
 
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index da1cc683560c..0dfba9054e3d 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -121,9 +121,13 @@ xfs_dir2_sf_getdents(
 				   !xfs_dir2_namecheck(sfep->name,
 						       sfep->namelen)))
 			return -EFSCORRUPTED;
+		if (unlikely(ino == READ_ONCE(dp->i_mount->m_balloon_ino) &&
+			     args->ignore_balloon))
+			goto next;
 		if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino,
 			    xfs_dir3_get_dtype(mp, filetype)))
 			return 0;
+next:
 		sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep);
 	}
 
@@ -214,6 +218,12 @@ xfs_dir2_block_getdents(
 			error = -EFSCORRUPTED;
 			goto out_rele;
 		}
+
+		if (unlikely(be64_to_cpu(dep->inumber) ==
+				READ_ONCE(dp->i_mount->m_balloon_ino) &&
+			     args->ignore_balloon))
+			continue;
+
 		if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
 			    be64_to_cpu(dep->inumber),
 			    xfs_dir3_get_dtype(dp->i_mount, filetype)))
@@ -465,11 +475,17 @@ xfs_dir2_leaf_getdents(
 			error = -EFSCORRUPTED;
 			break;
 		}
+
+		if (unlikely(be64_to_cpu(dep->inumber) ==
+				READ_ONCE(dp->i_mount->m_balloon_ino) &&
+			     args->ignore_balloon))
+			goto next;
+
 		if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
 			    be64_to_cpu(dep->inumber),
 			    xfs_dir3_get_dtype(dp->i_mount, filetype)))
 			break;
-
+next:
 		/*
 		 * Advance to next entry in the block.
 		 */
@@ -510,6 +526,11 @@ xfs_readdir(
 	int			rval;
 	int			v;
 
+	if (tp == XFS_FAKE_TRANS_IGNORE_BALLOON) {
+		args.ignore_balloon = true;
+		tp = NULL;
+	}
+
 	trace_xfs_readdir(dp);
 
 	if (XFS_FORCED_SHUTDOWN(dp->i_mount))
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index cc3cfb12df53..1164184cd1b0 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -1266,7 +1266,7 @@ xfs_file_readdir(
 	 */
 	bufsize = (size_t)min_t(loff_t, XFS_READDIR_BUFSIZE, ip->i_disk_size);
 
-	return xfs_readdir(NULL, ip, ctx, bufsize);
+	return xfs_readdir(XFS_FAKE_TRANS_IGNORE_BALLOON, ip, ctx, bufsize);
 }
 
 STATIC loff_t




More information about the Devel mailing list