aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-09-25 22:52:02 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-10-05 18:23:57 -0400
commita7c2242166eb4b4447b0145705e4b66f5be89798 (patch)
treebba898ec9601dace788924ed1e59d693fb0be48e
parent523ac9afc73acdcf9f00bd35b6ffb4a7c624a7d7 (diff)
relay: simplify relay_file_read()
to hell with actors... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--kernel/relay.c78
1 files changed, 20 insertions, 58 deletions
diff --git a/kernel/relay.c b/kernel/relay.c
index d797502140b9..6fa398e90eb3 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -1121,51 +1121,23 @@ static size_t relay_file_read_end_pos(struct rchan_buf *buf,
1121 return end_pos; 1121 return end_pos;
1122} 1122}
1123 1123
1124/* 1124static ssize_t relay_file_read(struct file *filp,
1125 * subbuf_read_actor - read up to one subbuf's worth of data 1125 char __user *buffer,
1126 */ 1126 size_t count,
1127static int subbuf_read_actor(size_t read_start, 1127 loff_t *ppos)
1128 struct rchan_buf *buf,
1129 size_t avail,
1130 read_descriptor_t *desc)
1131{
1132 void *from;
1133 int ret = 0;
1134
1135 from = buf->start + read_start;
1136 ret = avail;
1137 if (copy_to_user(desc->arg.buf, from, avail)) {
1138 desc->error = -EFAULT;
1139 ret = 0;
1140 }
1141 desc->arg.data += ret;
1142 desc->written += ret;
1143 desc->count -= ret;
1144
1145 return ret;
1146}
1147
1148typedef int (*subbuf_actor_t) (size_t read_start,
1149 struct rchan_buf *buf,
1150 size_t avail,
1151 read_descriptor_t *desc);
1152
1153/*
1154 * relay_file_read_subbufs - read count bytes, bridging subbuf boundaries
1155 */
1156static ssize_t relay_file_read_subbufs(struct file *filp, loff_t *ppos,
1157 subbuf_actor_t subbuf_actor,
1158 read_descriptor_t *desc)
1159{ 1128{
1160 struct rchan_buf *buf = filp->private_data; 1129 struct rchan_buf *buf = filp->private_data;
1161 size_t read_start, avail; 1130 size_t read_start, avail;
1131 size_t written = 0;
1162 int ret; 1132 int ret;
1163 1133
1164 if (!desc->count) 1134 if (!count)
1165 return 0; 1135 return 0;
1166 1136
1167 inode_lock(file_inode(filp)); 1137 inode_lock(file_inode(filp));
1168 do { 1138 do {
1139 void *from;
1140
1169 if (!relay_file_read_avail(buf, *ppos)) 1141 if (!relay_file_read_avail(buf, *ppos))
1170 break; 1142 break;
1171 1143
@@ -1174,32 +1146,22 @@ static ssize_t relay_file_read_subbufs(struct file *filp, loff_t *ppos,
1174 if (!avail) 1146 if (!avail)
1175 break; 1147 break;
1176 1148
1177 avail = min(desc->count, avail); 1149 avail = min(count, avail);
1178 ret = subbuf_actor(read_start, buf, avail, desc); 1150 from = buf->start + read_start;
1179 if (desc->error < 0) 1151 ret = avail;
1152 if (copy_to_user(buffer, from, avail))
1180 break; 1153 break;
1181 1154
1182 if (ret) { 1155 buffer += ret;
1183 relay_file_read_consume(buf, read_start, ret); 1156 written += ret;
1184 *ppos = relay_file_read_end_pos(buf, read_start, ret); 1157 count -= ret;
1185 }
1186 } while (desc->count && ret);
1187 inode_unlock(file_inode(filp));
1188 1158
1189 return desc->written; 1159 relay_file_read_consume(buf, read_start, ret);
1190} 1160 *ppos = relay_file_read_end_pos(buf, read_start, ret);
1161 } while (count);
1162 inode_unlock(file_inode(filp));
1191 1163
1192static ssize_t relay_file_read(struct file *filp, 1164 return written;
1193 char __user *buffer,
1194 size_t count,
1195 loff_t *ppos)
1196{
1197 read_descriptor_t desc;
1198 desc.written = 0;
1199 desc.count = count;
1200 desc.arg.buf = buffer;
1201 desc.error = 0;
1202 return relay_file_read_subbufs(filp, ppos, subbuf_read_actor, &desc);
1203} 1165}
1204 1166
1205static void relay_consume_bytes(struct rchan_buf *rbuf, int bytes_consumed) 1167static void relay_consume_bytes(struct rchan_buf *rbuf, int bytes_consumed)