Re: [PATCH v3 15/21] fs: xfs: iomap: Sub-extent zeroing

From: Dave Chinner
Date: Wed May 01 2024 - 21:27:07 EST


On Wed, May 01, 2024 at 12:36:02PM +0100, John Garry wrote:
> On 01/05/2024 02:32, Dave Chinner wrote:
> > On Mon, Apr 29, 2024 at 05:47:40PM +0000, John Garry wrote:
> > > Set iomap->extent_size when sub-extent zeroing is required.
> > >
> > > We treat a sub-extent write same as an unaligned write, so we can leverage
> > > the existing sub-FSblock unaligned write support, i.e. try a shared lock
> > > with IOMAP_DIO_OVERWRITE_ONLY flag, if this fails then try the exclusive
> > > lock.
> > >
> > > In xfs_iomap_write_unwritten(), FSB calcs are now based on the extsize.
> >
> > If forcedalign is set, should we just reject unaligned DIOs?
>
> Why would we? That's very restrictive. Indeed, we got to the point of adding
> the sub-extent zeroing just for supporting that.
> > > @@ -646,9 +647,9 @@ xfs_file_dio_write_unaligned(
> > > ssize_t ret;
> > > /*
> > > - * Extending writes need exclusivity because of the sub-block zeroing
> > > - * that the DIO code always does for partial tail blocks beyond EOF, so
> > > - * don't even bother trying the fast path in this case.
> > > + * Extending writes need exclusivity because of the sub-block/extent
> > > + * zeroing that the DIO code always does for partial tail blocks
> > > + * beyond EOF, so don't even bother trying the fast path in this case.
> > > */
> > > if (iocb->ki_pos > isize || iocb->ki_pos + count >= isize) {
> > > if (iocb->ki_flags & IOCB_NOWAIT)
> > > @@ -714,11 +715,19 @@ xfs_file_dio_write(
> > > struct xfs_inode *ip = XFS_I(file_inode(iocb->ki_filp));
> > > struct xfs_buftarg *target = xfs_inode_buftarg(ip);
> > > size_t count = iov_iter_count(from);
> > > + struct xfs_mount *mp = ip->i_mount;
> > > + unsigned int blockmask;
> > > /* direct I/O must be aligned to device logical sector size */
> > > if ((iocb->ki_pos | count) & target->bt_logical_sectormask)
> > > return -EINVAL;
> > > - if ((iocb->ki_pos | count) & ip->i_mount->m_blockmask)
> > > +
> > > + if (xfs_inode_has_forcealign(ip) && ip->i_extsize > 1)
> > > + blockmask = XFS_FSB_TO_B(mp, ip->i_extsize) - 1;
> > > + else
> > > + blockmask = mp->m_blockmask;
> >
> > alignmask = XFS_FSB_TO_B(mp, xfs_inode_alignment(ip)) - 1;
>
> Do you mean xfs_extent_alignment() instead of xfs_inode_alignment()?

Yes, I was.

I probably should have named it xfs_inode_extent_alignment() because
clearly I kept thinking of it as "inode alignment"... :)

-Dave.
--
Dave Chinner
david@xxxxxxxxxxxxx