From: Brian Foster <bfoster@redhat.com>
To: Dave Chinner <david@fromorbit.com>
Cc: xfs@oss.sgi.com
Subject: Re: [PATCH 2/8] xfs: move DIO mapping size calculation
Date: Tue, 14 Apr 2015 10:24:03 -0400 [thread overview]
Message-ID: <20150414142402.GC36198@bfoster.bfoster> (raw)
In-Reply-To: <1428996411-1507-3-git-send-email-david@fromorbit.com>
On Tue, Apr 14, 2015 at 05:26:45PM +1000, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
>
> The mapping size calculation is done last in __xfs_get_blocks(), but
> we are going to need the actual mapping size we will use to map the
> direct IO correctly in xfs_map_direct(). Factor out the calculation
> for code clarity, and move the call to be the first operation in
> mapping the extent to the returned buffer.
>
> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> ---
Reviewed-by: Brian Foster <bfoster@redhat.com>
> fs/xfs/xfs_aops.c | 79 ++++++++++++++++++++++++++++++++-----------------------
> 1 file changed, 46 insertions(+), 33 deletions(-)
>
> diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
> index 5f7ddd5..8f63520 100644
> --- a/fs/xfs/xfs_aops.c
> +++ b/fs/xfs/xfs_aops.c
> @@ -1249,6 +1249,47 @@ xfs_map_direct(
> }
> }
>
> +
> +/*
> + * If this is O_DIRECT or the mpage code calling tell them how large the mapping
> + * is, so that we can avoid repeated get_blocks calls.
> + *
> + * If the mapping spans EOF, then we have to break the mapping up as the mapping
> + * for blocks beyond EOF must be marked new so that sub block regions can be
> + * correctly zeroed. We can't do this for mappings within EOF unless the mapping
> + * was just allocated or is unwritten, otherwise the callers would overwrite
> + * existing data with zeros. Hence we have to split the mapping into a range up
> + * to and including EOF, and a second mapping for beyond EOF.
> + */
> +static void
> +xfs_map_trim_size(
> + struct inode *inode,
> + sector_t iblock,
> + struct buffer_head *bh_result,
> + struct xfs_bmbt_irec *imap,
> + xfs_off_t offset,
> + ssize_t size)
> +{
> + xfs_off_t mapping_size;
> +
> + mapping_size = imap->br_startoff + imap->br_blockcount - iblock;
> + mapping_size <<= inode->i_blkbits;
> +
> + ASSERT(mapping_size > 0);
> + if (mapping_size > size)
> + mapping_size = size;
> + if (offset < i_size_read(inode) &&
> + offset + mapping_size >= i_size_read(inode)) {
> + /* limit mapping to block that spans EOF */
> + mapping_size = roundup_64(i_size_read(inode) - offset,
> + 1 << inode->i_blkbits);
> + }
> + if (mapping_size > LONG_MAX)
> + mapping_size = LONG_MAX;
> +
> + bh_result->b_size = mapping_size;
> +}
> +
> STATIC int
> __xfs_get_blocks(
> struct inode *inode,
> @@ -1347,6 +1388,11 @@ __xfs_get_blocks(
> goto out_unlock;
> }
>
> + /* trim mapping down to size requested */
> + if (direct || size > (1 << inode->i_blkbits))
> + xfs_map_trim_size(inode, iblock, bh_result,
> + &imap, offset, size);
> +
> if (imap.br_startblock != HOLESTARTBLOCK &&
> imap.br_startblock != DELAYSTARTBLOCK &&
> (create || !ISUNWRITTEN(&imap))) {
> @@ -1388,39 +1434,6 @@ __xfs_get_blocks(
> }
> }
>
> - /*
> - * If this is O_DIRECT or the mpage code calling tell them how large
> - * the mapping is, so that we can avoid repeated get_blocks calls.
> - *
> - * If the mapping spans EOF, then we have to break the mapping up as the
> - * mapping for blocks beyond EOF must be marked new so that sub block
> - * regions can be correctly zeroed. We can't do this for mappings within
> - * EOF unless the mapping was just allocated or is unwritten, otherwise
> - * the callers would overwrite existing data with zeros. Hence we have
> - * to split the mapping into a range up to and including EOF, and a
> - * second mapping for beyond EOF.
> - */
> - if (direct || size > (1 << inode->i_blkbits)) {
> - xfs_off_t mapping_size;
> -
> - mapping_size = imap.br_startoff + imap.br_blockcount - iblock;
> - mapping_size <<= inode->i_blkbits;
> -
> - ASSERT(mapping_size > 0);
> - if (mapping_size > size)
> - mapping_size = size;
> - if (offset < i_size_read(inode) &&
> - offset + mapping_size >= i_size_read(inode)) {
> - /* limit mapping to block that spans EOF */
> - mapping_size = roundup_64(i_size_read(inode) - offset,
> - 1 << inode->i_blkbits);
> - }
> - if (mapping_size > LONG_MAX)
> - mapping_size = LONG_MAX;
> -
> - bh_result->b_size = mapping_size;
> - }
> -
> return 0;
>
> out_unlock:
> --
> 2.0.0
>
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2015-04-14 14:24 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-14 7:26 [PATCH 0/8 v2] xfs: fix direct IO completion issues Dave Chinner
2015-04-14 7:26 ` [PATCH 1/8] xfs: factor DIO write mapping from get_blocks Dave Chinner
2015-04-14 14:23 ` Brian Foster
2015-04-14 20:06 ` Dave Chinner
2015-04-14 7:26 ` [PATCH 2/8] xfs: move DIO mapping size calculation Dave Chinner
2015-04-14 14:24 ` Brian Foster [this message]
2015-04-14 7:26 ` [PATCH 3/8] xfs: DIO needs an ioend for writes Dave Chinner
2015-04-14 14:24 ` Brian Foster
2015-04-14 7:26 ` [PATCH 4/8] xfs: handle DIO overwrite EOF update completion correctly Dave Chinner
2015-04-14 14:35 ` Brian Foster
2015-04-14 15:35 ` Brian Foster
2015-04-14 20:12 ` Dave Chinner
2015-04-14 7:26 ` [PATCH 5/8] xfs: DIO writes within EOF don't need an ioend Dave Chinner
2015-04-14 14:35 ` Brian Foster
2015-04-14 20:18 ` Dave Chinner
2015-04-14 7:26 ` [PATCH 6/8] xfs: DIO write completion size updates race Dave Chinner
2015-04-14 14:35 ` Brian Foster
2015-04-14 7:26 ` [PATCH 7/8] xfs: direct IO EOF zeroing needs to drain AIO Dave Chinner
2015-04-14 14:35 ` Brian Foster
2015-04-14 7:26 ` [PATCH 8/8] xfs: using generic_file_direct_write() is unnecessary Dave Chinner
2015-04-14 14:35 ` Brian Foster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150414142402.GC36198@bfoster.bfoster \
--to=bfoster@redhat.com \
--cc=david@fromorbit.com \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.