The commit is pushed to "branch-rh9-5.14.vz9.1.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git after rh9-5.14.0-4.vz9.10.16 ------> commit a582ee7309cc7cc2e18efe80577339268fa68647 Author: Kirill Tkhai <ktk...@virtuozzo.com> Date: Mon Oct 25 15:49:49 2021 +0300
xfs: Teach the fs where the balloon inode is This adds balloon_ino=XXX mount option for xfs. https://jira.sw.ru/browse/PSBM-133811 Signed-off-by: Kirill Tkhai <ktk...@virtuozzo.com> --- fs/xfs/xfs_mount.h | 2 ++ fs/xfs/xfs_super.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_super.h | 2 ++ 3 files changed, 83 insertions(+) diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index c78b63fe779a..4eb318bb44ac 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -154,6 +154,8 @@ typedef struct xfs_mount { uint8_t m_rt_checked; uint8_t m_rt_sick; + uint64_t m_balloon_ino; + /* * End of read-mostly variables. Frequently written variables and locks * should be placed below this comment from now on. The first variable diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index fd1cd6aacd10..bd28e2a0d496 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -95,6 +95,7 @@ enum { Opt_prjquota, Opt_uquota, Opt_gquota, Opt_pquota, Opt_uqnoenforce, Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce, Opt_discard, Opt_nodiscard, Opt_dax, Opt_dax_enum, + Opt_balloon_ino, }; static const struct fs_parameter_spec xfs_fs_parameters[] = { @@ -139,6 +140,7 @@ static const struct fs_parameter_spec xfs_fs_parameters[] = { fsparam_flag("nodiscard", Opt_nodiscard), fsparam_flag("dax", Opt_dax), fsparam_enum("dax", Opt_dax_enum, dax_param_enums), + fsparam_u64("balloon_ino", Opt_balloon_ino), {} }; @@ -171,6 +173,7 @@ xfs_fs_show_options( }; struct xfs_mount *mp = XFS_M(root->d_sb); struct proc_xfs_info *xfs_infop; + u64 balloon_ino; for (xfs_infop = xfs_info_set; xfs_infop->flag; xfs_infop++) { if (mp->m_flags & xfs_infop->flag) @@ -224,6 +227,9 @@ xfs_fs_show_options( if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT)) seq_puts(m, ",noquota"); + if ((balloon_ino = READ_ONCE(mp->m_balloon_ino)) != 0) + seq_printf(m, ",balloon_ino=%llu", + balloon_ino); return 0; } @@ -776,6 +782,41 @@ xfs_fs_sync_fs( return 0; } +struct xfs_inode * +xfs_balloon_get(struct xfs_mount *mp, u64 balloon_ino, uint flags) +{ + struct xfs_inode *ip; + struct inode *inode; + int error; + + if (!xfs_verify_dir_ino(mp, balloon_ino)) + return ERR_PTR(-EINVAL); + + error = xfs_iget(mp, NULL, balloon_ino, flags, 0, &ip); + if (error) + return ERR_PTR(error); + inode = VFS_I(ip); + if (!S_ISREG(inode->i_mode) || IS_IMMUTABLE(inode)) + return ERR_PTR(-EINVAL); + + return ip; +} + +STATIC int +xfs_balloon_check(struct xfs_mount *mp, u64 balloon_ino) +{ + struct xfs_inode *ip; + + if (!balloon_ino) + return 0; + + ip = xfs_balloon_get(mp, balloon_ino, XFS_IGET_UNTRUSTED); + if (IS_ERR(ip)) + return PTR_ERR(ip); + xfs_irele(ip); + return 0; +} + STATIC int xfs_fs_statfs( struct dentry *dentry, @@ -790,6 +831,7 @@ xfs_fs_statfs( uint64_t fdblocks; xfs_extlen_t lsize; int64_t ffree; + u64 balloon_ino; statp->f_type = XFS_SUPER_MAGIC; statp->f_namelen = MAXNAMELEN - 1; @@ -840,6 +882,17 @@ xfs_fs_statfs( sbp->sb_frextents * sbp->sb_rextsize; } + if ((balloon_ino = READ_ONCE(mp->m_balloon_ino)) != 0) { + struct xfs_inode *ip; + + ip = xfs_balloon_get(mp, balloon_ino, 0); + if (ip) { + /* Note, i_nblocks also contains metadata blocks */ + statp->f_blocks -= ip->i_nblocks + ip->i_delayed_blks; + xfs_irele(ip); + } + } + return 0; } @@ -1273,6 +1326,9 @@ xfs_fs_parse_param( xfs_mount_set_dax_mode(parsing_mp, result.uint_32); return 0; #endif + case Opt_balloon_ino: + parsing_mp->m_balloon_ino = result.uint_64; + return 0; /* Following mount options will be removed in September 2025 */ case Opt_ikeep: xfs_fs_warn_deprecated(fc, param, XFS_MOUNT_IKEEP, true); @@ -1603,6 +1659,10 @@ xfs_fs_fill_super( if (error) goto out_filestream_unmount; + error = xfs_balloon_check(mp, mp->m_balloon_ino); + if (error) + goto out_unmount; + root = igrab(VFS_I(mp->m_rootip)); if (!root) { error = -ENOENT; @@ -1809,6 +1869,25 @@ xfs_fs_reconfigure( return error; } + if (mp->m_balloon_ino != new_mp->m_balloon_ino) { + /* We never replace balloon file, so prohibit this */ + if (mp->m_balloon_ino) + return -EBUSY; + /* + * Note, that there maybe tasks, which have already + * opened the new balloon file. So, in general this + * is racy (someone even may remove this file) + * though the synchronization here would be too heavy. + * Since the effects of the race are not serious, and + * the race is not possible in process of our normal + * usage, we just ignore it. + */ + error = xfs_balloon_check(mp, new_mp->m_balloon_ino); + if (error) + return error; + WRITE_ONCE(mp->m_balloon_ino, new_mp->m_balloon_ino); + } + return 0; } diff --git a/fs/xfs/xfs_super.h b/fs/xfs/xfs_super.h index 167d23f92ffe..34409cbb11e3 100644 --- a/fs/xfs/xfs_super.h +++ b/fs/xfs/xfs_super.h @@ -100,4 +100,6 @@ extern struct workqueue_struct *xfs_discard_wq; #define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info)) +extern struct xfs_inode *xfs_balloon_get(struct xfs_mount *mp, + u64 balloon_ino, uint flags); #endif /* __XFS_SUPER_H__ */ _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel