From: yury Date: Sun, 5 Nov 2006 14:12:23 +0000 (+0000) Subject: - optimization for open. In case mdt_reint_open() sees that child object does not... X-Git-Tag: v1_8_0_110~486^2~234 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=7f8ffff20ef5f4f39211c914a15bc1db95d702a0;p=fs%2Flustre-release.git - optimization for open. In case mdt_reint_open() sees that child object does not exist and should be created, tell mdd do not lookup child object again in sanity check. --- diff --git a/lustre/include/md_object.h b/lustre/include/md_object.h index c24074c..827ca72 100644 --- a/lustre/include/md_object.h +++ b/lustre/include/md_object.h @@ -150,8 +150,14 @@ struct md_create_spec { int eadatalen; } sp_ea; } u; - /* create flag from client: such as MDS_OPEN_CREAT, and others */ + + /* Create flag from client: such as MDS_OPEN_CREAT, and others. */ __u32 sp_cr_flags; + + /* Should mdd do lookup sanity check or not. */ + int sp_cr_lookup; + + /* Current lock mode for parent dir where create is performing. */ mdl_mode_t sp_cr_mode; }; diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 90d612e..8b3b5f8 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -982,7 +982,8 @@ int mdd_object_initialize(const struct lu_env *env, const struct lu_fid *pfid, static int mdd_create_sanity_check(const struct lu_env *env, struct md_object *pobj, const char *name, - struct md_attr *ma) + struct md_attr *ma, + int lookup) { struct mdd_thread_info *info = mdd_env_info(env); struct lu_attr *la = &info->mti_la; @@ -996,15 +997,21 @@ static int mdd_create_sanity_check(const struct lu_env *env, RETURN(-ENOENT); /* - * Check if the name already exist, though it will be checked - * in _index_insert also, for avoiding rolling back if exists - * _index_insert. + * In some cases this lookup is not needed - we know before that if name + * exists or not. */ - rc = __mdd_lookup_locked(env, pobj, name, fid, - MAY_WRITE | MAY_EXEC); - if (rc != -ENOENT) - RETURN(rc ? : -EEXIST); - + if (lookup) { + /* + * Check if the name already exist, though it will be checked in + * _index_insert also, for avoiding rolling back if exists + * _index_insert. + */ + rc = __mdd_lookup_locked(env, pobj, name, fid, + MAY_WRITE | MAY_EXEC); + if (rc != -ENOENT) + RETURN(rc ? : -EEXIST); + } + /* sgid check */ mdd_read_lock(env, obj); rc = mdd_la_get(env, obj, la, BYPASS_CAPA); @@ -1096,8 +1103,8 @@ static int mdd_create(const struct lu_env *env, * 2. insert (__mdd_index_insert(), lookup again) */ - /* sanity checks before big job */ - rc = mdd_create_sanity_check(env, pobj, name, ma); + /* Sanity checks before big job. */ + rc = mdd_create_sanity_check(env, pobj, name, ma, spec->sp_cr_lookup); if (rc) RETURN(rc); diff --git a/lustre/mdd/mdd_lov.c b/lustre/mdd/mdd_lov.c index a435e43..07224e6 100644 --- a/lustre/mdd/mdd_lov.c +++ b/lustre/mdd/mdd_lov.c @@ -538,7 +538,7 @@ int mdd_lov_create(const struct lu_env *env, struct mdd_device *mdd, rc = obd_packmd(lov_exp, lmm, lsm); if (rc < 0) { - CERROR("cannot pack lsm, err = %d\n", rc); + CERROR("Cannot pack lsm, err = %d\n", rc); GOTO(out_oti, rc); } *lmm_size = rc; diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index ccf0d21..2bef61b 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -1133,9 +1133,7 @@ static int mdd_open_sanity_check(const struct lu_env *env, S_ISBLK(tmp_la->la_mode) || S_ISCHR(tmp_la->la_mode)) flag &= ~MDS_OPEN_TRUNC; - /* - * For writing append-only file must open it with append mode. - */ + /* For writing append-only file must open it with append mode. */ if (mdd_is_append(obj)) { if ((flag & FMODE_WRITE) && !(flag & MDS_OPEN_APPEND)) RETURN(-EPERM); diff --git a/lustre/mdd/mdd_permission.c b/lustre/mdd/mdd_permission.c index 1df8a92..eed2885 100644 --- a/lustre/mdd/mdd_permission.c +++ b/lustre/mdd/mdd_permission.c @@ -488,7 +488,6 @@ int __mdd_permission_internal(const struct lu_env *env, struct md_ucred *uc = md_ucred(env); __u32 mode; int rc; - ENTRY; if (mask == 0) diff --git a/lustre/mdt/mdt_open.c b/lustre/mdt/mdt_open.c index fc83a3a..46aba69 100644 --- a/lustre/mdt/mdt_open.c +++ b/lustre/mdt/mdt_open.c @@ -401,8 +401,9 @@ static int mdt_mfd_open(struct mdt_thread_info *info, repbody->valid |= OBD_MD_FLOSSCAPA; } - /* if we are following a symlink, don't open; and - * do not return open handle for special nodes as client required + /* + * If we are following a symlink, don't open; and do not return open + * handle for special nodes as client required. */ if (islnk || (!isreg && !isdir && (req->rq_export->exp_connect_flags & OBD_CONNECT_NODEVOH))) { @@ -411,16 +412,18 @@ static int mdt_mfd_open(struct mdt_thread_info *info, } mdt_set_disposition(info, rep, DISP_OPEN_OPEN); - /* we need to return the existing object's fid back, so it is done - * here, after preparing the reply */ + + /* + * We need to return the existing object's fid back, so it is done here, + * after preparing the reply. + */ if (!created && (flags & MDS_OPEN_EXCL) && (flags & MDS_OPEN_CREAT)) RETURN(-EEXIST); /* This can't be done earlier, we need to return reply body */ if (isdir) { if (flags & (MDS_OPEN_CREAT | FMODE_WRITE)) { - /* we are trying to create or - * write an existing dir. */ + /* We are trying to create or write an existing dir. */ RETURN(-EISDIR); } } else if (flags & MDS_OPEN_DIRECTORY) @@ -496,11 +499,13 @@ static int mdt_mfd_open(struct mdt_thread_info *info, mfd = mdt_mfd_new(); if (mfd != NULL) { - /* keep a reference on this object for this open, - * and is released by mdt_mfd_close() */ + /* + * Keep a reference on this object for this open, and is + * released by mdt_mfd_close(). + */ mdt_object_get(info->mti_env, o); - /* open handling */ + /* Open handling. */ mfd->mfd_mode = flags; mfd->mfd_object = o; mfd->mfd_xid = req->rq_xid; @@ -625,8 +630,9 @@ static int mdt_open_by_fid(struct mdt_thread_info* info, if (IS_ERR(o)) RETURN(rc = PTR_ERR(o)); - /* FIXME: capability in replay open request might have expired, disable - * capability check for this kind of request. security hole? + /* + * XXX: capability in replay open request might have expired, disable + * capability check for this kind of request. Security hole? */ if (mdt->mdt_opts.mo_mds_capa) mdt->mdt_child->md_ops->mdo_init_capa_ctxt(env, next, 0, 0, 0, @@ -775,7 +781,7 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) (DISP_IT_EXECD | DISP_LOOKUP_EXECD)); if (rr->rr_name[0] == 0) { - /* this is cross-ref open */ + /* This is cross-ref open */ mdt_set_disposition(info, ldlm_rep, DISP_LOOKUP_POS); result = mdt_cross_open(info, rr->rr_fid1, ldlm_rep, create_flags); @@ -804,7 +810,7 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) mdt_set_disposition(info, ldlm_rep, DISP_LOOKUP_NEG); if (result == -ESTALE) { /* - * ESTALE means the parent is a dead(unlinked) dir, so + * -ESTALE means the parent is a dead(unlinked) dir, so * it should return -ENOENT to in accordance with the * original mds implementaion. */ @@ -813,10 +819,9 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) if (!(create_flags & MDS_OPEN_CREAT)) GOTO(out_parent, result); *child_fid = *info->mti_rr.rr_fid2; - /* new object will be created. see the following */ } else { /* - * Check for O_EXCL is moved to the mdt_mfd_open, we need to + * Check for O_EXCL is moved to the mdt_mfd_open(), we need to * return FID back in that case. */ mdt_set_disposition(info, ldlm_rep, DISP_LOOKUP_POS); @@ -835,6 +840,13 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) /* Let lower layers know what is lock mode on directory. */ info->mti_spec.sp_cr_mode = mdt_dlm_mode2mdl_mode(lh->mlh_pdo_mode); + + /* + * Do not perform lookup sanity check. We know that name does + * not exist. + */ + info->mti_spec.sp_cr_lookup = 0; + result = mdo_create(info->mti_env, mdt_object_child(parent), rr->rr_name, @@ -844,8 +856,7 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) if (result == -ERESTART) { mdt_clear_disposition(info, ldlm_rep, DISP_OPEN_CREATE); GOTO(out_child, result); - } - else { + } else { if (result != 0) GOTO(out_child, result); } @@ -902,9 +913,7 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) /* Try to open it now. */ result = mdt_mfd_open(info, parent, child, create_flags, created, ldlm_rep); - GOTO(finish_open, result); -finish_open: if (result != 0 && created) { int rc2; ma->ma_need = 0; @@ -916,8 +925,9 @@ finish_open: rr->rr_name, &info->mti_attr); if (rc2 != 0) - CERROR("error in cleanup of open"); + CERROR("Error in cleanup of open\n"); } + EXIT; out_child: mdt_object_put(info->mti_env, child); out_parent: diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index 524aebf..d7dfb65 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -70,14 +70,21 @@ static int mdt_md_create(struct mdt_thread_info *info) mdt_fail_write(info->mti_env, info->mti_mdt->mdt_bottom, OBD_FAIL_MDS_REINT_CREATE_WRITE); + /* Let lower layer know current lock mode. */ info->mti_spec.sp_cr_mode = mdt_dlm_mode2mdl_mode(lh->mlh_pdo_mode); + /* + * Do perform lookup sanity check. We do not know if name exists + * or not. + */ + info->mti_spec.sp_cr_lookup = 1; + rc = mdo_create(info->mti_env, next, rr->rr_name, mdt_object_child(child), &info->mti_spec, ma); if (rc == 0) { - /* return fid & attr to client. */ + /* Return fid & attr to client. */ if (ma->ma_valid & MA_INODE) mdt_pack_attr2body(info, repbody, &ma->ma_attr, mdt_object_fid(child)); diff --git a/lustre/osc/osc_create.c b/lustre/osc/osc_create.c index 3b15b58..85ecd8d 100644 --- a/lustre/osc/osc_create.c +++ b/lustre/osc/osc_create.c @@ -235,8 +235,8 @@ int oscc_recovering(struct osc_creator *oscc) int osc_create(struct obd_export *exp, struct obdo *oa, struct lov_stripe_md **ea, struct obd_trans_info *oti) { - struct lov_stripe_md *lsm; struct osc_creator *oscc = &exp->exp_obd->u.cli.cl_oscc; + struct lov_stripe_md *lsm; int try_again = 1, rc = 0; ENTRY;