diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_bmap.c')
| -rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 44773c9eb957..bfc00de5c6f1 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c | |||
| @@ -3629,7 +3629,7 @@ xfs_bmap_btalloc( | |||
| 3629 | align = xfs_get_cowextsz_hint(ap->ip); | 3629 | align = xfs_get_cowextsz_hint(ap->ip); |
| 3630 | else if (xfs_alloc_is_userdata(ap->datatype)) | 3630 | else if (xfs_alloc_is_userdata(ap->datatype)) |
| 3631 | align = xfs_get_extsz_hint(ap->ip); | 3631 | align = xfs_get_extsz_hint(ap->ip); |
| 3632 | if (unlikely(align)) { | 3632 | if (align) { |
| 3633 | error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, | 3633 | error = xfs_bmap_extsize_align(mp, &ap->got, &ap->prev, |
| 3634 | align, 0, ap->eof, 0, ap->conv, | 3634 | align, 0, ap->eof, 0, ap->conv, |
| 3635 | &ap->offset, &ap->length); | 3635 | &ap->offset, &ap->length); |
| @@ -3701,7 +3701,7 @@ xfs_bmap_btalloc( | |||
| 3701 | args.minlen = ap->minlen; | 3701 | args.minlen = ap->minlen; |
| 3702 | } | 3702 | } |
| 3703 | /* apply extent size hints if obtained earlier */ | 3703 | /* apply extent size hints if obtained earlier */ |
| 3704 | if (unlikely(align)) { | 3704 | if (align) { |
| 3705 | args.prod = align; | 3705 | args.prod = align; |
| 3706 | if ((args.mod = (xfs_extlen_t)do_mod(ap->offset, args.prod))) | 3706 | if ((args.mod = (xfs_extlen_t)do_mod(ap->offset, args.prod))) |
| 3707 | args.mod = (xfs_extlen_t)(args.prod - args.mod); | 3707 | args.mod = (xfs_extlen_t)(args.prod - args.mod); |
| @@ -4514,8 +4514,6 @@ xfs_bmapi_write( | |||
| 4514 | int n; /* current extent index */ | 4514 | int n; /* current extent index */ |
| 4515 | xfs_fileoff_t obno; /* old block number (offset) */ | 4515 | xfs_fileoff_t obno; /* old block number (offset) */ |
| 4516 | int whichfork; /* data or attr fork */ | 4516 | int whichfork; /* data or attr fork */ |
| 4517 | char inhole; /* current location is hole in file */ | ||
| 4518 | char wasdelay; /* old extent was delayed */ | ||
| 4519 | 4517 | ||
| 4520 | #ifdef DEBUG | 4518 | #ifdef DEBUG |
| 4521 | xfs_fileoff_t orig_bno; /* original block number value */ | 4519 | xfs_fileoff_t orig_bno; /* original block number value */ |
| @@ -4603,22 +4601,44 @@ xfs_bmapi_write( | |||
| 4603 | bma.firstblock = firstblock; | 4601 | bma.firstblock = firstblock; |
| 4604 | 4602 | ||
| 4605 | while (bno < end && n < *nmap) { | 4603 | while (bno < end && n < *nmap) { |
| 4606 | inhole = eof || bma.got.br_startoff > bno; | 4604 | bool need_alloc = false, wasdelay = false; |
| 4607 | wasdelay = !inhole && isnullstartblock(bma.got.br_startblock); | ||
| 4608 | 4605 | ||
| 4609 | /* | 4606 | /* in hole or beyoned EOF? */ |
| 4610 | * Make sure we only reflink into a hole. | 4607 | if (eof || bma.got.br_startoff > bno) { |
| 4611 | */ | 4608 | if (flags & XFS_BMAPI_DELALLOC) { |
| 4612 | if (flags & XFS_BMAPI_REMAP) | 4609 | /* |
| 4613 | ASSERT(inhole); | 4610 | * For the COW fork we can reasonably get a |
| 4614 | if (flags & XFS_BMAPI_COWFORK) | 4611 | * request for converting an extent that races |
| 4615 | ASSERT(!inhole); | 4612 | * with other threads already having converted |
| 4613 | * part of it, as there converting COW to | ||
| 4614 | * regular blocks is not protected using the | ||
| 4615 | * IOLOCK. | ||
| 4616 | */ | ||
| 4617 | ASSERT(flags & XFS_BMAPI_COWFORK); | ||
| 4618 | if (!(flags & XFS_BMAPI_COWFORK)) { | ||
| 4619 | error = -EIO; | ||
| 4620 | goto error0; | ||
| 4621 | } | ||
| 4622 | |||
| 4623 | if (eof || bno >= end) | ||
| 4624 | break; | ||
| 4625 | } else { | ||
| 4626 | need_alloc = true; | ||
| 4627 | } | ||
| 4628 | } else { | ||
| 4629 | /* | ||
| 4630 | * Make sure we only reflink into a hole. | ||
| 4631 | */ | ||
| 4632 | ASSERT(!(flags & XFS_BMAPI_REMAP)); | ||
| 4633 | if (isnullstartblock(bma.got.br_startblock)) | ||
| 4634 | wasdelay = true; | ||
| 4635 | } | ||
| 4616 | 4636 | ||
| 4617 | /* | 4637 | /* |
| 4618 | * First, deal with the hole before the allocated space | 4638 | * First, deal with the hole before the allocated space |
| 4619 | * that we found, if any. | 4639 | * that we found, if any. |
| 4620 | */ | 4640 | */ |
| 4621 | if (inhole || wasdelay) { | 4641 | if (need_alloc || wasdelay) { |
| 4622 | bma.eof = eof; | 4642 | bma.eof = eof; |
| 4623 | bma.conv = !!(flags & XFS_BMAPI_CONVERT); | 4643 | bma.conv = !!(flags & XFS_BMAPI_CONVERT); |
| 4624 | bma.wasdel = wasdelay; | 4644 | bma.wasdel = wasdelay; |
