From 6ce5bf3204486ce85ecf13266db8d8d3aeda1f5a Mon Sep 17 00:00:00 2001 From: wangdi Date: Mon, 7 Aug 2006 15:31:59 +0000 Subject: [PATCH] Branch: b_new_cmd add rename checking for rename --- lustre/mdd/mdd_handler.c | 109 +++++++++++++++++++++++++++++++++++++++++++++- lustre/mdd/mdd_internal.h | 4 ++ 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/lustre/mdd/mdd_handler.c b/lustre/mdd/mdd_handler.c index 68a993c..9a93d23 100644 --- a/lustre/mdd/mdd_handler.c +++ b/lustre/mdd/mdd_handler.c @@ -126,6 +126,29 @@ static void mdd_object_free(const struct lu_context *ctxt, struct lu_object *o) OBD_FREE_PTR(mdd); } +struct mdd_object *mdd_object_find(const struct lu_context *ctxt, + struct mdd_device *d, + const struct lu_fid *f) +{ + struct lu_object *o; + struct mdd_object *m; + ENTRY; + + o = lu_object_find(ctxt, d->mdd_md_dev.md_lu_dev.ld_site, f); + if (IS_ERR(o)) + m = (struct mdd_object *)o; + else + m = lu2mdd_obj(lu_object_locate(o->lo_header, + d->mdd_md_dev.md_lu_dev.ld_type)); + RETURN(m); +} + +static inline void mdd_object_put(const struct lu_context *ctxt, + struct mdd_object *o) +{ + lu_object_put(ctxt, &o->mod_obj.mo_lu); +} + static int mdd_attr_get(const struct lu_context *ctxt, struct md_object *obj, struct md_attr *ma) { @@ -606,6 +629,45 @@ static int __mdd_index_delete(const struct lu_context *ctxt, RETURN(rc); } +/*Check whether it may create the cobj under the pobj*/ +static int mdd_may_create(const struct lu_context *ctxt, + struct mdd_object *pobj, struct mdd_object *cobj) +{ + ENTRY; + if (cobj && lu_object_exists(ctxt, &cobj->mod_obj.mo_lu)) + RETURN(-EEXIST); + + /*check pobj may create or not*/ + RETURN(0); +} +/*Check whether it may delete the cobj under the pobj*/ +static int mdd_may_delete(const struct lu_context *ctxt, + struct mdd_object *pobj, struct mdd_object *cobj, + struct lu_attr *cla, int is_dir) +{ + struct mdd_device *mdd = mdo2mdd(&pobj->mod_obj); + int rc = 0; + + ENTRY; + if (!cobj || !lu_object_exists(ctxt, &cobj->mod_obj.mo_lu)) + RETURN(-ENOENT); + + /*TODO:check append flags*/ + if (is_dir) { + if (!S_ISDIR(cla->la_mode)) + RETURN(-ENOTDIR); + + if (lu_fid_eq(mdd2_lu_fid(cobj), + &mdd->mdd_root_fid)) + RETURN(-EBUSY); + + } else if (S_ISDIR(cla->la_mode)) + RETURN(-EISDIR); + + /*DEAD dir checking*/ + RETURN(rc); +} + static int mdd_link(const struct lu_context *ctxt, struct md_object *tgt_obj, struct md_object *src_obj, const char *name) { @@ -821,6 +883,49 @@ static umode_t mdd_object_type(const struct mdd_object *obj) return obj->mod_obj.mo_lu.lo_header->loh_attr; } +static int mdd_rename_sanity_check (const struct lu_context *ctxt, + struct md_object *src_pobj, + struct md_object *tgt_pobj, + const struct lu_fid *lf, + struct md_object *tobj) +{ + struct mdd_device *mdd =mdo2mdd(src_pobj); + struct mdd_object *sobj = mdd_object_find(ctxt, mdd, lf); + struct lu_attr *la = &mdd_ctx_info(ctxt)->mti_la; + struct dt_object *next; + int rc = 0, src_is_dir, tgt_is_dir; + ENTRY; + + next = mdd_object_child(sobj); + rc = next->do_ops->do_attr_get(ctxt, next, la); + if (rc) + GOTO(out, rc); + src_is_dir = S_ISDIR(la->la_mode); + rc = mdd_may_delete(ctxt, md2mdd_obj(src_pobj), sobj, la, src_is_dir); + if (rc) + GOTO(out, rc); + if (!tobj) { + rc = mdd_may_create(ctxt, md2mdd_obj(tgt_pobj), NULL); + GOTO(out, rc); + } + + next = mdd_object_child(md2mdd_obj(tobj)); + rc = next->do_ops->do_attr_get(ctxt, next, la); + if (rc) + GOTO(out, rc); + rc = mdd_may_delete(ctxt, md2mdd_obj(tgt_pobj),md2mdd_obj(tobj), + la, src_is_dir); + if (rc) + GOTO(out, rc); + + tgt_is_dir = S_ISDIR(la->la_mode); + if (tgt_is_dir && mdd_dir_is_empty(ctxt, md2mdd_obj(tobj))) + GOTO(out, rc = -ENOTEMPTY); +out: + mdd_object_put(ctxt, sobj); + RETURN(rc); +} + static int mdd_rename(const struct lu_context *ctxt, struct md_object *src_pobj, struct md_object *tgt_pobj, const struct lu_fid *lf, const char *sname, struct md_object *tobj, @@ -834,6 +939,9 @@ static int mdd_rename(const struct lu_context *ctxt, struct md_object *src_pobj, int rc, locked = 0; ENTRY; + rc = mdd_rename_sanity_check(ctxt, src_pobj, tgt_pobj, lf, tobj); + if (rc) + RETURN(rc); mdd_txn_param_build(ctxt, &MDD_TXN_RENAME); handle = mdd_trans_start(ctxt, mdd); if (IS_ERR(handle)) @@ -863,7 +971,6 @@ static int mdd_rename(const struct lu_context *ctxt, struct md_object *src_pobj, if (rc) GOTO(cleanup, rc); - if (tobj && lu_object_exists(ctxt, &tobj->mo_lu)) { __mdd_ref_del(ctxt, mdd_tobj, handle); if (S_ISDIR(mdd_object_type(mdd_tobj))) diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h index b2cfc8f..f8d113a 100644 --- a/lustre/mdd/mdd_internal.h +++ b/lustre/mdd/mdd_internal.h @@ -123,6 +123,10 @@ static inline struct obd_device *mdd2_obd(struct mdd_device *mdd) { return mdd->mdd_md_dev.md_lu_dev.ld_obd; } +static inline const struct lu_fid *mdd2_lu_fid(struct mdd_object *mdd) +{ + return lu_object_fid(&mdd->mod_obj.mo_lu); +} int mdd_lov_mdsize(const struct lu_context *ctxt, struct mdd_device *mdd, int *md_size); -- 1.8.3.1