X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fmdd%2Fmdd_object.c;h=95420dcf5e7f7bf12a56f1dc83c3fd40523f8d21;hp=a735f7f70f21c291ed6a403beb78b634fa5509f2;hb=e2d9b897acb9c54f8a3f799b251335452824e5c1;hpb=3c55f5cf85fbb790dfea40f3da76d7b0d17f29ba diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index a735f7f..95420dc 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -245,7 +245,7 @@ struct lov_mds_md *mdd_max_lmm_get(const struct lu_env *env, } if (unlikely(mti->mti_max_lmm == NULL)) { OBD_ALLOC(mti->mti_max_lmm, max_lmm_size); - if (unlikely(mti->mti_max_lmm != NULL)) + if (likely(mti->mti_max_lmm != NULL)) mti->mti_max_lmm_size = max_lmm_size; } return mti->mti_max_lmm; @@ -714,9 +714,9 @@ static int __mdd_lma_get(const struct lu_env *env, struct mdd_object *mdd_obj, /* Swab and copy LMA */ if (ma->ma_need & MA_HSM) { if (lma->lma_compat & LMAC_HSM) - ma->ma_hsm_flags = lma->lma_flags & HSM_FLAGS_MASK; + ma->ma_hsm.mh_flags = lma->lma_flags & HSM_FLAGS_MASK; else - ma->ma_hsm_flags = 0; + ma->ma_hsm.mh_flags = 0; ma->ma_valid |= MA_HSM; } @@ -733,8 +733,7 @@ static int __mdd_lma_get(const struct lu_env *env, struct mdd_object *mdd_obj, RETURN(0); } -static int mdd_attr_get_internal(const struct lu_env *env, - struct mdd_object *mdd_obj, +int mdd_attr_get_internal(const struct lu_env *env, struct mdd_object *mdd_obj, struct md_attr *ma) { int rc = 0; @@ -762,8 +761,8 @@ static int mdd_attr_get_internal(const struct lu_env *env, rc = mdd_def_acl_get(env, mdd_obj, ma); } #endif - CDEBUG(D_INODE, "after getattr rc = %d, ma_valid = "LPX64"\n", - rc, ma->ma_valid); + CDEBUG(D_INODE, "after getattr rc = %d, ma_valid = "LPX64" ma_lmm=%p\n", + rc, ma->ma_valid, ma->ma_lmm); RETURN(rc); } @@ -1057,8 +1056,9 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, if (la->la_valid == LA_ATIME) { /* This is atime only set for read atime update on close. */ - if (la->la_atime <= tmp_la->la_atime + - mdd_obj2mdd_dev(obj)->mdd_atime_diff) + if (la->la_atime > tmp_la->la_atime && + la->la_atime <= (tmp_la->la_atime + + mdd_obj2mdd_dev(obj)->mdd_atime_diff)) la->la_valid &= ~LA_ATIME; RETURN(0); } @@ -1231,6 +1231,7 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, static int mdd_changelog_data_store(const struct lu_env *env, struct mdd_device *mdd, enum changelog_rec_type type, + int flags, struct mdd_object *mdd_obj, struct thandle *handle) { @@ -1240,13 +1241,16 @@ static int mdd_changelog_data_store(const struct lu_env *env, int reclen; int rc; + /* Not recording */ if (!(mdd->mdd_cl.mc_flags & CLM_ON)) RETURN(0); + if ((mdd->mdd_cl.mc_mask & (1 << type)) == 0) + RETURN(0); LASSERT(handle != NULL); LASSERT(mdd_obj != NULL); - if ((type == CL_TIME) && + if ((type >= CL_MTIME) && (type <= CL_ATIME) && cfs_time_before_64(mdd->mdd_cl.mc_starttime, mdd_obj->mod_cltime)) { /* Don't need multiple updates in this log */ /* Don't check under lock - no big deal if we get an extra @@ -1260,7 +1264,7 @@ static int mdd_changelog_data_store(const struct lu_env *env, RETURN(-ENOMEM); rec = (struct llog_changelog_rec *)buf->lb_buf; - rec->cr.cr_flags = CLF_VERSION; + rec->cr.cr_flags = CLF_VERSION | (CLF_FLAGMASK & flags); rec->cr.cr_type = (__u32)type; rec->cr.cr_tfid = *tfid; rec->cr.cr_namelen = 0; @@ -1276,6 +1280,28 @@ static int mdd_changelog_data_store(const struct lu_env *env, return 0; } +int mdd_changelog(const struct lu_env *env, enum changelog_rec_type type, + int flags, struct md_object *obj) +{ + struct thandle *handle; + struct mdd_object *mdd_obj = md2mdd_obj(obj); + struct mdd_device *mdd = mdo2mdd(obj); + int rc; + ENTRY; + + handle = mdd_trans_start(env, mdd); + + if (IS_ERR(handle)) + return(PTR_ERR(handle)); + + rc = mdd_changelog_data_store(env, mdd, type, flags, mdd_obj, + handle); + + mdd_trans_stop(env, mdd, rc, handle); + + RETURN(rc); +} + /** * Should be called with write lock held. * @@ -1306,7 +1332,7 @@ static int __mdd_lma_set(const struct lu_env *env, struct mdd_object *mdd_obj, /* Copy HSM data */ if (ma->ma_valid & MA_HSM) { - lma->lma_flags |= ma->ma_hsm_flags & HSM_FLAGS_MASK; + lma->lma_flags |= ma->ma_hsm.mh_flags & HSM_FLAGS_MASK; lma->lma_compat |= LMAC_HSM; } @@ -1353,6 +1379,36 @@ static int mdd_lma_set_locked(const struct lu_env *env, return rc; } +/* Precedence for choosing record type when multiple + * attributes change: setattr > mtime > ctime > atime + * (ctime changes when mtime does, plus chmod/chown. + * atime and ctime are independent.) */ +static int mdd_attr_set_changelog(const struct lu_env *env, + struct md_object *obj, struct thandle *handle, + __u64 valid) +{ + struct mdd_device *mdd = mdo2mdd(obj); + int bits, type = 0; + + bits = (valid & ~(LA_CTIME|LA_MTIME|LA_ATIME)) ? 1 << CL_SETATTR : 0; + bits |= (valid & LA_MTIME) ? 1 << CL_MTIME : 0; + bits |= (valid & LA_CTIME) ? 1 << CL_CTIME : 0; + bits |= (valid & LA_ATIME) ? 1 << CL_ATIME : 0; + bits = bits & mdd->mdd_cl.mc_mask; + if (bits == 0) + return 0; + + /* The record type is the lowest non-masked set bit */ + while (bits && ((bits & 1) == 0)) { + bits = bits >> 1; + type++; + } + + /* FYI we only store the first CLF_FLAGMASK bits of la_valid */ + return mdd_changelog_data_store(env, mdd, type, (int)valid, + md2mdd_obj(obj), handle); +} + /* set attr and LOV EA at once, return updated attr */ static int mdd_attr_set(const struct lu_env *env, struct md_object *obj, const struct md_attr *ma) @@ -1375,6 +1431,16 @@ static int mdd_attr_set(const struct lu_env *env, struct md_object *obj, #endif ENTRY; + *la_copy = ma->ma_attr; + rc = mdd_fix_attr(env, mdd_obj, la_copy, ma); + if (rc != 0) + RETURN(rc); + + /* setattr on "close" only change atime, or do nothing */ + if (ma->ma_valid == MA_INODE && + ma->ma_attr.la_valid == LA_ATIME && la_copy->la_valid == 0) + RETURN(0); + mdd_setattr_txn_param_build(env, obj, (struct md_attr *)ma, MDD_TXN_ATTR_SET_OP); handle = mdd_trans_start(env, mdd); @@ -1400,11 +1466,6 @@ static int mdd_attr_set(const struct lu_env *env, struct md_object *obj, CDEBUG(D_INODE, "setting mtime "LPU64", ctime "LPU64"\n", ma->ma_attr.la_mtime, ma->ma_attr.la_ctime); - *la_copy = ma->ma_attr; - rc = mdd_fix_attr(env, mdd_obj, la_copy, ma); - if (rc) - GOTO(cleanup, rc); - #ifdef HAVE_QUOTA_SUPPORT if (mds->mds_quota && la_copy->la_valid & (LA_UID | LA_GID)) { struct obd_export *exp = md_quota(env)->mq_exp; @@ -1478,11 +1539,8 @@ static int mdd_attr_set(const struct lu_env *env, struct md_object *obj, } cleanup: if (rc == 0) - rc = mdd_changelog_data_store(env, mdd, - (ma->ma_attr.la_valid & - ~(LA_MTIME|LA_CTIME|LA_ATIME)) ? - CL_SETATTR : CL_TIME, - mdd_obj, handle); + rc = mdd_attr_set_changelog(env, obj, handle, + ma->ma_attr.la_valid); mdd_trans_stop(env, mdd, rc, handle); if (rc == 0 && (lmm != NULL && lmm_size > 0 )) { /*set obd attr, if needed*/ @@ -1572,9 +1630,8 @@ static int mdd_xattr_set(const struct lu_env *env, struct md_object *obj, rc = mdd_xattr_set_txn(env, mdd_obj, buf, name, fl, handle); /* Only record user xattr changes */ - if ((rc == 0) && (mdd->mdd_cl.mc_flags & CLM_ON) && - (strncmp("user.", name, 5) == 0)) - rc = mdd_changelog_data_store(env, mdd, CL_XATTR, mdd_obj, + if ((rc == 0) && (strncmp("user.", name, 5) == 0)) + rc = mdd_changelog_data_store(env, mdd, CL_XATTR, 0, mdd_obj, handle); mdd_trans_stop(env, mdd, rc, handle); @@ -1609,9 +1666,8 @@ int mdd_xattr_del(const struct lu_env *env, struct md_object *obj, mdd_write_unlock(env, mdd_obj); /* Only record user xattr changes */ - if ((rc == 0) && (mdd->mdd_cl.mc_flags & CLM_ON) && - (strncmp("user.", name, 5) != 0)) - rc = mdd_changelog_data_store(env, mdd, CL_XATTR, mdd_obj, + if ((rc == 0) && (strncmp("user.", name, 5) != 0)) + rc = mdd_changelog_data_store(env, mdd, CL_XATTR, 0, mdd_obj, handle); mdd_trans_stop(env, mdd, rc, handle); @@ -2012,7 +2068,7 @@ static int mdd_close(const struct lu_env *env, struct md_object *obj, { struct mdd_object *mdd_obj = md2mdd_obj(obj); struct mdd_device *mdd = mdo2mdd(obj); - struct thandle *handle; + struct thandle *handle = NULL; int rc; int reset = 1; @@ -2024,14 +2080,26 @@ static int mdd_close(const struct lu_env *env, struct md_object *obj, #endif ENTRY; - rc = mdd_log_txn_param_build(env, obj, ma, MDD_TXN_UNLINK_OP); - if (rc) - RETURN(rc); - handle = mdd_trans_start(env, mdo2mdd(obj)); - if (IS_ERR(handle)) - RETURN(PTR_ERR(handle)); + /* check without any lock */ + if (mdd_obj->mod_count == 1 && + (mdd_obj->mod_flags & (ORPHAN_OBJ | DEAD_OBJ)) != 0) { + again: + rc = mdd_log_txn_param_build(env, obj, ma, MDD_TXN_UNLINK_OP); + if (rc) + RETURN(rc); + handle = mdd_trans_start(env, mdo2mdd(obj)); + if (IS_ERR(handle)) + RETURN(PTR_ERR(handle)); + } mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD); + if (handle == NULL && + mdd_obj->mod_count == 1 && + (mdd_obj->mod_flags & ORPHAN_OBJ) != 0) { + mdd_write_unlock(env, mdd_obj); + goto again; + } + /* release open count */ mdd_obj->mod_count --; @@ -2086,7 +2154,8 @@ out: ma->ma_valid &= ~(MA_LOV | MA_COOKIE); mdd_write_unlock(env, mdd_obj); - mdd_trans_stop(env, mdo2mdd(obj), rc, handle); + if (handle != NULL) + mdd_trans_stop(env, mdo2mdd(obj), rc, handle); #ifdef HAVE_QUOTA_SUPPORT if (quota_opc) /* Trigger dqrel on the owner of child. If failed, @@ -2378,9 +2447,12 @@ const struct md_object_operations mdd_obj_ops = { .moo_close = mdd_close, .moo_readpage = mdd_readpage, .moo_readlink = mdd_readlink, + .moo_changelog = mdd_changelog, .moo_capa_get = mdd_capa_get, .moo_object_sync = mdd_object_sync, .moo_version_get = mdd_version_get, .moo_version_set = mdd_version_set, .moo_path = mdd_path, + .moo_file_lock = mdd_file_lock, + .moo_file_unlock = mdd_file_unlock, };