From 04898c5e480faa12522570d8aa184eb02e79fc59 Mon Sep 17 00:00:00 2001 From: Alex Zhuravlev Date: Wed, 12 Sep 2012 21:34:17 +0400 Subject: [PATCH] LU-1304 mdd: do not use ma internally this is the first step to prepare mdd for LOD and removing LOV management from MDD Signed-off-by: Alex Zhuravlev Change-Id: I65a6f6bc867ff3107eb6fb927da60ace304754af Reviewed-on: http://review.whamcloud.com/4032 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: wangdi Reviewed-by: Oleg Drokin --- lustre/mdd/mdd_dir.c | 366 ++++++++++++++++++++++----------------- lustre/mdd/mdd_internal.h | 34 ++-- lustre/mdd/mdd_object.c | 131 ++++++-------- lustre/mdd/mdd_permission.c | 33 ++-- lustre/osd-ldiskfs/osd_handler.c | 1 - 5 files changed, 285 insertions(+), 280 deletions(-) diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 69fd1dc..8f65973 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -300,7 +300,6 @@ int mdd_may_create(const struct lu_env *env, struct mdd_object *pobj, rc = mdd_permission_internal_locked(env, pobj, NULL, MAY_WRITE | MAY_EXEC, MOR_TGT_PARENT); - if (!rc && check_nlink) rc = __mdd_may_link(env, pobj); @@ -311,7 +310,7 @@ int mdd_may_create(const struct lu_env *env, struct mdd_object *pobj, * Check whether can unlink from the pobj in the case of "cobj == NULL". */ int mdd_may_unlink(const struct lu_env *env, struct mdd_object *pobj, - const struct md_attr *ma) + const struct lu_attr *attr) { int rc; ENTRY; @@ -319,8 +318,8 @@ int mdd_may_unlink(const struct lu_env *env, struct mdd_object *pobj, if (mdd_is_dead_obj(pobj)) RETURN(-ENOENT); - if ((ma->ma_attr.la_valid & LA_FLAGS) && - (ma->ma_attr.la_flags & (LUSTRE_APPEND_FL | LUSTRE_IMMUTABLE_FL))) + if ((attr->la_valid & LA_FLAGS) && + (attr->la_flags & (LUSTRE_APPEND_FL | LUSTRE_IMMUTABLE_FL))) RETURN(-EPERM); rc = mdd_permission_internal_locked(env, pobj, NULL, @@ -372,8 +371,8 @@ static inline int mdd_is_sticky(const struct lu_env *env, * pobj maybe NULL */ int mdd_may_delete(const struct lu_env *env, struct mdd_object *pobj, - struct mdd_object *cobj, struct md_attr *ma, - int check_perm, int check_empty) + struct mdd_object *cobj, struct lu_attr *cattr, + struct lu_attr *src_attr, int check_perm, int check_empty) { int rc = 0; ENTRY; @@ -404,29 +403,31 @@ int mdd_may_delete(const struct lu_env *env, struct mdd_object *pobj, RETURN(-EPERM); } - if (!(ma->ma_attr_flags & MDS_VTX_BYPASS) && - mdd_is_sticky(env, pobj, cobj)) + if (mdd_is_sticky(env, pobj, cobj)) RETURN(-EPERM); if (mdd_is_immutable(cobj) || mdd_is_append(cobj)) RETURN(-EPERM); - if ((ma->ma_attr.la_valid & LA_FLAGS) && - (ma->ma_attr.la_flags & (LUSTRE_APPEND_FL | LUSTRE_IMMUTABLE_FL))) + if ((cattr->la_valid & LA_FLAGS) && + (cattr->la_flags & (LUSTRE_APPEND_FL | LUSTRE_IMMUTABLE_FL))) RETURN(-EPERM); - if (S_ISDIR(ma->ma_attr.la_mode)) { - struct mdd_device *mdd = mdo2mdd(&cobj->mod_obj); + /* additional check the rename case */ + if (src_attr) { + if (S_ISDIR(src_attr->la_mode)) { + struct mdd_device *mdd = mdo2mdd(&cobj->mod_obj); - if (!S_ISDIR(mdd_object_type(cobj))) - RETURN(-ENOTDIR); + if (!S_ISDIR(cattr->la_mode)) + RETURN(-ENOTDIR); - if (lu_fid_eq(mdo2fid(cobj), &mdd->mdd_root_fid)) - RETURN(-EBUSY); - } else if (S_ISDIR(mdd_object_type(cobj))) - RETURN(-EISDIR); + if (lu_fid_eq(mdo2fid(cobj), &mdd->mdd_root_fid)) + RETURN(-EBUSY); + } else if (S_ISDIR(cattr->la_mode)) + RETURN(-EISDIR); + } - if (S_ISDIR(ma->ma_attr.la_mode) && check_empty) + if (S_ISDIR(cattr->la_mode) && check_empty) rc = mdd_dir_is_empty(env, cobj); RETURN(rc); @@ -900,7 +901,7 @@ static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj, la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime; la->la_valid = LA_CTIME | LA_MTIME; - rc = mdd_attr_check_set_internal_locked(env, mdd_tobj, la, handle, 0); + rc = mdd_attr_check_set_internal(env, mdd_tobj, la, handle, 0); if (rc) GOTO(out_unlock, rc); @@ -954,17 +955,14 @@ int mdd_finish_unlink(const struct lu_env *env, struct mdd_object *obj, struct md_attr *ma, struct thandle *th) { - int rc; + int rc = 0; int reset = 1; int is_dir = S_ISDIR(ma->ma_attr.la_mode); ENTRY; LASSERT(mdd_write_locked(env, obj) != 0); - /* read HSM flags, needed to set changelogs flags */ - ma->ma_need = MA_HSM | MA_INODE; - rc = mdd_attr_get_internal(env, obj, ma); - if (rc == 0 && (ma->ma_attr.la_nlink == 0 || is_dir)) { + if (rc == 0 && (ma->ma_attr.la_nlink == 0 || is_dir)) { obj->mod_flags |= DEAD_OBJ; /* add new orphan and the object * will be deleted during mdd_close() */ @@ -986,10 +984,6 @@ int mdd_finish_unlink(const struct lu_env *env, if (rc == 0) reset = 0; } - - /* get the i_nlink */ - ma->ma_need = MA_INODE; - rc = mdd_attr_get_internal(env, obj, ma); } if (reset) ma->ma_valid &= ~(MA_LOV | MA_COOKIE); @@ -1002,12 +996,12 @@ int mdd_finish_unlink(const struct lu_env *env, * has mdd_write_lock on cobj already, but not on pobj yet */ int mdd_unlink_sanity_check(const struct lu_env *env, struct mdd_object *pobj, - struct mdd_object *cobj, struct md_attr *ma) + struct mdd_object *cobj, struct lu_attr *cattr) { int rc; ENTRY; - rc = mdd_may_delete(env, pobj, cobj, ma, 1, 1); + rc = mdd_may_delete(env, pobj, cobj, cattr, NULL, 1, 1); RETURN(rc); } @@ -1061,6 +1055,7 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, struct md_attr *ma) { const char *name = lname->ln_name; + struct lu_attr *cattr = &mdd_env_info(env)->mti_cattr; struct lu_attr *la = &mdd_env_info(env)->mti_la_for_fix; struct mdd_object *mdd_pobj = md2mdd_obj(pobj); struct mdd_object *mdd_cobj = md2mdd_obj(cobj); @@ -1074,8 +1069,7 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, unsigned int qpids[MAXQUOTAS] = { 0, 0 }; int quota_opc = 0; #endif - int is_dir = S_ISDIR(ma->ma_attr.la_mode); - int rc; + int rc, is_dir; ENTRY; if (mdd_object_exists(mdd_cobj) <= 0) @@ -1096,15 +1090,17 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, dlh = mdd_pdo_write_lock(env, mdd_pobj, name, MOR_TGT_PARENT); if (dlh == NULL) - GOTO(out_trans, rc = -ENOMEM); + GOTO(stop, rc = -ENOMEM); mdd_write_lock(env, mdd_cobj, MOR_TGT_CHILD); - rc = mdd_unlink_sanity_check(env, mdd_pobj, mdd_cobj, ma); + /* fetch cattr */ + rc = mdd_la_get(env, mdd_cobj, cattr, mdd_object_capa(env, mdd_cobj)); if (rc) GOTO(cleanup, rc); - rc = __mdd_index_delete(env, mdd_pobj, name, is_dir, handle, - mdd_object_capa(env, mdd_pobj)); + is_dir = S_ISDIR(cattr->la_mode); + + rc = mdd_unlink_sanity_check(env, mdd_pobj, mdd_cobj, cattr); if (rc) GOTO(cleanup, rc); @@ -1116,19 +1112,29 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, GOTO(cleanup, rc); } + rc = __mdd_index_delete(env, mdd_pobj, name, is_dir, handle, + mdd_object_capa(env, mdd_pobj)); + if (rc) + GOTO(cleanup, rc); + if (is_dir) /* unlink dot */ mdo_ref_del(env, mdd_cobj, handle); + /* fetch updated nlink */ + rc = mdd_la_get(env, mdd_cobj, cattr, mdd_object_capa(env, mdd_cobj)); + if (rc) + GOTO(cleanup, rc); + LASSERT(ma->ma_attr.la_valid & LA_CTIME); la->la_ctime = la->la_mtime = ma->ma_attr.la_ctime; la->la_valid = LA_CTIME | LA_MTIME; - rc = mdd_attr_check_set_internal_locked(env, mdd_pobj, la, handle, 0); + rc = mdd_attr_check_set_internal(env, mdd_pobj, la, handle, 0); if (rc) GOTO(cleanup, rc); - if (ma->ma_attr.la_nlink > 0 || mdd_cobj->mod_count > 0) { + if (cattr->la_nlink > 0 || mdd_cobj->mod_count > 0) { /* update ctime of an unlinked file only if it is still * opened or a link still exists */ la->la_valid = LA_CTIME; @@ -1137,7 +1143,16 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, GOTO(cleanup, rc); } + /* XXX: this transfer to ma will be removed with LOD/OSP */ + ma->ma_attr = *cattr; + ma->ma_valid |= MA_INODE; rc = mdd_finish_unlink(env, mdd_cobj, ma, handle); + + /* fetch updated nlink */ + if (rc == 0) + rc = mdd_la_get(env, mdd_cobj, cattr, + mdd_object_capa(env, mdd_cobj)); + #ifdef HAVE_QUOTA_SUPPORT if (mds->mds_quota && ma->ma_valid & MA_INODE && ma->ma_attr.la_nlink == 0) { @@ -1160,15 +1175,19 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, mdd_links_rename(env, mdd_cobj, mdo2fid(mdd_pobj), lname, NULL, NULL, handle); + /* if object is removed then we can't get its attrs, use last get */ + if (cattr->la_nlink == 0) { + ma->ma_attr = *cattr; + ma->ma_valid |= MA_INODE; + } EXIT; cleanup: mdd_write_unlock(env, mdd_cobj); mdd_pdo_write_unlock(env, mdd_pobj, dlh); -out_trans: if (rc == 0) { int cl_flags; - cl_flags = (ma->ma_attr.la_nlink == 0) ? CLF_UNLINK_LAST : 0; + cl_flags = (cattr->la_nlink == 0) ? CLF_UNLINK_LAST : 0; if ((ma->ma_valid & MA_HSM) && (ma->ma_hsm.mh_flags & HS_EXISTS)) cl_flags |= CLF_UNLINK_HSM_EXISTS; @@ -1368,19 +1387,20 @@ __mdd_lookup(const struct lu_env *env, struct md_object *pobj, } int mdd_declare_object_initialize(const struct lu_env *env, - struct mdd_object *child, - struct md_attr *ma, - struct thandle *handle) + struct mdd_object *child, + struct lu_attr *attr, + struct thandle *handle) { int rc; - rc = mdo_declare_attr_set(env, child, &ma->ma_attr, handle); - if (rc == 0 && S_ISDIR(ma->ma_attr.la_mode)) { - rc = mdo_declare_index_insert(env, child, mdo2fid(child), - dot, handle); + rc = mdo_declare_attr_set(env, child, attr, handle); + if (rc == 0 && S_ISDIR(attr->la_mode)) { + rc = mdo_declare_index_insert(env, child, mdo2fid(child), + dot, handle); if (rc == 0) rc = mdo_declare_ref_add(env, child, handle); } + if (rc == 0) mdd_declare_links_add(env, child, handle); @@ -1388,9 +1408,9 @@ int mdd_declare_object_initialize(const struct lu_env *env, } int mdd_object_initialize(const struct lu_env *env, const struct lu_fid *pfid, - const struct lu_name *lname, struct mdd_object *child, - struct md_attr *ma, struct thandle *handle, - const struct md_op_spec *spec) + const struct lu_name *lname, struct mdd_object *child, + struct lu_attr *attr, struct thandle *handle, + const struct md_op_spec *spec) { int rc; ENTRY; @@ -1403,11 +1423,11 @@ int mdd_object_initialize(const struct lu_env *env, const struct lu_fid *pfid, * (2) maybe, the child attributes should be set in OSD when creation. */ - rc = mdd_attr_set_internal(env, child, &ma->ma_attr, handle, 0); + rc = mdd_attr_set_internal(env, child, attr, handle, 0); if (rc != 0) RETURN(rc); - if (S_ISDIR(ma->ma_attr.la_mode)) { + if (S_ISDIR(attr->la_mode)) { /* Add "." and ".." for newly created dir */ mdo_ref_add(env, child, handle); rc = __mdd_index_insert_only(env, child, mdo2fid(child), @@ -1428,12 +1448,12 @@ int mdd_object_initialize(const struct lu_env *env, const struct lu_fid *pfid, /* has not lock on pobj yet */ static int mdd_create_sanity_check(const struct lu_env *env, struct md_object *pobj, + struct lu_attr *pattr, const struct lu_name *lname, - struct md_attr *ma, + struct lu_attr *cattr, struct md_op_spec *spec) { struct mdd_thread_info *info = mdd_env_info(env); - struct lu_attr *la = &info->mti_la; struct lu_fid *fid = &info->mti_fid; struct mdd_object *obj = md2mdd_obj(pobj); struct mdd_device *m = mdo2mdd(pobj); @@ -1466,26 +1486,22 @@ static int mdd_create_sanity_check(const struct lu_env *env, * EXEC permission have been checked * when lookup before create already. */ - rc = mdd_permission_internal_locked(env, obj, NULL, MAY_WRITE, - MOR_TGT_PARENT); + rc = mdd_permission_internal_locked(env, obj, pattr, MAY_WRITE, + MOR_TGT_PARENT); if (rc) RETURN(rc); } /* sgid check */ - rc = mdd_la_get(env, obj, la, BYPASS_CAPA); - if (rc != 0) - RETURN(rc); - - if (la->la_mode & S_ISGID) { - ma->ma_attr.la_gid = la->la_gid; - if (S_ISDIR(ma->ma_attr.la_mode)) { - ma->ma_attr.la_mode |= S_ISGID; - ma->ma_attr.la_valid |= LA_MODE; - } - } + if (pattr->la_mode & S_ISGID) { + cattr->la_gid = pattr->la_gid; + if (S_ISDIR(cattr->la_mode)) { + cattr->la_mode |= S_ISGID; + cattr->la_valid |= LA_MODE; + } + } - switch (ma->ma_attr.la_mode & S_IFMT) { + switch (cattr->la_mode & S_IFMT) { case S_IFLNK: { unsigned int symlen = strlen(spec->u.sp_symname) + 1; @@ -1509,22 +1525,19 @@ static int mdd_create_sanity_check(const struct lu_env *env, RETURN(rc); } -static int mdd_declare_create(const struct lu_env *env, - struct mdd_device *mdd, - struct mdd_object *p, - struct mdd_object *c, - const struct lu_name *name, - struct md_attr *ma, - int lmm_size, +static int mdd_declare_create(const struct lu_env *env, struct mdd_device *mdd, + struct mdd_object *p, struct mdd_object *c, + const struct lu_name *name, + struct lu_attr *attr, int lmm_size, int got_def_acl, - struct thandle *handle, - const struct md_op_spec *spec) + struct thandle *handle, + const struct md_op_spec *spec) { struct mdd_thread_info *info = mdd_env_info(env); struct lu_buf *buf = &mdd_env_info(env)->mti_buf; int rc = 0; - rc = mdd_declare_object_create_internal(env, p, c, ma, handle, spec); + rc = mdd_declare_object_create_internal(env, p, c, attr, handle, spec); if (rc) GOTO(out, rc); @@ -1534,7 +1547,7 @@ static int mdd_declare_create(const struct lu_env *env, acl_buf = mdd_buf_get(env, NULL, got_def_acl); /* if dir, then can inherit default ACl */ - if (S_ISDIR(ma->ma_attr.la_mode)) { + if (S_ISDIR(attr->la_mode)) { rc = mdo_declare_xattr_set(env, c, acl_buf, XATTR_NAME_ACL_DEFAULT, 0, handle); @@ -1553,16 +1566,13 @@ static int mdd_declare_create(const struct lu_env *env, } #endif - /* if dir, then can inherit default ACl */ - buf->lb_buf = NULL; - buf->lb_len = lmm_size; - if (S_ISDIR(ma->ma_attr.la_mode)) { + if (S_ISDIR(attr->la_mode)) { rc = mdo_declare_ref_add(env, p, handle); if (rc) GOTO(out, rc); } - rc = mdd_declare_object_initialize(env, c, ma, handle); + rc = mdd_declare_object_initialize(env, c, attr, handle); if (rc) GOTO(out, rc); @@ -1576,14 +1586,15 @@ static int mdd_declare_create(const struct lu_env *env, if (rc) GOTO(out, rc); - if (S_ISLNK(ma->ma_attr.la_mode)) { + if (S_ISLNK(attr->la_mode)) { rc = dt_declare_record_write(env, mdd_object_child(c), strlen(spec->u.sp_symname), 0, handle); if (rc) GOTO(out, rc); } - rc = mdo_declare_attr_set(env, p, &ma->ma_attr, handle); + + rc = mdo_declare_attr_set(env, p, attr, handle); if (rc) return rc; @@ -1601,12 +1612,9 @@ out: /* * Create object and insert it into namespace. */ -static int mdd_create(const struct lu_env *env, - struct md_object *pobj, - const struct lu_name *lname, - struct md_object *child, - struct md_op_spec *spec, - struct md_attr* ma) +static int mdd_create(const struct lu_env *env, struct md_object *pobj, + const struct lu_name *lname, struct md_object *child, + struct md_op_spec *spec, struct md_attr* ma) { struct mdd_thread_info *info = mdd_env_info(env); struct lu_attr *la = &info->mti_la_for_fix; @@ -1616,6 +1624,7 @@ static int mdd_create(const struct lu_env *env, struct lu_attr *attr = &ma->ma_attr; struct lov_mds_md *lmm = NULL; struct thandle *handle; + struct lu_attr *pattr = &info->mti_pattr; struct dynlock_handle *dlh; const char *name = lname->ln_name; int rc, created = 0, initialized = 0, inserted = 0, lmm_size = 0; @@ -1669,52 +1678,51 @@ static int mdd_create(const struct lu_env *env, * 2. insert (__mdd_index_insert(), lookup again) */ + rc = mdd_la_get(env, mdd_pobj, pattr, BYPASS_CAPA); + if (rc != 0) + RETURN(rc); + /* Sanity checks before big job. */ - rc = mdd_create_sanity_check(env, pobj, lname, ma, spec); + rc = mdd_create_sanity_check(env, pobj, pattr, lname, attr, spec); if (rc) RETURN(rc); #ifdef HAVE_QUOTA_SUPPORT if (mds->mds_quota) { - struct lu_attr *la_tmp = &mdd_env_info(env)->mti_la; - - rc = mdd_la_get(env, mdd_pobj, la_tmp, BYPASS_CAPA); - if (!rc) { - int same = 0; - - quota_opc = FSFILT_OP_CREATE; - mdd_quota_wrapper(&ma->ma_attr, qcids); - mdd_quota_wrapper(la_tmp, qpids); - /* get file quota for child */ - lquota_chkquota(mds_quota_interface_ref, obd, exp, - qcids, inode_pending, 1, NULL, 0, NULL, - 0); - switch (ma->ma_attr.la_mode & S_IFMT) { - case S_IFLNK: - case S_IFDIR: - block_count = 2; - break; - case S_IFREG: - block_count = 1; - break; - } - if (qcids[USRQUOTA] == qpids[USRQUOTA] && - qcids[GRPQUOTA] == qpids[GRPQUOTA]) { - block_count += 1; - same = 1; - } - /* get block quota for child and parent */ - if (block_count) - lquota_chkquota(mds_quota_interface_ref, obd, - exp, qcids, block_pending, - block_count, NULL, - LQUOTA_FLAGS_BLK, NULL, 0); - if (!same) - lquota_chkquota(mds_quota_interface_ref, obd, - exp, qpids, parent_pending, 1, - NULL, LQUOTA_FLAGS_BLK, NULL, - 0); - } + int same = 0; + + quota_opc = FSFILT_OP_CREATE; + mdd_quota_wrapper(attr, qcids); + mdd_quota_wrapper(pattr, qpids); + /* get file quota for child */ + lquota_chkquota(mds_quota_interface_ref, obd, exp, + qcids, inode_pending, 1, NULL, 0, NULL, + 0); + switch (attr->la_mode & S_IFMT) { + case S_IFLNK: + case S_IFDIR: + block_count = 2; + break; + case S_IFREG: + block_count = 1; + break; + } + if (qcids[USRQUOTA] == qpids[USRQUOTA] && + qcids[GRPQUOTA] == qpids[GRPQUOTA]) { + block_count += 1; + same = 1; + } + /* get block quota for child and parent */ + if (block_count) + lquota_chkquota(mds_quota_interface_ref, obd, + exp, qcids, block_pending, + block_count, NULL, + LQUOTA_FLAGS_BLK, NULL, 0); + if (!same) + lquota_chkquota(mds_quota_interface_ref, obd, + exp, qpids, parent_pending, 1, + NULL, LQUOTA_FLAGS_BLK, NULL, + 0); } #endif @@ -1754,7 +1762,7 @@ static int mdd_create(const struct lu_env *env, if (IS_ERR(handle)) GOTO(out_free, rc = PTR_ERR(handle)); - rc = mdd_declare_create(env, mdd, mdd_pobj, son, lname, ma, + rc = mdd_declare_create(env, mdd, mdd_pobj, son, lname, attr, got_def_acl, lmm_size, handle, spec); if (rc) GOTO(out_stop, rc); @@ -1768,7 +1776,7 @@ static int mdd_create(const struct lu_env *env, GOTO(out_trans, rc = -ENOMEM); mdd_write_lock(env, son, MOR_TGT_CHILD); - rc = mdd_object_create_internal(env, mdd_pobj, son, ma, handle, spec); + rc = mdd_object_create_internal(env, mdd_pobj, son, attr, handle, spec); if (rc) { mdd_write_unlock(env, son); GOTO(cleanup, rc); @@ -1790,7 +1798,7 @@ static int mdd_create(const struct lu_env *env, #endif rc = mdd_object_initialize(env, mdo2fid(mdd_pobj), lname, - son, ma, handle, spec); + son, attr, handle, spec); mdd_write_unlock(env, son); if (rc) /* @@ -1804,7 +1812,6 @@ static int mdd_create(const struct lu_env *env, rc = __mdd_index_insert(env, mdd_pobj, mdo2fid(son), name, S_ISDIR(attr->la_mode), handle, mdd_object_capa(env, mdd_pobj)); - if (rc) GOTO(cleanup, rc); @@ -1851,9 +1858,9 @@ static int mdd_create(const struct lu_env *env, GOTO(cleanup, rc = -EFAULT); } - *la = ma->ma_attr; + *la = *attr; la->la_valid = LA_CTIME | LA_MTIME; - rc = mdd_attr_check_set_internal_locked(env, mdd_pobj, la, handle, 0); + rc = mdd_attr_check_set_internal(env, mdd_pobj, la, handle, 0); if (rc) GOTO(cleanup, rc); @@ -1979,20 +1986,18 @@ static int mdd_rename_sanity_check(const struct lu_env *env, struct mdd_object *tgt_pobj, struct mdd_object *sobj, struct mdd_object *tobj, - struct md_attr *ma) + struct lu_attr *so_attr, + struct lu_attr *tg_attr) { int rc = 0; ENTRY; - if (unlikely(ma->ma_attr_flags & MDS_PERM_BYPASS)) - RETURN(0); - /* XXX: when get here, sobj must NOT be NULL, * the other case has been processed in cml_rename * before mdd_rename and enable MDS_PERM_BYPASS. */ LASSERT(sobj); - rc = mdd_may_delete(env, src_pobj, sobj, ma, 1, 0); + rc = mdd_may_delete(env, src_pobj, sobj, so_attr, NULL, 1, 0); if (rc) RETURN(rc); @@ -2005,11 +2010,11 @@ static int mdd_rename_sanity_check(const struct lu_env *env, rc = mdd_may_create(env, tgt_pobj, NULL, (src_pobj != tgt_pobj), 0); else - rc = mdd_may_delete(env, tgt_pobj, tobj, ma, + rc = mdd_may_delete(env, tgt_pobj, tobj, tg_attr, so_attr, (src_pobj != tgt_pobj), 1); if (!rc && !tobj && (src_pobj != tgt_pobj) && - S_ISDIR(ma->ma_attr.la_mode)) + S_ISDIR(so_attr->la_mode)) rc = __mdd_may_link(env, tgt_pobj); RETURN(rc); @@ -2139,6 +2144,8 @@ static int mdd_rename(const struct lu_env *env, const char *sname = lsname->ln_name; const char *tname = ltname->ln_name; struct lu_attr *la = &mdd_env_info(env)->mti_la_for_fix; + struct lu_attr *so_attr = &mdd_env_info(env)->mti_cattr; + struct lu_attr *tg_attr = &mdd_env_info(env)->mti_pattr; struct mdd_object *mdd_spobj = md2mdd_obj(src_pobj); /* source parent */ struct mdd_object *mdd_tpobj = md2mdd_obj(tgt_pobj); struct mdd_device *mdd = mdo2mdd(src_pobj); @@ -2164,9 +2171,6 @@ static int mdd_rename(const struct lu_env *env, #endif ENTRY; - LASSERT(ma->ma_attr.la_mode & S_IFMT); - is_dir = S_ISDIR(ma->ma_attr.la_mode); - if (tobj) mdd_tobj = md2mdd_obj(tobj); @@ -2236,11 +2240,25 @@ static int mdd_rename(const struct lu_env *env, if (sdlh == NULL || tdlh == NULL) GOTO(cleanup, rc = -ENOMEM); - rc = mdd_rename_sanity_check(env, mdd_spobj, mdd_tpobj, - mdd_sobj, mdd_tobj, ma); + rc = mdd_la_get(env, mdd_sobj, so_attr, + mdd_object_capa(env, mdd_sobj)); + if (rc) + GOTO(cleanup, rc); + + if (mdd_tobj) { + rc = mdd_la_get(env, mdd_tobj, tg_attr, + mdd_object_capa(env, mdd_tobj)); + if (rc) + GOTO(cleanup, rc); + } + + rc = mdd_rename_sanity_check(env, mdd_spobj, mdd_tpobj, mdd_sobj, + mdd_tobj, so_attr, tg_attr); if (rc) GOTO(cleanup, rc); + is_dir = S_ISDIR(so_attr->la_mode); + /* Remove source name from source directory */ rc = __mdd_index_delete(env, mdd_spobj, sname, is_dir, handle, mdd_object_capa(env, mdd_spobj)); @@ -2287,8 +2305,7 @@ static int mdd_rename(const struct lu_env *env, /* XXX: mdd_sobj must be local one if it is NOT NULL. */ if (mdd_sobj) { la->la_valid = LA_CTIME; - rc = mdd_attr_check_set_internal_locked(env, mdd_sobj, la, - handle, 0); + rc = mdd_attr_check_set_internal(env, mdd_sobj, la, handle, 0); if (rc) GOTO(fixup_tpobj, rc); } @@ -2310,20 +2327,38 @@ static int mdd_rename(const struct lu_env *env, mdo_ref_del(env, mdd_tobj, handle); /* Remove dot reference. */ - if (is_dir) + if (S_ISDIR(tg_attr->la_mode)) mdo_ref_del(env, mdd_tobj, handle); + /* fetch updated nlink */ + rc = mdd_la_get(env, mdd_tobj, tg_attr, + mdd_object_capa(env, mdd_tobj)); + if (rc) + GOTO(fixup_tpobj, rc); + la->la_valid = LA_CTIME; rc = mdd_attr_check_set_internal(env, mdd_tobj, la, handle, 0); if (rc) GOTO(fixup_tpobj, rc); + /* XXX: this transfer to ma will be removed with LOD/OSP */ + ma->ma_attr = *tg_attr; + ma->ma_valid |= MA_INODE; rc = mdd_finish_unlink(env, mdd_tobj, ma, handle); mdd_write_unlock(env, mdd_tobj); if (rc) GOTO(fixup_tpobj, rc); - if (ma->ma_valid & MA_INODE && ma->ma_attr.la_nlink == 0) { + /* fetch updated nlink */ + rc = mdd_la_get(env, mdd_tobj, tg_attr, + mdd_object_capa(env, mdd_tobj)); + if (rc) + GOTO(fixup_tpobj, rc); + /* XXX: this transfer to ma will be removed with LOD/OSP */ + ma->ma_attr = *tg_attr; + ma->ma_valid |= MA_INODE; + + if (so_attr->la_nlink == 0) { cl_flags |= CLF_RENAME_LAST; #ifdef HAVE_QUOTA_SUPPORT if (mds->mds_quota && mdd_tobj->mod_count == 0) { @@ -2335,14 +2370,14 @@ static int mdd_rename(const struct lu_env *env, } la->la_valid = LA_CTIME | LA_MTIME; - rc = mdd_attr_check_set_internal_locked(env, mdd_spobj, la, handle, 0); + rc = mdd_attr_check_set_internal(env, mdd_spobj, la, handle, 0); if (rc) GOTO(fixup_tpobj, rc); if (mdd_spobj != mdd_tpobj) { la->la_valid = LA_CTIME | LA_MTIME; - rc = mdd_attr_check_set_internal_locked(env, mdd_tpobj, la, - handle, 0); + rc = mdd_attr_check_set_internal(env, mdd_tpobj, la, + handle, 0); } if (rc == 0 && mdd_sobj) { @@ -2466,6 +2501,9 @@ struct lu_buf *mdd_links_get(const struct lu_env *env, if (buf->lb_buf == NULL) return ERR_PTR(-ENOMEM); + if (!mdd_object_exists(mdd_obj)) + return ERR_PTR(-ENODATA); + capa = mdd_object_capa(env, mdd_obj); rc = mdo_xattr_get(env, mdd_obj, buf, XATTR_NAME_LINK, capa); if (rc == -ERANGE) { @@ -2617,9 +2655,10 @@ static int mdd_links_add(const struct lu_env *env, RETURN(rc); leh = buf->lb_buf; - rc = __mdd_xattr_set(env, mdd_obj, + rc = mdo_xattr_set(env, mdd_obj, mdd_buf_get_const(env, buf->lb_buf, leh->leh_len), - XATTR_NAME_LINK, 0, handle); + XATTR_NAME_LINK, 0, handle, + mdd_object_capa(env, mdd_obj)); if (rc) { if (rc == -ENOSPC) CDEBUG(D_INODE, "link_ea add failed %d "DFID"\n", rc, @@ -2704,9 +2743,10 @@ static int mdd_links_rename(const struct lu_env *env, leh = buf->lb_buf; } - rc = __mdd_xattr_set(env, mdd_obj, - mdd_buf_get_const(env, buf->lb_buf, leh->leh_len), - XATTR_NAME_LINK, 0, handle); + rc = mdo_xattr_set(env, mdd_obj, + mdd_buf_get_const(env, buf->lb_buf, leh->leh_len), + XATTR_NAME_LINK, 0, handle, + mdd_object_capa(env, mdd_obj)); out: if (rc == 0) diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h index 09de0a1..c1f2e98 100644 --- a/lustre/mdd/mdd_internal.h +++ b/lustre/mdd/mdd_internal.h @@ -178,13 +178,13 @@ struct mdd_thread_info { struct lu_fid mti_fid2; /* used for be & cpu converting */ struct lu_attr mti_la; struct lu_attr mti_la_for_fix; + struct lu_attr mti_pattr; + struct lu_attr mti_cattr; struct md_attr mti_ma; struct obd_info mti_oi; /* mti_orph_ent and mti_orph_key must be conjoint, * then mti_orph_ent::lde_name will be mti_orph_key. */ struct lu_dirent mti_orph_ent; - struct lu_attr mti_pattr; - struct lu_attr mti_cattr; char mti_orph_key[NAME_MAX + 1]; struct obd_trans_info mti_oti; struct lu_buf mti_buf; @@ -277,9 +277,9 @@ int mdd_attr_get_internal_locked(const struct lu_env *env, struct mdd_object *mdd_obj, struct md_attr *ma); int mdd_object_create_internal(const struct lu_env *env, struct mdd_object *p, - struct mdd_object *c, struct md_attr *ma, - struct thandle *handle, - const struct md_op_spec *spec); + struct mdd_object *c, struct lu_attr *attr, + struct thandle *handle, + const struct md_op_spec *spec); int mdd_attr_check_set_internal_locked(const struct lu_env *env, struct mdd_object *obj, struct lu_attr *attr, @@ -313,18 +313,18 @@ int mdd_is_subdir(const struct lu_env *env, struct md_object *mo, int mdd_may_create(const struct lu_env *env, struct mdd_object *pobj, struct mdd_object *cobj, int check_perm, int check_nlink); int mdd_may_unlink(const struct lu_env *env, struct mdd_object *pobj, - const struct md_attr *ma); + const struct lu_attr *attr); int mdd_may_delete(const struct lu_env *env, struct mdd_object *pobj, - struct mdd_object *cobj, struct md_attr *ma, - int check_perm, int check_empty); + struct mdd_object *cobj, struct lu_attr *cattr, + struct lu_attr *src_attr, int check_perm, int check_empty); int mdd_unlink_sanity_check(const struct lu_env *env, struct mdd_object *pobj, - struct mdd_object *cobj, struct md_attr *ma); + struct mdd_object *cobj, struct lu_attr *cattr); int mdd_finish_unlink(const struct lu_env *env, struct mdd_object *obj, struct md_attr *ma, struct thandle *th); int mdd_object_initialize(const struct lu_env *env, const struct lu_fid *pfid, - const struct lu_name *lname, struct mdd_object *child, - struct md_attr *ma, struct thandle *handle, - const struct md_op_spec *spec); + const struct lu_name *lname, struct mdd_object *child, + struct lu_attr *attr, struct thandle *handle, + const struct md_op_spec *spec); int mdd_link_sanity_check(const struct lu_env *env, struct mdd_object *tgt_obj, const struct lu_name *lname, struct mdd_object *src_obj); int mdd_is_root(struct mdd_device *mdd, const struct lu_fid *fid); @@ -412,11 +412,11 @@ int mdd_declare_changelog_store(const struct lu_env *env, int mdd_changelog(const struct lu_env *env, enum changelog_rec_type type, int flags, struct md_object *obj); int mdd_declare_object_create_internal(const struct lu_env *env, - struct mdd_object *p, - struct mdd_object *c, - struct md_attr *ma, - struct thandle *handle, - const struct md_op_spec *spec); + struct mdd_object *p, + struct mdd_object *c, + struct lu_attr *attr, + struct thandle *handle, + const struct md_op_spec *spec); /* mdd_quota.c*/ #ifdef HAVE_QUOTA_SUPPORT int mdd_quota_notify(const struct lu_env *env, struct md_device *m); diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 9aa7170..218cbd6 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -935,11 +935,11 @@ static int mdd_xattr_list(const struct lu_env *env, struct md_object *obj, } int mdd_declare_object_create_internal(const struct lu_env *env, - struct mdd_object *p, - struct mdd_object *c, - struct md_attr *ma, - struct thandle *handle, - const struct md_op_spec *spec) + struct mdd_object *p, + struct mdd_object *c, + struct lu_attr *attr, + struct thandle *handle, + const struct md_op_spec *spec) { struct dt_object_format *dof = &mdd_env_info(env)->mti_dof; const struct dt_index_features *feat = spec->sp_feat; @@ -949,21 +949,20 @@ int mdd_declare_object_create_internal(const struct lu_env *env, if (feat != &dt_directory_features && feat != NULL) dof->dof_type = DFT_INDEX; else - dof->dof_type = dt_mode_to_dft(ma->ma_attr.la_mode); + dof->dof_type = dt_mode_to_dft(attr->la_mode); dof->u.dof_idx.di_feat = feat; - rc = mdo_declare_create_obj(env, c, &ma->ma_attr, NULL, dof, handle); + rc = mdo_declare_create_obj(env, c, attr, NULL, dof, handle); RETURN(rc); } int mdd_object_create_internal(const struct lu_env *env, struct mdd_object *p, - struct mdd_object *c, struct md_attr *ma, + struct mdd_object *c, struct lu_attr *attr, struct thandle *handle, const struct md_op_spec *spec) { - struct lu_attr *attr = &ma->ma_attr; struct dt_allocation_hint *hint = &mdd_env_info(env)->mti_hint; struct dt_object_format *dof = &mdd_env_info(env)->mti_dof; const struct dt_index_features *feat = spec->sp_feat; @@ -1014,11 +1013,9 @@ static inline int mdd_attr_check(const struct lu_env *env, RETURN(0); } -int mdd_attr_set_internal(const struct lu_env *env, - struct mdd_object *obj, - struct lu_attr *attr, - struct thandle *handle, - int needacl) +int mdd_attr_set_internal(const struct lu_env *env, struct mdd_object *obj, + struct lu_attr *attr, struct thandle *handle, + int needacl) { int rc; ENTRY; @@ -1032,10 +1029,8 @@ int mdd_attr_set_internal(const struct lu_env *env, } int mdd_attr_check_set_internal(const struct lu_env *env, - struct mdd_object *obj, - struct lu_attr *attr, - struct thandle *handle, - int needacl) + struct mdd_object *obj, struct lu_attr *attr, + struct thandle *handle, int needacl) { int rc; ENTRY; @@ -1049,24 +1044,6 @@ int mdd_attr_check_set_internal(const struct lu_env *env, RETURN(rc); } -static int mdd_attr_set_internal_locked(const struct lu_env *env, - struct mdd_object *obj, - struct lu_attr *attr, - struct thandle *handle, - int needacl) -{ - int rc; - ENTRY; - - needacl = needacl && (attr->la_valid & LA_MODE); - if (needacl) - mdd_write_lock(env, obj, MOR_TGT_CHILD); - rc = mdd_attr_set_internal(env, obj, attr, handle, needacl); - if (needacl) - mdd_write_unlock(env, obj); - RETURN(rc); -} - int mdd_attr_check_set_internal_locked(const struct lu_env *env, struct mdd_object *obj, struct lu_attr *attr, @@ -1109,7 +1086,7 @@ int __mdd_xattr_set(const struct lu_env *env, struct mdd_object *obj, * This API is ported from mds_fix_attr but remove some unnecesssary stuff. */ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, - struct lu_attr *la, const struct md_attr *ma) + struct lu_attr *la, const unsigned long flags) { struct lu_attr *tmp_la = &mdd_env_info(env)->mti_la; struct md_ucred *uc; @@ -1139,11 +1116,10 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, RETURN(rc); if (la->la_valid == LA_CTIME) { - if (!(ma->ma_attr_flags & MDS_PERM_BYPASS)) + if (!(flags & MDS_PERM_BYPASS)) /* This is only for set ctime when rename's source is * on remote MDS. */ - rc = mdd_may_delete(env, NULL, obj, - (struct md_attr *)ma, 1, 0); + rc = mdd_may_delete(env, NULL, obj, tmp_la, NULL, 1, 0); if (rc == 0 && la->la_ctime <= tmp_la->la_ctime) la->la_valid &= ~LA_CTIME; RETURN(rc); @@ -1184,7 +1160,7 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, if ((mdd_is_immutable(obj) || mdd_is_append(obj)) && (la->la_valid & ~LA_FLAGS) && - !(ma->ma_attr_flags & MDS_PERM_BYPASS)) + !(flags & MDS_PERM_BYPASS)) RETURN(-EPERM); /* Check for setting the obj time. */ @@ -1192,9 +1168,8 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, !(la->la_valid & ~(LA_MTIME | LA_ATIME | LA_CTIME))) { if ((uc->mu_fsuid != tmp_la->la_uid) && !mdd_capable(uc, CFS_CAP_FOWNER)) { - rc = mdd_permission_internal_locked(env, obj, tmp_la, - MAY_WRITE, - MOR_TGT_CHILD); + rc = mdd_permission_internal(env, obj, tmp_la, + MAY_WRITE); if (rc) RETURN(rc); } @@ -1223,7 +1198,7 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, /* Make sure a caller can chmod. */ if (la->la_valid & LA_MODE) { - if (!(ma->ma_attr_flags & MDS_PERM_BYPASS) && + if (!(flags & MDS_PERM_BYPASS) && (uc->mu_fsuid != tmp_la->la_uid) && !mdd_capable(uc, CFS_CAP_FOWNER)) RETURN(-EPERM); @@ -1295,11 +1270,11 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, /* For both Size-on-MDS case and truncate case, * "la->la_valid & (LA_SIZE | LA_BLOCKS)" are ture. - * We distinguish them by "ma->ma_attr_flags & MDS_SOM". + * We distinguish them by "flags & MDS_SOM". * For SOM case, it is true, the MAY_WRITE perm has been checked * when open, no need check again. For truncate case, it is false, * the MAY_WRITE perm should be checked here. */ - if (ma->ma_attr_flags & MDS_SOM) { + if (flags & MDS_SOM) { /* For the "Size-on-MDS" setattr update, merge coming * attributes with the set in the inode. BUG 10641 */ if ((la->la_valid & LA_ATIME) && @@ -1313,12 +1288,11 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj, la->la_valid &= ~(LA_MTIME | LA_CTIME); } else { if (la->la_valid & (LA_SIZE | LA_BLOCKS)) { - if (!((ma->ma_attr_flags & MDS_OPEN_OWNEROVERRIDE) && + if (!((flags & MDS_OPEN_OWNEROVERRIDE) && (uc->mu_fsuid == tmp_la->la_uid)) && - !(ma->ma_attr_flags & MDS_PERM_BYPASS)) { - rc = mdd_permission_internal_locked(env, obj, - tmp_la, MAY_WRITE, - MOR_TGT_CHILD); + !(flags & MDS_PERM_BYPASS)) { + rc = mdd_permission_internal(env, obj, + tmp_la, MAY_WRITE); if (rc) RETURN(rc); } @@ -1543,9 +1517,10 @@ static int mdd_declare_attr_set(const struct lu_env *env, struct thandle *handle) { struct lu_buf *buf = &mdd_env_info(env)->mti_buf; + struct lu_attr *attr = (struct lu_attr *) &ma->ma_attr; int rc, i; - rc = mdo_declare_attr_set(env, obj, &ma->ma_attr, handle); + rc = mdo_declare_attr_set(env, obj, attr, handle); if (rc) return rc; @@ -1572,10 +1547,10 @@ static int mdd_declare_attr_set(const struct lu_env *env, } #ifdef CONFIG_FS_POSIX_ACL - if (ma->ma_attr.la_valid & LA_MODE) { + if (attr->la_valid & LA_MODE) { mdd_read_lock(env, obj, MOR_TGT_CHILD); - rc = mdo_xattr_get(env, obj, &LU_BUF_NULL,XATTR_NAME_ACL_ACCESS, - BYPASS_CAPA); + rc = mdo_xattr_get(env, obj, &LU_BUF_NULL, + XATTR_NAME_ACL_ACCESS, BYPASS_CAPA); mdd_read_unlock(env, obj); if (rc == -EOPNOTSUPP || rc == -ENODATA) rc = 0; @@ -1583,8 +1558,7 @@ static int mdd_declare_attr_set(const struct lu_env *env, return rc; if (rc != 0) { - buf->lb_buf = NULL; - buf->lb_len = rc; + struct lu_buf *buf = mdd_buf_get(env, NULL, rc); rc = mdo_declare_xattr_set(env, obj, buf, XATTR_NAME_ACL_ACCESS, 0, handle); @@ -1639,6 +1613,7 @@ int mdd_attr_set(const struct lu_env *env, struct md_object *obj, struct llog_cookie *logcookies = NULL; int rc, lmm_size = 0, cookie_size = 0; struct lu_attr *la_copy = &mdd_env_info(env)->mti_la_for_fix; + const struct lu_attr *la = &ma->ma_attr; #ifdef HAVE_QUOTA_SUPPORT struct obd_device *obd = mdd->mdd_obd_dev; struct mds_obd *mds = &obd->u.mds; @@ -1651,13 +1626,12 @@ int mdd_attr_set(const struct lu_env *env, struct md_object *obj, ENTRY; *la_copy = ma->ma_attr; - rc = mdd_fix_attr(env, mdd_obj, la_copy, ma); - if (rc != 0) + rc = mdd_fix_attr(env, mdd_obj, la_copy, ma->ma_attr_flags); + if (rc) 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) + if (la->la_valid == LA_ATIME && la_copy->la_valid == 0) RETURN(0); if (S_ISREG(mdd_object_type(mdd_obj)) && @@ -1688,12 +1662,12 @@ int mdd_attr_set(const struct lu_env *env, struct md_object *obj, GOTO(stop, rc); /* permission changes may require sync operation */ - if (ma->ma_attr.la_valid & (LA_MODE|LA_UID|LA_GID)) + if (ma->ma_attr.la_valid & (LA_MODE|LA_UID|LA_GID)) handle->th_sync |= !!mdd->mdd_sync_permission; - if (ma->ma_attr.la_valid & (LA_MTIME | LA_CTIME)) + if (la->la_valid & (LA_MTIME | LA_CTIME)) CDEBUG(D_INODE, "setting mtime "LPU64", ctime "LPU64"\n", - ma->ma_attr.la_mtime, ma->ma_attr.la_ctime); + la->la_mtime, la->la_ctime); #ifdef HAVE_QUOTA_SUPPORT if (mds->mds_quota && la_copy->la_valid & (LA_UID | LA_GID)) { @@ -1724,13 +1698,11 @@ int mdd_attr_set(const struct lu_env *env, struct md_object *obj, #endif if (la_copy->la_valid & LA_FLAGS) { - rc = mdd_attr_set_internal_locked(env, mdd_obj, la_copy, - handle, 1); + rc = mdd_attr_set_internal(env, mdd_obj, la_copy, handle, 1); if (rc == 0) mdd_flags_xlate(mdd_obj, la_copy->la_flags); } else if (la_copy->la_valid) { /* setattr */ - rc = mdd_attr_set_internal_locked(env, mdd_obj, la_copy, - handle, 1); + rc = mdd_attr_set_internal(env, mdd_obj, la_copy, handle, 1); /* journal chown/chgrp in llog, just like unlink */ if (rc == 0 && lmm_size){ cookie_size = mdd_lov_cookiesize(env, mdd); @@ -1835,7 +1807,6 @@ static int mdd_declare_xattr_set(const struct lu_env *env, const struct lu_buf *buf, const char *name, struct thandle *handle) - { int rc; @@ -1889,15 +1860,20 @@ static int mdd_xattr_set(const struct lu_env *env, struct md_object *obj, if (!strcmp(name, XATTR_NAME_ACL_ACCESS)) handle->th_sync |= !!mdd->mdd_sync_permission; - rc = mdd_xattr_set_txn(env, mdd_obj, buf, name, fl, handle); + mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD); + rc = mdo_xattr_set(env, mdd_obj, buf, name, fl, handle, + mdd_object_capa(env, mdd_obj)); + mdd_write_unlock(env, mdd_obj); + if (rc) + GOTO(stop, rc); /* Only record system & user xattr changes */ - if ((rc == 0) && (strncmp(XATTR_USER_PREFIX, name, + if (strncmp(XATTR_USER_PREFIX, name, sizeof(XATTR_USER_PREFIX) - 1) == 0 || strncmp(POSIX_ACL_XATTR_ACCESS, name, sizeof(POSIX_ACL_XATTR_ACCESS) - 1) == 0 || strncmp(POSIX_ACL_XATTR_DEFAULT, name, - sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) == 0)) + sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) == 0) rc = mdd_changelog_data_store(env, mdd, CL_XATTR, 0, mdd_obj, handle); @@ -1959,14 +1935,16 @@ int mdd_xattr_del(const struct lu_env *env, struct md_object *obj, rc = mdo_xattr_del(env, mdd_obj, name, handle, mdd_object_capa(env, mdd_obj)); mdd_write_unlock(env, mdd_obj); + if (rc) + GOTO(stop, rc); /* Only record system & user xattr changes */ - if ((rc == 0) && (strncmp(XATTR_USER_PREFIX, name, + if (strncmp(XATTR_USER_PREFIX, name, sizeof(XATTR_USER_PREFIX) - 1) == 0 || strncmp(POSIX_ACL_XATTR_ACCESS, name, sizeof(POSIX_ACL_XATTR_ACCESS) - 1) == 0 || strncmp(POSIX_ACL_XATTR_DEFAULT, name, - sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) == 0)) + sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) == 0) rc = mdd_changelog_data_store(env, mdd, CL_XATTR, 0, mdd_obj, handle); @@ -2221,7 +2199,8 @@ static int mdd_close(const struct lu_env *env, struct md_object *obj, } } - rc = mdd_iattr_get(env, mdd_obj, ma); + rc = mdd_la_get(env, mdd_obj, &ma->ma_attr, + mdd_object_capa(env, mdd_obj)); /* Object maybe not in orphan list originally, it is rare case for * mdd_finish_unlink() failure. */ if (rc == 0 && (ma->ma_attr.la_nlink == 0 || is_orphan)) { diff --git a/lustre/mdd/mdd_permission.c b/lustre/mdd/mdd_permission.c index 1f3ba34..b74872b 100644 --- a/lustre/mdd/mdd_permission.c +++ b/lustre/mdd/mdd_permission.c @@ -362,7 +362,7 @@ int mdd_permission(const struct lu_env *env, { struct mdd_object *mdd_pobj, *mdd_cobj; struct md_ucred *uc = NULL; - struct lu_attr *la = NULL; + struct lu_attr *la = &mdd_env_info(env)->mti_cattr; int check_create, check_link; int check_unlink; int check_rename_src, check_rename_tar; @@ -374,17 +374,15 @@ int mdd_permission(const struct lu_env *env, LASSERT(cobj); mdd_cobj = md2mdd_obj(cobj); + rc = mdd_la_get(env, mdd_cobj, la, BYPASS_CAPA); + if (rc) + RETURN(rc); + /* For cross_open case, the "mask" is open flags, * so convert it to permission mask first. * XXX: MDS_OPEN_CROSS must be NOT equal to permission mask MAY_*. */ - if (unlikely(mask & MDS_OPEN_CROSS)) { - la = &mdd_env_info(env)->mti_la; - rc = mdd_la_get(env, mdd_cobj, la, BYPASS_CAPA); - if (rc) - RETURN(rc); - - mask = accmode(env, la, mask & ~MDS_OPEN_CROSS); - } + if (unlikely(mask & MDS_OPEN_CROSS)) + mask = accmode(env, la, mask & ~MDS_OPEN_CROSS); check_create = mask & MAY_CREATE; check_link = mask & MAY_LINK; @@ -407,22 +405,18 @@ int mdd_permission(const struct lu_env *env, if (!rc && (check_create || check_link)) rc = mdd_may_create(env, mdd_cobj, NULL, 1, check_link); - if (!rc && check_unlink) { - LASSERT(ma); - rc = mdd_may_unlink(env, mdd_cobj, ma); - } + if (!rc && check_unlink) + rc = mdd_may_unlink(env, mdd_cobj, la); if (!rc && (check_rename_src || check_rename_tar)) { LASSERT(pobj); - LASSERT(ma); mdd_pobj = md2mdd_obj(pobj); - rc = mdd_may_delete(env, mdd_pobj, mdd_cobj, ma, 1, + rc = mdd_may_delete(env, mdd_pobj, mdd_cobj, la, NULL, 1, check_rename_tar); } if (!rc && (check_vtx_part || check_vtx_full)) { uc = md_ucred(env); - LASSERT(ma); if (likely(!la)) { la = &mdd_env_info(env)->mti_la; rc = mdd_la_get(env, mdd_cobj, la, BYPASS_CAPA); @@ -445,13 +439,6 @@ int mdd_permission(const struct lu_env *env, if (likely(!uc)) uc = md_ucred(env); - if (likely(!la)) { - la = &mdd_env_info(env)->mti_la; - rc = mdd_la_get(env, mdd_cobj, la, BYPASS_CAPA); - if (rc) - RETURN(rc); - } - if (la->la_uid != uc->mu_fsuid && !mdd_capable(uc, CFS_CAP_FOWNER)) rc = -EPERM; diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 05cb0bc..17ad09a 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -2471,7 +2471,6 @@ static int osd_xattr_get(const struct lu_env *env, struct dt_object *dt, LASSERT(dt_object_exists(dt)); LASSERT(inode->i_op != NULL && inode->i_op->getxattr != NULL); - LASSERT(osd_read_locked(env, obj) || osd_write_locked(env, obj)); if (osd_object_auth(env, dt, capa, CAPA_OPC_META_READ)) return -EACCES; -- 1.8.3.1