aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-04-04 12:15:19 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-05-06 17:39:44 -0400
commitb42b15fdad3ebb790250041d1517acebb9bd56d9 (patch)
treedd273391e1cf117a0e5356c3b84aac6c5549deae
parent4908b822b300d2d7ad0341203181cfbd8a91092a (diff)
lustre: get rid of messing with iovecs
* switch to ->read_iter/->write_iter * keep a pointer to iov_iter instead of iov/nr_segs * do not modify iovecs; use iov_iter_truncate()/iov_iter_advance() and a new primitive - iov_iter_reexpand() (expand previously truncated iterator) istead. * (racy) check for lustre VMAs intersecting with iovecs kept for now as for_each_iov() loop. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--drivers/staging/lustre/lustre/include/lclient.h11
-rw-r--r--drivers/staging/lustre/lustre/lclient/lcommon_cl.c48
-rw-r--r--drivers/staging/lustre/lustre/llite/file.c106
-rw-r--r--drivers/staging/lustre/lustre/llite/llite_internal.h3
-rw-r--r--drivers/staging/lustre/lustre/llite/rw.c3
-rw-r--r--drivers/staging/lustre/lustre/llite/vvp_io.c29
-rw-r--r--include/linux/uio.h9
7 files changed, 46 insertions, 163 deletions
diff --git a/drivers/staging/lustre/lustre/include/lclient.h b/drivers/staging/lustre/lustre/include/lclient.h
index 827209ea6bd0..386a36c00f57 100644
--- a/drivers/staging/lustre/lustre/include/lclient.h
+++ b/drivers/staging/lustre/lustre/include/lclient.h
@@ -82,16 +82,7 @@ struct ccc_io {
82 /** 82 /**
83 * I/O vector information to or from which read/write is going. 83 * I/O vector information to or from which read/write is going.
84 */ 84 */
85 struct iovec *cui_iov; 85 struct iov_iter *cui_iter;
86 unsigned long cui_nrsegs;
87 /**
88 * Total iov count for left IO.
89 */
90 unsigned long cui_tot_nrsegs;
91 /**
92 * Old length for iov that was truncated partially.
93 */
94 size_t cui_iov_olen;
95 /** 86 /**
96 * Total size for the left IO. 87 * Total size for the left IO.
97 */ 88 */
diff --git a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c
index 6907a16dbbd1..a07d5156bc50 100644
--- a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c
+++ b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c
@@ -721,31 +721,12 @@ int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io,
721void ccc_io_update_iov(const struct lu_env *env, 721void ccc_io_update_iov(const struct lu_env *env,
722 struct ccc_io *cio, struct cl_io *io) 722 struct ccc_io *cio, struct cl_io *io)
723{ 723{
724 int i;
725 size_t size = io->u.ci_rw.crw_count; 724 size_t size = io->u.ci_rw.crw_count;
726 725
727 cio->cui_iov_olen = 0; 726 if (!cl_is_normalio(env, io) || cio->cui_iter == NULL)
728 if (!cl_is_normalio(env, io) || cio->cui_tot_nrsegs == 0)
729 return; 727 return;
730 728
731 for (i = 0; i < cio->cui_tot_nrsegs; i++) { 729 iov_iter_truncate(cio->cui_iter, size);
732 struct iovec *iv = &cio->cui_iov[i];
733
734 if (iv->iov_len < size)
735 size -= iv->iov_len;
736 else {
737 if (iv->iov_len > size) {
738 cio->cui_iov_olen = iv->iov_len;
739 iv->iov_len = size;
740 }
741 break;
742 }
743 }
744
745 cio->cui_nrsegs = i + 1;
746 LASSERTF(cio->cui_tot_nrsegs >= cio->cui_nrsegs,
747 "tot_nrsegs: %lu, nrsegs: %lu\n",
748 cio->cui_tot_nrsegs, cio->cui_nrsegs);
749} 730}
750 731
751int ccc_io_one_lock(const struct lu_env *env, struct cl_io *io, 732int ccc_io_one_lock(const struct lu_env *env, struct cl_io *io,
@@ -776,30 +757,7 @@ void ccc_io_advance(const struct lu_env *env,
776 if (!cl_is_normalio(env, io)) 757 if (!cl_is_normalio(env, io))
777 return; 758 return;
778 759
779 LASSERT(cio->cui_tot_nrsegs >= cio->cui_nrsegs); 760 iov_iter_reexpand(cio->cui_iter, cio->cui_tot_count -= nob);
780 LASSERT(cio->cui_tot_count >= nob);
781
782 cio->cui_iov += cio->cui_nrsegs;
783 cio->cui_tot_nrsegs -= cio->cui_nrsegs;
784 cio->cui_tot_count -= nob;
785
786 /* update the iov */
787 if (cio->cui_iov_olen > 0) {
788 struct iovec *iv;
789
790 cio->cui_iov--;
791 cio->cui_tot_nrsegs++;
792 iv = &cio->cui_iov[0];
793 if (io->ci_continue) {
794 iv->iov_base += iv->iov_len;
795 LASSERT(cio->cui_iov_olen > iv->iov_len);
796 iv->iov_len = cio->cui_iov_olen - iv->iov_len;
797 } else {
798 /* restore the iov_len, in case of restart io. */
799 iv->iov_len = cio->cui_iov_olen;
800 }
801 cio->cui_iov_olen = 0;
802 }
803} 761}
804 762
805/** 763/**
diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c
index 220bd8390a84..3efda2540d29 100644
--- a/drivers/staging/lustre/lustre/llite/file.c
+++ b/drivers/staging/lustre/lustre/llite/file.c
@@ -1105,9 +1105,7 @@ restart:
1105 1105
1106 switch (vio->cui_io_subtype) { 1106 switch (vio->cui_io_subtype) {
1107 case IO_NORMAL: 1107 case IO_NORMAL:
1108 cio->cui_iov = args->u.normal.via_iov; 1108 cio->cui_iter = args->u.normal.via_iter;
1109 cio->cui_nrsegs = args->u.normal.via_nrsegs;
1110 cio->cui_tot_nrsegs = cio->cui_nrsegs;
1111 cio->cui_iocb = args->u.normal.via_iocb; 1109 cio->cui_iocb = args->u.normal.via_iocb;
1112 if ((iot == CIT_WRITE) && 1110 if ((iot == CIT_WRITE) &&
1113 !(cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) { 1111 !(cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
@@ -1171,56 +1169,23 @@ out:
1171 return result; 1169 return result;
1172} 1170}
1173 1171
1174static ssize_t ll_file_aio_read(struct kiocb *iocb, const struct iovec *iov, 1172static ssize_t ll_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
1175 unsigned long nr_segs, loff_t pos)
1176{ 1173{
1177 struct lu_env *env; 1174 struct lu_env *env;
1178 struct vvp_io_args *args; 1175 struct vvp_io_args *args;
1179 size_t count = 0;
1180 ssize_t result; 1176 ssize_t result;
1181 int refcheck; 1177 int refcheck;
1182 1178
1183 count = iov_length(iov, nr_segs);
1184
1185 env = cl_env_get(&refcheck); 1179 env = cl_env_get(&refcheck);
1186 if (IS_ERR(env)) 1180 if (IS_ERR(env))
1187 return PTR_ERR(env); 1181 return PTR_ERR(env);
1188 1182
1189 args = vvp_env_args(env, IO_NORMAL); 1183 args = vvp_env_args(env, IO_NORMAL);
1190 args->u.normal.via_iov = (struct iovec *)iov; 1184 args->u.normal.via_iter = to;
1191 args->u.normal.via_nrsegs = nr_segs;
1192 args->u.normal.via_iocb = iocb; 1185 args->u.normal.via_iocb = iocb;
1193 1186
1194 result = ll_file_io_generic(env, args, iocb->ki_filp, CIT_READ, 1187 result = ll_file_io_generic(env, args, iocb->ki_filp, CIT_READ,
1195 &iocb->ki_pos, count); 1188 &iocb->ki_pos, iov_iter_count(to));
1196 cl_env_put(env, &refcheck);
1197 return result;
1198}
1199
1200static ssize_t ll_file_read(struct file *file, char *buf, size_t count,
1201 loff_t *ppos)
1202{
1203 struct lu_env *env;
1204 struct iovec *local_iov;
1205 struct kiocb *kiocb;
1206 ssize_t result;
1207 int refcheck;
1208
1209 env = cl_env_get(&refcheck);
1210 if (IS_ERR(env))
1211 return PTR_ERR(env);
1212
1213 local_iov = &vvp_env_info(env)->vti_local_iov;
1214 kiocb = &vvp_env_info(env)->vti_kiocb;
1215 local_iov->iov_base = (void __user *)buf;
1216 local_iov->iov_len = count;
1217 init_sync_kiocb(kiocb, file);
1218 kiocb->ki_pos = *ppos;
1219 kiocb->ki_nbytes = count;
1220
1221 result = ll_file_aio_read(kiocb, local_iov, 1, kiocb->ki_pos);
1222 *ppos = kiocb->ki_pos;
1223
1224 cl_env_put(env, &refcheck); 1189 cl_env_put(env, &refcheck);
1225 return result; 1190 return result;
1226} 1191}
@@ -1228,12 +1193,10 @@ static ssize_t ll_file_read(struct file *file, char *buf, size_t count,
1228/* 1193/*
1229 * Write to a file (through the page cache). 1194 * Write to a file (through the page cache).
1230 */ 1195 */
1231static ssize_t ll_file_aio_write(struct kiocb *iocb, const struct iovec *iov, 1196static ssize_t ll_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
1232 unsigned long nr_segs, loff_t pos)
1233{ 1197{
1234 struct lu_env *env; 1198 struct lu_env *env;
1235 struct vvp_io_args *args; 1199 struct vvp_io_args *args;
1236 size_t count = iov_length(iov, nr_segs);
1237 ssize_t result; 1200 ssize_t result;
1238 int refcheck; 1201 int refcheck;
1239 1202
@@ -1242,46 +1205,15 @@ static ssize_t ll_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
1242 return PTR_ERR(env); 1205 return PTR_ERR(env);
1243 1206
1244 args = vvp_env_args(env, IO_NORMAL); 1207 args = vvp_env_args(env, IO_NORMAL);
1245 args->u.normal.via_iov = (struct iovec *)iov; 1208 args->u.normal.via_iter = from;
1246 args->u.normal.via_nrsegs = nr_segs;
1247 args->u.normal.via_iocb = iocb; 1209 args->u.normal.via_iocb = iocb;
1248 1210
1249 result = ll_file_io_generic(env, args, iocb->ki_filp, CIT_WRITE, 1211 result = ll_file_io_generic(env, args, iocb->ki_filp, CIT_WRITE,
1250 &iocb->ki_pos, count); 1212 &iocb->ki_pos, iov_iter_count(from));
1251 cl_env_put(env, &refcheck); 1213 cl_env_put(env, &refcheck);
1252 return result; 1214 return result;
1253} 1215}
1254 1216
1255static ssize_t ll_file_write(struct file *file, const char *buf, size_t count,
1256 loff_t *ppos)
1257{
1258 struct lu_env *env;
1259 struct iovec *local_iov;
1260 struct kiocb *kiocb;
1261 ssize_t result;
1262 int refcheck;
1263
1264 env = cl_env_get(&refcheck);
1265 if (IS_ERR(env))
1266 return PTR_ERR(env);
1267
1268 local_iov = &vvp_env_info(env)->vti_local_iov;
1269 kiocb = &vvp_env_info(env)->vti_kiocb;
1270 local_iov->iov_base = (void __user *)buf;
1271 local_iov->iov_len = count;
1272 init_sync_kiocb(kiocb, file);
1273 kiocb->ki_pos = *ppos;
1274 kiocb->ki_nbytes = count;
1275
1276 result = ll_file_aio_write(kiocb, local_iov, 1, kiocb->ki_pos);
1277 *ppos = kiocb->ki_pos;
1278
1279 cl_env_put(env, &refcheck);
1280 return result;
1281}
1282
1283
1284
1285/* 1217/*
1286 * Send file content (through pagecache) somewhere with helper 1218 * Send file content (through pagecache) somewhere with helper
1287 */ 1219 */
@@ -3133,10 +3065,10 @@ int ll_inode_permission(struct inode *inode, int mask)
3133 3065
3134/* -o localflock - only provides locally consistent flock locks */ 3066/* -o localflock - only provides locally consistent flock locks */
3135struct file_operations ll_file_operations = { 3067struct file_operations ll_file_operations = {
3136 .read = ll_file_read, 3068 .read = new_sync_read,
3137 .aio_read = ll_file_aio_read, 3069 .read_iter = ll_file_read_iter,
3138 .write = ll_file_write, 3070 .write = new_sync_write,
3139 .aio_write = ll_file_aio_write, 3071 .write_iter = ll_file_write_iter,
3140 .unlocked_ioctl = ll_file_ioctl, 3072 .unlocked_ioctl = ll_file_ioctl,
3141 .open = ll_file_open, 3073 .open = ll_file_open,
3142 .release = ll_file_release, 3074 .release = ll_file_release,
@@ -3148,10 +3080,10 @@ struct file_operations ll_file_operations = {
3148}; 3080};
3149 3081
3150struct file_operations ll_file_operations_flock = { 3082struct file_operations ll_file_operations_flock = {
3151 .read = ll_file_read, 3083 .read = new_sync_read,
3152 .aio_read = ll_file_aio_read, 3084 .read_iter = ll_file_read_iter,
3153 .write = ll_file_write, 3085 .write = new_sync_write,
3154 .aio_write = ll_file_aio_write, 3086 .write_iter = ll_file_write_iter,
3155 .unlocked_ioctl = ll_file_ioctl, 3087 .unlocked_ioctl = ll_file_ioctl,
3156 .open = ll_file_open, 3088 .open = ll_file_open,
3157 .release = ll_file_release, 3089 .release = ll_file_release,
@@ -3166,10 +3098,10 @@ struct file_operations ll_file_operations_flock = {
3166 3098
3167/* These are for -o noflock - to return ENOSYS on flock calls */ 3099/* These are for -o noflock - to return ENOSYS on flock calls */
3168struct file_operations ll_file_operations_noflock = { 3100struct file_operations ll_file_operations_noflock = {
3169 .read = ll_file_read, 3101 .read = new_sync_read,
3170 .aio_read = ll_file_aio_read, 3102 .read_iter = ll_file_read_iter,
3171 .write = ll_file_write, 3103 .write = new_sync_write,
3172 .aio_write = ll_file_aio_write, 3104 .write_iter = ll_file_write_iter,
3173 .unlocked_ioctl = ll_file_ioctl, 3105 .unlocked_ioctl = ll_file_ioctl,
3174 .open = ll_file_open, 3106 .open = ll_file_open,
3175 .release = ll_file_release, 3107 .release = ll_file_release,
diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h
index 69aba0afca41..fbb8650ead34 100644
--- a/drivers/staging/lustre/lustre/llite/llite_internal.h
+++ b/drivers/staging/lustre/lustre/llite/llite_internal.h
@@ -974,8 +974,7 @@ struct vvp_io_args {
974 union { 974 union {
975 struct { 975 struct {
976 struct kiocb *via_iocb; 976 struct kiocb *via_iocb;
977 struct iovec *via_iov; 977 struct iov_iter *via_iter;
978 unsigned long via_nrsegs;
979 } normal; 978 } normal;
980 struct { 979 struct {
981 struct pipe_inode_info *via_pipe; 980 struct pipe_inode_info *via_pipe;
diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c
index 416f7a094a6d..b345dfa599f3 100644
--- a/drivers/staging/lustre/lustre/llite/rw.c
+++ b/drivers/staging/lustre/lustre/llite/rw.c
@@ -157,8 +157,7 @@ static struct ll_cl_context *ll_cl_init(struct file *file,
157 result = cl_io_rw_init(env, io, CIT_WRITE, pos, PAGE_CACHE_SIZE); 157 result = cl_io_rw_init(env, io, CIT_WRITE, pos, PAGE_CACHE_SIZE);
158 if (result == 0) { 158 if (result == 0) {
159 cio->cui_fd = LUSTRE_FPRIVATE(file); 159 cio->cui_fd = LUSTRE_FPRIVATE(file);
160 cio->cui_iov = NULL; 160 cio->cui_iter = NULL;
161 cio->cui_nrsegs = 0;
162 result = cl_io_iter_init(env, io); 161 result = cl_io_iter_init(env, io);
163 if (result == 0) { 162 if (result == 0) {
164 result = cl_io_lock(env, io); 163 result = cl_io_lock(env, io);
diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c
index c7d70091246e..cfe8c625ae64 100644
--- a/drivers/staging/lustre/lustre/llite/vvp_io.c
+++ b/drivers/staging/lustre/lustre/llite/vvp_io.c
@@ -211,27 +211,26 @@ static int vvp_mmap_locks(const struct lu_env *env,
211 struct cl_lock_descr *descr = &cti->cti_descr; 211 struct cl_lock_descr *descr = &cti->cti_descr;
212 ldlm_policy_data_t policy; 212 ldlm_policy_data_t policy;
213 unsigned long addr; 213 unsigned long addr;
214 unsigned long seg;
215 ssize_t count; 214 ssize_t count;
216 int result; 215 int result;
216 struct iov_iter i;
217 struct iovec iov;
217 218
218 LASSERT(io->ci_type == CIT_READ || io->ci_type == CIT_WRITE); 219 LASSERT(io->ci_type == CIT_READ || io->ci_type == CIT_WRITE);
219 220
220 if (!cl_is_normalio(env, io)) 221 if (!cl_is_normalio(env, io))
221 return 0; 222 return 0;
222 223
223 if (vio->cui_iov == NULL) /* nfs or loop back device write */ 224 if (vio->cui_iter == NULL) /* nfs or loop back device write */
224 return 0; 225 return 0;
225 226
226 /* No MM (e.g. NFS)? No vmas too. */ 227 /* No MM (e.g. NFS)? No vmas too. */
227 if (mm == NULL) 228 if (mm == NULL)
228 return 0; 229 return 0;
229 230
230 for (seg = 0; seg < vio->cui_nrsegs; seg++) { 231 iov_for_each(iov, i, *(vio->cui_iter)) {
231 const struct iovec *iv = &vio->cui_iov[seg]; 232 addr = (unsigned long)iov.iov_base;
232 233 count = iov.iov_len;
233 addr = (unsigned long)iv->iov_base;
234 count = iv->iov_len;
235 if (count == 0) 234 if (count == 0)
236 continue; 235 continue;
237 236
@@ -527,9 +526,7 @@ static int vvp_io_read_start(const struct lu_env *env,
527 switch (vio->cui_io_subtype) { 526 switch (vio->cui_io_subtype) {
528 case IO_NORMAL: 527 case IO_NORMAL:
529 LASSERT(cio->cui_iocb->ki_pos == pos); 528 LASSERT(cio->cui_iocb->ki_pos == pos);
530 result = generic_file_aio_read(cio->cui_iocb, 529 result = generic_file_read_iter(cio->cui_iocb, cio->cui_iter);
531 cio->cui_iov, cio->cui_nrsegs,
532 cio->cui_iocb->ki_pos);
533 break; 530 break;
534 case IO_SPLICE: 531 case IO_SPLICE:
535 result = generic_file_splice_read(file, &pos, 532 result = generic_file_splice_read(file, &pos,
@@ -595,12 +592,11 @@ static int vvp_io_write_start(const struct lu_env *env,
595 592
596 CDEBUG(D_VFSTRACE, "write: [%lli, %lli)\n", pos, pos + (long long)cnt); 593 CDEBUG(D_VFSTRACE, "write: [%lli, %lli)\n", pos, pos + (long long)cnt);
597 594
598 if (cio->cui_iov == NULL) /* from a temp io in ll_cl_init(). */ 595 if (cio->cui_iter == NULL) /* from a temp io in ll_cl_init(). */
599 result = 0; 596 result = 0;
600 else 597 else
601 result = generic_file_aio_write(cio->cui_iocb, 598 result = generic_file_write_iter(cio->cui_iocb, cio->cui_iter);
602 cio->cui_iov, cio->cui_nrsegs, 599
603 cio->cui_iocb->ki_pos);
604 if (result > 0) { 600 if (result > 0) {
605 if (result < cnt) 601 if (result < cnt)
606 io->ci_continue = 0; 602 io->ci_continue = 0;
@@ -1162,10 +1158,9 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj,
1162 * results." -- Single Unix Spec */ 1158 * results." -- Single Unix Spec */
1163 if (count == 0) 1159 if (count == 0)
1164 result = 1; 1160 result = 1;
1165 else { 1161 else
1166 cio->cui_tot_count = count; 1162 cio->cui_tot_count = count;
1167 cio->cui_tot_nrsegs = 0; 1163
1168 }
1169 /* for read/write, we store the jobid in the inode, and 1164 /* for read/write, we store the jobid in the inode, and
1170 * it'll be fetched by osc when building RPC. 1165 * it'll be fetched by osc when building RPC.
1171 * 1166 *
diff --git a/include/linux/uio.h b/include/linux/uio.h
index 66012352d333..e8a109a75de1 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -90,6 +90,15 @@ static inline void iov_iter_truncate(struct iov_iter *i, size_t count)
90 i->count = count; 90 i->count = count;
91} 91}
92 92
93/*
94 * reexpand a previously truncated iterator; count must be no more than how much
95 * we had shrunk it.
96 */
97static inline void iov_iter_reexpand(struct iov_iter *i, size_t count)
98{
99 i->count = count;
100}
101
93int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); 102int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
94int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len); 103int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len);
95 104