summaryrefslogtreecommitdiffstats
path: root/fs/aio.c
diff options
context:
space:
mode:
authorKent Overstreet <koverstreet@google.com>2013-05-09 18:03:42 -0400
committerBenjamin LaHaise <bcrl@kvack.org>2013-07-30 11:53:12 -0400
commit73a7075e3f6ec63dc359064eea6fd84f406cf2a5 (patch)
tree23a85d1f72746340b15636627a00f1e0346eb74b /fs/aio.c
parent5ffac122dbda89fbb29885f35a5d47b0edb8936d (diff)
aio: Kill aio_rw_vect_retry()
This code doesn't serve any purpose anymore, since the aio retry infrastructure has been removed. This change should be safe because aio_read/write are also used for synchronous IO, and called from do_sync_read()/do_sync_write() - and there's no looping done in the sync case (the read and write syscalls). Signed-off-by: Kent Overstreet <koverstreet@google.com> Cc: Zach Brown <zab@redhat.com> Cc: Felipe Balbi <balbi@ti.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Mark Fasheh <mfasheh@suse.com> Cc: Joel Becker <jlbec@evilplan.org> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Jens Axboe <axboe@kernel.dk> Cc: Asai Thambi S P <asamymuthupa@micron.com> Cc: Selvan Mani <smani@micron.com> Cc: Sam Bradshaw <sbradshaw@micron.com> Cc: Jeff Moyer <jmoyer@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Benjamin LaHaise <bcrl@kvack.org> Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>
Diffstat (limited to 'fs/aio.c')
-rw-r--r--fs/aio.c91
1 files changed, 18 insertions, 73 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 57b02791d04e..d00904db69b7 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -707,7 +707,7 @@ static inline struct kiocb *aio_get_req(struct kioctx *ctx)
707 if (unlikely(!req)) 707 if (unlikely(!req))
708 goto out_put; 708 goto out_put;
709 709
710 atomic_set(&req->ki_users, 2); 710 atomic_set(&req->ki_users, 1);
711 req->ki_ctx = ctx; 711 req->ki_ctx = ctx;
712 return req; 712 return req;
713out_put: 713out_put:
@@ -1051,75 +1051,9 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx)
1051 return -EINVAL; 1051 return -EINVAL;
1052} 1052}
1053 1053
1054static void aio_advance_iovec(struct kiocb *iocb, ssize_t ret)
1055{
1056 struct iovec *iov = &iocb->ki_iovec[iocb->ki_cur_seg];
1057
1058 BUG_ON(ret <= 0);
1059
1060 while (iocb->ki_cur_seg < iocb->ki_nr_segs && ret > 0) {
1061 ssize_t this = min((ssize_t)iov->iov_len, ret);
1062 iov->iov_base += this;
1063 iov->iov_len -= this;
1064 iocb->ki_left -= this;
1065 ret -= this;
1066 if (iov->iov_len == 0) {
1067 iocb->ki_cur_seg++;
1068 iov++;
1069 }
1070 }
1071
1072 /* the caller should not have done more io than what fit in
1073 * the remaining iovecs */
1074 BUG_ON(ret > 0 && iocb->ki_left == 0);
1075}
1076
1077typedef ssize_t (aio_rw_op)(struct kiocb *, const struct iovec *, 1054typedef ssize_t (aio_rw_op)(struct kiocb *, const struct iovec *,
1078 unsigned long, loff_t); 1055 unsigned long, loff_t);
1079 1056
1080static ssize_t aio_rw_vect_retry(struct kiocb *iocb, int rw, aio_rw_op *rw_op)
1081{
1082 struct file *file = iocb->ki_filp;
1083 struct address_space *mapping = file->f_mapping;
1084 struct inode *inode = mapping->host;
1085 ssize_t ret = 0;
1086
1087 /* This matches the pread()/pwrite() logic */
1088 if (iocb->ki_pos < 0)
1089 return -EINVAL;
1090
1091 if (rw == WRITE)
1092 file_start_write(file);
1093 do {
1094 ret = rw_op(iocb, &iocb->ki_iovec[iocb->ki_cur_seg],
1095 iocb->ki_nr_segs - iocb->ki_cur_seg,
1096 iocb->ki_pos);
1097 if (ret > 0)
1098 aio_advance_iovec(iocb, ret);
1099
1100 /* retry all partial writes. retry partial reads as long as its a
1101 * regular file. */
1102 } while (ret > 0 && iocb->ki_left > 0 &&
1103 (rw == WRITE ||
1104 (!S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode))));
1105 if (rw == WRITE)
1106 file_end_write(file);
1107
1108 /* This means we must have transferred all that we could */
1109 /* No need to retry anymore */
1110 if ((ret == 0) || (iocb->ki_left == 0))
1111 ret = iocb->ki_nbytes - iocb->ki_left;
1112
1113 /* If we managed to write some out we return that, rather than
1114 * the eventual error. */
1115 if (rw == WRITE
1116 && ret < 0 && ret != -EIOCBQUEUED
1117 && iocb->ki_nbytes - iocb->ki_left)
1118 ret = iocb->ki_nbytes - iocb->ki_left;
1119
1120 return ret;
1121}
1122
1123static ssize_t aio_setup_vectored_rw(int rw, struct kiocb *kiocb, bool compat) 1057static ssize_t aio_setup_vectored_rw(int rw, struct kiocb *kiocb, bool compat)
1124{ 1058{
1125 ssize_t ret; 1059 ssize_t ret;
@@ -1204,9 +1138,22 @@ rw_common:
1204 return ret; 1138 return ret;
1205 1139
1206 req->ki_nbytes = ret; 1140 req->ki_nbytes = ret;
1207 req->ki_left = ret;
1208 1141
1209 ret = aio_rw_vect_retry(req, rw, rw_op); 1142 /* XXX: move/kill - rw_verify_area()? */
1143 /* This matches the pread()/pwrite() logic */
1144 if (req->ki_pos < 0) {
1145 ret = -EINVAL;
1146 break;
1147 }
1148
1149 if (rw == WRITE)
1150 file_start_write(file);
1151
1152 ret = rw_op(req, req->ki_iovec,
1153 req->ki_nr_segs, req->ki_pos);
1154
1155 if (rw == WRITE)
1156 file_end_write(file);
1210 break; 1157 break;
1211 1158
1212 case IOCB_CMD_FDSYNC: 1159 case IOCB_CMD_FDSYNC:
@@ -1301,19 +1248,17 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
1301 req->ki_pos = iocb->aio_offset; 1248 req->ki_pos = iocb->aio_offset;
1302 1249
1303 req->ki_buf = (char __user *)(unsigned long)iocb->aio_buf; 1250 req->ki_buf = (char __user *)(unsigned long)iocb->aio_buf;
1304 req->ki_left = req->ki_nbytes = iocb->aio_nbytes; 1251 req->ki_nbytes = iocb->aio_nbytes;
1305 req->ki_opcode = iocb->aio_lio_opcode; 1252 req->ki_opcode = iocb->aio_lio_opcode;
1306 1253
1307 ret = aio_run_iocb(req, compat); 1254 ret = aio_run_iocb(req, compat);
1308 if (ret) 1255 if (ret)
1309 goto out_put_req; 1256 goto out_put_req;
1310 1257
1311 aio_put_req(req); /* drop extra ref to req */
1312 return 0; 1258 return 0;
1313out_put_req: 1259out_put_req:
1314 put_reqs_available(ctx, 1); 1260 put_reqs_available(ctx, 1);
1315 aio_put_req(req); /* drop extra ref to req */ 1261 aio_put_req(req);
1316 aio_put_req(req); /* drop i/o ref to req */
1317 return ret; 1262 return ret;
1318} 1263}
1319 1264