From: Kirill Tkhai <ktk...@virtuozzo.com> 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.
https://jira.sw.ru/browse/PSBM-133811 Signed-off-by: Kirill Tkhai <ktk...@virtuozzo.com> Feature: fs/xfs: fast online shrink support --- 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 ffa3df5b2893..eab089397488 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 9046d08554e9..1673c8fa7fa0 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 9f3ceb461515..a6484c184d01 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); } @@ -215,6 +219,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))) @@ -469,11 +479,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. */ @@ -515,6 +531,11 @@ xfs_readdir( bool isblock; int error; + if (tp == XFS_FAKE_TRANS_IGNORE_BALLOON) { + args.ignore_balloon = true; + tp = NULL; + } + trace_xfs_readdir(dp); if (xfs_is_shutdown(dp->i_mount)) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 9a57da209801..5774bf0461c9 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1231,7 +1231,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 -- 2.43.5 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel