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

Reply via email to