Whamcloud - gitweb
LU-15978 osp: fix striped directory deletion fails for 64K PAGE_SIZE 12/47812/33
authorXinliang Liu <xinliang.liu@linaro.org>
Tue, 28 Jun 2022 08:34:46 +0000 (08:34 +0000)
committerOleg Drokin <green@whamcloud.com>
Sat, 19 Aug 2023 05:34:16 +0000 (05:34 +0000)
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>
lustre/include/dt_object.h
lustre/obdclass/dt_object.c
lustre/osp/osp_object.c
lustre/ptlrpc/nodemap_storage.c

index cb1f79c..ef7cbf7 100644 (file)
@@ -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)
index 819b3ca..8a732b3 100644 (file)
@@ -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)
 {
index d890439..4e24e1e 100644 (file)
@@ -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);
 }
index c982eee..ba95da5 100644 (file)
@@ -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,