X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fosc%2Fosc_io.c;h=5818b8d924d13916c29e97eb1347f68028a77e45;hp=40876d04aa1dab65580f192163af56f3135e180b;hb=2d337a3da6bee76d66450fedda8386f9ede035fa;hpb=65701b4a30efdb695776bcf690a2b3cabc928da1 diff --git a/lustre/osc/osc_io.c b/lustre/osc/osc_io.c index 40876d0..5818b8d 100644 --- a/lustre/osc/osc_io.c +++ b/lustre/osc/osc_io.c @@ -1,6 +1,4 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * +/* * GPL HEADER START * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -38,6 +36,7 @@ * Implementation of cl_io for OSC layer. * * Author: Nikita Danilov + * Author: Jinshan Xiong */ #define DEBUG_SUBSYSTEM S_OSC @@ -94,19 +93,12 @@ struct cl_page *osc_oap2cl_page(struct osc_async_page *oap) return container_of(oap, struct osc_page, ops_oap)->ops_cl.cpl_page; } -static void osc_io_unplug(const struct lu_env *env, struct osc_object *osc, - struct client_obd *cli) -{ - loi_list_maint(cli, osc->oo_oinfo); - osc_check_rpcs(env, cli); -} - /** * An implementation of cl_io_operations::cio_io_submit() method for osc * layer. Iterates over pages in the in-queue, prepares each for io by calling * cl_page_prep() and then either submits them through osc_io_submit_page() * or, if page is already submitted, changes osc flags through - * osc_set_async_flags_base(). + * osc_set_async_flags(). */ static int osc_io_submit(const struct lu_env *env, const struct cl_io_slice *ios, @@ -174,19 +166,17 @@ static int osc_io_submit(const struct lu_env *env, osc_io_submit_page(env, cl2osc_io(env, ios), opg, crt); } else { - result = osc_set_async_flags_base(cli, - osc->oo_oinfo, - oap, - OSC_FLAGS); - /* - * bug 18881: we can't just break out here when - * error occurs after cl_page_prep has been - * called against the page. The correct - * way is to call page's completion routine, - * as in osc_oap_interrupted. For simplicity, - * we just force osc_set_async_flags_base() to - * not return error. - */ + result = osc_set_async_flags(osc, opg, + OSC_FLAGS); + /* + * bug 18881: we can't just break out here when + * error occurs after cl_page_prep has been + * called against the page. The correct + * way is to call page's completion routine, + * as in osc_oap_interrupted. For simplicity, + * we just force osc_set_async_flags() to + * not return error. + */ LASSERT(result == 0); } opg->ops_submit_time = cfs_time_current(); @@ -219,7 +209,7 @@ static int osc_io_submit(const struct lu_env *env, LASSERT(ergo(result == 0, osc == osc0)); if (queued > 0) - osc_io_unplug(env, osc, cli); + osc_io_unplug(env, cli, osc, PDL_POLICY_ROUND); if (osc0) client_obd_list_unlock(&cli->cl_loi_list_lock); CDEBUG(D_INFO, "%d/%d %d\n", qin->pl_nr, qout->pl_nr, result); @@ -373,9 +363,9 @@ static int osc_io_fault_start(const struct lu_env *env, RETURN(0); } -static int osc_setattr_upcall(void *a, int rc) +static int osc_async_upcall(void *a, int rc) { - struct osc_setattr_cbargs *args = a; + struct osc_async_cbargs *args = a; args->opc_rc = rc; cfs_complete(&args->opc_sync); @@ -451,7 +441,7 @@ static int osc_io_setattr_start(const struct lu_env *env, struct lov_oinfo *loi = cl2osc(obj)->oo_oinfo; struct cl_attr *attr = &osc_env_info(env)->oti_attr; struct obdo *oa = &oio->oi_oa; - struct osc_setattr_cbargs *cbargs = &oio->oi_setattr_cbarg; + struct osc_async_cbargs *cbargs = &oio->oi_cbarg; loff_t size = io->u.ci_setattr.sa_attr.lvb_size; unsigned int ia_valid = io->u.ci_setattr.sa_valid; int result = 0; @@ -514,12 +504,12 @@ static int osc_io_setattr_start(const struct lu_env *env, if (ia_valid & ATTR_SIZE) result = osc_punch_base(osc_export(cl2osc(obj)), - &oinfo, osc_setattr_upcall, + &oinfo, osc_async_upcall, cbargs, PTLRPCD_SET); else result = osc_setattr_async_base(osc_export(cl2osc(obj)), &oinfo, NULL, - osc_setattr_upcall, + osc_async_upcall, cbargs, PTLRPCD_SET); } return result; @@ -530,7 +520,7 @@ static void osc_io_setattr_end(const struct lu_env *env, { struct cl_io *io = slice->cis_io; struct osc_io *oio = cl2osc_io(env, slice); - struct osc_setattr_cbargs *cbargs = &oio->oi_setattr_cbarg; + struct osc_async_cbargs *cbargs = &oio->oi_cbarg; int result; cfs_wait_for_completion(&cbargs->opc_sync); @@ -594,6 +584,52 @@ static int osc_io_write_start(const struct lu_env *env, RETURN(result); } +static int osc_io_fsync_start(const struct lu_env *env, + const struct cl_io_slice *slice) +{ + struct cl_io *io = slice->cis_io; + struct osc_io *oio = cl2osc_io(env, slice); + struct obdo *oa = &oio->oi_oa; + struct obd_info *oinfo = &oio->oi_info; + struct osc_async_cbargs *cbargs = &oio->oi_cbarg; + struct cl_object *obj = slice->cis_obj; + struct lov_oinfo *loi = cl2osc(obj)->oo_oinfo; + int result = 0; + ENTRY; + + memset(oa, 0, sizeof(*oa)); + oa->o_id = loi->loi_id; + oa->o_seq = loi->loi_seq; + oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP; + + /* reload size and blocks for start and end of sync range */ + oa->o_size = io->u.ci_fsync.fi_start; + oa->o_blocks = io->u.ci_fsync.fi_end; + oa->o_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS; + + obdo_set_parent_fid(oa, io->u.ci_fsync.fi_fid); + + memset(oinfo, 0, sizeof(*oinfo)); + oinfo->oi_oa = oa; + oinfo->oi_capa = io->u.ci_fsync.fi_capa; + cfs_init_completion(&cbargs->opc_sync); + + result = osc_sync_base(osc_export(cl2osc(obj)), oinfo, + osc_async_upcall, cbargs, PTLRPCD_SET); + RETURN(result); +} + +static void osc_io_fsync_end(const struct lu_env *env, + const struct cl_io_slice *slice) +{ + struct cl_io *io = slice->cis_io; + struct osc_io *oio = cl2osc_io(env, slice); + struct osc_async_cbargs *cbargs = &oio->oi_cbarg; + + cfs_wait_for_completion(&cbargs->opc_sync); + io->ci_result = cbargs->opc_rc; +} + static const struct cl_io_operations osc_io_ops = { .op = { [CIT_READ] = { @@ -612,6 +648,11 @@ static const struct cl_io_operations osc_io_ops = { .cio_fini = osc_io_fini, .cio_start = osc_io_fault_start }, + [CIT_FSYNC] = { + .cio_start = osc_io_fsync_start, + .cio_end = osc_io_fsync_end, + .cio_fini = osc_io_fini + }, [CIT_MISC] = { .cio_fini = osc_io_fini }