aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/android/logger.c2
-rw-r--r--drivers/usb/gadget/inode.c6
-rw-r--r--fs/aio.c91
-rw-r--r--fs/block_dev.c2
-rw-r--r--fs/nfs/direct.c1
-rw-r--r--fs/ocfs2/file.c6
-rw-r--r--fs/read_write.c3
-rw-r--r--fs/udf/file.c2
-rw-r--r--include/linux/aio.h2
-rw-r--r--mm/page_io.c1
-rw-r--r--net/socket.c2
11 files changed, 28 insertions, 90 deletions
diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c
index 080abf2faf97..d72b47195ecf 100644
--- a/drivers/staging/android/logger.c
+++ b/drivers/staging/android/logger.c
@@ -481,7 +481,7 @@ static ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov,
481 header.sec = now.tv_sec; 481 header.sec = now.tv_sec;
482 header.nsec = now.tv_nsec; 482 header.nsec = now.tv_nsec;
483 header.euid = current_euid(); 483 header.euid = current_euid();
484 header.len = min_t(size_t, iocb->ki_left, LOGGER_ENTRY_MAX_PAYLOAD); 484 header.len = min_t(size_t, iocb->ki_nbytes, LOGGER_ENTRY_MAX_PAYLOAD);
485 header.hdr_size = sizeof(struct logger_entry); 485 header.hdr_size = sizeof(struct logger_entry);
486 486
487 /* null writes succeed, return zero */ 487 /* null writes succeed, return zero */
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index e02c1e04529e..f255ad7f4c74 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -708,11 +708,11 @@ ep_aio_read(struct kiocb *iocb, const struct iovec *iov,
708 if (unlikely(usb_endpoint_dir_in(&epdata->desc))) 708 if (unlikely(usb_endpoint_dir_in(&epdata->desc)))
709 return -EINVAL; 709 return -EINVAL;
710 710
711 buf = kmalloc(iocb->ki_left, GFP_KERNEL); 711 buf = kmalloc(iocb->ki_nbytes, GFP_KERNEL);
712 if (unlikely(!buf)) 712 if (unlikely(!buf))
713 return -ENOMEM; 713 return -ENOMEM;
714 714
715 return ep_aio_rwtail(iocb, buf, iocb->ki_left, epdata, iov, nr_segs); 715 return ep_aio_rwtail(iocb, buf, iocb->ki_nbytes, epdata, iov, nr_segs);
716} 716}
717 717
718static ssize_t 718static ssize_t
@@ -727,7 +727,7 @@ ep_aio_write(struct kiocb *iocb, const struct iovec *iov,
727 if (unlikely(!usb_endpoint_dir_in(&epdata->desc))) 727 if (unlikely(!usb_endpoint_dir_in(&epdata->desc)))
728 return -EINVAL; 728 return -EINVAL;
729 729
730 buf = kmalloc(iocb->ki_left, GFP_KERNEL); 730 buf = kmalloc(iocb->ki_nbytes, GFP_KERNEL);
731 if (unlikely(!buf)) 731 if (unlikely(!buf))
732 return -ENOMEM; 732 return -ENOMEM;
733 733
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
diff --git a/fs/block_dev.c b/fs/block_dev.c
index c7bda5cd3da7..8772b155cb30 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1542,7 +1542,7 @@ static ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
1542 return 0; 1542 return 0;
1543 1543
1544 size -= pos; 1544 size -= pos;
1545 if (size < iocb->ki_left) 1545 if (size < iocb->ki_nbytes)
1546 nr_segs = iov_shorten((struct iovec *)iov, nr_segs, size); 1546 nr_segs = iov_shorten((struct iovec *)iov, nr_segs, size);
1547 return generic_file_aio_read(iocb, iov, nr_segs, pos); 1547 return generic_file_aio_read(iocb, iov, nr_segs, pos);
1548} 1548}
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 0bd7a55a5f07..91ff089d3412 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -130,7 +130,6 @@ ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_
130 130
131 return -EINVAL; 131 return -EINVAL;
132#else 132#else
133 VM_BUG_ON(iocb->ki_left != PAGE_SIZE);
134 VM_BUG_ON(iocb->ki_nbytes != PAGE_SIZE); 133 VM_BUG_ON(iocb->ki_nbytes != PAGE_SIZE);
135 134
136 if (rw == READ || rw == KERNEL_READ) 135 if (rw == READ || rw == KERNEL_READ)
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 41000f223ca4..dd1a4901a54b 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -2245,7 +2245,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
2245 file->f_path.dentry->d_name.name, 2245 file->f_path.dentry->d_name.name,
2246 (unsigned int)nr_segs); 2246 (unsigned int)nr_segs);
2247 2247
2248 if (iocb->ki_left == 0) 2248 if (iocb->ki_nbytes == 0)
2249 return 0; 2249 return 0;
2250 2250
2251 appending = file->f_flags & O_APPEND ? 1 : 0; 2251 appending = file->f_flags & O_APPEND ? 1 : 0;
@@ -2296,7 +2296,7 @@ relock:
2296 2296
2297 can_do_direct = direct_io; 2297 can_do_direct = direct_io;
2298 ret = ocfs2_prepare_inode_for_write(file, ppos, 2298 ret = ocfs2_prepare_inode_for_write(file, ppos,
2299 iocb->ki_left, appending, 2299 iocb->ki_nbytes, appending,
2300 &can_do_direct, &has_refcount); 2300 &can_do_direct, &has_refcount);
2301 if (ret < 0) { 2301 if (ret < 0) {
2302 mlog_errno(ret); 2302 mlog_errno(ret);
@@ -2304,7 +2304,7 @@ relock:
2304 } 2304 }
2305 2305
2306 if (direct_io && !is_sync_kiocb(iocb)) 2306 if (direct_io && !is_sync_kiocb(iocb))
2307 unaligned_dio = ocfs2_is_io_unaligned(inode, iocb->ki_left, 2307 unaligned_dio = ocfs2_is_io_unaligned(inode, iocb->ki_nbytes,
2308 *ppos); 2308 *ppos);
2309 2309
2310 /* 2310 /*
diff --git a/fs/read_write.c b/fs/read_write.c
index 122a3846d9e1..e3cd280b158c 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -367,7 +367,6 @@ ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *pp
367 367
368 init_sync_kiocb(&kiocb, filp); 368 init_sync_kiocb(&kiocb, filp);
369 kiocb.ki_pos = *ppos; 369 kiocb.ki_pos = *ppos;
370 kiocb.ki_left = len;
371 kiocb.ki_nbytes = len; 370 kiocb.ki_nbytes = len;
372 371
373 ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos); 372 ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
@@ -417,7 +416,6 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof
417 416
418 init_sync_kiocb(&kiocb, filp); 417 init_sync_kiocb(&kiocb, filp);
419 kiocb.ki_pos = *ppos; 418 kiocb.ki_pos = *ppos;
420 kiocb.ki_left = len;
421 kiocb.ki_nbytes = len; 419 kiocb.ki_nbytes = len;
422 420
423 ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); 421 ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
@@ -599,7 +597,6 @@ static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
599 597
600 init_sync_kiocb(&kiocb, filp); 598 init_sync_kiocb(&kiocb, filp);
601 kiocb.ki_pos = *ppos; 599 kiocb.ki_pos = *ppos;
602 kiocb.ki_left = len;
603 kiocb.ki_nbytes = len; 600 kiocb.ki_nbytes = len;
604 601
605 ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos); 602 ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 29569dd08168..c02a27a19c6d 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -141,7 +141,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
141 struct file *file = iocb->ki_filp; 141 struct file *file = iocb->ki_filp;
142 struct inode *inode = file_inode(file); 142 struct inode *inode = file_inode(file);
143 int err, pos; 143 int err, pos;
144 size_t count = iocb->ki_left; 144 size_t count = iocb->ki_nbytes;
145 struct udf_inode_info *iinfo = UDF_I(inode); 145 struct udf_inode_info *iinfo = UDF_I(inode);
146 146
147 down_write(&iinfo->i_data_sem); 147 down_write(&iinfo->i_data_sem);
diff --git a/include/linux/aio.h b/include/linux/aio.h
index 8c8dd1d84d2e..7bb766e73968 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -50,11 +50,9 @@ struct kiocb {
50 unsigned short ki_opcode; 50 unsigned short ki_opcode;
51 size_t ki_nbytes; /* copy of iocb->aio_nbytes */ 51 size_t ki_nbytes; /* copy of iocb->aio_nbytes */
52 char __user *ki_buf; /* remaining iocb->aio_buf */ 52 char __user *ki_buf; /* remaining iocb->aio_buf */
53 size_t ki_left; /* remaining bytes */
54 struct iovec ki_inline_vec; /* inline vector */ 53 struct iovec ki_inline_vec; /* inline vector */
55 struct iovec *ki_iovec; 54 struct iovec *ki_iovec;
56 unsigned long ki_nr_segs; 55 unsigned long ki_nr_segs;
57 unsigned long ki_cur_seg;
58 56
59 struct list_head ki_list; /* the aio core uses this 57 struct list_head ki_list; /* the aio core uses this
60 * for cancellation */ 58 * for cancellation */
diff --git a/mm/page_io.c b/mm/page_io.c
index ba05b64e5d8d..8c79a4764be0 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -266,7 +266,6 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,
266 266
267 init_sync_kiocb(&kiocb, swap_file); 267 init_sync_kiocb(&kiocb, swap_file);
268 kiocb.ki_pos = page_file_offset(page); 268 kiocb.ki_pos = page_file_offset(page);
269 kiocb.ki_left = PAGE_SIZE;
270 kiocb.ki_nbytes = PAGE_SIZE; 269 kiocb.ki_nbytes = PAGE_SIZE;
271 270
272 set_page_writeback(page); 271 set_page_writeback(page);
diff --git a/net/socket.c b/net/socket.c
index 829b460acb87..fea902f2ba58 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -931,7 +931,7 @@ static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
931 if (pos != 0) 931 if (pos != 0)
932 return -ESPIPE; 932 return -ESPIPE;
933 933
934 if (iocb->ki_left == 0) /* Match SYS5 behaviour */ 934 if (iocb->ki_nbytes == 0) /* Match SYS5 behaviour */
935 return 0; 935 return 0;
936 936
937 937