diff options
author | Minchan Kim <minchan@kernel.org> | 2017-09-06 19:20:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-06 20:27:25 -0400 |
commit | ae85a8075c5b025b9d503554ddc480a346a24536 (patch) | |
tree | 633d5dda845b81d541008af1633412af06242deb /drivers/block/zram | |
parent | 1363d4662a0d28dfdb81ef426c88c9a8dbf7c338 (diff) |
zram: identify asynchronous IO's return value
For upcoming asynchronous IO like writeback, zram_rw_page should be
aware of that whether requested IO was completed or submitted
successfully, otherwise error.
For the goal, zram_bvec_rw has three return values.
-errno: returns error number
0: IO request is done synchronously
1: IO request is issued successfully.
Link: http://lkml.kernel.org/r/1498459987-24562-7-git-send-email-minchan@kernel.org
Signed-off-by: Minchan Kim <minchan@kernel.org>
Cc: Juneho Choi <juno.choi@lge.com>
Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/block/zram')
-rw-r--r-- | drivers/block/zram/zram_drv.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index fcdbbb1e7745..8975f75f113d 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c | |||
@@ -772,7 +772,7 @@ out: | |||
772 | 772 | ||
773 | static int __zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index) | 773 | static int __zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index) |
774 | { | 774 | { |
775 | int ret; | 775 | int ret = 0; |
776 | unsigned long alloced_pages; | 776 | unsigned long alloced_pages; |
777 | unsigned long handle = 0; | 777 | unsigned long handle = 0; |
778 | unsigned int comp_len = 0; | 778 | unsigned int comp_len = 0; |
@@ -877,7 +877,7 @@ out: | |||
877 | 877 | ||
878 | /* Update stats */ | 878 | /* Update stats */ |
879 | atomic64_inc(&zram->stats.pages_stored); | 879 | atomic64_inc(&zram->stats.pages_stored); |
880 | return 0; | 880 | return ret; |
881 | } | 881 | } |
882 | 882 | ||
883 | static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, | 883 | static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, |
@@ -959,6 +959,11 @@ static void zram_bio_discard(struct zram *zram, u32 index, | |||
959 | } | 959 | } |
960 | } | 960 | } |
961 | 961 | ||
962 | /* | ||
963 | * Returns errno if it has some problem. Otherwise return 0 or 1. | ||
964 | * Returns 0 if IO request was done synchronously | ||
965 | * Returns 1 if IO request was successfully submitted. | ||
966 | */ | ||
962 | static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index, | 967 | static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index, |
963 | int offset, bool is_write) | 968 | int offset, bool is_write) |
964 | { | 969 | { |
@@ -980,7 +985,7 @@ static int zram_bvec_rw(struct zram *zram, struct bio_vec *bvec, u32 index, | |||
980 | 985 | ||
981 | generic_end_io_acct(rw_acct, &zram->disk->part0, start_time); | 986 | generic_end_io_acct(rw_acct, &zram->disk->part0, start_time); |
982 | 987 | ||
983 | if (unlikely(ret)) { | 988 | if (unlikely(ret < 0)) { |
984 | if (!is_write) | 989 | if (!is_write) |
985 | atomic64_inc(&zram->stats.failed_reads); | 990 | atomic64_inc(&zram->stats.failed_reads); |
986 | else | 991 | else |
@@ -1073,7 +1078,7 @@ static void zram_slot_free_notify(struct block_device *bdev, | |||
1073 | static int zram_rw_page(struct block_device *bdev, sector_t sector, | 1078 | static int zram_rw_page(struct block_device *bdev, sector_t sector, |
1074 | struct page *page, bool is_write) | 1079 | struct page *page, bool is_write) |
1075 | { | 1080 | { |
1076 | int offset, err = -EIO; | 1081 | int offset, ret; |
1077 | u32 index; | 1082 | u32 index; |
1078 | struct zram *zram; | 1083 | struct zram *zram; |
1079 | struct bio_vec bv; | 1084 | struct bio_vec bv; |
@@ -1082,7 +1087,7 @@ static int zram_rw_page(struct block_device *bdev, sector_t sector, | |||
1082 | 1087 | ||
1083 | if (!valid_io_request(zram, sector, PAGE_SIZE)) { | 1088 | if (!valid_io_request(zram, sector, PAGE_SIZE)) { |
1084 | atomic64_inc(&zram->stats.invalid_io); | 1089 | atomic64_inc(&zram->stats.invalid_io); |
1085 | err = -EINVAL; | 1090 | ret = -EINVAL; |
1086 | goto out; | 1091 | goto out; |
1087 | } | 1092 | } |
1088 | 1093 | ||
@@ -1093,7 +1098,7 @@ static int zram_rw_page(struct block_device *bdev, sector_t sector, | |||
1093 | bv.bv_len = PAGE_SIZE; | 1098 | bv.bv_len = PAGE_SIZE; |
1094 | bv.bv_offset = 0; | 1099 | bv.bv_offset = 0; |
1095 | 1100 | ||
1096 | err = zram_bvec_rw(zram, &bv, index, offset, is_write); | 1101 | ret = zram_bvec_rw(zram, &bv, index, offset, is_write); |
1097 | out: | 1102 | out: |
1098 | /* | 1103 | /* |
1099 | * If I/O fails, just return error(ie, non-zero) without | 1104 | * If I/O fails, just return error(ie, non-zero) without |
@@ -1103,9 +1108,20 @@ out: | |||
1103 | * bio->bi_end_io does things to handle the error | 1108 | * bio->bi_end_io does things to handle the error |
1104 | * (e.g., SetPageError, set_page_dirty and extra works). | 1109 | * (e.g., SetPageError, set_page_dirty and extra works). |
1105 | */ | 1110 | */ |
1106 | if (err == 0) | 1111 | if (unlikely(ret < 0)) |
1112 | return ret; | ||
1113 | |||
1114 | switch (ret) { | ||
1115 | case 0: | ||
1107 | page_endio(page, is_write, 0); | 1116 | page_endio(page, is_write, 0); |
1108 | return err; | 1117 | break; |
1118 | case 1: | ||
1119 | ret = 0; | ||
1120 | break; | ||
1121 | default: | ||
1122 | WARN_ON(1); | ||
1123 | } | ||
1124 | return ret; | ||
1109 | } | 1125 | } |
1110 | 1126 | ||
1111 | static void zram_reset_device(struct zram *zram) | 1127 | static void zram_reset_device(struct zram *zram) |