Commit b2e7bbb3 authored by Stephen Champion's avatar Stephen Champion Committed by Greg Kroah-Hartman

staging: lustre: llite: handle concurrent use of cob_transient_pages

With the lockless __generic_file_aio_write introduced in LU-1669,
ll_direct_IO_26 is no longer protected by the inode i_isem.

This renders obsoltete checks that all transient pages have been
handled before and after entry, and requires atomic access to their
counter.
Signed-off-by: default avatarStephen Champion <schamp@sgi.com>
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5700
Reviewed-on: http://review.whamcloud.com/12179Reviewed-by: default avatarJinshan Xiong <jinshan.xiong@intel.com>
Reviewed-by: default avatarBobi Jam <bobijam@gmail.com>
Reviewed-by: default avatarOleg Drokin <oleg.drokin@intel.com>
Signed-off-by: default avatarJames Simmons <jsimmons@infradead.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 4660dd9b
...@@ -345,7 +345,6 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter) ...@@ -345,7 +345,6 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter)
struct cl_io *io; struct cl_io *io;
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host; struct inode *inode = file->f_mapping->host;
struct vvp_object *obj = cl_inode2vvp(inode);
loff_t file_offset = iocb->ki_pos; loff_t file_offset = iocb->ki_pos;
ssize_t count = iov_iter_count(iter); ssize_t count = iov_iter_count(iter);
ssize_t tot_bytes = 0, result = 0; ssize_t tot_bytes = 0, result = 0;
...@@ -374,7 +373,6 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter) ...@@ -374,7 +373,6 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter)
io = vvp_env_io(env)->vui_cl.cis_io; io = vvp_env_io(env)->vui_cl.cis_io;
LASSERT(io); LASSERT(io);
LASSERT(obj->vob_transient_pages == 0);
while (iov_iter_count(iter)) { while (iov_iter_count(iter)) {
struct page **pages; struct page **pages;
size_t offs; size_t offs;
...@@ -422,8 +420,6 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter) ...@@ -422,8 +420,6 @@ static ssize_t ll_direct_IO_26(struct kiocb *iocb, struct iov_iter *iter)
file_offset += result; file_offset += result;
} }
out: out:
LASSERT(obj->vob_transient_pages == 0);
if (tot_bytes > 0) { if (tot_bytes > 0) {
struct vvp_io *vio = vvp_env_io(env); struct vvp_io *vio = vvp_env_io(env);
......
...@@ -217,11 +217,12 @@ struct vvp_object { ...@@ -217,11 +217,12 @@ struct vvp_object {
struct list_head vob_pending_list; struct list_head vob_pending_list;
/** /**
* Access this counter is protected by inode->i_sem. Now that * Number of transient pages. This is no longer protected by i_sem,
* the lifetime of transient pages must be covered by inode sem, * and needs to be atomic. This is not actually used for anything,
* we don't need to hold any lock.. * and can probably be removed.
*/ */
int vob_transient_pages; atomic_t vob_transient_pages;
/** /**
* Number of outstanding mmaps on this file. * Number of outstanding mmaps on this file.
* *
......
...@@ -67,8 +67,8 @@ static int vvp_object_print(const struct lu_env *env, void *cookie, ...@@ -67,8 +67,8 @@ static int vvp_object_print(const struct lu_env *env, void *cookie,
(*p)(env, cookie, "(%s %d %d) inode: %p ", (*p)(env, cookie, "(%s %d %d) inode: %p ",
list_empty(&obj->vob_pending_list) ? "-" : "+", list_empty(&obj->vob_pending_list) ? "-" : "+",
obj->vob_transient_pages, atomic_read(&obj->vob_mmap_cnt), atomic_read(&obj->vob_transient_pages),
inode); atomic_read(&obj->vob_mmap_cnt), inode);
if (inode) { if (inode) {
lli = ll_i2info(inode); lli = ll_i2info(inode);
(*p)(env, cookie, "%lu/%u %o %u %d %p "DFID, (*p)(env, cookie, "%lu/%u %o %u %d %p "DFID,
...@@ -220,7 +220,7 @@ static int vvp_object_init0(const struct lu_env *env, ...@@ -220,7 +220,7 @@ static int vvp_object_init0(const struct lu_env *env,
const struct cl_object_conf *conf) const struct cl_object_conf *conf)
{ {
vob->vob_inode = conf->coc_inode; vob->vob_inode = conf->coc_inode;
vob->vob_transient_pages = 0; atomic_set(&vob->vob_transient_pages, 0);
cl_object_page_init(&vob->vob_cl, sizeof(struct vvp_page)); cl_object_page_init(&vob->vob_cl, sizeof(struct vvp_page));
return 0; return 0;
} }
......
...@@ -506,7 +506,7 @@ static void vvp_transient_page_fini(const struct lu_env *env, ...@@ -506,7 +506,7 @@ static void vvp_transient_page_fini(const struct lu_env *env,
struct vvp_object *clobj = cl2vvp(clp->cp_obj); struct vvp_object *clobj = cl2vvp(clp->cp_obj);
vvp_page_fini_common(vpg); vvp_page_fini_common(vpg);
clobj->vob_transient_pages--; atomic_dec(&clobj->vob_transient_pages);
} }
static const struct cl_page_operations vvp_transient_page_ops = { static const struct cl_page_operations vvp_transient_page_ops = {
...@@ -555,7 +555,7 @@ int vvp_page_init(const struct lu_env *env, struct cl_object *obj, ...@@ -555,7 +555,7 @@ int vvp_page_init(const struct lu_env *env, struct cl_object *obj,
cl_page_slice_add(page, &vpg->vpg_cl, obj, index, cl_page_slice_add(page, &vpg->vpg_cl, obj, index,
&vvp_transient_page_ops); &vvp_transient_page_ops);
clobj->vob_transient_pages++; atomic_inc(&clobj->vob_transient_pages);
} }
return 0; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment