From f80d45a441f952b6d35152b36d42633761b0c23e Mon Sep 17 00:00:00 2001 From: yury Date: Thu, 2 Nov 2006 12:48:43 +0000 Subject: [PATCH] - fixes in split about le/cpu byte order, cleanups; - added dump page in split in case of error in remove page code. --- lustre/cmm/cmm_split.c | 91 ++++++++++++++++++++++++++++++-------- lustre/cmm/mdc_object.c | 4 +- lustre/include/lustre/lustre_idl.h | 10 +++++ lustre/mdd/mdd_dir.c | 5 ++- lustre/mdd/mdd_object.c | 5 ++- lustre/mdt/mdt_handler.c | 12 +++-- lustre/tests/sanity-lmv.sh | 2 +- 7 files changed, 99 insertions(+), 30 deletions(-) diff --git a/lustre/cmm/cmm_split.c b/lustre/cmm/cmm_split.c index 5d052f8..ac29088 100644 --- a/lustre/cmm/cmm_split.c +++ b/lustre/cmm/cmm_split.c @@ -369,6 +369,66 @@ cleanup: return rc; } +static inline int cmm_split_special_entry(struct lu_dirent *ent) +{ + if (!strncmp(ent->lde_name, ".", le16_to_cpu(ent->lde_namelen)) || + !strncmp(ent->lde_name, "..", le16_to_cpu(ent->lde_namelen))) + return 1; + return 0; +} + +static void cmm_split_dump_entry(const struct lu_env *env, + struct md_object *mo, + struct lu_dirent *ent) +{ + struct cmm_device *cmm = cmm_obj2dev(md2cmm_obj(mo)); + struct lu_fid *ef = &cmm_env_info(env)->cmi_fid; + struct cmm_object *obj; + int local; + + fid_le_to_cpu(ef, &ent->lde_fid); + obj = cmm_object_find(env, cmm, ef); + if (IS_ERR(obj)) { + CERROR("Error while find object by "DFID + ", rc %d\n", ef, (int)PTR_ERR(obj)); + return; + } + + local = (lu_object_exists(&obj->cmo_obj.mo_lu) > 0); + + printk("%4.4x "DFID" %*.*s/%8.8x [%4.4x] (%s)\n", + le16_to_cpu(ent->lde_reclen), PFID(ef), + le16_to_cpu(ent->lde_namelen), + le16_to_cpu(ent->lde_namelen), + ent->lde_name, le32_to_cpu(ent->lde_hash), + le16_to_cpu(ent->lde_namelen), + (local ? "lc" : "cr")); + + cmm_object_put(env, obj); +} + +static void cmm_split_dump_page(const struct lu_env *env, + struct md_object *mo, + struct lu_dirpage *dp, + __u32 hash_end) +{ + struct lu_dirent *ent; + + if (le16_to_cpu(dp->ldp_flags) & LDF_EMPTY) + return; + + printk("Dump: page: [%8.8x-%8.8x]/[%8.8x], flags: " + "%4.4x\n", le32_to_cpu(dp->ldp_hash_start), + le32_to_cpu(dp->ldp_hash_end), hash_end, + le16_to_cpu(dp->ldp_flags)); + + for (ent = lu_dirent_start(dp); + ent != NULL && le32_to_cpu(ent->lde_hash) < hash_end; + ent = lu_dirent_next(ent)) { + cmm_split_dump_entry(env, mo, ent); + } +} + /* * Remove one entry from local MDT. Do not corrupt byte order in page, it will * be sent to remote MDT. @@ -383,8 +443,7 @@ static int cmm_split_remove_entry(const struct lu_env *env, char *name; ENTRY; - if (!strncmp(ent->lde_name, ".", le16_to_cpu(ent->lde_namelen)) || - !strncmp(ent->lde_name, "..", le16_to_cpu(ent->lde_namelen))) + if (cmm_split_special_entry(ent)) RETURN(0); fid_le_to_cpu(&cmm_env_info(env)->cmi_fid, &ent->lde_fid); @@ -415,7 +474,7 @@ static int cmm_split_remove_entry(const struct lu_env *env, GOTO(cleanup, rc); /* - * This @ent will be transferred to slave MDS and insert it there, so in + * This @ent will be transferred to slave MDS and insert there, so in * the slave MDS, we should know whether this object is dir or not, so * use the highest bit of the hash to indicate that (because we do not * use highest bit of hash). @@ -444,9 +503,9 @@ static int cmm_split_remove_page(const struct lu_env *env, int rc = 0; ENTRY; + *len = 0; kmap(rdpg->rp_pages[0]); dp = page_address(rdpg->rp_pages[0]); - *len = 0; for (ent = lu_dirent_start(dp); ent != NULL && le32_to_cpu(ent->lde_hash) < hash_end; ent = lu_dirent_next(ent)) { @@ -457,20 +516,14 @@ static int cmm_split_remove_page(const struct lu_env *env, * currently we assumed it will success anyway in * verfication test. */ - CWARN("Can not del %*.*s rc %d\n", le16_to_cpu(ent->lde_namelen), - le16_to_cpu(ent->lde_namelen), ent->lde_name, rc); + CWARN("Can not del %*.*s rc %d\n", + le16_to_cpu(ent->lde_namelen), + le16_to_cpu(ent->lde_namelen), + ent->lde_name, rc); + cmm_split_dump_page(env, mo, dp, hash_end); GOTO(unmap, rc); } - if (le16_to_cpu(ent->lde_reclen) == 0) - /* - * This is the last ent, whose rec size set to 0 - * so recompute here - */ - *len += (sizeof(*ent) + - le16_to_cpu(ent->lde_namelen) + - 3) & ~3; - else - *len += le16_to_cpu(ent->lde_reclen); + *len += lu_dirent_size(ent); } if (ent != lu_dirent_start(dp)) @@ -657,8 +710,8 @@ int cmm_split_try(const struct lu_env *env, struct md_object *mo) la_size = ma->ma_attr.la_size; /* Split should be done now, let's do it. */ - CWARN("Dir "DFID" is going to split\n", - PFID(lu_object_fid(&mo->mo_lu))); + CWARN("Dir "DFID" is going to split (dir size: "LPU64")\n", + PFID(lu_object_fid(&mo->mo_lu)), la_size); /* * Disable transacrions for split, since there will be so many trans in @@ -707,7 +760,7 @@ int cmm_split_try(const struct lu_env *env, struct md_object *mo) * Finally, split succeed, tell client to repeat opetartion on correct * MDT. */ - CWARN("Dir "DFID" has been split (on size: "LPU64")\n", + CWARN("Dir "DFID" has been split (dir size: "LPU64")\n", PFID(lu_object_fid(&mo->mo_lu)), la_size); rc = -ERESTART; diff --git a/lustre/cmm/mdc_object.c b/lustre/cmm/mdc_object.c index 7d4d111..1c91a42d 100644 --- a/lustre/cmm/mdc_object.c +++ b/lustre/cmm/mdc_object.c @@ -487,10 +487,8 @@ static int mdc_is_subdir(const struct lu_env *env, struct md_object *mo, PFID(&body->fid1)); *sfid = body->fid1; } - EXIT; -out: ptlrpc_req_finished(mci->mci_req); - return rc; + RETURN(rc); } static struct md_dir_operations mdc_dir_ops = { diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 8f0b9c9..6d642ad 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -313,9 +313,19 @@ static inline struct lu_dirent *lu_dirent_next(struct lu_dirent *ent) next = ((void *)ent) + le16_to_cpu(ent->lde_reclen); else next = NULL; + return next; } +static inline int lu_dirent_size(struct lu_dirent *ent) +{ + if (le16_to_cpu(ent->lde_reclen) == 0) { + return (sizeof(*ent) + + le16_to_cpu(ent->lde_namelen) + 3) & ~3; + } + return le16_to_cpu(ent->lde_reclen); +} + #define MEA_MAGIC_LAST_CHAR 0xb2221ca1 #define MEA_MAGIC_ALL_CHARS 0xb222a11c #define MEA_MAGIC_HASH_SEGMENT 0xb222a11b diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 15ed8bd..742e8cc 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -724,8 +724,8 @@ static int mdd_name_remove(const struct lu_env *env, struct lu_attr *la_copy = &mdd_env_info(env)->mti_la_for_fix; struct mdd_device *mdd = mdo2mdd(pobj); struct mdd_object *mdd_obj = md2mdd_obj(pobj); - struct thandle *handle; struct dynlock_handle *dlh; + struct thandle *handle; int rc; ENTRY; @@ -749,11 +749,12 @@ static int mdd_name_remove(const struct lu_env *env, rc = mdd_attr_set_internal_locked(env, mdd_obj, la_copy, handle, 0); } + EXIT; out_unlock: mdd_pdo_write_unlock(env, mdd_obj, dlh); out_trans: mdd_trans_stop(env, mdd, rc, handle); - RETURN(rc); + return rc; } static int mdd_rt_sanity_check(const struct lu_env *env, diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 839fd27..9b4bd2f 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -1264,7 +1264,7 @@ static int mdd_dir_page_build(const struct lu_env *env, int first, fid = (struct lu_fid *)iops->rec(env, it); - recsize = (sizeof *ent + len + 3) & ~3; + recsize = (sizeof(*ent) + len + 3) & ~3; hash = iops->store(env, it); *end = hash; CDEBUG(D_INFO, "%p %p %d "DFID": %#8.8x (%d) \"%*.*s\"\n", @@ -1407,9 +1407,10 @@ static int mdd_readpage(const struct lu_env *env, struct md_object *obj, rc = __mdd_readpage(env, mdd_obj, rdpg); + EXIT; out_unlock: mdd_read_unlock(env, mdd_obj); - RETURN(rc); + return rc; } struct md_object_operations mdd_obj_ops = { diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 0cc0938..80c6a8a 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -1052,12 +1052,13 @@ static int mdt_write_dir_page(struct mdt_thread_info *info, struct page *page, for (ent = lu_dirent_start(dp); ent != NULL; ent = lu_dirent_next(ent)) { - struct lu_fid *lf = &ent->lde_fid; + struct lu_fid *lf = &info->mti_tmp_fid2; char *name; if (le16_to_cpu(ent->lde_namelen) == 0) continue; + fid_le_to_cpu(lf, &ent->lde_fid); is_dir = le32_to_cpu(ent->lde_hash) & MAX_HASH_HIGHEST_BIT; OBD_ALLOC(name, le16_to_cpu(ent->lde_namelen) + 1); if (name == NULL) @@ -1068,10 +1069,15 @@ static int mdt_write_dir_page(struct mdt_thread_info *info, struct page *page, md_object_next(&object->mot_obj), name, lf, is_dir); OBD_FREE(name, le16_to_cpu(ent->lde_namelen) + 1); - if (rc) + if (rc) { + CERROR("Can't insert %*.*s, rc %d\n", + le16_to_cpu(ent->lde_namelen), + le16_to_cpu(ent->lde_namelen), + ent->lde_name, rc); GOTO(out, rc); + } - offset += le16_to_cpu(ent->lde_reclen); + offset += lu_dirent_size(ent); if (offset >= size) break; } diff --git a/lustre/tests/sanity-lmv.sh b/lustre/tests/sanity-lmv.sh index ce1cb0d..9957232 100644 --- a/lustre/tests/sanity-lmv.sh +++ b/lustre/tests/sanity-lmv.sh @@ -235,7 +235,7 @@ umask 077 test_0a() { mkdir $DIR/0a0 || error - for ((i=0;i<5000;i++)); do + for ((i=0;i<15000;i++)); do mkdir $DIR/0a0/`uuidgen -t` || error done rm -rf $DIR/0a0 || error -- 1.8.3.1