diff options
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_aops.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_aops.c | 91 |
1 files changed, 34 insertions, 57 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 64c909e5c1e5..98d26c8e0565 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -806,7 +806,8 @@ xfs_page_state_convert( | |||
806 | unsigned int type; | 806 | unsigned int type; |
807 | __uint64_t end_offset; | 807 | __uint64_t end_offset; |
808 | pgoff_t end_index, last_index, tlast; | 808 | pgoff_t end_index, last_index, tlast; |
809 | int flags, len, err, iomap_valid = 0, uptodate = 1; | 809 | ssize_t size, len; |
810 | int flags, err, iomap_valid = 0, uptodate = 1; | ||
810 | int page_dirty, count = 0, trylock_flag = 0; | 811 | int page_dirty, count = 0, trylock_flag = 0; |
811 | 812 | ||
812 | /* wait for other IO threads? */ | 813 | /* wait for other IO threads? */ |
@@ -875,21 +876,36 @@ xfs_page_state_convert( | |||
875 | * | 876 | * |
876 | * Second case, allocate space for a delalloc buffer. | 877 | * Second case, allocate space for a delalloc buffer. |
877 | * We can return EAGAIN here in the release page case. | 878 | * We can return EAGAIN here in the release page case. |
878 | */ | 879 | * |
879 | if (buffer_unwritten(bh) || buffer_delay(bh)) { | 880 | * Third case, an unmapped buffer was found, and we are |
881 | * in a path where we need to write the whole page out. | ||
882 | */ | ||
883 | if (buffer_unwritten(bh) || buffer_delay(bh) || | ||
884 | ((buffer_uptodate(bh) || PageUptodate(page)) && | ||
885 | !buffer_mapped(bh) && (unmapped || startio))) { | ||
880 | if (buffer_unwritten(bh)) { | 886 | if (buffer_unwritten(bh)) { |
881 | type = IOMAP_UNWRITTEN; | 887 | type = IOMAP_UNWRITTEN; |
882 | flags = BMAPI_WRITE|BMAPI_IGNSTATE; | 888 | flags = BMAPI_WRITE|BMAPI_IGNSTATE; |
883 | } else { | 889 | } else if (buffer_delay(bh)) { |
884 | type = IOMAP_DELAY; | 890 | type = IOMAP_DELAY; |
885 | flags = BMAPI_ALLOCATE; | 891 | flags = BMAPI_ALLOCATE; |
886 | if (!startio) | 892 | if (!startio) |
887 | flags |= trylock_flag; | 893 | flags |= trylock_flag; |
894 | } else { | ||
895 | type = 0; | ||
896 | flags = BMAPI_WRITE|BMAPI_MMAP; | ||
888 | } | 897 | } |
889 | 898 | ||
890 | if (!iomap_valid) { | 899 | if (!iomap_valid) { |
891 | err = xfs_map_blocks(inode, offset, len, &iomap, | 900 | if (type == 0) { |
892 | flags); | 901 | size = xfs_probe_unmapped_cluster(inode, |
902 | page, bh, head); | ||
903 | } else { | ||
904 | size = len; | ||
905 | } | ||
906 | |||
907 | err = xfs_map_blocks(inode, offset, size, | ||
908 | &iomap, flags); | ||
893 | if (err) | 909 | if (err) |
894 | goto error; | 910 | goto error; |
895 | iomap_valid = xfs_iomap_valid(&iomap, offset); | 911 | iomap_valid = xfs_iomap_valid(&iomap, offset); |
@@ -909,61 +925,22 @@ xfs_page_state_convert( | |||
909 | page_dirty--; | 925 | page_dirty--; |
910 | count++; | 926 | count++; |
911 | } | 927 | } |
912 | } else if ((buffer_uptodate(bh) || PageUptodate(page)) && | 928 | } else if (buffer_uptodate(bh) && startio) { |
913 | (unmapped || startio)) { | ||
914 | |||
915 | type = 0; | 929 | type = 0; |
916 | if (!buffer_mapped(bh)) { | 930 | |
917 | 931 | if (!test_and_set_bit(BH_Lock, &bh->b_state)) { | |
918 | /* | 932 | ASSERT(buffer_mapped(bh)); |
919 | * Getting here implies an unmapped buffer | 933 | xfs_add_to_ioend(inode, |
920 | * was found, and we are in a path where we | 934 | bh, p_offset, type, |
921 | * need to write the whole page out. | 935 | &ioend, !iomap_valid); |
922 | */ | 936 | page_dirty--; |
923 | if (!iomap_valid) { | 937 | count++; |
924 | int size; | ||
925 | |||
926 | size = xfs_probe_unmapped_cluster( | ||
927 | inode, page, bh, head); | ||
928 | err = xfs_map_blocks(inode, offset, | ||
929 | size, &iomap, | ||
930 | BMAPI_WRITE|BMAPI_MMAP); | ||
931 | if (err) | ||
932 | goto error; | ||
933 | iomap_valid = xfs_iomap_valid(&iomap, | ||
934 | offset); | ||
935 | } | ||
936 | if (iomap_valid) { | ||
937 | xfs_map_at_offset(bh, offset, | ||
938 | inode->i_blkbits, | ||
939 | &iomap); | ||
940 | if (startio) { | ||
941 | xfs_add_to_ioend(inode, | ||
942 | bh, p_offset, type, | ||
943 | &ioend, !iomap_valid); | ||
944 | } else { | ||
945 | set_buffer_dirty(bh); | ||
946 | unlock_buffer(bh); | ||
947 | mark_buffer_dirty(bh); | ||
948 | } | ||
949 | page_dirty--; | ||
950 | count++; | ||
951 | } | ||
952 | } else if (startio) { | ||
953 | if (buffer_uptodate(bh) && | ||
954 | !test_and_set_bit(BH_Lock, &bh->b_state)) { | ||
955 | ASSERT(buffer_mapped(bh)); | ||
956 | xfs_add_to_ioend(inode, | ||
957 | bh, p_offset, type, | ||
958 | &ioend, !iomap_valid); | ||
959 | page_dirty--; | ||
960 | count++; | ||
961 | } else { | ||
962 | iomap_valid = 0; | ||
963 | } | ||
964 | } else { | 938 | } else { |
965 | iomap_valid = 0; | 939 | iomap_valid = 0; |
966 | } | 940 | } |
941 | } else if ((buffer_uptodate(bh) || PageUptodate(page)) && | ||
942 | (unmapped || startio)) { | ||
943 | iomap_valid = 0; | ||
967 | } | 944 | } |
968 | 945 | ||
969 | if (!iohead) | 946 | if (!iohead) |