From: Andriy Skulysh Date: Wed, 16 Dec 2015 14:05:31 +0000 (+0200) Subject: LU-7382 llite: Fix iovec references accounting in ll_file_aio_read/write X-Git-Tag: 2.7.66~42 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=57f055f8d0df80e140724b00d1729f454222a83a LU-7382 llite: Fix iovec references accounting in ll_file_aio_read/write lti_local_iov is used to store iovec in case of 1 segment. It is needed to hold reference on lu_env during call of ll_file_write_iter() or ll_file_read_iter(). Otherwise an assertion fails: vvp_io_update_iov()) ASSERTION( vio->vui_tot_nrsegs >= vio->vui_iter->nr_segs ) failed Change-Id: Iaff4c81c6ced9ac0e1557dd0eb1fab5205b48e28 Signed-off-by: Andriy Skulysh Reviewed-on: http://review.whamcloud.com/17632 Tested-by: Maloo Reviewed-by: Bobi Jam Reviewed-by: Jinshan Xiong Reviewed-by: Patrick Farrell Reviewed-by: Oleg Drokin --- diff --git a/lustre/llite/file.c b/lustre/llite/file.c index d620c12..b4f3779 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -1249,6 +1249,8 @@ static ssize_t ll_file_aio_read(struct kiocb *iocb, const struct iovec *iov, struct iov_iter *to; size_t iov_count; ssize_t result; + struct lu_env *env = NULL; + __u16 refcheck; ENTRY; result = ll_file_get_iov_count(iov, &nr_segs, &iov_count); @@ -1256,8 +1258,6 @@ static ssize_t ll_file_aio_read(struct kiocb *iocb, const struct iovec *iov, RETURN(result); if (nr_segs == 1) { - struct lu_env *env; - __u16 refcheck; env = cl_env_get(&refcheck); if (IS_ERR(env)) @@ -1266,7 +1266,6 @@ static ssize_t ll_file_aio_read(struct kiocb *iocb, const struct iovec *iov, local_iov = &ll_env_info(env)->lti_local_iov; *local_iov = *iov; - cl_env_put(env, &refcheck); } else { OBD_ALLOC(local_iov, sizeof(*iov) * nr_segs); if (local_iov == NULL) @@ -1290,7 +1289,9 @@ static ssize_t ll_file_aio_read(struct kiocb *iocb, const struct iovec *iov, OBD_FREE_PTR(to); out: - if (nr_segs > 1) + if (nr_segs == 1) + cl_env_put(env, &refcheck); + else OBD_FREE(local_iov, sizeof(*iov) * nr_segs); RETURN(result); @@ -1337,6 +1338,8 @@ static ssize_t ll_file_aio_write(struct kiocb *iocb, const struct iovec *iov, struct iov_iter *from; size_t iov_count; ssize_t result; + struct lu_env *env = NULL; + __u16 refcheck; ENTRY; result = ll_file_get_iov_count(iov, &nr_segs, &iov_count); @@ -1344,17 +1347,12 @@ static ssize_t ll_file_aio_write(struct kiocb *iocb, const struct iovec *iov, RETURN(result); if (nr_segs == 1) { - struct lu_env *env; - __u16 refcheck; - env = cl_env_get(&refcheck); if (IS_ERR(env)) RETURN(PTR_ERR(env)); local_iov = &ll_env_info(env)->lti_local_iov; *local_iov = *iov; - - cl_env_put(env, &refcheck); } else { OBD_ALLOC(local_iov, sizeof(*iov) * nr_segs); if (local_iov == NULL) @@ -1378,7 +1376,9 @@ static ssize_t ll_file_aio_write(struct kiocb *iocb, const struct iovec *iov, OBD_FREE_PTR(from); out: - if (nr_segs > 1) + if (nr_segs == 1) + cl_env_put(env, &refcheck); + else OBD_FREE(local_iov, sizeof(*iov) * nr_segs); RETURN(result);