X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fosc%2Fosc_object.c;h=16eab5fdf593b3cf212899e3c43653feb310bd0b;hp=77f6b03168d9d3de02b8dd03a3b8bc263dba1ff9;hb=269a157c600a68fac5f5d2bb383338db807129f6;hpb=68ff85b8858e845eee1ca9d6d2ba639cdc2fb470 diff --git a/lustre/osc/osc_object.c b/lustre/osc/osc_object.c index 77f6b03..16eab5f 100644 --- a/lustre/osc/osc_object.c +++ b/lustre/osc/osc_object.c @@ -23,11 +23,10 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2015, Intel Corporation. + * Copyright (c) 2011, 2017, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. * * Implementation of cl_object for OSC layer. * @@ -49,6 +48,17 @@ * Object operations. * */ +static void osc_obj_build_res_name(struct osc_object *osc, + struct ldlm_res_id *resname) +{ + ostid_build_res_name(&osc->oo_oinfo->loi_oi, resname); +} + +static const struct osc_object_operations osc_object_ops = { + .oto_build_res_name = osc_obj_build_res_name, + .oto_dlmlock_at_pgoff = osc_obj_dlmlock_at_pgoff, +}; + int osc_object_init(const struct lu_env *env, struct lu_object *obj, const struct lu_object_conf *conf) { @@ -79,6 +89,8 @@ int osc_object_init(const struct lu_env *env, struct lu_object *obj, atomic_set(&osc->oo_nr_ios, 0); init_waitqueue_head(&osc->oo_io_waitq); + LASSERT(osc->oo_obj_ops != NULL); + cl_object_page_init(lu2cl(obj), sizeof(struct osc_page)); return 0; @@ -105,6 +117,7 @@ void osc_object_free(const struct lu_env *env, struct lu_object *obj) LASSERT(atomic_read(&osc->oo_nr_ios) == 0); lu_object_fini(obj); + /* osc doen't contain an lu_object_header, so we don't need call_rcu */ OBD_SLAB_FREE_PTR(osc, osc_object_kmem); } EXPORT_SYMBOL(osc_object_free); @@ -187,25 +200,53 @@ EXPORT_SYMBOL(osc_object_glimpse); static int osc_object_ast_clear(struct ldlm_lock *lock, void *data) { + struct osc_object *osc = (struct osc_object *)data; + struct ost_lvb *lvb = lock->l_lvb_data; + struct lov_oinfo *oinfo; ENTRY; - if (lock->l_ast_data == data) + if (lock->l_ast_data == data) { lock->l_ast_data = NULL; + + LASSERT(osc != NULL); + LASSERT(osc->oo_oinfo != NULL); + LASSERT(lvb != NULL); + + /* Updates lvb in lock by the cached oinfo */ + oinfo = osc->oo_oinfo; + + LDLM_DEBUG(lock, "update lock size %llu blocks %llu [cma]time: " + "%llu %llu %llu by oinfo size %llu blocks %llu " + "[cma]time %llu %llu %llu", lvb->lvb_size, + lvb->lvb_blocks, lvb->lvb_ctime, lvb->lvb_mtime, + lvb->lvb_atime, oinfo->loi_lvb.lvb_size, + oinfo->loi_lvb.lvb_blocks, oinfo->loi_lvb.lvb_ctime, + oinfo->loi_lvb.lvb_mtime, oinfo->loi_lvb.lvb_atime); + LASSERTF(oinfo->loi_lvb.lvb_size >= oinfo->loi_kms, + "lvb_size %#llx, loi_kms %#llx\n", + oinfo->loi_lvb.lvb_size, oinfo->loi_kms); + + cl_object_attr_lock(&osc->oo_cl); + memcpy(lvb, &oinfo->loi_lvb, sizeof(oinfo->loi_lvb)); + cl_object_attr_unlock(&osc->oo_cl); + ldlm_clear_lvb_cached(lock); + } RETURN(LDLM_ITER_CONTINUE); } -static int osc_object_prune(const struct lu_env *env, struct cl_object *obj) +int osc_object_prune(const struct lu_env *env, struct cl_object *obj) { - struct osc_object *osc = cl2osc(obj); - struct ldlm_res_id *resname = &osc_env_info(env)->oti_resname; + struct osc_object *osc = cl2osc(obj); + struct ldlm_res_id *resname = &osc_env_info(env)->oti_resname; /* DLM locks don't hold a reference of osc_object so we have to * clear it before the object is being destroyed. */ - ostid_build_res_name(&osc->oo_oinfo->loi_oi, resname); + osc_build_res_name(osc, resname); ldlm_resource_iterate(osc_export(osc)->exp_obd->obd_namespace, resname, osc_object_ast_clear, osc); return 0; } +EXPORT_SYMBOL(osc_object_prune); static int osc_object_fiemap(const struct lu_env *env, struct cl_object *obj, struct ll_fiemap_info_key *fmkey, @@ -240,7 +281,7 @@ static int osc_object_fiemap(const struct lu_env *env, struct cl_object *obj, mode = ldlm_lock_match(exp->exp_obd->obd_namespace, LDLM_FL_BLOCK_GRANTED | LDLM_FL_LVB_READY, &resid, LDLM_EXTENT, &policy, - LCK_PR | LCK_PW, &lockh, 0); + LCK_PR | LCK_PW, &lockh); if (mode) { /* lock is cached on client */ if (mode != LCK_PR) { ldlm_lock_addref(&lockh, LCK_PR); @@ -292,24 +333,11 @@ drop_lock: RETURN(rc); } -void osc_object_set_contended(struct osc_object *obj) -{ - obj->oo_contention_time = cfs_time_current(); - /* mb(); */ - obj->oo_contended = 1; -} - -void osc_object_clear_contended(struct osc_object *obj) -{ - obj->oo_contended = 0; -} - int osc_object_is_contended(struct osc_object *obj) { - struct osc_device *dev = lu2osc_dev(obj->oo_cl.co_lu.lo_dev); - int osc_contention_time = dev->od_contention_time; - cfs_time_t cur_time = cfs_time_current(); - cfs_time_t retry_time; + struct osc_device *dev = lu2osc_dev(obj->oo_cl.co_lu.lo_dev); + time64_t osc_contention_time = dev->od_contention_time; + ktime_t retry_time; if (OBD_FAIL_CHECK(OBD_FAIL_OSC_OBJECT_CONTENTION)) return 1; @@ -317,18 +345,15 @@ int osc_object_is_contended(struct osc_object *obj) if (!obj->oo_contended) return 0; - /* - * I like copy-paste. the code is copied from - * ll_file_is_contended. - */ - retry_time = cfs_time_add(obj->oo_contention_time, - cfs_time_seconds(osc_contention_time)); - if (cfs_time_after(cur_time, retry_time)) { - osc_object_clear_contended(obj); - return 0; - } - return 1; + retry_time = ktime_add_ns(obj->oo_contention_time, + osc_contention_time * NSEC_PER_SEC); + if (ktime_after(ktime_get(), retry_time)) { + osc_object_clear_contended(obj); + return 0; + } + return 1; } +EXPORT_SYMBOL(osc_object_is_contended); /** * Implementation of struct cl_object_operations::coo_req_attr_set() for osc @@ -351,7 +376,12 @@ static void osc_req_attr_set(const struct lu_env *env, struct cl_object *obj, oa->o_mtime = lvb->lvb_mtime; oa->o_valid |= OBD_MD_FLMTIME; } - if ((flags & OBD_MD_FLATIME) != 0) { + /* XXX: + * I don't understand this part, what for OSC resets atime just + * set by VVP layer to 0 so that OST gets 0 instead of actual + * atime, bzzz. please inspect this place with extra care. + */ + if ((flags & OBD_MD_FLATIME) && lvb->lvb_atime > oa->o_atime) { oa->o_atime = lvb->lvb_atime; oa->o_valid |= OBD_MD_FLATIME; } @@ -441,6 +471,7 @@ struct lu_object *osc_object_alloc(const struct lu_env *env, lu_object_init(obj, NULL, dev); osc->oo_cl.co_ops = &osc_ops; obj->lo_ops = &osc_lu_obj_ops; + osc->oo_obj_ops = &osc_object_ops; } else obj = NULL; return obj; @@ -448,13 +479,12 @@ struct lu_object *osc_object_alloc(const struct lu_env *env, int osc_object_invalidate(const struct lu_env *env, struct osc_object *osc) { - struct l_wait_info lwi = { 0 }; ENTRY; CDEBUG(D_INODE, "Invalidate osc object: %p, # of active IOs: %d\n", osc, atomic_read(&osc->oo_nr_ios)); - l_wait_event(osc->oo_io_waitq, atomic_read(&osc->oo_nr_ios) == 0, &lwi); + wait_event_idle(osc->oo_io_waitq, atomic_read(&osc->oo_nr_ios) == 0); /* Discard all dirty pages of this object. */ osc_cache_truncate_start(env, osc, 0, NULL); @@ -463,9 +493,9 @@ int osc_object_invalidate(const struct lu_env *env, struct osc_object *osc) osc_lock_discard_pages(env, osc, 0, CL_PAGE_EOF, true); /* Clear ast data of dlm lock. Do this after discarding all pages */ - osc_object_prune(env, osc2cl(osc)); + cl_object_prune(env, osc2cl(osc)); RETURN(0); } - +EXPORT_SYMBOL(osc_object_invalidate); /** @} osc */