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 <xinliang.liu@linaro.org>
Co-authored-by: Kevin Zhao <kevin.zhao@linaro.org>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/47812
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Lai Siyao <lai.siyao@whamcloud.com>
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)
/* end of index */
break;
}
- kunmap(rdpg->rp_pages[i]);
+ kunmap(rdpg->rp_pages[pageidx]);
}
out:
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);
}
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)
{
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;
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++) {
rc = osp_it_fetch(env, it);
if (rc == 0)
- goto again0;
+ goto start;
RETURN(rc);
}
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;
}
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,