aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/data.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/f2fs/data.c')
-rw-r--r--fs/f2fs/data.c80
1 files changed, 27 insertions, 53 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 5c43b2d606ec..d67c599510d9 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -783,7 +783,6 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
783 loff_t isize = i_size_read(inode); 783 loff_t isize = i_size_read(inode);
784 u64 logical = 0, phys = 0, size = 0; 784 u64 logical = 0, phys = 0, size = 0;
785 u32 flags = 0; 785 u32 flags = 0;
786 bool past_eof = false, whole_file = false;
787 int ret = 0; 786 int ret = 0;
788 787
789 ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC); 788 ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC);
@@ -797,17 +796,18 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
797 } 796 }
798 797
799 mutex_lock(&inode->i_mutex); 798 mutex_lock(&inode->i_mutex);
799 if (start >= isize)
800 goto out;
800 801
801 if (len >= isize) { 802 if (start + len > isize)
802 whole_file = true; 803 len = isize - start;
803 len = isize;
804 }
805 804
806 if (logical_to_blk(inode, len) == 0) 805 if (logical_to_blk(inode, len) == 0)
807 len = blk_to_logical(inode, 1); 806 len = blk_to_logical(inode, 1);
808 807
809 start_blk = logical_to_blk(inode, start); 808 start_blk = logical_to_blk(inode, start);
810 last_blk = logical_to_blk(inode, start + len - 1); 809 last_blk = logical_to_blk(inode, start + len - 1);
810
811next: 811next:
812 memset(&map_bh, 0, sizeof(struct buffer_head)); 812 memset(&map_bh, 0, sizeof(struct buffer_head));
813 map_bh.b_size = len; 813 map_bh.b_size = len;
@@ -819,59 +819,33 @@ next:
819 819
820 /* HOLE */ 820 /* HOLE */
821 if (!buffer_mapped(&map_bh)) { 821 if (!buffer_mapped(&map_bh)) {
822 start_blk++; 822 /* Go through holes util pass the EOF */
823 823 if (blk_to_logical(inode, start_blk++) < isize)
824 if (!past_eof && blk_to_logical(inode, start_blk) >= isize) 824 goto prep_next;
825 past_eof = 1; 825 /* Found a hole beyond isize means no more extents.
826 826 * Note that the premise is that filesystems don't
827 if (past_eof && size) { 827 * punch holes beyond isize and keep size unchanged.
828 flags |= FIEMAP_EXTENT_LAST; 828 */
829 ret = fiemap_fill_next_extent(fieinfo, logical, 829 flags |= FIEMAP_EXTENT_LAST;
830 phys, size, flags); 830 }
831 } else if (size) {
832 ret = fiemap_fill_next_extent(fieinfo, logical,
833 phys, size, flags);
834 size = 0;
835 }
836 831
837 /* if we have holes up to/past EOF then we're done */ 832 if (size)
838 if (start_blk > last_blk || past_eof || ret) 833 ret = fiemap_fill_next_extent(fieinfo, logical,
839 goto out; 834 phys, size, flags);
840 } else {
841 if (start_blk > last_blk && !whole_file) {
842 ret = fiemap_fill_next_extent(fieinfo, logical,
843 phys, size, flags);
844 goto out;
845 }
846 835
847 /* 836 if (start_blk > last_blk || ret)
848 * if size != 0 then we know we already have an extent 837 goto out;
849 * to add, so add it.
850 */
851 if (size) {
852 ret = fiemap_fill_next_extent(fieinfo, logical,
853 phys, size, flags);
854 if (ret)
855 goto out;
856 }
857 838
858 logical = blk_to_logical(inode, start_blk); 839 logical = blk_to_logical(inode, start_blk);
859 phys = blk_to_logical(inode, map_bh.b_blocknr); 840 phys = blk_to_logical(inode, map_bh.b_blocknr);
860 size = map_bh.b_size; 841 size = map_bh.b_size;
861 flags = 0; 842 flags = 0;
862 if (buffer_unwritten(&map_bh)) 843 if (buffer_unwritten(&map_bh))
863 flags = FIEMAP_EXTENT_UNWRITTEN; 844 flags = FIEMAP_EXTENT_UNWRITTEN;
864 845
865 start_blk += logical_to_blk(inode, size); 846 start_blk += logical_to_blk(inode, size);
866 847
867 /* 848prep_next:
868 * If we are past the EOF, then we need to make sure as
869 * soon as we find a hole that the last extent we found
870 * is marked with FIEMAP_EXTENT_LAST
871 */
872 if (!past_eof && logical + size >= isize)
873 past_eof = true;
874 }
875 cond_resched(); 849 cond_resched();
876 if (fatal_signal_pending(current)) 850 if (fatal_signal_pending(current))
877 ret = -EINTR; 851 ret = -EINTR;