From: Xinliang Liu Date: Tue, 28 Jun 2022 08:34:46 +0000 (+0000) Subject: LU-15978 osp: fix striped directory deletion fails for 64K PAGE_SIZE X-Git-Tag: 2.15.58~112 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=7576d294582b818b20559138500cf1e58607cfc8;p=fs%2Flustre-release.git LU-15978 osp: fix striped directory deletion fails for 64K PAGE_SIZE This fixes the rmdir errors below: rmdir: failed to remove '/mnt/lustre/d1.sanity/d2': Invalid argument LustreError: 381691:0:(osp_object.c:1998:osp_it_next_page()) lustre-MDT0000-osp-MDT0001: invalid magic (0 != 8a6d6b6c) for page 0/1 while read layout orphan index. For 64K PAGE_SIZE, when created an striped directory, e.g. created with function test_mkdir() defined in test-framework.sh when MDSCOUNT >= 2, deleting it will fail. For PAGE_SIZE > LU_PAGE_SIZE, if the end system page fills less than LU_PAGE_COUNT lu_idxpages, init the header of the remain lu_idxpages. So that the clients handle this partial filling correctly. Also make goto labels meaningful and avoid not freeing pages for lip_nr == 0 in osp_it_next_page(). This patch also fixes wrong page idx for page kunmap in dt_index_walk(). This server end fix also necessary for the idxpage reading clients nodemap_process_idx_pages() and qsd_reint_entries(). So this patch also includes fix for LU-15992: nodemap create and check failed on 64K page size. Fixes: 77eea1985bb1 ("LU-3336 lfsck: orphan OST-objects iteration") Change-Id: I75bd9603c31bed8ea15fdba693677d41affaf61c Signed-off-by: Xinliang Liu Co-authored-by: Kevin Zhao Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/47812 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: James Simmons Reviewed-by: Oleg Drokin Reviewed-by: Lai Siyao --- diff --git a/lustre/include/dt_object.h b/lustre/include/dt_object.h index cb1f79c..ef7cbf7 100644 --- a/lustre/include/dt_object.h +++ b/lustre/include/dt_object.h @@ -2256,6 +2256,8 @@ int dt_index_walk(const struct lu_env *env, struct dt_object *obj, void *arg); int dt_index_read(const struct lu_env *env, struct dt_device *dev, struct idx_info *ii, const struct lu_rdpg *rdpg); +void dt_index_page_adjust(struct page **pages, const u32 npages, + const size_t nlupgs); static inline struct thandle *dt_trans_create(const struct lu_env *env, struct dt_device *d) diff --git a/lustre/obdclass/dt_object.c b/lustre/obdclass/dt_object.c index 819b3ca..8a732b3 100644 --- a/lustre/obdclass/dt_object.c +++ b/lustre/obdclass/dt_object.c @@ -1031,7 +1031,7 @@ int dt_index_walk(const struct lu_env *env, struct dt_object *obj, /* end of index */ break; } - kunmap(rdpg->rp_pages[i]); + kunmap(rdpg->rp_pages[pageidx]); } out: @@ -1129,6 +1129,14 @@ int dt_index_read(const struct lu_env *env, struct dt_device *dev, ii->ii_hash_end = II_END_OFF; } + /* + * For partial lu_idxpage filling of the end system page, + * init the header of the remain lu_idxpages. + */ + if (rc > 0) + dt_index_page_adjust(rdpg->rp_pages, rdpg->rp_npages, + ii->ii_count); + GOTO(out, rc); out: dt_object_put(env, obj); @@ -1136,6 +1144,47 @@ out: } EXPORT_SYMBOL(dt_index_read); +#if PAGE_SIZE > LU_PAGE_SIZE +/* + * For partial lu_idxpage filling of the end system page, init the header of the + * remain lu_idxpages. So that the clients handle partial filling correctly. + * Current lu_idxpage read clients are osp_it_next_page(), + * nodemap_process_idx_pages() and qsd_reint_entries(). + */ +void dt_index_page_adjust(struct page **pages, const u32 npages, + const size_t nlupgs) +{ + u32 nlupgs_mod = nlupgs % LU_PAGE_COUNT; + u32 remain_nlupgs; + u32 pgidx; + struct lu_idxpage *lip; + union lu_page *lp; + int i; + + if (nlupgs_mod) { + pgidx = nlupgs / LU_PAGE_COUNT; + LASSERT(pgidx < npages); + lp = kmap(pages[pgidx]); + remain_nlupgs = LU_PAGE_COUNT - nlupgs_mod; + + /* initialize the header for the remain lu_pages */ + for (i = 0, lp += nlupgs_mod; i < remain_nlupgs; i++, lp++) { + lip = &lp->lp_idx; + memset(lip, 0, LIP_HDR_SIZE); + lip->lip_magic = LIP_MAGIC; + } + + kunmap(pages[pgidx]); + } +} +#else +void dt_index_page_adjust(struct page **pages, const u32 npages, + const size_t nlupgs) +{ +} +#endif +EXPORT_SYMBOL(dt_index_page_adjust); + #ifdef CONFIG_PROC_FS int lprocfs_dt_blksize_seq_show(struct seq_file *m, void *v) { diff --git a/lustre/osp/osp_object.c b/lustre/osp/osp_object.c index d890439..4e24e1e 100644 --- a/lustre/osp/osp_object.c +++ b/lustre/osp/osp_object.c @@ -1978,21 +1978,22 @@ int osp_it_next_page(const struct lu_env *env, struct dt_it *di) int i; ENTRY; -again2: +process_idxpage: idxpage = it->ooi_cur_idxpage; if (idxpage != NULL) { if (idxpage->lip_nr == 0) - RETURN(1); + goto finish_cur_idxpage; if (it->ooi_pos_ent < idxpage->lip_nr) { CDEBUG(D_INFO, "ooi_pos %d nr %d\n", (int)it->ooi_pos_ent, (int)idxpage->lip_nr); RETURN(0); } +finish_cur_idxpage: it->ooi_cur_idxpage = NULL; it->ooi_pos_lu_page++; -again1: +process_page: if (it->ooi_pos_lu_page < LU_PAGE_COUNT) { it->ooi_cur_idxpage = (void *)it->ooi_cur_page + LU_PAGE_SIZE * it->ooi_pos_lu_page; @@ -2013,19 +2014,19 @@ again1: RETURN(-EINVAL); } it->ooi_pos_ent = -1; - goto again2; + goto process_idxpage; } kunmap(it->ooi_cur_page); it->ooi_cur_page = NULL; it->ooi_pos_page++; -again0: +start: pages = it->ooi_pages; if (it->ooi_pos_page < it->ooi_valid_npages) { it->ooi_cur_page = kmap(pages[it->ooi_pos_page]); it->ooi_pos_lu_page = 0; - goto again1; + goto process_page; } for (i = 0; i < it->ooi_total_npages; i++) { @@ -2049,7 +2050,7 @@ again0: rc = osp_it_fetch(env, it); if (rc == 0) - goto again0; + goto start; RETURN(rc); } diff --git a/lustre/ptlrpc/nodemap_storage.c b/lustre/ptlrpc/nodemap_storage.c index c982eee..ba95da5 100644 --- a/lustre/ptlrpc/nodemap_storage.c +++ b/lustre/ptlrpc/nodemap_storage.c @@ -1608,6 +1608,14 @@ int nodemap_index_read(struct lu_env *env, if (rc >= 0) ii->ii_version = version; + /* + * For partial lu_idxpage filling of the end system page, + * init the header of the remain lu_idxpages. + */ + if (rc > 0) + dt_index_page_adjust(rdpg->rp_pages, rdpg->rp_npages, + ii->ii_count); + dt_read_unlock(env, nodemap_idx); return rc; } @@ -1670,6 +1678,7 @@ int nodemap_get_config_req(struct obd_device *mgs_obd, nodemap_ii.ii_flags = II_FL_NOHASH; nodemap_ii.ii_version = rqexp_ted->ted_nodemap_version; nodemap_ii.ii_attrs = body->mcb_nm_cur_pass; + nodemap_ii.ii_count = 0; bytes = nodemap_index_read(req->rq_svc_thread->t_env, obd2obt(mgs_obd)->obt_nodemap_config_file,