diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-14 13:14:59 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-14 13:14:59 -0500 |
commit | 6556677a80400ca5744340d8ff6fbed22621293e (patch) | |
tree | bca737a2d803b775016daf8996548d1cedc9e020 | |
parent | 694a20dae6efc3803740971fa9f7c86b8c8d4685 (diff) | |
parent | 49edd5bf429c405b3a7f75503845d9f66a47dd4b (diff) |
Merge tag 'gfs2-4.16.rc1.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull gfs2 fix from Bob Peterson:
"Fix regressions in the gfs2 iomap for block_map implementation we
recently discovered in commit 3974320ca6"
* tag 'gfs2-4.16.rc1.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2:
gfs2: Fixes to "Implement iomap for block_map"
-rw-r--r-- | fs/gfs2/bmap.c | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 86863792f36a..86d6a4435c87 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -716,7 +716,7 @@ int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length, | |||
716 | __be64 *ptr; | 716 | __be64 *ptr; |
717 | sector_t lblock; | 717 | sector_t lblock; |
718 | sector_t lend; | 718 | sector_t lend; |
719 | int ret; | 719 | int ret = 0; |
720 | int eob; | 720 | int eob; |
721 | unsigned int len; | 721 | unsigned int len; |
722 | struct buffer_head *bh; | 722 | struct buffer_head *bh; |
@@ -728,12 +728,14 @@ int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length, | |||
728 | goto out; | 728 | goto out; |
729 | } | 729 | } |
730 | 730 | ||
731 | if ((flags & IOMAP_REPORT) && gfs2_is_stuffed(ip)) { | 731 | if (gfs2_is_stuffed(ip)) { |
732 | gfs2_stuffed_iomap(inode, iomap); | 732 | if (flags & IOMAP_REPORT) { |
733 | if (pos >= iomap->length) | 733 | gfs2_stuffed_iomap(inode, iomap); |
734 | return -ENOENT; | 734 | if (pos >= iomap->length) |
735 | ret = 0; | 735 | ret = -ENOENT; |
736 | goto out; | 736 | goto out; |
737 | } | ||
738 | BUG_ON(!(flags & IOMAP_WRITE)); | ||
737 | } | 739 | } |
738 | 740 | ||
739 | lblock = pos >> inode->i_blkbits; | 741 | lblock = pos >> inode->i_blkbits; |
@@ -744,7 +746,7 @@ int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length, | |||
744 | iomap->type = IOMAP_HOLE; | 746 | iomap->type = IOMAP_HOLE; |
745 | iomap->length = (u64)(lend - lblock) << inode->i_blkbits; | 747 | iomap->length = (u64)(lend - lblock) << inode->i_blkbits; |
746 | iomap->flags = IOMAP_F_MERGED; | 748 | iomap->flags = IOMAP_F_MERGED; |
747 | bmap_lock(ip, 0); | 749 | bmap_lock(ip, flags & IOMAP_WRITE); |
748 | 750 | ||
749 | /* | 751 | /* |
750 | * Directory data blocks have a struct gfs2_meta_header header, so the | 752 | * Directory data blocks have a struct gfs2_meta_header header, so the |
@@ -787,27 +789,28 @@ int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length, | |||
787 | iomap->flags |= IOMAP_F_BOUNDARY; | 789 | iomap->flags |= IOMAP_F_BOUNDARY; |
788 | iomap->length = (u64)len << inode->i_blkbits; | 790 | iomap->length = (u64)len << inode->i_blkbits; |
789 | 791 | ||
790 | ret = 0; | ||
791 | |||
792 | out_release: | 792 | out_release: |
793 | release_metapath(&mp); | 793 | release_metapath(&mp); |
794 | bmap_unlock(ip, 0); | 794 | bmap_unlock(ip, flags & IOMAP_WRITE); |
795 | out: | 795 | out: |
796 | trace_gfs2_iomap_end(ip, iomap, ret); | 796 | trace_gfs2_iomap_end(ip, iomap, ret); |
797 | return ret; | 797 | return ret; |
798 | 798 | ||
799 | do_alloc: | 799 | do_alloc: |
800 | if (!(flags & IOMAP_WRITE)) { | 800 | if (flags & IOMAP_WRITE) { |
801 | if (pos >= i_size_read(inode)) { | 801 | ret = gfs2_iomap_alloc(inode, iomap, flags, &mp); |
802 | } else if (flags & IOMAP_REPORT) { | ||
803 | loff_t size = i_size_read(inode); | ||
804 | if (pos >= size) | ||
802 | ret = -ENOENT; | 805 | ret = -ENOENT; |
803 | goto out_release; | 806 | else if (height <= ip->i_height) |
804 | } | 807 | iomap->length = hole_size(inode, lblock, &mp); |
805 | ret = 0; | 808 | else |
806 | iomap->length = hole_size(inode, lblock, &mp); | 809 | iomap->length = size - pos; |
807 | goto out_release; | 810 | } else { |
811 | if (height <= ip->i_height) | ||
812 | iomap->length = hole_size(inode, lblock, &mp); | ||
808 | } | 813 | } |
809 | |||
810 | ret = gfs2_iomap_alloc(inode, iomap, flags, &mp); | ||
811 | goto out_release; | 814 | goto out_release; |
812 | } | 815 | } |
813 | 816 | ||