Message ID | 20250102140411.14617-7-john.g.garry@oracle.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | large atomic writes for xfs | expand |
On Thu, Jan 02, 2025 at 02:04:10PM +0000, John Garry wrote: > rtvol guarantees alloc unit alignment through rt_extsize. As such, it is > possible to atomically write multiple FS blocks in a rtvol (up to > rt_extsize). > > Add a member to xfs_mount to hold the pre-calculated atomic write unit max. > > The value in rt_extsize is not necessarily a power-of-2, so find the > largest power-of-2 evenly divisible into rt_extsize. > > Signed-off-by: John Garry <john.g.garry@oracle.com> I guess that works. Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> --D > --- > fs/xfs/libxfs/xfs_sb.c | 3 +++ > fs/xfs/xfs_mount.h | 1 + > fs/xfs/xfs_rtalloc.c | 23 +++++++++++++++++++++++ > fs/xfs/xfs_rtalloc.h | 4 ++++ > 4 files changed, 31 insertions(+) > > diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c > index 3b5623611eba..6381060df901 100644 > --- a/fs/xfs/libxfs/xfs_sb.c > +++ b/fs/xfs/libxfs/xfs_sb.c > @@ -25,6 +25,7 @@ > #include "xfs_da_format.h" > #include "xfs_health.h" > #include "xfs_ag.h" > +#include "xfs_rtalloc.h" > #include "xfs_rtbitmap.h" > #include "xfs_exchrange.h" > #include "xfs_rtgroup.h" > @@ -1149,6 +1150,8 @@ xfs_sb_mount_rextsize( > rgs->blklog = 0; > rgs->blkmask = (uint64_t)-1; > } > + > + xfs_rt_awu_update(mp); > } > > /* Update incore sb rt extent size, then recompute the cached rt geometry. */ > diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h > index db9dade7d22a..f2f1d2c667cc 100644 > --- a/fs/xfs/xfs_mount.h > +++ b/fs/xfs/xfs_mount.h > @@ -191,6 +191,7 @@ typedef struct xfs_mount { > bool m_fail_unmount; > bool m_finobt_nores; /* no per-AG finobt resv. */ > bool m_update_sb; /* sb needs update in mount */ > + xfs_extlen_t m_rt_awu_max; /* rt atomic write unit max */ > > /* > * Bitsets of per-fs metadata that have been checked and/or are sick. > diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c > index fcfa6e0eb3ad..e3093f3c7670 100644 > --- a/fs/xfs/xfs_rtalloc.c > +++ b/fs/xfs/xfs_rtalloc.c > @@ -735,6 +735,28 @@ xfs_rtginode_ensure( > return xfs_rtginode_create(rtg, type, true); > } > > +void > +xfs_rt_awu_update( > + struct xfs_mount *mp) > +{ > + xfs_agblock_t rsize = mp->m_sb.sb_rextsize; > + xfs_extlen_t awu_max; > + > + if (is_power_of_2(rsize)) { > + mp->m_rt_awu_max = rsize; > + return; > + } > + > + /* Find highest power-of-2 evenly divisible into sb_rextsize */ > + awu_max = 1; > + while (1) { > + if (rsize % (awu_max * 2)) > + break; > + awu_max *= 2; > + } > + mp->m_rt_awu_max = awu_max; > +} > + > static struct xfs_mount * > xfs_growfs_rt_alloc_fake_mount( > const struct xfs_mount *mp, > @@ -969,6 +991,7 @@ xfs_growfs_rt_bmblock( > */ > mp->m_rsumlevels = nmp->m_rsumlevels; > mp->m_rsumblocks = nmp->m_rsumblocks; > + mp->m_rt_awu_max = nmp->m_rt_awu_max; > > /* > * Recompute the growfsrt reservation from the new rsumsize. > diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h > index 8e2a07b8174b..fcb7bb3df470 100644 > --- a/fs/xfs/xfs_rtalloc.h > +++ b/fs/xfs/xfs_rtalloc.h > @@ -42,6 +42,10 @@ xfs_growfs_rt( > struct xfs_mount *mp, /* file system mount structure */ > xfs_growfs_rt_t *in); /* user supplied growfs struct */ > > +void > +xfs_rt_awu_update( > + struct xfs_mount *mp); > + > int xfs_rtalloc_reinit_frextents(struct xfs_mount *mp); > #else > # define xfs_growfs_rt(mp,in) (-ENOSYS) > -- > 2.31.1 > >
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 3b5623611eba..6381060df901 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -25,6 +25,7 @@ #include "xfs_da_format.h" #include "xfs_health.h" #include "xfs_ag.h" +#include "xfs_rtalloc.h" #include "xfs_rtbitmap.h" #include "xfs_exchrange.h" #include "xfs_rtgroup.h" @@ -1149,6 +1150,8 @@ xfs_sb_mount_rextsize( rgs->blklog = 0; rgs->blkmask = (uint64_t)-1; } + + xfs_rt_awu_update(mp); } /* Update incore sb rt extent size, then recompute the cached rt geometry. */ diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index db9dade7d22a..f2f1d2c667cc 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -191,6 +191,7 @@ typedef struct xfs_mount { bool m_fail_unmount; bool m_finobt_nores; /* no per-AG finobt resv. */ bool m_update_sb; /* sb needs update in mount */ + xfs_extlen_t m_rt_awu_max; /* rt atomic write unit max */ /* * Bitsets of per-fs metadata that have been checked and/or are sick. diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index fcfa6e0eb3ad..e3093f3c7670 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -735,6 +735,28 @@ xfs_rtginode_ensure( return xfs_rtginode_create(rtg, type, true); } +void +xfs_rt_awu_update( + struct xfs_mount *mp) +{ + xfs_agblock_t rsize = mp->m_sb.sb_rextsize; + xfs_extlen_t awu_max; + + if (is_power_of_2(rsize)) { + mp->m_rt_awu_max = rsize; + return; + } + + /* Find highest power-of-2 evenly divisible into sb_rextsize */ + awu_max = 1; + while (1) { + if (rsize % (awu_max * 2)) + break; + awu_max *= 2; + } + mp->m_rt_awu_max = awu_max; +} + static struct xfs_mount * xfs_growfs_rt_alloc_fake_mount( const struct xfs_mount *mp, @@ -969,6 +991,7 @@ xfs_growfs_rt_bmblock( */ mp->m_rsumlevels = nmp->m_rsumlevels; mp->m_rsumblocks = nmp->m_rsumblocks; + mp->m_rt_awu_max = nmp->m_rt_awu_max; /* * Recompute the growfsrt reservation from the new rsumsize. diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h index 8e2a07b8174b..fcb7bb3df470 100644 --- a/fs/xfs/xfs_rtalloc.h +++ b/fs/xfs/xfs_rtalloc.h @@ -42,6 +42,10 @@ xfs_growfs_rt( struct xfs_mount *mp, /* file system mount structure */ xfs_growfs_rt_t *in); /* user supplied growfs struct */ +void +xfs_rt_awu_update( + struct xfs_mount *mp); + int xfs_rtalloc_reinit_frextents(struct xfs_mount *mp); #else # define xfs_growfs_rt(mp,in) (-ENOSYS)
rtvol guarantees alloc unit alignment through rt_extsize. As such, it is possible to atomically write multiple FS blocks in a rtvol (up to rt_extsize). Add a member to xfs_mount to hold the pre-calculated atomic write unit max. The value in rt_extsize is not necessarily a power-of-2, so find the largest power-of-2 evenly divisible into rt_extsize. Signed-off-by: John Garry <john.g.garry@oracle.com> --- fs/xfs/libxfs/xfs_sb.c | 3 +++ fs/xfs/xfs_mount.h | 1 + fs/xfs/xfs_rtalloc.c | 23 +++++++++++++++++++++++ fs/xfs/xfs_rtalloc.h | 4 ++++ 4 files changed, 31 insertions(+)