diff options
Diffstat (limited to 'drivers/staging/lustre/lustre/llite/rw.c')
-rw-r--r-- | drivers/staging/lustre/lustre/llite/rw.c | 151 |
1 files changed, 61 insertions, 90 deletions
diff --git a/drivers/staging/lustre/lustre/llite/rw.c b/drivers/staging/lustre/lustre/llite/rw.c index 336397773..87393c4bd 100644 --- a/drivers/staging/lustre/lustre/llite/rw.c +++ b/drivers/staging/lustre/lustre/llite/rw.c @@ -15,11 +15,7 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -59,84 +55,6 @@ #include "llite_internal.h" #include "../include/linux/lustre_compat25.h" -/** - * Finalizes cl-data before exiting typical address_space operation. Dual to - * ll_cl_init(). - */ -void ll_cl_fini(struct ll_cl_context *lcc) -{ - struct lu_env *env = lcc->lcc_env; - struct cl_io *io = lcc->lcc_io; - struct cl_page *page = lcc->lcc_page; - - LASSERT(lcc->lcc_cookie == current); - LASSERT(env); - - if (page) { - lu_ref_del(&page->cp_reference, "cl_io", io); - cl_page_put(env, page); - } - - cl_env_put(env, &lcc->lcc_refcheck); -} - -/** - * Initializes common cl-data at the typical address_space operation entry - * point. - */ -struct ll_cl_context *ll_cl_init(struct file *file, struct page *vmpage) -{ - struct ll_cl_context *lcc; - struct lu_env *env; - struct cl_io *io; - struct cl_object *clob; - struct vvp_io *vio; - - int refcheck; - int result = 0; - - clob = ll_i2info(file_inode(file))->lli_clob; - LASSERT(clob); - - env = cl_env_get(&refcheck); - if (IS_ERR(env)) - return ERR_CAST(env); - - lcc = &ll_env_info(env)->lti_io_ctx; - memset(lcc, 0, sizeof(*lcc)); - lcc->lcc_env = env; - lcc->lcc_refcheck = refcheck; - lcc->lcc_cookie = current; - - vio = vvp_env_io(env); - io = vio->vui_cl.cis_io; - lcc->lcc_io = io; - if (!io) - result = -EIO; - - if (result == 0 && vmpage) { - struct cl_page *page; - - LASSERT(io->ci_state == CIS_IO_GOING); - LASSERT(vio->vui_fd == LUSTRE_FPRIVATE(file)); - page = cl_page_find(env, clob, vmpage->index, vmpage, - CPT_CACHEABLE); - if (!IS_ERR(page)) { - lcc->lcc_page = page; - lu_ref_add(&page->cp_reference, "cl_io", io); - result = 0; - } else { - result = PTR_ERR(page); - } - } - if (result) { - ll_cl_fini(lcc); - lcc = ERR_PTR(result); - } - - return lcc; -} - static void ll_ra_stats_inc_sbi(struct ll_sb_info *sbi, enum ra_stat which); /** @@ -1112,17 +1030,70 @@ int ll_writepages(struct address_space *mapping, struct writeback_control *wbc) return result; } +struct ll_cl_context *ll_cl_find(struct file *file) +{ + struct ll_file_data *fd = LUSTRE_FPRIVATE(file); + struct ll_cl_context *lcc; + struct ll_cl_context *found = NULL; + + read_lock(&fd->fd_lock); + list_for_each_entry(lcc, &fd->fd_lccs, lcc_list) { + if (lcc->lcc_cookie == current) { + found = lcc; + break; + } + } + read_unlock(&fd->fd_lock); + + return found; +} + +void ll_cl_add(struct file *file, const struct lu_env *env, struct cl_io *io) +{ + struct ll_file_data *fd = LUSTRE_FPRIVATE(file); + struct ll_cl_context *lcc = &ll_env_info(env)->lti_io_ctx; + + memset(lcc, 0, sizeof(*lcc)); + INIT_LIST_HEAD(&lcc->lcc_list); + lcc->lcc_cookie = current; + lcc->lcc_env = env; + lcc->lcc_io = io; + + write_lock(&fd->fd_lock); + list_add(&lcc->lcc_list, &fd->fd_lccs); + write_unlock(&fd->fd_lock); +} + +void ll_cl_remove(struct file *file, const struct lu_env *env) +{ + struct ll_file_data *fd = LUSTRE_FPRIVATE(file); + struct ll_cl_context *lcc = &ll_env_info(env)->lti_io_ctx; + + write_lock(&fd->fd_lock); + list_del_init(&lcc->lcc_list); + write_unlock(&fd->fd_lock); +} + int ll_readpage(struct file *file, struct page *vmpage) { + struct cl_object *clob = ll_i2info(file_inode(file))->lli_clob; struct ll_cl_context *lcc; + const struct lu_env *env; + struct cl_io *io; + struct cl_page *page; int result; - lcc = ll_cl_init(file, vmpage); - if (!IS_ERR(lcc)) { - struct lu_env *env = lcc->lcc_env; - struct cl_io *io = lcc->lcc_io; - struct cl_page *page = lcc->lcc_page; + lcc = ll_cl_find(file); + if (!lcc) { + unlock_page(vmpage); + return -EIO; + } + env = lcc->lcc_env; + io = lcc->lcc_io; + LASSERT(io->ci_state == CIS_IO_GOING); + page = cl_page_find(env, clob, vmpage->index, vmpage, CPT_CACHEABLE); + if (!IS_ERR(page)) { LASSERT(page->cp_type == CPT_CACHEABLE); if (likely(!PageUptodate(vmpage))) { cl_page_assume(env, io, page); @@ -1132,10 +1103,10 @@ int ll_readpage(struct file *file, struct page *vmpage) unlock_page(vmpage); result = 0; } - ll_cl_fini(lcc); + cl_page_put(env, page); } else { unlock_page(vmpage); - result = PTR_ERR(lcc); + result = PTR_ERR(page); } return result; } |