X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fmdt%2Fmdt_xattr.c;h=9bd7526595158985c60d313b84a8be6e687a8bbb;hp=7d7e15d7fedbddc1bcd73d43769825f1665da7a0;hb=a42be217b5662bc88a9f381f82482f2c5a0e8fb7;hpb=165f65a7aa07d55d284d419cdaa04eed2d96ade3 diff --git a/lustre/mdt/mdt_xattr.c b/lustre/mdt/mdt_xattr.c index 7d7e15d..9bd7526 100644 --- a/lustre/mdt/mdt_xattr.c +++ b/lustre/mdt/mdt_xattr.c @@ -15,11 +15,7 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -27,7 +23,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2014, Intel Corporation. + * Copyright (c) 2011, 2017, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -55,37 +51,48 @@ /* return EADATA length to the caller. negative value means error */ static int mdt_getxattr_pack_reply(struct mdt_thread_info * info) { - struct req_capsule *pill = info->mti_pill ; - struct ptlrpc_request *req = mdt_info_req(info); - char *xattr_name; - __u64 valid; - static const char user_string[] = "user."; - int size, rc; - ENTRY; - - if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETXATTR_PACK)) - RETURN(-ENOMEM); + struct req_capsule *pill = info->mti_pill; + struct ptlrpc_request *req = mdt_info_req(info); + const char *xattr_name; + u64 valid; + static const char user_string[] = "user."; + int size; + int rc = 0; + int rc2; + ENTRY; valid = info->mti_body->mbo_valid & (OBD_MD_FLXATTR | OBD_MD_FLXATTRLS); - /* Determine how many bytes we need */ + /* Determine how many bytes we need */ if (valid == OBD_MD_FLXATTR) { - xattr_name = req_capsule_client_get(pill, &RMF_NAME); - if (!xattr_name) - RETURN(-EFAULT); + xattr_name = req_capsule_client_get(pill, &RMF_NAME); + if (!xattr_name) + RETURN(-EFAULT); if (!(exp_connect_flags(req->rq_export) & OBD_CONNECT_XATTR) && !strncmp(xattr_name, user_string, sizeof(user_string) - 1)) RETURN(-EOPNOTSUPP); - size = mo_xattr_get(info->mti_env, - mdt_object_child(info->mti_object), - &LU_BUF_NULL, xattr_name); - } else if (valid == OBD_MD_FLXATTRLS) { - size = mo_xattr_list(info->mti_env, - mdt_object_child(info->mti_object), - &LU_BUF_NULL); + size = mo_xattr_get(info->mti_env, + mdt_object_child(info->mti_object), + &LU_BUF_NULL, xattr_name); + if (size == -ENODATA) { + /* XXX: Some client code will not handle -ENODATA + * for XATTR_NAME_LOV (trusted.lov) properly. */ + if (strcmp(xattr_name, XATTR_NAME_LOV) == 0) + rc = 0; + else + rc = -ENODATA; + + size = 0; + } + } else if (valid == OBD_MD_FLXATTRLS) { + xattr_name = "list"; + size = mo_xattr_list(info->mti_env, + mdt_object_child(info->mti_object), + &LU_BUF_NULL); } else if (valid == OBD_MD_FLXATTRALL) { + xattr_name = "all"; /* N.B. eadatasize = 0 is not valid for FLXATTRALL */ /* We could calculate accurate sizes, but this would * introduce a lot of overhead, let's do it later... */ @@ -93,69 +100,63 @@ static int mdt_getxattr_pack_reply(struct mdt_thread_info * info) req_capsule_set_size(pill, &RMF_EAVALS, RCL_SERVER, size); req_capsule_set_size(pill, &RMF_EAVALS_LENS, RCL_SERVER, size); } else { - CDEBUG(D_INFO, "Valid bits: "LPX64"\n", + CDEBUG(D_INFO, "Valid bits: %#llx\n", info->mti_body->mbo_valid); - RETURN(-EINVAL); - } - - if (size == -ENODATA) { - size = 0; - } else if (size < 0) { - if (size != -EOPNOTSUPP) - CERROR("Error geting EA size: %d\n", size); + RETURN(-EINVAL); + } + + if (size < 0) { + if (size != -EOPNOTSUPP && size != -ENOENT) + CERROR("%s: error geting EA size for '%s': rc = %d\n", + mdt_obd_name(info->mti_mdt), xattr_name, size); RETURN(size); } - req_capsule_set_size(pill, &RMF_EADATA, RCL_SERVER, + if (req_capsule_has_field(pill, &RMF_ACL, RCL_SERVER)) + req_capsule_set_size(pill, &RMF_ACL, RCL_SERVER, + LUSTRE_POSIX_ACL_MAX_SIZE_OLD); + + req_capsule_set_size(pill, &RMF_EADATA, RCL_SERVER, info->mti_body->mbo_eadatasize == 0 ? 0 : size); - rc = req_capsule_server_pack(pill); - if (rc) { - LASSERT(rc < 0); - RETURN(rc); - } - RETURN(size); + rc2 = req_capsule_server_pack(pill); + if (rc2 < 0) + RETURN(rc2); + + if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETXATTR_PACK)) + RETURN(-ENOMEM); + + RETURN(rc < 0 ? rc : size); } -static int -mdt_getxattr_one(struct mdt_thread_info *info, - char *xattr_name, struct md_object *next, - struct lu_buf *buf, struct mdt_export_data *med, - struct lu_ucred *uc) +static int mdt_nodemap_map_acl(struct mdt_thread_info *info, void *buf, + size_t size, const char *name, + enum nodemap_tree_type tree_type) { - __u32 remote = exp_connect_rmtclient(info->mti_exp); - int flags = CFS_IC_NOTHING, rc; + struct lu_nodemap *nodemap; + struct obd_export *exp = info->mti_exp; + int rc = size; ENTRY; - CDEBUG(D_INODE, "getxattr %s\n", xattr_name); - - rc = mo_xattr_get(info->mti_env, next, buf, xattr_name); - if (rc < 0) - GOTO(out, rc); - - if (info->mti_body->mbo_valid & - (OBD_MD_FLRMTLSETFACL | OBD_MD_FLRMTLGETFACL)) - flags = CFS_IC_ALL; - else if (info->mti_body->mbo_valid & OBD_MD_FLRMTRGETFACL) - flags = CFS_IC_MAPPED; - - if (rc > 0 && flags != CFS_IC_NOTHING) { - int rc1; + if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0 || + strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) { + if (size > info->mti_mdt->mdt_max_ea_size || + (!exp_connect_large_acl(exp) && + size > LUSTRE_POSIX_ACL_MAX_SIZE_OLD)) + GOTO(out, rc = -ERANGE); - if (unlikely(!remote)) - GOTO(out, rc = -EINVAL); + nodemap = nodemap_get_from_exp(exp); + if (IS_ERR(nodemap)) + GOTO(out, rc = PTR_ERR(nodemap)); - rc1 = lustre_posix_acl_xattr_id2client(uc, - med->med_idmap, - (posix_acl_xattr_header *)(buf->lb_buf), - rc, flags); - if (unlikely(rc1 < 0)) - rc = rc1; + rc = nodemap_map_acl(nodemap, buf, size, tree_type); + nodemap_putref(nodemap); + if (rc < 0) + GOTO(out, rc); } - out: - return rc; + RETURN(rc); } static int mdt_getxattr_all(struct mdt_thread_info *info, @@ -163,9 +164,6 @@ static int mdt_getxattr_all(struct mdt_thread_info *info, struct lu_buf *buf, struct md_object *next) { const struct lu_env *env = info->mti_env; - struct ptlrpc_request *req = mdt_info_req(info); - struct mdt_export_data *med = mdt_req2med(req); - struct lu_ucred *uc = mdt_ucred(info); char *v, *b, *eadatahead, *eadatatail; __u32 *sizes; int eadatasize, eavallen = 0, eavallens = 0, rc; @@ -182,10 +180,11 @@ static int mdt_getxattr_all(struct mdt_thread_info *info, eadatahead = buf->lb_buf; /* Fill out EADATA first */ - eadatasize = mo_xattr_list(env, next, buf); - if (eadatasize < 0) - GOTO(out, rc = eadatasize); + rc = mo_xattr_list(env, next, buf); + if (rc < 0) + GOTO(out_shrink, rc); + eadatasize = rc; eadatatail = eadatahead + eadatasize; v = req_capsule_server_get(info->mti_pill, &RMF_EAVALS); @@ -195,15 +194,24 @@ static int mdt_getxattr_all(struct mdt_thread_info *info, for (b = eadatahead; b < eadatatail; b += strlen(b) + 1, v += rc) { buf->lb_buf = v; buf->lb_len = reqbody->mbo_eadatasize - eavallen; - rc = mdt_getxattr_one(info, b, next, buf, med, uc); + rc = mo_xattr_get(env, next, buf, b); if (rc < 0) - GOTO(out, rc); - + GOTO(out_shrink, rc); + rc = mdt_nodemap_map_acl(info, buf->lb_buf, rc, b, + NODEMAP_FS_TO_CLIENT); + if (rc < 0) + GOTO(out_shrink, rc); sizes[eavallens] = rc; eavallens++; eavallen += rc; } +out_shrink: + if (rc < 0) { + eadatasize = 0; + eavallens = 0; + eavallen = 0; + } repbody->mbo_aclsize = eavallen; repbody->mbo_max_mdsize = eavallens; @@ -212,22 +220,18 @@ static int mdt_getxattr_all(struct mdt_thread_info *info, eavallens * sizeof(__u32), RCL_SERVER); req_capsule_shrink(info->mti_pill, &RMF_EADATA, eadatasize, RCL_SERVER); - GOTO(out, rc = eadatasize); -out: + if (rc >= 0) + RETURN(eadatasize); return rc; } int mdt_getxattr(struct mdt_thread_info *info) { struct ptlrpc_request *req = mdt_info_req(info); - struct mdt_export_data *med = mdt_req2med(req); - struct lu_ucred *uc = lu_ucred(info->mti_env); struct mdt_body *reqbody; struct mdt_body *repbody = NULL; struct md_object *next; struct lu_buf *buf; - __u32 remote = exp_connect_rmtclient(info->mti_exp); - __u32 perm; int easize, rc; u64 valid; ENTRY; @@ -246,25 +250,11 @@ int mdt_getxattr(struct mdt_thread_info *info) RETURN(err_serious(rc)); next = mdt_object_child(info->mti_object); - - if (info->mti_body->mbo_valid & OBD_MD_FLRMTRGETFACL) { - if (unlikely(!remote)) - GOTO(out, rc = err_serious(-EINVAL)); - - perm = mdt_identity_get_perm(uc->uc_identity, remote, - req->rq_peer.nid); - if (!(perm & CFS_RMTACL_PERM)) - GOTO(out, rc = err_serious(-EPERM)); - - rc = mo_permission(info->mti_env, NULL, next, NULL, - MAY_RGETFACL); - if (rc) - GOTO(out, rc = err_serious(rc)); - } - easize = mdt_getxattr_pack_reply(info); - if (easize < 0) - GOTO(out, rc = err_serious(easize)); + if (easize == -ENODATA) + GOTO(out, rc = easize); + else if (easize < 0) + GOTO(out, rc = err_serious(easize)); repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY); LASSERT(repbody != NULL); @@ -280,9 +270,14 @@ int mdt_getxattr(struct mdt_thread_info *info) valid = info->mti_body->mbo_valid & (OBD_MD_FLXATTR | OBD_MD_FLXATTRLS); if (valid == OBD_MD_FLXATTR) { - char *xattr_name = req_capsule_client_get(info->mti_pill, - &RMF_NAME); - rc = mdt_getxattr_one(info, xattr_name, next, buf, med, uc); + const char *xattr_name = req_capsule_client_get(info->mti_pill, + &RMF_NAME); + rc = mo_xattr_get(info->mti_env, next, buf, xattr_name); + if (rc < 0) + GOTO(out, rc); + + rc = mdt_nodemap_map_acl(info, buf->lb_buf, rc, xattr_name, + NODEMAP_FS_TO_CLIENT); } else if (valid == OBD_MD_FLXATTRLS) { CDEBUG(D_INODE, "listxattr\n"); @@ -299,6 +294,10 @@ int mdt_getxattr(struct mdt_thread_info *info) out: if (rc >= 0) { mdt_counter_incr(req, LPROC_MDT_GETXATTR); + /* LU-11109: Set OBD_MD_FLXATTR on success so that + * newer clients can distinguish between nonexistent + * xattrs and zero length values. */ + repbody->mbo_valid |= OBD_MD_FLXATTR; repbody->mbo_eadatasize = rc; rc = 0; } @@ -306,58 +305,164 @@ out: return rc; } -static int mdt_rmtlsetfacl(struct mdt_thread_info *info, - struct md_object *next, - const char *xattr_name, - ext_acl_xattr_header *header, - posix_acl_xattr_header **out) +/* shrink dir layout after migration */ +static int mdt_dir_layout_shrink(struct mdt_thread_info *info) { - struct ptlrpc_request *req = mdt_info_req(info); - struct mdt_export_data *med = mdt_req2med(req); - struct lu_ucred *uc = mdt_ucred(info); - struct lu_buf *buf = &info->mti_buf; - int rc; - ENTRY; + const struct lu_env *env = info->mti_env; + struct mdt_device *mdt = info->mti_mdt; + struct mdt_reint_record *rr = &info->mti_rr; + struct lmv_user_md *lmu = rr->rr_eadata; + __u32 lum_stripe_count = lmu->lum_stripe_count; + struct lu_buf *buf = &info->mti_buf; + struct lmv_mds_md_v1 *lmv; + struct md_attr *ma = &info->mti_attr; + struct ldlm_enqueue_info *einfo = &info->mti_einfo[0]; + struct mdt_object *pobj = NULL; + struct mdt_object *obj; + struct mdt_lock_handle *lhp = NULL; + struct mdt_lock_handle *lhc; + int rc; - rc = lustre_ext_acl_xattr_id2server(uc, med->med_idmap, header); - if (rc) - RETURN(rc); + ENTRY; - rc = mo_xattr_get(info->mti_env, next, &LU_BUF_NULL, xattr_name); - if (rc == -ENODATA) - rc = 0; - else if (rc < 0) - RETURN(rc); + rc = mdt_remote_dir_permission(info); + if (rc) + RETURN(rc); + + /* mti_big_lmm is used to save LMV, but it may be uninitialized. */ + if (unlikely(!info->mti_big_lmm)) { + info->mti_big_lmmsize = lmv_mds_md_size(64, LMV_MAGIC); + OBD_ALLOC(info->mti_big_lmm, info->mti_big_lmmsize); + if (!info->mti_big_lmm) + RETURN(-ENOMEM); + } + + obj = mdt_object_find(env, mdt, rr->rr_fid1); + if (IS_ERR(obj)) + RETURN(PTR_ERR(obj)); + +relock: + /* lock object */ + lhc = &info->mti_lh[MDT_LH_CHILD]; + mdt_lock_reg_init(lhc, LCK_EX); + rc = mdt_reint_striped_lock(info, obj, lhc, MDS_INODELOCK_FULL, einfo, + true); + if (rc) + GOTO(put_obj, rc); + + ma->ma_lmv = info->mti_big_lmm; + ma->ma_lmv_size = info->mti_big_lmmsize; + ma->ma_valid = 0; + rc = mdt_stripe_get(info, obj, ma, XATTR_NAME_LMV); + if (rc) + GOTO(unlock_obj, rc); - buf->lb_len = rc; - if (buf->lb_len > 0) { - OBD_ALLOC_LARGE(buf->lb_buf, buf->lb_len); - if (unlikely(buf->lb_buf == NULL)) - RETURN(-ENOMEM); + /* user may run 'lfs migrate' multiple times, so it's shrunk already */ + if (!(ma->ma_valid & MA_LMV)) + GOTO(unlock_obj, rc = -EALREADY); - rc = mo_xattr_get(info->mti_env, next, buf, xattr_name); - if (rc < 0) { - CERROR("getxattr failed: %d\n", rc); - GOTO(_out, rc); - } - } else - buf->lb_buf = NULL; + lmv = &ma->ma_lmv->lmv_md_v1; - rc = lustre_acl_xattr_merge2posix((posix_acl_xattr_header *)(buf->lb_buf), - buf->lb_len, header, out); - EXIT; + /* ditto */ + if (!(le32_to_cpu(lmv->lmv_hash_type) & LMV_HASH_FLAG_MIGRATION)) + GOTO(unlock_obj, rc = -EALREADY); + + lum_stripe_count = lmu->lum_stripe_count; + if (!lum_stripe_count) + lum_stripe_count = cpu_to_le32(1); + + if (lmv->lmv_migrate_offset != lum_stripe_count) { + CERROR("%s: "DFID" migrate mdt count mismatch %u != %u\n", + mdt_obd_name(info->mti_mdt), PFID(rr->rr_fid1), + lmv->lmv_migrate_offset, lmu->lum_stripe_count); + GOTO(unlock_obj, rc = -EINVAL); + } + + if (lmv->lmv_master_mdt_index != lmu->lum_stripe_offset) { + CERROR("%s: "DFID" migrate mdt index mismatch %u != %u\n", + mdt_obd_name(info->mti_mdt), PFID(rr->rr_fid1), + lmv->lmv_master_mdt_index, lmu->lum_stripe_offset); + GOTO(unlock_obj, rc = -EINVAL); + } + + if (lum_stripe_count > 1 && + (lmv->lmv_hash_type & cpu_to_le32(LMV_HASH_TYPE_MASK)) != + lmu->lum_hash_type) { + CERROR("%s: "DFID" migrate mdt hash mismatch %u != %u\n", + mdt_obd_name(info->mti_mdt), PFID(rr->rr_fid1), + lmv->lmv_hash_type, lmu->lum_hash_type); + GOTO(unlock_obj, rc = -EINVAL); + } + + if (le32_to_cpu(lmu->lum_stripe_count) < 2 && !pobj) { + /* + * lock parent because dir will be shrunk to be 1 stripe, which + * should be converted to normal directory, but that will + * change dir fid and update namespace of parent. + */ + lhp = &info->mti_lh[MDT_LH_PARENT]; + mdt_lock_reg_init(lhp, LCK_PW); + + /* get parent from PFID */ + ma->ma_need |= MA_PFID; + ma->ma_valid = 0; + rc = mdt_attr_get_complex(info, obj, ma); + if (rc) + GOTO(unlock_obj, rc); + + if (!(ma->ma_valid & MA_PFID)) + GOTO(unlock_obj, rc = -ENOTSUPP); + + pobj = mdt_object_find(env, mdt, &ma->ma_pfid); + if (IS_ERR(pobj)) { + rc = PTR_ERR(pobj); + pobj = NULL; + GOTO(unlock_obj, rc); + } + + mdt_reint_striped_unlock(info, obj, lhc, einfo, 1); + + if (mdt_object_remote(pobj)) { + rc = mdt_remote_object_lock(info, pobj, rr->rr_fid1, + &lhp->mlh_rreg_lh, LCK_EX, + MDS_INODELOCK_LOOKUP, + false); + if (rc != ELDLM_OK) { + mdt_object_put(env, pobj); + GOTO(put_obj, rc); + } + mdt_object_unlock(info, NULL, lhp, 1); + } + + rc = mdt_reint_object_lock(info, pobj, lhp, + MDS_INODELOCK_UPDATE, true); + if (rc) { + mdt_object_put(env, pobj); + GOTO(put_obj, rc); + } + + goto relock; + } -_out: - if (rc <= 0 && buf->lb_buf != NULL) - OBD_FREE_LARGE(buf->lb_buf, buf->lb_len); - return rc; + buf->lb_buf = rr->rr_eadata; + buf->lb_len = rr->rr_eadatalen; + rc = mo_xattr_set(env, mdt_object_child(obj), buf, XATTR_NAME_LMV, 0); + GOTO(unlock_obj, rc); + +unlock_obj: + mdt_reint_striped_unlock(info, obj, lhc, einfo, rc); + if (pobj) + mdt_object_unlock_put(info, pobj, lhp, rc); +put_obj: + mdt_object_put(env, obj); + + return rc; } int mdt_reint_setxattr(struct mdt_thread_info *info, struct mdt_lock_handle *unused) { struct ptlrpc_request *req = mdt_info_req(info); - struct lu_ucred *uc = lu_ucred(info->mti_env); struct mdt_lock_handle *lh; const struct lu_env *env = info->mti_env; struct lu_buf *buf = &info->mti_buf; @@ -366,16 +471,11 @@ int mdt_reint_setxattr(struct mdt_thread_info *info, struct lu_attr *attr = &info->mti_attr.ma_attr; struct mdt_object *obj; struct md_object *child; - struct obd_export *exp = info->mti_exp; - struct lu_nodemap *nodemap = exp->exp_target_data.ted_nodemap; __u64 valid = attr->la_valid; const char *xattr_name = rr->rr_name.ln_name; int xattr_len = rr->rr_eadatalen; - __u64 lockpart; + __u64 lockpart = MDS_INODELOCK_UPDATE; int rc; - posix_acl_xattr_header *new_xattr = NULL; - __u32 remote = exp_connect_rmtclient(info->mti_exp); - __u32 perm; ENTRY; CDEBUG(D_INODE, "setxattr for "DFID": %s %s\n", PFID(rr->rr_fid1), @@ -391,16 +491,6 @@ int mdt_reint_setxattr(struct mdt_thread_info *info, if (rc != 0) RETURN(rc); - if (valid & OBD_MD_FLRMTRSETFACL) { - if (unlikely(!remote)) - GOTO(out, rc = err_serious(-EINVAL)); - - perm = mdt_identity_get_perm(uc->uc_identity, remote, - req->rq_peer.nid); - if (!(perm & CFS_RMTACL_PERM)) - GOTO(out, rc = err_serious(-EPERM)); - } - if (strncmp(xattr_name, XATTR_USER_PREFIX, sizeof(XATTR_USER_PREFIX) - 1) == 0) { if (!(exp_connect_flags(req->rq_export) & OBD_CONNECT_XATTR)) @@ -408,6 +498,21 @@ int mdt_reint_setxattr(struct mdt_thread_info *info, } else if (strncmp(xattr_name, XATTR_TRUSTED_PREFIX, sizeof(XATTR_TRUSTED_PREFIX) - 1) == 0) { + /* setxattr(LMV) with lum is used to shrink dir layout */ + if (strcmp(xattr_name, XATTR_NAME_LMV) == 0) { + __u32 *magic = rr->rr_eadata; + + /* we don't let to remove LMV? */ + if (!rr->rr_eadata) + GOTO(out, rc = 0); + + if (le32_to_cpu(*magic) == LMV_USER_MAGIC || + le32_to_cpu(*magic) == LMV_USER_MAGIC_SPECIFIC) { + rc = mdt_dir_layout_shrink(info); + GOTO(out, rc); + } + } + if (!md_capable(mdt_ucred(info), CFS_CAP_SYS_ADMIN)) GOTO(out, rc = -EPERM); @@ -421,30 +526,34 @@ int mdt_reint_setxattr(struct mdt_thread_info *info, strcmp(xattr_name, XATTR_NAME_HSM) == 0 || strcmp(xattr_name, XATTR_NAME_LFSCK_NAMESPACE) == 0) GOTO(out, rc = 0); - -#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 8, 53, 0) - if (strcmp(xattr_name, XATTR_NAME_LFSCK_NAMESPACE_OLD) == 0) - GOTO(out, rc = 0); -#endif } else if ((valid & OBD_MD_FLXATTR) && (strcmp(xattr_name, XATTR_NAME_ACL_ACCESS) == 0 || strcmp(xattr_name, XATTR_NAME_ACL_DEFAULT) == 0)) { - - /* currently lustre limit acl access size */ - if (xattr_len > LUSTRE_POSIX_ACL_MAX_SIZE) - GOTO(out, rc = -ERANGE); - - rc = nodemap_map_acl(nodemap, rr->rr_eadata, xattr_len, - NODEMAP_CLIENT_TO_FS); + rc = mdt_nodemap_map_acl(info, rr->rr_eadata, xattr_len, + xattr_name, NODEMAP_CLIENT_TO_FS); if (rc < 0) GOTO(out, rc); - /* ACLs were mapped out, return an error so the user knows */ if (rc != xattr_len) GOTO(out, rc = -EPERM); + } else if ((strlen(xattr_name) > strlen(XATTR_LUSTRE_LOV) + 1) && + strncmp(xattr_name, XATTR_LUSTRE_LOV, + strlen(XATTR_LUSTRE_LOV)) == 0) { + + if (strncmp(xattr_name, XATTR_LUSTRE_LOV".add", + strlen(XATTR_LUSTRE_LOV".add")) && + strncmp(xattr_name, XATTR_LUSTRE_LOV".set", + strlen(XATTR_LUSTRE_LOV".set")) && + strncmp(xattr_name, XATTR_LUSTRE_LOV".del", + strlen(XATTR_LUSTRE_LOV".del"))) { + CERROR("%s: invalid xattr name: %s\n", + mdt_obd_name(info->mti_mdt), xattr_name); + GOTO(out, rc = -EINVAL); + } + + lockpart |= MDS_INODELOCK_LAYOUT; } - lockpart = MDS_INODELOCK_UPDATE; /* Revoke all clients' lookup lock, since the access * permissions for this inode is changed when ACL_ACCESS is * set. This isn't needed for ACL_DEFAULT, since that does @@ -476,29 +585,16 @@ int mdt_reint_setxattr(struct mdt_thread_info *info, /* This isn't strictly an error, but all current clients * should set OBD_MD_FLCTIME when setting attributes. */ CWARN("%s: client miss to set OBD_MD_FLCTIME when " - "setxattr %s: [object "DFID"] [valid "LPU64"]\n", + "setxattr %s: [object "DFID"] [valid %llu]\n", mdt_obd_name(info->mti_mdt), xattr_name, PFID(rr->rr_fid1), valid); - attr->la_ctime = cfs_time_current_sec(); + attr->la_ctime = ktime_get_real_seconds(); } attr->la_valid = LA_CTIME; child = mdt_object_child(obj); if (valid & OBD_MD_FLXATTR) { - void *xattr = rr->rr_eadata; int flags = 0; - if (valid & OBD_MD_FLRMTLSETFACL) { - if (unlikely(!remote)) - GOTO(out_unlock, rc = -EINVAL); - - xattr_len = mdt_rmtlsetfacl(info, child, xattr_name, - xattr, &new_xattr); - if (xattr_len < 0) - GOTO(out_unlock, rc = xattr_len); - - xattr = new_xattr; - } - if (attr->la_flags & XATTR_REPLACE) flags |= LU_XATTR_REPLACE; @@ -508,7 +604,7 @@ int mdt_reint_setxattr(struct mdt_thread_info *info, mdt_fail_write(env, info->mti_mdt->mdt_bottom, OBD_FAIL_MDS_SETXATTR_WRITE); - buf->lb_buf = xattr; + buf->lb_buf = rr->rr_eadata; buf->lb_len = xattr_len; rc = mo_xattr_set(env, child, buf, xattr_name, flags); /* update ctime after xattr changed */ @@ -523,18 +619,17 @@ int mdt_reint_setxattr(struct mdt_thread_info *info, ma->ma_attr_flags |= MDS_PERM_BYPASS; mo_attr_set(env, child, ma); } - } else { - CDEBUG(D_INFO, "valid bits: "LPX64"\n", valid); - rc = -EINVAL; - } - if (rc == 0) + } else { + CDEBUG(D_INFO, "valid bits: %#llx\n", valid); + rc = -EINVAL; + } + + if (rc == 0) mdt_counter_incr(req, LPROC_MDT_SETXATTR); EXIT; out_unlock: mdt_object_unlock_put(info, obj, lh, rc); - if (unlikely(new_xattr != NULL)) - lustre_posix_acl_xattr_free(new_xattr, xattr_len); out: mdt_exit_ucred(info); return rc;