aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-12-12 00:34:36 -0500
committerBen Myers <bpm@sgi.com>2013-12-17 10:30:12 -0500
commit33177f05364c6cd13b06d0f3500dad07cf4647c2 (patch)
tree53737ce77a1e4bef9bbe5b38d4d6ec06d6f60da0 /fs/xfs
parent83a0adc3f93aae4ab9c59113e3145c7bdb2b4a8c (diff)
xfs: swalloc doesn't align allocations properly
When swalloc is specified as a mount option, allocations are supposed to be aligned to the stripe width rather than the stripe unit of the underlying filesystem. However, it does not do this. What the implementation does is round up the allocation size to a stripe width, hence ensuring that all allocations span a full stripe width. It does not, however, ensure that that allocation is aligned to a stripe width, and hence the allocations can span multiple underlying stripes and so still see RMW cycles for things like direct IO on MD RAID. So, if the swalloc mount option is set, change the allocation alignment in xfs_bmap_btalloc() to use the stripe width rather than the stripe unit. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Ben Myers <bpm@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_bmap.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 8401f11f378f..3b2c14b6f0fb 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -3648,10 +3648,19 @@ xfs_bmap_btalloc(
3648 int isaligned; 3648 int isaligned;
3649 int tryagain; 3649 int tryagain;
3650 int error; 3650 int error;
3651 int stripe_align;
3651 3652
3652 ASSERT(ap->length); 3653 ASSERT(ap->length);
3653 3654
3654 mp = ap->ip->i_mount; 3655 mp = ap->ip->i_mount;
3656
3657 /* stripe alignment for allocation is determined by mount parameters */
3658 stripe_align = 0;
3659 if (mp->m_swidth && (mp->m_flags & XFS_MOUNT_SWALLOC))
3660 stripe_align = mp->m_swidth;
3661 else if (mp->m_dalign)
3662 stripe_align = mp->m_dalign;
3663
3655 align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0; 3664 align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0;
3656 if (unlikely(align)) { 3665 if (unlikely(align)) {
3657 error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, 3666 error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev,
@@ -3660,6 +3669,8 @@ xfs_bmap_btalloc(
3660 ASSERT(!error); 3669 ASSERT(!error);
3661 ASSERT(ap->length); 3670 ASSERT(ap->length);
3662 } 3671 }
3672
3673
3663 nullfb = *ap->firstblock == NULLFSBLOCK; 3674 nullfb = *ap->firstblock == NULLFSBLOCK;
3664 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock); 3675 fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, *ap->firstblock);
3665 if (nullfb) { 3676 if (nullfb) {
@@ -3735,7 +3746,7 @@ xfs_bmap_btalloc(
3735 */ 3746 */
3736 if (!ap->flist->xbf_low && ap->aeof) { 3747 if (!ap->flist->xbf_low && ap->aeof) {
3737 if (!ap->offset) { 3748 if (!ap->offset) {
3738 args.alignment = mp->m_dalign; 3749 args.alignment = stripe_align;
3739 atype = args.type; 3750 atype = args.type;
3740 isaligned = 1; 3751 isaligned = 1;
3741 /* 3752 /*
@@ -3760,13 +3771,13 @@ xfs_bmap_btalloc(
3760 * of minlen+alignment+slop doesn't go up 3771 * of minlen+alignment+slop doesn't go up
3761 * between the calls. 3772 * between the calls.
3762 */ 3773 */
3763 if (blen > mp->m_dalign && blen <= args.maxlen) 3774 if (blen > stripe_align && blen <= args.maxlen)
3764 nextminlen = blen - mp->m_dalign; 3775 nextminlen = blen - stripe_align;
3765 else 3776 else
3766 nextminlen = args.minlen; 3777 nextminlen = args.minlen;
3767 if (nextminlen + mp->m_dalign > args.minlen + 1) 3778 if (nextminlen + stripe_align > args.minlen + 1)
3768 args.minalignslop = 3779 args.minalignslop =
3769 nextminlen + mp->m_dalign - 3780 nextminlen + stripe_align -
3770 args.minlen - 1; 3781 args.minlen - 1;
3771 else 3782 else
3772 args.minalignslop = 0; 3783 args.minalignslop = 0;
@@ -3788,7 +3799,7 @@ xfs_bmap_btalloc(
3788 */ 3799 */
3789 args.type = atype; 3800 args.type = atype;
3790 args.fsbno = ap->blkno; 3801 args.fsbno = ap->blkno;
3791 args.alignment = mp->m_dalign; 3802 args.alignment = stripe_align;
3792 args.minlen = nextminlen; 3803 args.minlen = nextminlen;
3793 args.minalignslop = 0; 3804 args.minalignslop = 0;
3794 isaligned = 1; 3805 isaligned = 1;