From 1ebc9ed460922e6fcf2432f70f2f6412974e963a Mon Sep 17 00:00:00 2001 From: Lai Siyao Date: Thu, 19 May 2022 18:31:07 -0400 Subject: [PATCH] LU-15902 obdclass: dt_try_as_dir() check dir exists If an object is not directory, but dt_lookup() is called on it, it may crash because .do_lookup is NULL for non-directory file. Add argument to check object existence and type in dt_try_as_dir(), and for object to create, skip this check. Signed-off-by: Lai Siyao Change-Id: I51df0cbb5a4e7abca370ee27dac678f995b76159 Reviewed-on: https://review.whamcloud.com/47483 Tested-by: jenkins Reviewed-by: John L. Hammond Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/include/dt_object.h | 2 +- lustre/lfsck/lfsck_bookmark.c | 2 +- lustre/lfsck/lfsck_engine.c | 2 +- lustre/lfsck/lfsck_layout.c | 2 +- lustre/lfsck/lfsck_lib.c | 29 ++++++++++------------------- lustre/lfsck/lfsck_namespace.c | 28 ++++++++++++++-------------- lustre/lfsck/lfsck_striped_dir.c | 6 +++--- lustre/lod/lod_object.c | 20 ++++++++++---------- lustre/mdd/mdd_dir.c | 9 ++++----- lustre/mdd/mdd_internal.h | 14 +++++++------- lustre/mdd/mdd_object.c | 14 ++++---------- lustre/mdd/mdd_orphans.c | 5 +++-- lustre/mgs/mgs_fs.c | 2 +- lustre/obdclass/dt_object.c | 36 ++++++++++++++++++++++++++++++++---- lustre/obdclass/llog_osd.c | 4 ++-- lustre/obdclass/local_storage.c | 2 +- lustre/obdclass/scrub.c | 2 +- lustre/quota/lquota_disk.c | 2 +- lustre/target/out_handler.c | 2 +- lustre/target/out_lib.c | 16 ++++++---------- lustre/target/update_recovery.c | 4 ++-- 21 files changed, 106 insertions(+), 97 deletions(-) diff --git a/lustre/include/dt_object.h b/lustre/include/dt_object.h index cb386cd..30090709 100644 --- a/lustre/include/dt_object.h +++ b/lustre/include/dt_object.h @@ -2055,7 +2055,7 @@ int dt_txn_hook_start(const struct lu_env *env, struct dt_device *dev, struct thandle *txn); int dt_txn_hook_stop(const struct lu_env *env, struct thandle *txn); -int dt_try_as_dir(const struct lu_env *env, struct dt_object *obj); +int dt_try_as_dir(const struct lu_env *env, struct dt_object *obj, bool check); /** * Callback function used for parsing path. diff --git a/lustre/lfsck/lfsck_bookmark.c b/lustre/lfsck/lfsck_bookmark.c index 0aa94fa0..e8f1ec9 100644 --- a/lustre/lfsck/lfsck_bookmark.c +++ b/lustre/lfsck/lfsck_bookmark.c @@ -166,7 +166,7 @@ int lfsck_bookmark_setup(const struct lu_env *env, if (IS_ERR(root)) RETURN(PTR_ERR(root)); - if (unlikely(!dt_try_as_dir(env, root))) { + if (unlikely(!dt_try_as_dir(env, root, true))) { lfsck_object_put(env, root); RETURN(-ENOTDIR); diff --git a/lustre/lfsck/lfsck_engine.c b/lustre/lfsck/lfsck_engine.c index d6fb21d..7487ea4 100644 --- a/lustre/lfsck/lfsck_engine.c +++ b/lustre/lfsck/lfsck_engine.c @@ -350,7 +350,7 @@ int lfsck_open_dir(const struct lu_env *env, LASSERT(obj != NULL); LASSERT(di == NULL); - if (unlikely(!dt_try_as_dir(env, obj))) + if (unlikely(!dt_try_as_dir(env, obj, true))) GOTO(out, rc = -ENOTDIR); list_for_each_entry(com, &lfsck->li_list_dir, lc_link_dir) { diff --git a/lustre/lfsck/lfsck_layout.c b/lustre/lfsck/lfsck_layout.c index 30d0c82..034f63a 100644 --- a/lustre/lfsck/lfsck_layout.c +++ b/lustre/lfsck/lfsck_layout.c @@ -6978,7 +6978,7 @@ int lfsck_layout_setup(const struct lu_env *env, struct lfsck_instance *lfsck) if (IS_ERR(root)) GOTO(out, rc = PTR_ERR(root)); - if (unlikely(!dt_try_as_dir(env, root))) + if (unlikely(!dt_try_as_dir(env, root, true))) GOTO(out, rc = -ENOTDIR); obj = local_file_find_or_create(env, lfsck->li_los, root, diff --git a/lustre/lfsck/lfsck_lib.c b/lustre/lfsck/lfsck_lib.c index 7e36a18..64da238 100644 --- a/lustre/lfsck/lfsck_lib.c +++ b/lustre/lfsck/lfsck_lib.c @@ -697,7 +697,7 @@ static int lfsck_create_lpf_local(const struct lu_env *env, if (rc != 0) GOTO(stop, rc); - if (!dt_try_as_dir(env, child)) + if (!dt_try_as_dir(env, child, false)) GOTO(stop, rc = -ENOTDIR); /* 2a. increase child nlink */ @@ -875,7 +875,7 @@ static int lfsck_create_lpf_remote(const struct lu_env *env, if (rc != 0) GOTO(stop, rc); - if (!dt_try_as_dir(env, child)) + if (!dt_try_as_dir(env, child, false)) GOTO(stop, rc = -ENOTDIR); /* 2a. increase child nlink */ @@ -1077,8 +1077,8 @@ static int lfsck_create_lpf(const struct lu_env *env, if (IS_ERR(child)) GOTO(unlock, rc = PTR_ERR(child)); - if (dt_object_exists(child) != 0) { - if (unlikely(!dt_try_as_dir(env, child))) + if (dt_object_exists(child)) { + if (unlikely(!dt_try_as_dir(env, child, true))) rc = -ENOTDIR; else lfsck->li_lpf_obj = child; @@ -1293,13 +1293,7 @@ static int lfsck_verify_lpf_pairs(const struct lu_env *env, if (IS_ERR(parent2)) GOTO(linkea, parent2); - if (!dt_object_exists(parent2)) { - lfsck_object_put(env, parent2); - - GOTO(linkea, parent2 = ERR_PTR(-ENOENT)); - } - - if (!dt_try_as_dir(env, parent2)) { + if (!dt_try_as_dir(env, parent2, true)) { lfsck_object_put(env, parent2); GOTO(linkea, parent2 = ERR_PTR(-ENOTDIR)); @@ -1450,7 +1444,7 @@ int lfsck_verify_lpf(const struct lu_env *env, struct lfsck_instance *lfsck) LASSERT(dt_object_exists(parent)); - if (unlikely(!dt_try_as_dir(env, parent))) { + if (unlikely(!dt_try_as_dir(env, parent, true))) { lfsck_object_put(env, parent); GOTO(put, rc = -ENOTDIR); @@ -1499,7 +1493,7 @@ int lfsck_verify_lpf(const struct lu_env *env, struct lfsck_instance *lfsck) goto find_child1; } - if (unlikely(!dt_try_as_dir(env, child2))) + if (unlikely(!dt_try_as_dir(env, child2, true))) GOTO(put, rc = -ENOTDIR); find_child1: @@ -1562,7 +1556,7 @@ find_child1: goto check_child2; } - if (unlikely(!dt_try_as_dir(env, child1))) { + if (unlikely(!dt_try_as_dir(env, child1, true))) { lfsck_object_put(env, child1); child1 = NULL; rc = -ENOTDIR; @@ -1583,7 +1577,7 @@ check_child2: put: if (lfsck->li_lpf_obj != NULL) { - if (unlikely(!dt_try_as_dir(env, lfsck->li_lpf_obj))) { + if (unlikely(!dt_try_as_dir(env, lfsck->li_lpf_obj, true))) { lfsck_object_put(env, lfsck->li_lpf_obj); lfsck->li_lpf_obj = NULL; rc = -ENOTDIR; @@ -2021,7 +2015,7 @@ lfsck_assistant_object_load(const struct lu_env *env, return ERR_PTR(-ENOENT); } - if (lso->lso_is_dir && unlikely(!dt_try_as_dir(env, obj))) { + if (lso->lso_is_dir && unlikely(!dt_try_as_dir(env, obj, true))) { lfsck_object_put(env, obj); return ERR_PTR(-ENOTDIR); @@ -3738,9 +3732,6 @@ int lfsck_register(const struct lu_env *env, struct dt_device *key, if (rc != 0) GOTO(out, rc); - if (unlikely(!dt_try_as_dir(env, obj))) - GOTO(out, rc = -ENOTDIR); - *pfid = *fid; rc = dt_lookup_dir(env, obj, lostfound, fid); if (rc != 0) diff --git a/lustre/lfsck/lfsck_namespace.c b/lustre/lfsck/lfsck_namespace.c index df57d18..3bdcbe6 100644 --- a/lustre/lfsck/lfsck_namespace.c +++ b/lustre/lfsck/lfsck_namespace.c @@ -1317,7 +1317,7 @@ static int lfsck_namespace_insert_normal(const struct lu_env *env, } } - if (unlikely(!dt_try_as_dir(env, parent))) + if (unlikely(!dt_try_as_dir(env, parent, true))) GOTO(unlock, rc = -ENOTDIR); th = lfsck_trans_create(env, dev, lfsck); @@ -1480,7 +1480,7 @@ static int lfsck_namespace_create_orphan_dir(const struct lu_env *env, if (IS_ERR(parent)) GOTO(log, rc = PTR_ERR(parent)); - if (unlikely(!dt_try_as_dir(env, parent))) + if (unlikely(!dt_try_as_dir(env, parent, true))) GOTO(log, rc = -ENOTDIR); } else { if (unlikely(lfsck->li_lpf_obj == NULL)) @@ -1552,7 +1552,7 @@ again: if (rc != 0) GOTO(stop, rc); - if (unlikely(!dt_try_as_dir(env, orphan))) + if (unlikely(!dt_try_as_dir(env, orphan, false))) GOTO(stop, rc = -ENOTDIR); rc = dt_declare_ref_add(env, orphan, th); @@ -1954,7 +1954,7 @@ static int lfsck_namespace_replace_cond(const struct lu_env *env, if (IS_ERR(parent)) GOTO(log, rc = PTR_ERR(parent)); - if (unlikely(!dt_try_as_dir(env, parent))) + if (unlikely(!dt_try_as_dir(env, parent, true))) GOTO(log, rc = -ENOTDIR); rc = lfsck_lock(env, lfsck, parent, name, pllh, @@ -2226,7 +2226,7 @@ int lfsck_namespace_repair_dirent(const struct lu_env *env, if (IS_ERR(parent)) GOTO(log, rc = PTR_ERR(parent)); - if (unlikely(!dt_try_as_dir(env, parent))) + if (unlikely(!dt_try_as_dir(env, parent, true))) GOTO(log, rc = -ENOTDIR); if (!update || strcmp(name, name2) == 0) @@ -2657,7 +2657,7 @@ lost_parent: } /* !dt_object_exists(parent) */ /* The unique linkEA entry with bad parent will be handled as orphan. */ - if (unlikely(!dt_try_as_dir(env, parent))) { + if (unlikely(!dt_try_as_dir(env, parent, true))) { if (!lustre_handle_is_used(lh) && retry != NULL) *retry = true; else @@ -2913,7 +2913,7 @@ again: } /* The linkEA entry with bad parent will be removed. */ - if (unlikely(!dt_try_as_dir(env, parent))) { + if (unlikely(!dt_try_as_dir(env, parent, true))) { lfsck_object_put(env, parent); lfsck_linkea_del_buf(ldata, cname); continue; @@ -3256,7 +3256,7 @@ static int lfsck_namespace_double_scan_dir(const struct lu_env *env, RETURN(0); } - if (unlikely(!dt_try_as_dir(env, child))) + if (unlikely(!dt_try_as_dir(env, child, true))) GOTO(out, rc = -ENOTDIR); /* We only take ldlm lock on the @child when required. When the @@ -3861,7 +3861,7 @@ lost_parent: } /* !dt_object_exists(parent) */ /* The linkEA entry with bad parent will be removed. */ - if (unlikely(!dt_try_as_dir(env, parent))) { + if (unlikely(!dt_try_as_dir(env, parent, true))) { lfsck_object_put(env, parent); rc = lfsck_namespace_shrink_linkea(env, com, child, &ldata, cname, pfid, true); @@ -4237,7 +4237,7 @@ static int lfsck_namespace_reset(const struct lu_env *env, if (IS_ERR(root)) GOTO(log, rc = PTR_ERR(root)); - if (unlikely(!dt_try_as_dir(env, root))) + if (unlikely(!dt_try_as_dir(env, root, true))) GOTO(put, rc = -ENOTDIR); down_write(&com->lc_sem); @@ -5323,7 +5323,7 @@ int lfsck_namespace_repair_dangling(const struct lu_env *env, if (IS_ERR(parent)) GOTO(log, rc = PTR_ERR(parent)); - if (unlikely(!dt_try_as_dir(env, parent))) + if (unlikely(!dt_try_as_dir(env, parent, true))) GOTO(log, rc = -ENOTDIR); child = lfsck_object_locate(dev, child); @@ -5395,7 +5395,7 @@ int lfsck_namespace_repair_dangling(const struct lu_env *env, GOTO(stop, rc); if (S_ISDIR(type)) { - if (unlikely(!dt_try_as_dir(env, child))) + if (unlikely(!dt_try_as_dir(env, child, false))) GOTO(stop, rc = -ENOTDIR); /* 2a. increase child nlink */ @@ -6287,7 +6287,7 @@ static void lfsck_namespace_scan_local_lpf(const struct lu_env *env, if (!dt_object_exists(parent)) GOTO(out, rc = 0); - if (unlikely(!dt_try_as_dir(env, parent))) + if (unlikely(!dt_try_as_dir(env, parent, true))) GOTO(out, rc = -ENOTDIR); CDEBUG(D_LFSCK, "%s: start to scan backend /lost+found\n", @@ -7122,7 +7122,7 @@ int lfsck_namespace_setup(const struct lu_env *env, if (IS_ERR(root)) GOTO(out, rc = PTR_ERR(root)); - if (unlikely(!dt_try_as_dir(env, root))) + if (unlikely(!dt_try_as_dir(env, root, true))) GOTO(out, rc = -ENOTDIR); obj = local_index_find_or_create(env, lfsck->li_los, root, diff --git a/lustre/lfsck/lfsck_striped_dir.c b/lustre/lfsck/lfsck_striped_dir.c index 63a8754..493b42b 100644 --- a/lustre/lfsck/lfsck_striped_dir.c +++ b/lustre/lfsck/lfsck_striped_dir.c @@ -1171,7 +1171,7 @@ static int lfsck_allow_regenerate_master_lmv(const struct lu_env *env, __u16 type; ENTRY; - if (unlikely(!dt_try_as_dir(env, obj))) + if (unlikely(!dt_try_as_dir(env, obj, true))) RETURN(-ENOTDIR); /* Check whether the shard and the master MDT-object matches or not. */ @@ -1637,7 +1637,7 @@ int lfsck_namespace_scan_shard(const struct lu_env *env, if (lmv->lmv_magic != LMV_MAGIC_STRIPE) RETURN(1); - if (unlikely(!dt_try_as_dir(env, child))) + if (unlikely(!dt_try_as_dir(env, child, true))) RETURN(-ENOTDIR); OBD_ALLOC_PTR(llmv); @@ -1782,7 +1782,7 @@ int lfsck_namespace_verify_stripe_slave(const struct lu_env *env, if (unlikely(!dt_object_exists(parent))) GOTO(out, rc = 1); - if (unlikely(!dt_try_as_dir(env, parent))) + if (unlikely(!dt_try_as_dir(env, parent, true))) GOTO(out, rc = -ENOTDIR); rc = lfsck_read_stripe_lmv(env, lfsck, parent, plmv); diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index a2d36fa..9e7073b 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -878,7 +878,7 @@ int lod_load_lmv_shards(const struct lu_env *env, struct lod_object *lo, memcpy(buf->lb_buf, tbuf.lb_buf, tbuf.lb_len); } - if (unlikely(!dt_try_as_dir(env, obj))) + if (unlikely(!dt_try_as_dir(env, obj, true))) RETURN(-ENOTDIR); memset(&lmv1->lmv_stripe_fids[0], 0, stripes * sizeof(struct lu_fid)); @@ -1930,7 +1930,7 @@ static int lod_dir_declare_create_stripes(const struct lu_env *env, slave_lmv_buf.lb_buf = slave_lmm; slave_lmv_buf.lb_len = sizeof(*slave_lmm); - if (!dt_try_as_dir(env, dt_object_child(dt))) + if (!dt_try_as_dir(env, dt_object_child(dt), false)) GOTO(out, rc = -EINVAL); rec->rec_type = S_IFDIR; @@ -1952,7 +1952,7 @@ static int lod_dir_declare_create_stripes(const struct lu_env *env, if (rc != 0) GOTO(out, rc); - if (!dt_try_as_dir(env, dto)) + if (!dt_try_as_dir(env, dto, false)) GOTO(out, rc = -EINVAL); rc = lod_sub_declare_ref_add(env, dto, th); @@ -8328,8 +8328,8 @@ static int lod_dir_declare_layout_attach(const struct lu_env *env, if (!lmv_is_sane(lmv)) RETURN(-EINVAL); - if (!dt_try_as_dir(env, dt)) - return -ENOTDIR; + if (!dt_try_as_dir(env, dt, false)) + RETURN(-ENOTDIR); dof->dof_type = DFT_DIR; @@ -8369,7 +8369,7 @@ static int lod_dir_declare_layout_attach(const struct lu_env *env, stripes[i + lo->ldo_dir_stripe_count] = dto; - if (!dt_try_as_dir(env, dto)) + if (!dt_try_as_dir(env, dto, true)) GOTO(out, rc = -ENOTDIR); rc = lod_sub_declare_ref_add(env, dto, th); @@ -8462,7 +8462,7 @@ static int lod_dir_declare_layout_detach(const struct lu_env *env, int i; int rc = 0; - if (!dt_try_as_dir(env, dt)) + if (!dt_try_as_dir(env, dt, true)) return -ENOTDIR; if (!lo->ldo_dir_stripe_count) @@ -8474,7 +8474,7 @@ static int lod_dir_declare_layout_detach(const struct lu_env *env, if (!dto) continue; - if (!dt_try_as_dir(env, dto)) + if (!dt_try_as_dir(env, dto, true)) return -ENOTDIR; rc = lod_sub_declare_delete(env, dto, @@ -8507,7 +8507,7 @@ static int dt_dir_is_empty(const struct lu_env *env, ENTRY; - if (!dt_try_as_dir(env, obj)) + if (!dt_try_as_dir(env, obj, true)) RETURN(-ENOTDIR); iops = &obj->do_index_ops->dio_it; @@ -8554,7 +8554,7 @@ static int lod_dir_declare_layout_shrink(const struct lu_env *env, LASSERT(lmu); - if (!dt_try_as_dir(env, dt)) + if (!dt_try_as_dir(env, dt, true)) return -ENOTDIR; /* shouldn't be called on plain directory */ diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 1250bd1..1b83614 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -101,8 +101,7 @@ __mdd_lookup(const struct lu_env *env, struct md_object *pobj, if (rc) RETURN(rc); - if (likely(S_ISDIR(mdd_object_type(mdd_obj)) && - dt_try_as_dir(env, dir))) + if (likely(dt_try_as_dir(env, dir, true))) rc = dt_lookup(env, dir, (struct dt_rec *)fid, key); else rc = -ENOTDIR; @@ -369,7 +368,7 @@ int mdd_dir_is_empty(const struct lu_env *env, struct mdd_object *dir) ENTRY; obj = mdd_object_child(dir); - if (!dt_try_as_dir(env, obj)) + if (!dt_try_as_dir(env, obj, true)) RETURN(-ENOTDIR); iops = &obj->do_index_ops->dio_it; @@ -660,7 +659,7 @@ static int __mdd_index_delete_only(const struct lu_env *env, struct mdd_object * int rc; ENTRY; - if (dt_try_as_dir(env, next)) + if (dt_try_as_dir(env, next, true)) rc = dt_delete(env, next, (struct dt_key *)name, handle); else rc = -ENOTDIR; @@ -677,7 +676,7 @@ static int __mdd_index_insert_only(const struct lu_env *env, int rc; ENTRY; - if (dt_try_as_dir(env, next)) { + if (dt_try_as_dir(env, next, true)) { struct dt_insert_rec *rec = &mdd_env_info(env)->mdi_dt_rec; rec->rec_fid = lf; diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h index 1986d27..daffa1c 100644 --- a/lustre/mdd/mdd_internal.h +++ b/lustre/mdd/mdd_internal.h @@ -740,7 +740,7 @@ int mdo_declare_index_insert(const struct lu_env *env, struct mdd_object *obj, */ rc = -ENOTDIR; - if (dt_try_as_dir(env, next)) { + if (dt_try_as_dir(env, next, false)) { struct dt_insert_rec *rec = &mdd_env_info(env)->mdi_dt_rec; rec->rec_fid = fid; @@ -754,15 +754,15 @@ int mdo_declare_index_insert(const struct lu_env *env, struct mdd_object *obj, static inline int mdo_declare_index_delete(const struct lu_env *env, struct mdd_object *obj, - const char *name, struct thandle *handle) + const char *name, struct thandle *handle) { - struct dt_object *next = mdd_object_child(obj); + struct dt_object *next = mdd_object_child(obj); - if (!dt_try_as_dir(env, next)) - return -ENOTDIR; + if (!dt_try_as_dir(env, next, true)) + return -ENOTDIR; - return dt_declare_delete(env, next, (const struct dt_key *)name, - handle); + return dt_declare_delete(env, next, (const struct dt_key *)name, + handle); } static inline int mdo_declare_ref_add(const struct lu_env *env, diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 7de1017..b58559a 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -3577,18 +3577,12 @@ stop: * no need check again. */ static int mdd_readpage_sanity_check(const struct lu_env *env, - struct mdd_object *obj) + struct mdd_object *obj) { - struct dt_object *next = mdd_object_child(obj); - int rc; - ENTRY; - - if (S_ISDIR(mdd_object_type(obj)) && dt_try_as_dir(env, next)) - rc = 0; - else - rc = -ENOTDIR; + if (!dt_try_as_dir(env, mdd_object_child(obj), true)) + return -ENOTDIR; - RETURN(rc); + return 0; } static int mdd_dir_page_build(const struct lu_env *env, struct dt_object *obj, diff --git a/lustre/mdd/mdd_orphans.c b/lustre/mdd/mdd_orphans.c index 1dde5f3..e698390 100644 --- a/lustre/mdd/mdd_orphans.c +++ b/lustre/mdd/mdd_orphans.c @@ -173,6 +173,7 @@ int mdd_orphan_insert(const struct lu_env *env, struct mdd_object *obj, GOTO(out, rc); mdo_ref_add(env, obj, th); + if (!S_ISDIR(mdd_object_type(obj))) GOTO(out, rc = 0); @@ -180,7 +181,7 @@ int mdd_orphan_insert(const struct lu_env *env, struct mdd_object *obj, dt_ref_add(env, mdd->mdd_orphans, th); /* try best to fixup directory, do not return errors from here */ - if (!dt_try_as_dir(env, next)) + if (!dt_try_as_dir(env, next, true)) GOTO(out, rc = 0); dt_delete(env, next, (const struct dt_key *)dotdot, th); @@ -509,7 +510,7 @@ int mdd_orphan_index_init(const struct lu_env *env, struct mdd_device *mdd) if (IS_ERR(d)) RETURN(PTR_ERR(d)); LASSERT(lu_object_exists(&d->do_lu)); - if (!dt_try_as_dir(env, d)) { + if (!dt_try_as_dir(env, d, true)) { CERROR("%s: orphan dir '%s' is not an index: rc = %d\n", mdd2obd_dev(mdd)->obd_name, mdd_orphan_index_name, rc); dt_object_put(env, d); diff --git a/lustre/mgs/mgs_fs.c b/lustre/mgs/mgs_fs.c index 6d3a152..cdbad80 100644 --- a/lustre/mgs/mgs_fs.c +++ b/lustre/mgs/mgs_fs.c @@ -150,7 +150,7 @@ int mgs_fs_setup(const struct lu_env *env, struct mgs_device *mgs) if (IS_ERR(o)) GOTO(out_root, rc = PTR_ERR(o)); - if (!dt_try_as_dir(env, o)) { + if (!dt_try_as_dir(env, o, true)) { dt_object_put(env, o); GOTO(out_root, rc = -ENOTDIR); } diff --git a/lustre/obdclass/dt_object.c b/lustre/obdclass/dt_object.c index 95f54b8..1d0a39c 100644 --- a/lustre/obdclass/dt_object.c +++ b/lustre/obdclass/dt_object.c @@ -167,10 +167,38 @@ void dt_object_fini(struct dt_object *obj) } EXPORT_SYMBOL(dt_object_fini); -int dt_try_as_dir(const struct lu_env *env, struct dt_object *obj) +/** + * Set directory .do_index_ops. + * + * Set directory index operations, if the caller knows directory exists, + * \a check should be set to ensure object is directory and exists, while for + * new directories, skip check and the index operations will be used to create + * ".." under directory. + * + * Normally this is called before dt_lookup() to ensure directory objects + * exists and .do_index_ops is correctly set. + * + * \param env lu_env object. + * \param obj dt object. + * \param check check \a obj existence and type, return if index ops is set. + * \retval 1 on success. + * \retval 0 on error. + */ +int dt_try_as_dir(const struct lu_env *env, struct dt_object *obj, bool check) { - if (obj->do_index_ops == NULL) - obj->do_ops->do_index_try(env, obj, &dt_directory_features); + if (check) { + if (unlikely(!dt_object_exists(obj))) + return 0; + + if (unlikely(!S_ISDIR(lu_object_attr(&obj->do_lu)))) + return 0; + + if (obj->do_index_ops) + return 1; + } + + obj->do_ops->do_index_try(env, obj, &dt_directory_features); + return obj->do_index_ops != NULL; } EXPORT_SYMBOL(dt_try_as_dir); @@ -211,7 +239,7 @@ EXPORT_SYMBOL(dt_mode_to_dft); int dt_lookup_dir(const struct lu_env *env, struct dt_object *dir, const char *name, struct lu_fid *fid) { - if (dt_try_as_dir(env, dir)) + if (dt_try_as_dir(env, dir, true)) return dt_lookup(env, dir, (struct dt_rec *)fid, (const struct dt_key *)name); return -ENOTDIR; diff --git a/lustre/obdclass/llog_osd.c b/lustre/obdclass/llog_osd.c index 8354dd5..33b1133 100644 --- a/lustre/obdclass/llog_osd.c +++ b/lustre/obdclass/llog_osd.c @@ -1247,7 +1247,7 @@ static struct dt_object *llog_osd_dir_get(const struct lu_env *env, return ERR_PTR(rc); dir = dt_locate(env, dt, &dti->dti_fid); - if (!IS_ERR(dir) && !dt_try_as_dir(env, dir)) { + if (!IS_ERR(dir) && !dt_try_as_dir(env, dir, true)) { dt_object_put(env, dir); return ERR_PTR(-ENOTDIR); } @@ -1454,7 +1454,7 @@ struct dt_object *llog_osd_get_regular_fid_dir(const struct lu_env *env, if (IS_ERR(dir)) RETURN(dir); - if (!dt_try_as_dir(env, dir)) { + if (!dt_try_as_dir(env, dir, true)) { dt_object_put(env, dir); RETURN(ERR_PTR(-ENOTDIR)); } diff --git a/lustre/obdclass/local_storage.c b/lustre/obdclass/local_storage.c index 2e2a0c4..91518ac 100644 --- a/lustre/obdclass/local_storage.c +++ b/lustre/obdclass/local_storage.c @@ -347,7 +347,7 @@ static struct dt_object *__local_file_create(const struct lu_env *env, GOTO(trans_stop, rc); if (dti->dti_dof.dof_type == DFT_DIR) { - if (!dt_try_as_dir(env, dto)) + if (!dt_try_as_dir(env, dto, false)) GOTO(trans_stop, rc = -ENOTDIR); rec->rec_type = S_IFDIR; diff --git a/lustre/obdclass/scrub.c b/lustre/obdclass/scrub.c index d3d46b8..0a7b953 100644 --- a/lustre/obdclass/scrub.c +++ b/lustre/obdclass/scrub.c @@ -1168,7 +1168,7 @@ int lustre_index_restore(const struct lu_env *env, struct dt_device *dev, LASSERT(dt_object_exists(parent_obj)); - if (unlikely(!dt_try_as_dir(env, parent_obj))) + if (unlikely(!dt_try_as_dir(env, parent_obj, true))) GOTO(out, rc = -ENOTDIR); rc = dt_attr_get(env, tgt_obj, la); diff --git a/lustre/quota/lquota_disk.c b/lustre/quota/lquota_disk.c index bc71833..ac1b220 100644 --- a/lustre/quota/lquota_disk.c +++ b/lustre/quota/lquota_disk.c @@ -202,7 +202,7 @@ struct dt_object *lquota_disk_dir_find_create(const struct lu_env *env, if (IS_ERR(qt_dir)) GOTO(out, rc = PTR_ERR(qt_dir)); - if (!dt_try_as_dir(env, qt_dir)) + if (!dt_try_as_dir(env, qt_dir, true)) GOTO(out, rc = -ENOTDIR); EXIT; out: diff --git a/lustre/target/out_handler.c b/lustre/target/out_handler.c index c09f221..f81a77a 100644 --- a/lustre/target/out_handler.c +++ b/lustre/target/out_handler.c @@ -370,7 +370,7 @@ static int out_index_lookup(struct tgt_session_info *tsi) } dt_read_lock(env, obj, DT_TGT_CHILD); - if (!dt_try_as_dir(env, obj)) + if (!dt_try_as_dir(env, obj, true)) GOTO(out_unlock, rc = -ENOTDIR); rc = dt_lookup(env, obj, (struct dt_rec *)&tti->tti_fid1, diff --git a/lustre/target/out_lib.c b/lustre/target/out_lib.c index 5a0c0da..05987a7 100644 --- a/lustre/target/out_lib.c +++ b/lustre/target/out_lib.c @@ -1069,7 +1069,7 @@ static int out_obj_index_insert(const struct lu_env *env, (char *)key, PFID(((struct dt_insert_rec *)rec)->rec_fid), ((struct dt_insert_rec *)rec)->rec_type); - if (dt_try_as_dir(env, dt_obj) == 0) + if (!dt_try_as_dir(env, dt_obj, true)) return -ENOTDIR; dt_write_lock(env, dt_obj, DT_TGT_CHILD); @@ -1090,7 +1090,7 @@ static int out_obj_index_delete(const struct lu_env *env, dt_obd_name(th->th_dev), PFID(lu_object_fid(&dt_obj->do_lu)), (char *)key); - if (dt_try_as_dir(env, dt_obj) == 0) + if (!dt_try_as_dir(env, dt_obj, true)) return -ENOTDIR; dt_write_lock(env, dt_obj, DT_TGT_CHILD); @@ -1140,10 +1140,8 @@ int out_index_insert_add_exec(const struct lu_env *env, struct tx_arg *arg; int rc; - if (dt_try_as_dir(env, dt_obj) == 0) { - rc = -ENOTDIR; - return rc; - } + if (!dt_try_as_dir(env, dt_obj, false)) + return -ENOTDIR; rc = dt_declare_insert(env, dt_obj, rec, key, th); if (rc != 0) @@ -1202,10 +1200,8 @@ int out_index_delete_add_exec(const struct lu_env *env, struct tx_arg *arg; int rc; - if (dt_try_as_dir(env, dt_obj) == 0) { - rc = -ENOTDIR; - return rc; - } + if (!dt_try_as_dir(env, dt_obj, true)) + return -ENOTDIR; LASSERT(ta->ta_handle != NULL); rc = dt_declare_delete(env, dt_obj, key, th); diff --git a/lustre/target/update_recovery.c b/lustre/target/update_recovery.c index b483a26..95e28b7 100644 --- a/lustre/target/update_recovery.c +++ b/lustre/target/update_recovery.c @@ -948,7 +948,7 @@ static int update_recovery_index_insert(const struct lu_env *env, RETURN(-EIO); type = le32_to_cpu(*ptype); - if (dt_try_as_dir(env, dt_obj) == 0) + if (!dt_try_as_dir(env, dt_obj, false)) RETURN(-ENOTDIR); uti->uti_rec.rec_fid = fid; @@ -982,7 +982,7 @@ static int update_recovery_index_delete(const struct lu_env *env, if (name == NULL) RETURN(-EIO); - if (dt_try_as_dir(env, dt_obj) == 0) + if (!dt_try_as_dir(env, dt_obj, true)) RETURN(-ENOTDIR); rc = out_tx_index_delete(env, dt_obj, -- 1.8.3.1