Skip to content

Commit b42b15f

Browse files
author
Al Viro
committed
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>
1 parent 4908b82 commit b42b15f

File tree

7 files changed

+46
-163
lines changed

7 files changed

+46
-163
lines changed

drivers/staging/lustre/lustre/include/lclient.h

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,7 @@ struct ccc_io {
8282
/**
8383
* I/O vector information to or from which read/write is going.
8484
*/
85-
struct iovec *cui_iov;
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;
85+
struct iov_iter *cui_iter;
9586
/**
9687
* Total size for the left IO.
9788
*/

drivers/staging/lustre/lustre/lclient/lcommon_cl.c

Lines changed: 3 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -721,31 +721,12 @@ int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io,
721721
void ccc_io_update_iov(const struct lu_env *env,
722722
struct ccc_io *cio, struct cl_io *io)
723723
{
724-
int i;
725724
size_t size = io->u.ci_rw.crw_count;
726725

727-
cio->cui_iov_olen = 0;
728-
if (!cl_is_normalio(env, io) || cio->cui_tot_nrsegs == 0)
726+
if (!cl_is_normalio(env, io) || cio->cui_iter == NULL)
729727
return;
730728

731-
for (i = 0; i < cio->cui_tot_nrsegs; i++) {
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);
729+
iov_iter_truncate(cio->cui_iter, size);
749730
}
750731

751732
int 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,
776757
if (!cl_is_normalio(env, io))
777758
return;
778759

779-
LASSERT(cio->cui_tot_nrsegs >= cio->cui_nrsegs);
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-
}
760+
iov_iter_reexpand(cio->cui_iter, cio->cui_tot_count -= nob);
803761
}
804762

805763
/**

drivers/staging/lustre/lustre/llite/file.c

Lines changed: 19 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,9 +1105,7 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args,
11051105

11061106
switch (vio->cui_io_subtype) {
11071107
case IO_NORMAL:
1108-
cio->cui_iov = args->u.normal.via_iov;
1109-
cio->cui_nrsegs = args->u.normal.via_nrsegs;
1110-
cio->cui_tot_nrsegs = cio->cui_nrsegs;
1108+
cio->cui_iter = args->u.normal.via_iter;
11111109
cio->cui_iocb = args->u.normal.via_iocb;
11121110
if ((iot == CIT_WRITE) &&
11131111
!(cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
@@ -1171,69 +1169,34 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args,
11711169
return result;
11721170
}
11731171

1174-
static ssize_t ll_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
1175-
unsigned long nr_segs, loff_t pos)
1172+
static ssize_t ll_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
11761173
{
11771174
struct lu_env *env;
11781175
struct vvp_io_args *args;
1179-
size_t count = 0;
11801176
ssize_t result;
11811177
int refcheck;
11821178

1183-
count = iov_length(iov, nr_segs);
1184-
11851179
env = cl_env_get(&refcheck);
11861180
if (IS_ERR(env))
11871181
return PTR_ERR(env);
11881182

11891183
args = vvp_env_args(env, IO_NORMAL);
1190-
args->u.normal.via_iov = (struct iovec *)iov;
1191-
args->u.normal.via_nrsegs = nr_segs;
1184+
args->u.normal.via_iter = to;
11921185
args->u.normal.via_iocb = iocb;
11931186

11941187
result = ll_file_io_generic(env, args, iocb->ki_filp, CIT_READ,
1195-
&iocb->ki_pos, count);
1196-
cl_env_put(env, &refcheck);
1197-
return result;
1198-
}
1199-
1200-
static 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-
1188+
&iocb->ki_pos, iov_iter_count(to));
12241189
cl_env_put(env, &refcheck);
12251190
return result;
12261191
}
12271192

12281193
/*
12291194
* Write to a file (through the page cache).
12301195
*/
1231-
static ssize_t ll_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
1232-
unsigned long nr_segs, loff_t pos)
1196+
static ssize_t ll_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
12331197
{
12341198
struct lu_env *env;
12351199
struct vvp_io_args *args;
1236-
size_t count = iov_length(iov, nr_segs);
12371200
ssize_t result;
12381201
int refcheck;
12391202

@@ -1242,46 +1205,15 @@ static ssize_t ll_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
12421205
return PTR_ERR(env);
12431206

12441207
args = vvp_env_args(env, IO_NORMAL);
1245-
args->u.normal.via_iov = (struct iovec *)iov;
1246-
args->u.normal.via_nrsegs = nr_segs;
1208+
args->u.normal.via_iter = from;
12471209
args->u.normal.via_iocb = iocb;
12481210

12491211
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));
12511213
cl_env_put(env, &refcheck);
12521214
return result;
12531215
}
12541216

1255-
static 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-
12851217
/*
12861218
* Send file content (through pagecache) somewhere with helper
12871219
*/
@@ -3133,10 +3065,10 @@ int ll_inode_permission(struct inode *inode, int mask)
31333065

31343066
/* -o localflock - only provides locally consistent flock locks */
31353067
struct file_operations ll_file_operations = {
3136-
.read = ll_file_read,
3137-
.aio_read = ll_file_aio_read,
3138-
.write = ll_file_write,
3139-
.aio_write = ll_file_aio_write,
3068+
.read = new_sync_read,
3069+
.read_iter = ll_file_read_iter,
3070+
.write = new_sync_write,
3071+
.write_iter = ll_file_write_iter,
31403072
.unlocked_ioctl = ll_file_ioctl,
31413073
.open = ll_file_open,
31423074
.release = ll_file_release,
@@ -3148,10 +3080,10 @@ struct file_operations ll_file_operations = {
31483080
};
31493081

31503082
struct file_operations ll_file_operations_flock = {
3151-
.read = ll_file_read,
3152-
.aio_read = ll_file_aio_read,
3153-
.write = ll_file_write,
3154-
.aio_write = ll_file_aio_write,
3083+
.read = new_sync_read,
3084+
.read_iter = ll_file_read_iter,
3085+
.write = new_sync_write,
3086+
.write_iter = ll_file_write_iter,
31553087
.unlocked_ioctl = ll_file_ioctl,
31563088
.open = ll_file_open,
31573089
.release = ll_file_release,
@@ -3166,10 +3098,10 @@ struct file_operations ll_file_operations_flock = {
31663098

31673099
/* These are for -o noflock - to return ENOSYS on flock calls */
31683100
struct file_operations ll_file_operations_noflock = {
3169-
.read = ll_file_read,
3170-
.aio_read = ll_file_aio_read,
3171-
.write = ll_file_write,
3172-
.aio_write = ll_file_aio_write,
3101+
.read = new_sync_read,
3102+
.read_iter = ll_file_read_iter,
3103+
.write = new_sync_write,
3104+
.write_iter = ll_file_write_iter,
31733105
.unlocked_ioctl = ll_file_ioctl,
31743106
.open = ll_file_open,
31753107
.release = ll_file_release,

drivers/staging/lustre/lustre/llite/llite_internal.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -974,8 +974,7 @@ struct vvp_io_args {
974974
union {
975975
struct {
976976
struct kiocb *via_iocb;
977-
struct iovec *via_iov;
978-
unsigned long via_nrsegs;
977+
struct iov_iter *via_iter;
979978
} normal;
980979
struct {
981980
struct pipe_inode_info *via_pipe;

drivers/staging/lustre/lustre/llite/rw.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,7 @@ static struct ll_cl_context *ll_cl_init(struct file *file,
157157
result = cl_io_rw_init(env, io, CIT_WRITE, pos, PAGE_CACHE_SIZE);
158158
if (result == 0) {
159159
cio->cui_fd = LUSTRE_FPRIVATE(file);
160-
cio->cui_iov = NULL;
161-
cio->cui_nrsegs = 0;
160+
cio->cui_iter = NULL;
162161
result = cl_io_iter_init(env, io);
163162
if (result == 0) {
164163
result = cl_io_lock(env, io);

drivers/staging/lustre/lustre/llite/vvp_io.c

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -211,27 +211,26 @@ static int vvp_mmap_locks(const struct lu_env *env,
211211
struct cl_lock_descr *descr = &cti->cti_descr;
212212
ldlm_policy_data_t policy;
213213
unsigned long addr;
214-
unsigned long seg;
215214
ssize_t count;
216215
int result;
216+
struct iov_iter i;
217+
struct iovec iov;
217218

218219
LASSERT(io->ci_type == CIT_READ || io->ci_type == CIT_WRITE);
219220

220221
if (!cl_is_normalio(env, io))
221222
return 0;
222223

223-
if (vio->cui_iov == NULL) /* nfs or loop back device write */
224+
if (vio->cui_iter == NULL) /* nfs or loop back device write */
224225
return 0;
225226

226227
/* No MM (e.g. NFS)? No vmas too. */
227228
if (mm == NULL)
228229
return 0;
229230

230-
for (seg = 0; seg < vio->cui_nrsegs; seg++) {
231-
const struct iovec *iv = &vio->cui_iov[seg];
232-
233-
addr = (unsigned long)iv->iov_base;
234-
count = iv->iov_len;
231+
iov_for_each(iov, i, *(vio->cui_iter)) {
232+
addr = (unsigned long)iov.iov_base;
233+
count = iov.iov_len;
235234
if (count == 0)
236235
continue;
237236

@@ -527,9 +526,7 @@ static int vvp_io_read_start(const struct lu_env *env,
527526
switch (vio->cui_io_subtype) {
528527
case IO_NORMAL:
529528
LASSERT(cio->cui_iocb->ki_pos == pos);
530-
result = generic_file_aio_read(cio->cui_iocb,
531-
cio->cui_iov, cio->cui_nrsegs,
532-
cio->cui_iocb->ki_pos);
529+
result = generic_file_read_iter(cio->cui_iocb, cio->cui_iter);
533530
break;
534531
case IO_SPLICE:
535532
result = generic_file_splice_read(file, &pos,
@@ -595,12 +592,11 @@ static int vvp_io_write_start(const struct lu_env *env,
595592

596593
CDEBUG(D_VFSTRACE, "write: [%lli, %lli)\n", pos, pos + (long long)cnt);
597594

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(). */
599596
result = 0;
600597
else
601-
result = generic_file_aio_write(cio->cui_iocb,
602-
cio->cui_iov, cio->cui_nrsegs,
603-
cio->cui_iocb->ki_pos);
598+
result = generic_file_write_iter(cio->cui_iocb, cio->cui_iter);
599+
604600
if (result > 0) {
605601
if (result < cnt)
606602
io->ci_continue = 0;
@@ -1162,10 +1158,9 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj,
11621158
* results." -- Single Unix Spec */
11631159
if (count == 0)
11641160
result = 1;
1165-
else {
1161+
else
11661162
cio->cui_tot_count = count;
1167-
cio->cui_tot_nrsegs = 0;
1168-
}
1163+
11691164
/* for read/write, we store the jobid in the inode, and
11701165
* it'll be fetched by osc when building RPC.
11711166
*

include/linux/uio.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,15 @@ static inline void iov_iter_truncate(struct iov_iter *i, size_t count)
9090
i->count = count;
9191
}
9292

93+
/*
94+
* reexpand a previously truncated iterator; count must be no more than how much
95+
* we had shrunk it.
96+
*/
97+
static inline void iov_iter_reexpand(struct iov_iter *i, size_t count)
98+
{
99+
i->count = count;
100+
}
101+
93102
int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
94103
int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len);
95104

0 commit comments

Comments
 (0)