From: Oleg Drokin Date: Sun, 16 Dec 2012 20:21:49 +0000 (-0500) Subject: LU-2450: Do not store and use unreferenced oap pointers X-Git-Tag: 2.3.58~21 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=d551b2293327635f3aeb667470a2b4fe13cbbc75;p=fs%2Flustre-release.git LU-2450: Do not store and use unreferenced oap pointers osc_extent_finish looks for the last oap to see if it was a partial write or not, and does it by storing a pointer to it, but by the time we need the offsets from this OAP, it might have already been freed because completion was called. Change the code to store oap offset and byte count instead. Change-Id: Id52743e701d9b090907eb42ff4648c589193f000 Signed-off-by: Oleg Drokin Reviewed-on: http://review.whamcloud.com/4835 Tested-by: Hudson Reviewed-by: Jinshan Xiong Reviewed-by: Bobi Jam Tested-by: Maloo --- diff --git a/lustre/osc/osc_cache.c b/lustre/osc/osc_cache.c index 48ca84c..df7fb1e 100644 --- a/lustre/osc/osc_cache.c +++ b/lustre/osc/osc_cache.c @@ -799,10 +799,11 @@ int osc_extent_finish(const struct lu_env *env, struct osc_extent *ext, struct client_obd *cli = osc_cli(ext->oe_obj); struct osc_async_page *oap; struct osc_async_page *tmp; - struct osc_async_page *last = NULL; int nr_pages = ext->oe_nr_pages; int lost_grant = 0; int blocksize = cli->cl_import->imp_obd->obd_osfs.os_bsize ? : 4096; + __u64 last_off = 0; + int last_count = -1; ENTRY; OSC_EXTENT_DUMP(D_CACHE, ext, "extent finished.\n"); @@ -813,8 +814,10 @@ int osc_extent_finish(const struct lu_env *env, struct osc_extent *ext, oap_pending_item) { cfs_list_del_init(&oap->oap_rpc_item); cfs_list_del_init(&oap->oap_pending_item); - if (last == NULL || last->oap_obj_off < oap->oap_obj_off) - last = oap; + if (last_off <= oap->oap_obj_off) { + last_off = oap->oap_obj_off; + last_count = oap->oap_count; + } --ext->oe_nr_pages; osc_ap_completion(env, cli, oap, sent, rc); @@ -824,7 +827,7 @@ int osc_extent_finish(const struct lu_env *env, struct osc_extent *ext, if (!sent) { lost_grant = ext->oe_grants; } else if (blocksize < CFS_PAGE_SIZE && - last->oap_count != CFS_PAGE_SIZE) { + last_count != CFS_PAGE_SIZE) { /* For short writes we shouldn't count parts of pages that * span a whole chunk on the OST side, or our accounting goes * wrong. Should match the code in filter_grant_check. */