X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmdt%2Fmdt_lib.c;h=574a8f9978ae22632476bf1bac971a8464387c59;hb=003df3c38fe74a092f75569793edd6ec5a387d5c;hp=5ed23d6388c7992b7a7bbd38b3eaad6bf6e4eaf7;hpb=5cf3db0c06c2a659683b9ec3271bb4797a70c480;p=fs%2Flustre-release.git diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index 5ed23d6..574a8f9 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Whamcloud, Inc. + * Copyright (c) 2011, 2013, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -60,66 +60,68 @@ typedef enum ucred_init_type { void mdt_exit_ucred(struct mdt_thread_info *info) { - struct md_ucred *uc = mdt_ucred(info); - struct mdt_device *mdt = info->mti_mdt; - - if (uc->mu_valid != UCRED_INIT) { - uc->mu_suppgids[0] = uc->mu_suppgids[1] = -1; - if (uc->mu_ginfo) { - cfs_put_group_info(uc->mu_ginfo); - uc->mu_ginfo = NULL; - } - if (uc->mu_identity) { - mdt_identity_put(mdt->mdt_identity_cache, - uc->mu_identity); - uc->mu_identity = NULL; - } - uc->mu_valid = UCRED_INIT; - } + struct lu_ucred *uc = mdt_ucred(info); + struct mdt_device *mdt = info->mti_mdt; + + LASSERT(uc != NULL); + if (uc->uc_valid != UCRED_INIT) { + uc->uc_suppgids[0] = uc->uc_suppgids[1] = -1; + if (uc->uc_ginfo) { + put_group_info(uc->uc_ginfo); + uc->uc_ginfo = NULL; + } + if (uc->uc_identity) { + mdt_identity_put(mdt->mdt_identity_cache, + uc->uc_identity); + uc->uc_identity = NULL; + } + uc->uc_valid = UCRED_INIT; + } } -static int match_nosquash_list(cfs_rw_semaphore_t *sem, - cfs_list_t *nidlist, - lnet_nid_t peernid) +static int match_nosquash_list(struct rw_semaphore *sem, + cfs_list_t *nidlist, + lnet_nid_t peernid) { - int rc; - ENTRY; - cfs_down_read(sem); - rc = cfs_match_nid(peernid, nidlist); - cfs_up_read(sem); - RETURN(rc); + int rc; + ENTRY; + down_read(sem); + rc = cfs_match_nid(peernid, nidlist); + up_read(sem); + RETURN(rc); } /* root_squash for inter-MDS operations */ static int mdt_root_squash(struct mdt_thread_info *info, lnet_nid_t peernid) { - struct md_ucred *ucred = mdt_ucred(info); - ENTRY; - - if (!info->mti_mdt->mdt_squash_uid || ucred->mu_fsuid) - RETURN(0); - - if (match_nosquash_list(&info->mti_mdt->mdt_squash_sem, - &info->mti_mdt->mdt_nosquash_nids, - peernid)) { - CDEBUG(D_OTHER, "%s is in nosquash_nids list\n", - libcfs_nid2str(peernid)); - RETURN(0); - } + struct lu_ucred *ucred = mdt_ucred(info); + struct root_squash_info *squash = &info->mti_mdt->mdt_squash; + ENTRY; + + LASSERT(ucred != NULL); + if (!squash->rsi_uid || ucred->uc_fsuid) + RETURN(0); + + if (match_nosquash_list(&squash->rsi_sem, + &squash->rsi_nosquash_nids, + peernid)) { + CDEBUG(D_OTHER, "%s is in nosquash_nids list\n", + libcfs_nid2str(peernid)); + RETURN(0); + } - CDEBUG(D_OTHER, "squash req from %s, (%d:%d/%x)=>(%d:%d/%x)\n", - libcfs_nid2str(peernid), - ucred->mu_fsuid, ucred->mu_fsgid, ucred->mu_cap, - info->mti_mdt->mdt_squash_uid, info->mti_mdt->mdt_squash_gid, - 0); + CDEBUG(D_OTHER, "squash req from %s, (%d:%d/%x)=>(%d:%d/%x)\n", + libcfs_nid2str(peernid), + ucred->uc_fsuid, ucred->uc_fsgid, ucred->uc_cap, + squash->rsi_uid, squash->rsi_gid, 0); - ucred->mu_fsuid = info->mti_mdt->mdt_squash_uid; - ucred->mu_fsgid = info->mti_mdt->mdt_squash_gid; - ucred->mu_cap = 0; - ucred->mu_suppgids[0] = -1; - ucred->mu_suppgids[1] = -1; + ucred->uc_fsuid = squash->rsi_uid; + ucred->uc_fsgid = squash->rsi_gid; + ucred->uc_cap = 0; + ucred->uc_suppgids[0] = -1; + ucred->uc_suppgids[1] = -1; - RETURN(0); + RETURN(0); } static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, @@ -128,7 +130,7 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, struct ptlrpc_request *req = mdt_info_req(info); struct mdt_device *mdt = info->mti_mdt; struct ptlrpc_user_desc *pud = req->rq_user_desc; - struct md_ucred *ucred = mdt_ucred(info); + struct lu_ucred *ucred = mdt_ucred(info); lnet_nid_t peernid = req->rq_peer.nid; __u32 perm = 0; __u32 remote = exp_connect_rmtclient(info->mti_exp); @@ -141,30 +143,32 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, LASSERT(req->rq_auth_gss); LASSERT(!req->rq_auth_usr_mdt); LASSERT(req->rq_user_desc); + LASSERT(ucred != NULL); - ucred->mu_valid = UCRED_INVALID; + ucred->uc_valid = UCRED_INVALID; - ucred->mu_o_uid = pud->pud_uid; - ucred->mu_o_gid = pud->pud_gid; - ucred->mu_o_fsuid = pud->pud_fsuid; - ucred->mu_o_fsgid = pud->pud_fsgid; + ucred->uc_o_uid = pud->pud_uid; + ucred->uc_o_gid = pud->pud_gid; + ucred->uc_o_fsuid = pud->pud_fsuid; + ucred->uc_o_fsgid = pud->pud_fsgid; - if (type == BODY_INIT) { - struct mdt_body *body = (struct mdt_body *)buf; + if (type == BODY_INIT) { + struct mdt_body *body = (struct mdt_body *)buf; - ucred->mu_suppgids[0] = body->suppgid; - ucred->mu_suppgids[1] = -1; - } + ucred->uc_suppgids[0] = body->mbo_suppgid; + ucred->uc_suppgids[1] = -1; + } - /* sanity check: we expect the uid which client claimed is true */ - if (remote) { - if (req->rq_auth_mapped_uid == INVALID_UID) { - CDEBUG(D_SEC, "remote user not mapped, deny access!\n"); - RETURN(-EACCES); - } + /* sanity check: we expect the uid which client claimed is true */ + if (remote) { + if (!uid_valid(make_kuid(&init_user_ns, req->rq_auth_mapped_uid))) { + CDEBUG(D_SEC, "remote user not mapped, deny access!\n"); + CDEBUG(D_SEC, "remote user not mapped, deny access!\n"); + RETURN(-EACCES); + } - if (ptlrpc_user_desc_do_idmap(req, pud)) - RETURN(-EACCES); + if (ptlrpc_user_desc_do_idmap(req, pud)) + RETURN(-EACCES); if (req->rq_auth_mapped_uid != pud->pud_uid) { CDEBUG(D_SEC, "remote client %s: auth/mapped uid %u/%u " @@ -192,7 +196,7 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, "enabled!\n"); RETURN(-EACCES); } else { - ucred->mu_identity = NULL; + ucred->uc_identity = NULL; perm = CFS_SETUID_PERM | CFS_SETGID_PERM | CFS_SETGRP_PERM; } @@ -204,7 +208,7 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, if (IS_ERR(identity)) { if (unlikely(PTR_ERR(identity) == -EREMCHG && !remote)) { - ucred->mu_identity = NULL; + ucred->uc_identity = NULL; perm = CFS_SETUID_PERM | CFS_SETGID_PERM | CFS_SETGRP_PERM; } else { @@ -213,17 +217,17 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, RETURN(-EACCES); } } else { - ucred->mu_identity = identity; - perm = mdt_identity_get_perm(ucred->mu_identity, - remote, peernid); + ucred->uc_identity = identity; + perm = mdt_identity_get_perm(ucred->uc_identity, + remote, peernid); } } /* find out the setuid/setgid attempt */ setuid = (pud->pud_uid != pud->pud_fsuid); - setgid = ((pud->pud_gid != pud->pud_fsgid) || - (ucred->mu_identity && - (pud->pud_gid != ucred->mu_identity->mi_gid))); + setgid = ((pud->pud_gid != pud->pud_fsgid) || + (ucred->uc_identity && + (pud->pud_gid != ucred->uc_identity->mi_gid))); /* check permission of setuid */ if (setuid && !(perm & CFS_SETUID_PERM)) { @@ -234,72 +238,72 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, /* check permission of setgid */ if (setgid && !(perm & CFS_SETGID_PERM)) { - CDEBUG(D_SEC, "mdt blocked setgid attempt (%u:%u/%u:%u -> %u) " - "from %s\n", pud->pud_uid, pud->pud_gid, - pud->pud_fsuid, pud->pud_fsgid, - ucred->mu_identity->mi_gid, libcfs_nid2str(peernid)); - GOTO(out, rc = -EACCES); + CDEBUG(D_SEC, "mdt blocked setgid attempt (%u:%u/%u:%u -> %u) " + "from %s\n", pud->pud_uid, pud->pud_gid, + pud->pud_fsuid, pud->pud_fsgid, + ucred->uc_identity->mi_gid, libcfs_nid2str(peernid)); + GOTO(out, rc = -EACCES); } /* * NB: remote client not allowed to setgroups anyway. */ - if (!remote && perm & CFS_SETGRP_PERM) { - if (pud->pud_ngroups) { - /* setgroups for local client */ - ucred->mu_ginfo = cfs_groups_alloc(pud->pud_ngroups); - if (!ucred->mu_ginfo) { - CERROR("failed to alloc %d groups\n", - pud->pud_ngroups); - GOTO(out, rc = -ENOMEM); - } - - lustre_groups_from_list(ucred->mu_ginfo, - pud->pud_groups); - lustre_groups_sort(ucred->mu_ginfo); - } else { - ucred->mu_ginfo = NULL; - } - } else { - ucred->mu_suppgids[0] = -1; - ucred->mu_suppgids[1] = -1; - ucred->mu_ginfo = NULL; - } + if (!remote && perm & CFS_SETGRP_PERM) { + if (pud->pud_ngroups) { + /* setgroups for local client */ + ucred->uc_ginfo = groups_alloc(pud->pud_ngroups); + if (!ucred->uc_ginfo) { + CERROR("failed to alloc %d groups\n", + pud->pud_ngroups); + GOTO(out, rc = -ENOMEM); + } + + lustre_groups_from_list(ucred->uc_ginfo, + pud->pud_groups); + lustre_groups_sort(ucred->uc_ginfo); + } else { + ucred->uc_ginfo = NULL; + } + } else { + ucred->uc_suppgids[0] = -1; + ucred->uc_suppgids[1] = -1; + ucred->uc_ginfo = NULL; + } - ucred->mu_uid = pud->pud_uid; - ucred->mu_gid = pud->pud_gid; - ucred->mu_fsuid = pud->pud_fsuid; - ucred->mu_fsgid = pud->pud_fsgid; + ucred->uc_uid = pud->pud_uid; + ucred->uc_gid = pud->pud_gid; + ucred->uc_fsuid = pud->pud_fsuid; + ucred->uc_fsgid = pud->pud_fsgid; - /* process root_squash here. */ - mdt_root_squash(info, peernid); + /* process root_squash here. */ + mdt_root_squash(info, peernid); - /* remove fs privilege for non-root user. */ - if (ucred->mu_fsuid) - ucred->mu_cap = pud->pud_cap & ~CFS_CAP_FS_MASK; - else - ucred->mu_cap = pud->pud_cap; - if (remote && !(perm & CFS_RMTOWN_PERM)) - ucred->mu_cap &= ~(CFS_CAP_SYS_RESOURCE_MASK | - CFS_CAP_CHOWN_MASK); - ucred->mu_valid = UCRED_NEW; + /* remove fs privilege for non-root user. */ + if (ucred->uc_fsuid) + ucred->uc_cap = pud->pud_cap & ~CFS_CAP_FS_MASK; + else + ucred->uc_cap = pud->pud_cap; + if (remote && !(perm & CFS_RMTOWN_PERM)) + ucred->uc_cap &= ~(CFS_CAP_SYS_RESOURCE_MASK | + CFS_CAP_CHOWN_MASK); + ucred->uc_valid = UCRED_NEW; - EXIT; + EXIT; out: - if (rc) { - if (ucred->mu_ginfo) { - cfs_put_group_info(ucred->mu_ginfo); - ucred->mu_ginfo = NULL; - } - if (ucred->mu_identity) { - mdt_identity_put(mdt->mdt_identity_cache, - ucred->mu_identity); - ucred->mu_identity = NULL; - } - } + if (rc) { + if (ucred->uc_ginfo) { + put_group_info(ucred->uc_ginfo); + ucred->uc_ginfo = NULL; + } + if (ucred->uc_identity) { + mdt_identity_put(mdt->mdt_identity_cache, + ucred->uc_identity); + ucred->uc_identity = NULL; + } + } - return rc; + return rc; } int mdt_check_ucred(struct mdt_thread_info *info) @@ -307,7 +311,7 @@ int mdt_check_ucred(struct mdt_thread_info *info) struct ptlrpc_request *req = mdt_info_req(info); struct mdt_device *mdt = info->mti_mdt; struct ptlrpc_user_desc *pud = req->rq_user_desc; - struct md_ucred *ucred = mdt_ucred(info); + struct lu_ucred *ucred = mdt_ucred(info); struct md_identity *identity = NULL; lnet_nid_t peernid = req->rq_peer.nid; __u32 perm = 0; @@ -318,8 +322,9 @@ int mdt_check_ucred(struct mdt_thread_info *info) ENTRY; - if ((ucred->mu_valid == UCRED_OLD) || (ucred->mu_valid == UCRED_NEW)) - RETURN(0); + LASSERT(ucred != NULL); + if ((ucred->uc_valid == UCRED_OLD) || (ucred->uc_valid == UCRED_NEW)) + RETURN(0); if (!req->rq_auth_gss || req->rq_auth_usr_mdt || !req->rq_user_desc) RETURN(0); @@ -327,7 +332,7 @@ int mdt_check_ucred(struct mdt_thread_info *info) /* sanity check: if we use strong authentication, we expect the * uid which client claimed is true */ if (remote) { - if (req->rq_auth_mapped_uid == INVALID_UID) { + if (!uid_valid(make_kuid(&init_user_ns, req->rq_auth_mapped_uid))) { CDEBUG(D_SEC, "remote user not mapped, deny access!\n"); RETURN(-EACCES); } @@ -406,95 +411,98 @@ out: } static int old_init_ucred(struct mdt_thread_info *info, - struct mdt_body *body) + struct mdt_body *body) { - struct md_ucred *uc = mdt_ucred(info); - struct mdt_device *mdt = info->mti_mdt; - struct md_identity *identity = NULL; - - ENTRY; - - uc->mu_valid = UCRED_INVALID; - uc->mu_o_uid = uc->mu_uid = body->uid; - uc->mu_o_gid = uc->mu_gid = body->gid; - uc->mu_o_fsuid = uc->mu_fsuid = body->fsuid; - uc->mu_o_fsgid = uc->mu_fsgid = body->fsgid; - uc->mu_suppgids[0] = body->suppgid; - uc->mu_suppgids[1] = -1; - uc->mu_ginfo = NULL; - if (!is_identity_get_disabled(mdt->mdt_identity_cache)) { - identity = mdt_identity_get(mdt->mdt_identity_cache, - uc->mu_fsuid); - if (IS_ERR(identity)) { - if (unlikely(PTR_ERR(identity) == -EREMCHG)) { - identity = NULL; - } else { - CDEBUG(D_SEC, "Deny access without identity: " - "uid %u\n", uc->mu_fsuid); - RETURN(-EACCES); - } - } - } - uc->mu_identity = identity; + struct lu_ucred *uc = mdt_ucred(info); + struct mdt_device *mdt = info->mti_mdt; + struct md_identity *identity = NULL; + + ENTRY; + + LASSERT(uc != NULL); + uc->uc_valid = UCRED_INVALID; + uc->uc_o_uid = uc->uc_uid = body->mbo_uid; + uc->uc_o_gid = uc->uc_gid = body->mbo_gid; + uc->uc_o_fsuid = uc->uc_fsuid = body->mbo_fsuid; + uc->uc_o_fsgid = uc->uc_fsgid = body->mbo_fsgid; + uc->uc_suppgids[0] = body->mbo_suppgid; + uc->uc_suppgids[1] = -1; + uc->uc_ginfo = NULL; + if (!is_identity_get_disabled(mdt->mdt_identity_cache)) { + identity = mdt_identity_get(mdt->mdt_identity_cache, + uc->uc_fsuid); + if (IS_ERR(identity)) { + if (unlikely(PTR_ERR(identity) == -EREMCHG)) { + identity = NULL; + } else { + CDEBUG(D_SEC, "Deny access without identity: " + "uid %u\n", uc->uc_fsuid); + RETURN(-EACCES); + } + } + } + uc->uc_identity = identity; - /* process root_squash here. */ - mdt_root_squash(info, mdt_info_req(info)->rq_peer.nid); + /* process root_squash here. */ + mdt_root_squash(info, mdt_info_req(info)->rq_peer.nid); - /* remove fs privilege for non-root user. */ - if (uc->mu_fsuid) - uc->mu_cap = body->capability & ~CFS_CAP_FS_MASK; - else - uc->mu_cap = body->capability; - uc->mu_valid = UCRED_OLD; + /* remove fs privilege for non-root user. */ + if (uc->uc_fsuid) + uc->uc_cap = body->mbo_capability & ~CFS_CAP_FS_MASK; + else + uc->uc_cap = body->mbo_capability; + uc->uc_valid = UCRED_OLD; - RETURN(0); + RETURN(0); } static int old_init_ucred_reint(struct mdt_thread_info *info) { - struct md_ucred *uc = mdt_ucred(info); - struct mdt_device *mdt = info->mti_mdt; - struct md_identity *identity = NULL; - - ENTRY; - - uc->mu_valid = UCRED_INVALID; - uc->mu_o_uid = uc->mu_o_fsuid = uc->mu_uid = uc->mu_fsuid; - uc->mu_o_gid = uc->mu_o_fsgid = uc->mu_gid = uc->mu_fsgid; - uc->mu_ginfo = NULL; - if (!is_identity_get_disabled(mdt->mdt_identity_cache)) { - identity = mdt_identity_get(mdt->mdt_identity_cache, - uc->mu_fsuid); - if (IS_ERR(identity)) { - if (unlikely(PTR_ERR(identity) == -EREMCHG)) { - identity = NULL; - } else { - CDEBUG(D_SEC, "Deny access without identity: " - "uid %u\n", uc->mu_fsuid); - RETURN(-EACCES); - } - } - } - uc->mu_identity = identity; + struct lu_ucred *uc = mdt_ucred(info); + struct mdt_device *mdt = info->mti_mdt; + struct md_identity *identity = NULL; + + ENTRY; + + LASSERT(uc != NULL); + uc->uc_valid = UCRED_INVALID; + uc->uc_o_uid = uc->uc_o_fsuid = uc->uc_uid = uc->uc_fsuid; + uc->uc_o_gid = uc->uc_o_fsgid = uc->uc_gid = uc->uc_fsgid; + uc->uc_ginfo = NULL; + if (!is_identity_get_disabled(mdt->mdt_identity_cache)) { + identity = mdt_identity_get(mdt->mdt_identity_cache, + uc->uc_fsuid); + if (IS_ERR(identity)) { + if (unlikely(PTR_ERR(identity) == -EREMCHG)) { + identity = NULL; + } else { + CDEBUG(D_SEC, "Deny access without identity: " + "uid %u\n", uc->uc_fsuid); + RETURN(-EACCES); + } + } + } + uc->uc_identity = identity; - /* process root_squash here. */ - mdt_root_squash(info, mdt_info_req(info)->rq_peer.nid); + /* process root_squash here. */ + mdt_root_squash(info, mdt_info_req(info)->rq_peer.nid); - /* remove fs privilege for non-root user. */ - if (uc->mu_fsuid) - uc->mu_cap &= ~CFS_CAP_FS_MASK; - uc->mu_valid = UCRED_OLD; + /* remove fs privilege for non-root user. */ + if (uc->uc_fsuid) + uc->uc_cap &= ~CFS_CAP_FS_MASK; + uc->uc_valid = UCRED_OLD; - RETURN(0); + RETURN(0); } int mdt_init_ucred(struct mdt_thread_info *info, struct mdt_body *body) { struct ptlrpc_request *req = mdt_info_req(info); - struct md_ucred *uc = mdt_ucred(info); + struct lu_ucred *uc = mdt_ucred(info); - if ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW)) - return 0; + LASSERT(uc != NULL); + if ((uc->uc_valid == UCRED_OLD) || (uc->uc_valid == UCRED_NEW)) + return 0; mdt_exit_ucred(info); @@ -507,10 +515,11 @@ int mdt_init_ucred(struct mdt_thread_info *info, struct mdt_body *body) int mdt_init_ucred_reint(struct mdt_thread_info *info) { struct ptlrpc_request *req = mdt_info_req(info); - struct md_ucred *uc = mdt_ucred(info); + struct lu_ucred *uc = mdt_ucred(info); - if ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW)) - return 0; + LASSERT(uc != NULL); + if ((uc->uc_valid == UCRED_OLD) || (uc->uc_valid == UCRED_NEW)) + return 0; mdt_exit_ucred(info); @@ -521,27 +530,62 @@ int mdt_init_ucred_reint(struct mdt_thread_info *info) } /* copied from lov/lov_ea.c, just for debugging, will be removed later */ -void mdt_dump_lmm(int level, const struct lov_mds_md *lmm) +void mdt_dump_lmm(int level, const struct lov_mds_md *lmm, __u64 valid) { - const struct lov_ost_data_v1 *lod; - int i; - __u16 count; - - count = le16_to_cpu(((struct lov_user_md*)lmm)->lmm_stripe_count); - - CDEBUG(level, "objid "LPX64", magic 0x%08X, pattern %#X\n", - le64_to_cpu(lmm->lmm_object_id), le32_to_cpu(lmm->lmm_magic), - le32_to_cpu(lmm->lmm_pattern)); - CDEBUG(level,"stripe_size=0x%x, stripe_count=0x%x\n", - le32_to_cpu(lmm->lmm_stripe_size), count); - if (count == LOV_ALL_STRIPES) - return; - LASSERT(count <= LOV_MAX_STRIPE_COUNT); - for (i = 0, lod = lmm->lmm_objects; i < count; i++, lod++) - CDEBUG(level, "stripe %u idx %u subobj "LPX64"/"LPX64"\n", - i, le32_to_cpu(lod->l_ost_idx), - le64_to_cpu(lod->l_object_seq), - le64_to_cpu(lod->l_object_id)); + const struct lov_ost_data_v1 *lod; + int i; + __u16 count; + + if (likely(!cfs_cdebug_show(level, DEBUG_SUBSYSTEM))) + return; + + count = le16_to_cpu(((struct lov_user_md *)lmm)->lmm_stripe_count); + + CDEBUG(level, "objid "DOSTID", magic 0x%08X, pattern %#X\n", + POSTID(&lmm->lmm_oi), le32_to_cpu(lmm->lmm_magic), + le32_to_cpu(lmm->lmm_pattern)); + CDEBUG(level, "stripe_size=0x%x, stripe_count=0x%x\n", + le32_to_cpu(lmm->lmm_stripe_size), count); + + /* If it's a directory or a released file, then there are + * no actual objects to print, so bail out. */ + if (valid & OBD_MD_FLDIREA || + le32_to_cpu(lmm->lmm_pattern) & LOV_PATTERN_F_RELEASED) + return; + + LASSERT(count <= LOV_MAX_STRIPE_COUNT); + for (i = 0, lod = lmm->lmm_objects; i < count; i++, lod++) { + struct ost_id oi; + + ostid_le_to_cpu(&lod->l_ost_oi, &oi); + CDEBUG(level, "stripe %u idx %u subobj "DOSTID"\n", + i, le32_to_cpu(lod->l_ost_idx), POSTID(&oi)); + } +} + +void mdt_dump_lmv(unsigned int level, const union lmv_mds_md *lmv) +{ + const struct lmv_mds_md_v1 *lmm1; + int i; + + if (likely(!cfs_cdebug_show(level, DEBUG_SUBSYSTEM))) + return; + + lmm1 = &lmv->lmv_md_v1; + CDEBUG(level, "magic 0x%08X, master %#X stripe_count %#x\n", + le32_to_cpu(lmm1->lmv_magic), + le32_to_cpu(lmm1->lmv_master_mdt_index), + le32_to_cpu(lmm1->lmv_stripe_count)); + + if (le32_to_cpu(lmm1->lmv_magic) == LMV_MAGIC_STRIPE) + return; + + for (i = 0; i < le32_to_cpu(lmm1->lmv_stripe_count); i++) { + struct lu_fid fid; + + fid_le_to_cpu(&fid, &lmm1->lmv_stripe_fids[i]); + CDEBUG(level, "idx %u subobj "DFID"\n", i, PFID(&fid)); + } } /* Shrink and/or grow reply buffers */ @@ -557,24 +601,25 @@ int mdt_fix_reply(struct mdt_thread_info *info) body = req_capsule_server_get(pill, &RMF_MDT_BODY); LASSERT(body != NULL); - if (body->valid & (OBD_MD_FLDIREA | OBD_MD_FLEASIZE | OBD_MD_LINKNAME)) - md_size = body->eadatasize; - else - md_size = 0; + if (body->mbo_valid & (OBD_MD_FLDIREA | OBD_MD_FLEASIZE | + OBD_MD_LINKNAME)) + md_size = body->mbo_eadatasize; + else + md_size = 0; - acl_size = body->aclsize; + acl_size = body->mbo_aclsize; /* this replay - not send info to client */ - if (info->mti_spec.no_create == 1) { - md_size = 0; - acl_size = 0; - } + if (info->mti_spec.no_create) { + md_size = 0; + acl_size = 0; + } CDEBUG(D_INFO, "Shrink to md_size = %d cookie/acl_size = %d" - " MDSCAPA = %llx, OSSCAPA = %llx\n", - md_size, acl_size, - (unsigned long long)(body->valid & OBD_MD_FLMDSCAPA), - (unsigned long long)(body->valid & OBD_MD_FLOSSCAPA)); + " MDSCAPA = %llx, OSSCAPA = %llx\n", + md_size, acl_size, + (unsigned long long)(body->mbo_valid & OBD_MD_FLMDSCAPA), + (unsigned long long)(body->mbo_valid & OBD_MD_FLOSSCAPA)); /* &RMF_MDT_BODY, &RMF_MDT_MD, @@ -587,17 +632,21 @@ int mdt_fix_reply(struct mdt_thread_info *info) /* MDT_MD buffer may be bigger than packed value, let's shrink all * buffers before growing it */ if (info->mti_big_lmm_used) { - LASSERT(req_capsule_has_field(pill, &RMF_MDT_MD, RCL_SERVER)); - md_packed = req_capsule_get_size(pill, &RMF_MDT_MD, - RCL_SERVER); - LASSERT(md_packed > 0); - /* buffer must be allocated separately */ - LASSERT(info->mti_attr.ma_lmm != - req_capsule_server_get(pill, &RMF_MDT_MD)); - req_capsule_shrink(pill, &RMF_MDT_MD, 0, RCL_SERVER); - /* free big lmm if md_size is not needed */ - if (md_size == 0) + /* big_lmm buffer may be used even without packing the result + * into reply, just for internal server needs */ + if (req_capsule_has_field(pill, &RMF_MDT_MD, RCL_SERVER)) + md_packed = req_capsule_get_size(pill, &RMF_MDT_MD, + RCL_SERVER); + + /* free big lmm if md_size is not needed */ + if (md_size == 0 || md_packed == 0) { info->mti_big_lmm_used = 0; + } else { + /* buffer must be allocated separately */ + LASSERT(info->mti_attr.ma_lmm != + req_capsule_server_get(pill, &RMF_MDT_MD)); + req_capsule_shrink(pill, &RMF_MDT_MD, 0, RCL_SERVER); + } } else if (req_capsule_has_field(pill, &RMF_MDT_MD, RCL_SERVER)) { req_capsule_shrink(pill, &RMF_MDT_MD, md_size, RCL_SERVER); } @@ -609,12 +658,12 @@ int mdt_fix_reply(struct mdt_thread_info *info) acl_size, RCL_SERVER); if (req_capsule_has_field(pill, &RMF_CAPA1, RCL_SERVER) && - !(body->valid & OBD_MD_FLMDSCAPA)) - req_capsule_shrink(pill, &RMF_CAPA1, 0, RCL_SERVER); + !(body->mbo_valid & OBD_MD_FLMDSCAPA)) + req_capsule_shrink(pill, &RMF_CAPA1, 0, RCL_SERVER); - if (req_capsule_has_field(pill, &RMF_CAPA2, RCL_SERVER) && - !(body->valid & OBD_MD_FLOSSCAPA)) - req_capsule_shrink(pill, &RMF_CAPA2, 0, RCL_SERVER); + if (req_capsule_has_field(pill, &RMF_CAPA2, RCL_SERVER) && + !(body->mbo_valid & OBD_MD_FLOSSCAPA)) + req_capsule_shrink(pill, &RMF_CAPA2, 0, RCL_SERVER); /* * Some more field should be shrinked if needed. @@ -633,17 +682,25 @@ int mdt_fix_reply(struct mdt_thread_info *info) /* we can't answer with proper LOV EA, drop flags, * the rc is also returned so this request is * considered as failed */ - body->valid &= ~(OBD_MD_FLDIREA | OBD_MD_FLEASIZE); + body->mbo_valid &= ~(OBD_MD_FLDIREA | OBD_MD_FLEASIZE); /* don't return transno along with error */ lustre_msg_set_transno(pill->rc_req->rq_repmsg, 0); } else { - /* now we need to pack right LOV EA */ - lmm = req_capsule_server_get(pill, &RMF_MDT_MD); - LASSERT(req_capsule_get_size(pill, &RMF_MDT_MD, - RCL_SERVER) == - info->mti_attr.ma_lmm_size); - memcpy(lmm, info->mti_attr.ma_lmm, - info->mti_attr.ma_lmm_size); + /* now we need to pack right LOV/LMV EA */ + lmm = req_capsule_server_get(pill, &RMF_MDT_MD); + if (info->mti_attr.ma_valid & MA_LOV) { + LASSERT(req_capsule_get_size(pill, &RMF_MDT_MD, + RCL_SERVER) == + info->mti_attr.ma_lmm_size); + memcpy(lmm, info->mti_attr.ma_lmm, + info->mti_attr.ma_lmm_size); + } else if (info->mti_attr.ma_valid & MA_LMV) { + LASSERT(req_capsule_get_size(pill, &RMF_MDT_MD, + RCL_SERVER) == + info->mti_attr.ma_lmv_size); + memcpy(lmm, info->mti_attr.ma_lmv, + info->mti_attr.ma_lmv_size); + } } /* update mdt_max_mdsize so clients will be aware about that */ if (info->mti_mdt->mdt_max_mdsize < info->mti_attr.ma_lmm_size) @@ -675,16 +732,11 @@ int mdt_handle_last_unlink(struct mdt_thread_info *info, struct mdt_object *mo, CERROR("No need in LOV EA upon unlink\n"); dump_stack(); } - repbody->eadatasize = 0; - - if (ma->ma_cookie_size && (ma->ma_valid & MA_COOKIE)) { - repbody->aclsize = ma->ma_cookie_size; - repbody->valid |= OBD_MD_FLCOOKIE; - } + repbody->mbo_eadatasize = 0; - if (info->mti_mdt->mdt_opts.mo_oss_capa && - info->mti_exp->exp_connect_flags & OBD_CONNECT_OSS_CAPA && - repbody->valid & OBD_MD_FLEASIZE) { + if (info->mti_mdt->mdt_lut.lut_oss_capa && + exp_connect_flags(info->mti_exp) & OBD_CONNECT_OSS_CAPA && + repbody->mbo_valid & OBD_MD_FLEASIZE) { struct lustre_capa *capa; capa = req_capsule_server_get(info->mti_pill, &RMF_CAPA2); @@ -694,111 +746,132 @@ int mdt_handle_last_unlink(struct mdt_thread_info *info, struct mdt_object *mo, if (rc) RETURN(rc); - repbody->valid |= OBD_MD_FLOSSCAPA; + repbody->mbo_valid |= OBD_MD_FLOSSCAPA; } RETURN(0); } -static inline unsigned int attr_unpack(__u64 sa_valid) { - unsigned int ia_valid = 0; - - if (sa_valid & MDS_ATTR_MODE) - ia_valid |= ATTR_MODE; - if (sa_valid & MDS_ATTR_UID) - ia_valid |= ATTR_UID; - if (sa_valid & MDS_ATTR_GID) - ia_valid |= ATTR_GID; - if (sa_valid & MDS_ATTR_SIZE) - ia_valid |= ATTR_SIZE; - if (sa_valid & MDS_ATTR_ATIME) - ia_valid |= ATTR_ATIME; - if (sa_valid & MDS_ATTR_MTIME) - ia_valid |= ATTR_MTIME; - if (sa_valid & MDS_ATTR_CTIME) - ia_valid |= ATTR_CTIME; - if (sa_valid & MDS_ATTR_ATIME_SET) - ia_valid |= ATTR_ATIME_SET; - if (sa_valid & MDS_ATTR_MTIME_SET) - ia_valid |= ATTR_MTIME_SET; - if (sa_valid & MDS_ATTR_FORCE) - ia_valid |= ATTR_FORCE; - if (sa_valid & MDS_ATTR_ATTR_FLAG) - ia_valid |= ATTR_ATTR_FLAG; - if (sa_valid & MDS_ATTR_KILL_SUID) - ia_valid |= ATTR_KILL_SUID; - if (sa_valid & MDS_ATTR_KILL_SGID) - ia_valid |= ATTR_KILL_SGID; - if (sa_valid & MDS_ATTR_CTIME_SET) - ia_valid |= ATTR_CTIME_SET; - if (sa_valid & MDS_ATTR_FROM_OPEN) - ia_valid |= ATTR_FROM_OPEN; - if (sa_valid & MDS_ATTR_BLOCKS) - ia_valid |= ATTR_BLOCKS; - if (sa_valid & MDS_OPEN_OWNEROVERRIDE) - ia_valid |= MDS_OPEN_OWNEROVERRIDE; - return ia_valid; -} - static __u64 mdt_attr_valid_xlate(__u64 in, struct mdt_reint_record *rr, struct md_attr *ma) { - __u64 out; - - out = 0; - if (in & ATTR_MODE) - out |= LA_MODE; - if (in & ATTR_UID) - out |= LA_UID; - if (in & ATTR_GID) - out |= LA_GID; - if (in & ATTR_SIZE) - out |= LA_SIZE; - if (in & ATTR_BLOCKS) - out |= LA_BLOCKS; - - if (in & ATTR_FROM_OPEN) - rr->rr_flags |= MRF_OPEN_TRUNC; - - if (in & ATTR_ATIME_SET) - out |= LA_ATIME; - - if (in & ATTR_CTIME_SET) - out |= LA_CTIME; - - if (in & ATTR_MTIME_SET) - out |= LA_MTIME; - - if (in & ATTR_ATTR_FLAG) - out |= LA_FLAGS; - - if (in & ATTR_KILL_SUID) - out |= LA_KILL_SUID; - - if (in & ATTR_KILL_SGID) - out |= LA_KILL_SGID; - - if (in & MDS_OPEN_OWNEROVERRIDE) - ma->ma_attr_flags |= MDS_OPEN_OWNEROVERRIDE; - - if (in & ATTR_FORCE) - ma->ma_attr_flags |= MDS_PERM_BYPASS; - - /*XXX need ATTR_RAW?*/ - in &= ~(ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_BLOCKS| - ATTR_ATIME|ATTR_MTIME|ATTR_CTIME|ATTR_FROM_OPEN| - ATTR_ATIME_SET|ATTR_CTIME_SET|ATTR_MTIME_SET| - ATTR_ATTR_FLAG|ATTR_RAW|MDS_OPEN_OWNEROVERRIDE| - ATTR_FORCE|ATTR_KILL_SUID|ATTR_KILL_SGID); - if (in != 0) - CERROR("Unknown attr bits: "LPX64"\n", in); - return out; + __u64 out; + + out = 0; + if (in & MDS_ATTR_MODE) + out |= LA_MODE; + if (in & MDS_ATTR_UID) + out |= LA_UID; + if (in & MDS_ATTR_GID) + out |= LA_GID; + if (in & MDS_ATTR_SIZE) + out |= LA_SIZE; + if (in & MDS_ATTR_BLOCKS) + out |= LA_BLOCKS; + if (in & MDS_ATTR_ATIME_SET) + out |= LA_ATIME; + if (in & MDS_ATTR_CTIME_SET) + out |= LA_CTIME; + if (in & MDS_ATTR_MTIME_SET) + out |= LA_MTIME; + if (in & MDS_ATTR_ATTR_FLAG) + out |= LA_FLAGS; + if (in & MDS_ATTR_KILL_SUID) + out |= LA_KILL_SUID; + if (in & MDS_ATTR_KILL_SGID) + out |= LA_KILL_SGID; + + if (in & MDS_ATTR_FROM_OPEN) + rr->rr_flags |= MRF_OPEN_TRUNC; + if (in & MDS_OPEN_OWNEROVERRIDE) + ma->ma_attr_flags |= MDS_OWNEROVERRIDE; + if (in & MDS_ATTR_FORCE) + ma->ma_attr_flags |= MDS_PERM_BYPASS; + + in &= ~(MDS_ATTR_MODE | MDS_ATTR_UID | MDS_ATTR_GID | + MDS_ATTR_ATIME | MDS_ATTR_MTIME | MDS_ATTR_CTIME | + MDS_ATTR_ATIME_SET | MDS_ATTR_CTIME_SET | MDS_ATTR_MTIME_SET | + MDS_ATTR_SIZE | MDS_ATTR_BLOCKS | MDS_ATTR_ATTR_FLAG | + MDS_ATTR_FORCE | MDS_ATTR_KILL_SUID | MDS_ATTR_KILL_SGID | + MDS_ATTR_FROM_OPEN | MDS_OPEN_OWNEROVERRIDE); + if (in != 0) + CERROR("Unknown attr bits: "LPX64"\n", in); + return out; } + +void mdt_set_capainfo(struct mdt_thread_info *info, int offset, + const struct lu_fid *fid, struct lustre_capa *capa) +{ + struct lu_capainfo *lci; + + LASSERT(offset >= 0 && offset < LU_CAPAINFO_MAX); + if (!info->mti_mdt->mdt_lut.lut_mds_capa || + !(exp_connect_flags(info->mti_exp) & OBD_CONNECT_MDS_CAPA)) + return; + + lci = lu_capainfo_get(info->mti_env); + LASSERT(lci); + lci->lci_fid[offset] = *fid; + lci->lci_capa[offset] = capa; +} + +#ifdef DEBUG_CAPA +void mdt_dump_capainfo(struct mdt_thread_info *info) +{ + struct lu_capainfo *lci = lu_capainfo_get(info->mti_env); + int i; + + if (lci == NULL) + return; + + for (i = 0; i < LU_CAPAINFO_MAX; i++) { + if (lci->lci_capa[i] == NULL) { + CERROR("no capa for index %d "DFID"\n", + i, PFID(&lci->lci_fid[i])); + continue; + } + if (lci->lci_capa[i] == BYPASS_CAPA) { + CERROR("bypass for index %d "DFID"\n", + i, PFID(&lci->lci_fid[i])); + continue; + } + DEBUG_CAPA(D_ERROR, lci->lci_capa[i], "index %d", i); + } +} +#endif /* DEBUG_CAPA */ + /* unpacking */ +int mdt_name_unpack(struct req_capsule *pill, + const struct req_msg_field *field, + struct lu_name *ln, + enum mdt_name_flags flags) +{ + ln->ln_name = req_capsule_client_get(pill, field); + ln->ln_namelen = req_capsule_get_size(pill, field, RCL_CLIENT) - 1; + + if (!lu_name_is_valid(ln)) { + ln->ln_name = NULL; + ln->ln_namelen = 0; + + return -EPROTO; + } + + if ((flags & MNF_FIX_ANON) && + ln->ln_namelen == 1 && ln->ln_name[0] == '/') { + /* Newer (3.x) kernels use a name of "/" for the + * "anonymous" disconnected dentries from NFS + * filehandle conversion. See d_obtain_alias(). */ + ln->ln_name = NULL; + ln->ln_namelen = 0; + } + + return 0; +} + static int mdt_setattr_unpack_rec(struct mdt_thread_info *info) { - struct md_ucred *uc = mdt_ucred(info); + struct lu_ucred *uc = mdt_ucred(info); struct md_attr *ma = &info->mti_attr; struct lu_attr *la = &ma->ma_attr; struct req_capsule *pill = info->mti_pill; @@ -811,14 +884,29 @@ static int mdt_setattr_unpack_rec(struct mdt_thread_info *info) if (rec == NULL) RETURN(-EFAULT); - uc->mu_fsuid = rec->sa_fsuid; - uc->mu_fsgid = rec->sa_fsgid; - uc->mu_cap = rec->sa_cap; - uc->mu_suppgids[0] = rec->sa_suppgid; - uc->mu_suppgids[1] = -1; + /* This prior initialization is needed for old_init_ucred_reint() */ + uc->uc_fsuid = rec->sa_fsuid; + uc->uc_fsgid = rec->sa_fsgid; + uc->uc_cap = rec->sa_cap; + uc->uc_suppgids[0] = rec->sa_suppgid; + uc->uc_suppgids[1] = -1; rr->rr_fid1 = &rec->sa_fid; - la->la_valid = mdt_attr_valid_xlate(attr_unpack(rec->sa_valid), rr, ma); + la->la_valid = mdt_attr_valid_xlate(rec->sa_valid, rr, ma); + /* If MDS_ATTR_xTIME is set without MDS_ATTR_xTIME_SET and + * the client does not have OBD_CONNECT_FULL20, convert it + * to LA_xTIME. LU-3036 */ + if (!(exp_connect_flags(info->mti_exp) & OBD_CONNECT_FULL20)) { + if (!(rec->sa_valid & MDS_ATTR_ATIME_SET) && + (rec->sa_valid & MDS_ATTR_ATIME)) + la->la_valid |= LA_ATIME; + if (!(rec->sa_valid & MDS_ATTR_MTIME_SET) && + (rec->sa_valid & MDS_ATTR_MTIME)) + la->la_valid |= LA_MTIME; + if (!(rec->sa_valid & MDS_ATTR_CTIME_SET) && + (rec->sa_valid & MDS_ATTR_CTIME)) + la->la_valid |= LA_CTIME; + } la->la_mode = rec->sa_mode; la->la_flags = rec->sa_attr_flags; la->la_uid = rec->sa_uid; @@ -830,11 +918,21 @@ static int mdt_setattr_unpack_rec(struct mdt_thread_info *info) la->la_mtime = rec->sa_mtime; ma->ma_valid = MA_INODE; - if (req_capsule_get_size(pill, &RMF_CAPA1, RCL_CLIENT)) - mdt_set_capainfo(info, 0, rr->rr_fid1, - req_capsule_client_get(pill, &RMF_CAPA1)); + if (rec->sa_bias & MDS_DATA_MODIFIED) + ma->ma_attr_flags |= MDS_DATA_MODIFIED; + else + ma->ma_attr_flags &= ~MDS_DATA_MODIFIED; - RETURN(0); + if (rec->sa_bias & MDS_HSM_RELEASE) + ma->ma_attr_flags |= MDS_HSM_RELEASE; + else + ma->ma_attr_flags &= ~MDS_HSM_RELEASE; + + if (req_capsule_get_size(pill, &RMF_CAPA1, RCL_CLIENT)) + mdt_set_capainfo(info, 0, rr->rr_fid1, + req_capsule_client_get(pill, &RMF_CAPA1)); + + RETURN(0); } static int mdt_ioepoch_unpack(struct mdt_thread_info *info) @@ -881,15 +979,44 @@ static int mdt_setattr_unpack(struct mdt_thread_info *info) rr->rr_eadata = req_capsule_client_get(pill, &RMF_EADATA); rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA, RCL_CLIENT); - ma->ma_lmm_size = rr->rr_eadatalen; - if (ma->ma_lmm_size > 0) { - ma->ma_lmm = (void *)rr->rr_eadata; - ma->ma_valid |= MA_LOV; - } - } + if (rr->rr_eadatalen > 0) { + const struct lmv_user_md *lum; + + lum = rr->rr_eadata; + /* Sigh ma_valid(from req) does not indicate whether + * it will set LOV/LMV EA, so we have to check magic */ + if (le32_to_cpu(lum->lum_magic) == LMV_USER_MAGIC) { + ma->ma_valid |= MA_LMV; + ma->ma_lmv = (void *)rr->rr_eadata; + ma->ma_lmv_size = rr->rr_eadatalen; + } else { + ma->ma_valid |= MA_LOV; + ma->ma_lmm = (void *)rr->rr_eadata; + ma->ma_lmm_size = rr->rr_eadatalen; + } + } + } - rc = mdt_dlmreq_unpack(info); - RETURN(rc); + rc = mdt_dlmreq_unpack(info); + RETURN(rc); +} + +static int mdt_hsm_release_unpack(struct mdt_thread_info *info) +{ + struct md_attr *ma = &info->mti_attr; + struct req_capsule *pill = info->mti_pill; + ENTRY; + + if (!(ma->ma_attr_flags & MDS_HSM_RELEASE)) + RETURN(0); + + req_capsule_extend(pill, &RQF_MDS_RELEASE_CLOSE); + + if (!(req_capsule_has_field(pill, &RMF_CLOSE_DATA, RCL_CLIENT) && + req_capsule_field_present(pill, &RMF_CLOSE_DATA, RCL_CLIENT))) + RETURN(-EFAULT); + + RETURN(0); } int mdt_close_unpack(struct mdt_thread_info *info) @@ -901,12 +1028,20 @@ int mdt_close_unpack(struct mdt_thread_info *info) if (rc) RETURN(rc); - RETURN(mdt_setattr_unpack_rec(info)); + rc = mdt_setattr_unpack_rec(info); + if (rc) + RETURN(rc); + + rc = mdt_hsm_release_unpack(info); + if (rc) + RETURN(rc); + + RETURN(mdt_init_ucred_reint(info)); } static int mdt_create_unpack(struct mdt_thread_info *info) { - struct md_ucred *uc = mdt_ucred(info); + struct lu_ucred *uc = mdt_ucred(info); struct mdt_rec_create *rec; struct lu_attr *attr = &info->mti_attr.ma_attr; struct mdt_reint_record *rr = &info->mti_rr; @@ -920,12 +1055,13 @@ static int mdt_create_unpack(struct mdt_thread_info *info) if (rec == NULL) RETURN(-EFAULT); - uc->mu_fsuid = rec->cr_fsuid; - uc->mu_fsgid = rec->cr_fsgid; - uc->mu_cap = rec->cr_cap; - uc->mu_suppgids[0] = rec->cr_suppgid1; - uc->mu_suppgids[1] = -1; - uc->mu_umask = rec->cr_umask; + /* This prior initialization is needed for old_init_ucred_reint() */ + uc->uc_fsuid = rec->cr_fsuid; + uc->uc_fsgid = rec->cr_fsgid; + uc->uc_cap = rec->cr_cap; + uc->uc_suppgids[0] = rec->cr_suppgid1; + uc->uc_suppgids[1] = -1; + uc->uc_umask = rec->cr_umask; rr->rr_fid1 = &rec->cr_fid1; rr->rr_fid2 = &rec->cr_fid2; @@ -936,8 +1072,8 @@ static int mdt_create_unpack(struct mdt_thread_info *info) attr->la_ctime = rec->cr_time; attr->la_mtime = rec->cr_time; attr->la_atime = rec->cr_time; - attr->la_valid = LA_MODE | LA_RDEV | LA_UID | LA_GID | - LA_CTIME | LA_MTIME | LA_ATIME; + attr->la_valid = LA_MODE | LA_RDEV | LA_UID | LA_GID | LA_TYPE | + LA_CTIME | LA_MTIME | LA_ATIME; memset(&sp->u, 0, sizeof(sp->u)); sp->sp_cr_flags = get_mrc_cr_flags(rec); @@ -946,10 +1082,9 @@ static int mdt_create_unpack(struct mdt_thread_info *info) req_capsule_client_get(pill, &RMF_CAPA1)); mdt_set_capainfo(info, 1, rr->rr_fid2, BYPASS_CAPA); - rr->rr_name = req_capsule_client_get(pill, &RMF_NAME); - rr->rr_namelen = req_capsule_get_size(pill, &RMF_NAME, - RCL_CLIENT) - 1; - LASSERT(rr->rr_name && rr->rr_namelen > 0); + rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0); + if (rc < 0) + RETURN(rc); if (S_ISLNK(attr->la_mode)) { const char *tgt = NULL; @@ -963,15 +1098,24 @@ static int mdt_create_unpack(struct mdt_thread_info *info) RETURN(-EFAULT); } else { req_capsule_extend(pill, &RQF_MDS_REINT_CREATE_RMT_ACL); - } + if (S_ISDIR(attr->la_mode) && + req_capsule_get_size(pill, &RMF_EADATA, RCL_CLIENT) > 0) { + sp->u.sp_ea.eadata = + req_capsule_client_get(pill, &RMF_EADATA); + sp->u.sp_ea.eadatalen = + req_capsule_get_size(pill, &RMF_EADATA, + RCL_CLIENT); + sp->sp_cr_flags |= MDS_OPEN_HAS_EA; + } + } - rc = mdt_dlmreq_unpack(info); - RETURN(rc); + rc = mdt_dlmreq_unpack(info); + RETURN(rc); } static int mdt_link_unpack(struct mdt_thread_info *info) { - struct md_ucred *uc = mdt_ucred(info); + struct lu_ucred *uc = mdt_ucred(info); struct mdt_rec_link *rec; struct lu_attr *attr = &info->mti_attr.ma_attr; struct mdt_reint_record *rr = &info->mti_rr; @@ -984,11 +1128,12 @@ static int mdt_link_unpack(struct mdt_thread_info *info) if (rec == NULL) RETURN(-EFAULT); - uc->mu_fsuid = rec->lk_fsuid; - uc->mu_fsgid = rec->lk_fsgid; - uc->mu_cap = rec->lk_cap; - uc->mu_suppgids[0] = rec->lk_suppgid1; - uc->mu_suppgids[1] = rec->lk_suppgid2; + /* This prior initialization is needed for old_init_ucred_reint() */ + uc->uc_fsuid = rec->lk_fsuid; + uc->uc_fsgid = rec->lk_fsgid; + uc->uc_cap = rec->lk_cap; + uc->uc_suppgids[0] = rec->lk_suppgid1; + uc->uc_suppgids[1] = rec->lk_suppgid2; attr->la_uid = rec->lk_fsuid; attr->la_gid = rec->lk_fsgid; @@ -1005,20 +1150,18 @@ static int mdt_link_unpack(struct mdt_thread_info *info) mdt_set_capainfo(info, 1, rr->rr_fid2, req_capsule_client_get(pill, &RMF_CAPA2)); - rr->rr_name = req_capsule_client_get(pill, &RMF_NAME); - if (rr->rr_name == NULL) - RETURN(-EFAULT); - rr->rr_namelen = req_capsule_get_size(pill, &RMF_NAME, RCL_CLIENT) - 1; + rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0); + if (rc < 0) + RETURN(rc); - LASSERT(rr->rr_namelen > 0); + rc = mdt_dlmreq_unpack(info); - rc = mdt_dlmreq_unpack(info); - RETURN(rc); + RETURN(rc); } static int mdt_unlink_unpack(struct mdt_thread_info *info) { - struct md_ucred *uc = mdt_ucred(info); + struct lu_ucred *uc = mdt_ucred(info); struct mdt_rec_unlink *rec; struct md_attr *ma = &info->mti_attr; struct lu_attr *attr = &info->mti_attr.ma_attr; @@ -1032,11 +1175,12 @@ static int mdt_unlink_unpack(struct mdt_thread_info *info) if (rec == NULL) RETURN(-EFAULT); - uc->mu_fsuid = rec->ul_fsuid; - uc->mu_fsgid = rec->ul_fsgid; - uc->mu_cap = rec->ul_cap; - uc->mu_suppgids[0] = rec->ul_suppgid1; - uc->mu_suppgids[1] = -1; + /* This prior initialization is needed for old_init_ucred_reint() */ + uc->uc_fsuid = rec->ul_fsuid; + uc->uc_fsgid = rec->ul_fsgid; + uc->uc_cap = rec->ul_cap; + uc->uc_suppgids[0] = rec->ul_suppgid1; + uc->uc_suppgids[1] = -1; attr->la_uid = rec->ul_fsuid; attr->la_gid = rec->ul_fsgid; @@ -1051,25 +1195,30 @@ static int mdt_unlink_unpack(struct mdt_thread_info *info) mdt_set_capainfo(info, 0, rr->rr_fid1, req_capsule_client_get(pill, &RMF_CAPA1)); - rr->rr_name = req_capsule_client_get(pill, &RMF_NAME); - rr->rr_namelen = req_capsule_get_size(pill, &RMF_NAME, RCL_CLIENT) - 1; - if (rr->rr_name == NULL || rr->rr_namelen == 0) - RETURN(-EFAULT); + rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0); + if (rc < 0) + RETURN(rc); if (rec->ul_bias & MDS_VTX_BYPASS) ma->ma_attr_flags |= MDS_VTX_BYPASS; else ma->ma_attr_flags &= ~MDS_VTX_BYPASS; - info->mti_spec.no_create = !!req_is_replay(mdt_info_req(info)); + info->mti_spec.no_create = !!req_is_replay(mdt_info_req(info)); rc = mdt_dlmreq_unpack(info); RETURN(rc); } +static int mdt_rmentry_unpack(struct mdt_thread_info *info) +{ + info->mti_spec.sp_rm_entry = 1; + return mdt_unlink_unpack(info); +} + static int mdt_rename_unpack(struct mdt_thread_info *info) { - struct md_ucred *uc = mdt_ucred(info); + struct lu_ucred *uc = mdt_ucred(info); struct mdt_rec_rename *rec; struct md_attr *ma = &info->mti_attr; struct lu_attr *attr = &info->mti_attr.ma_attr; @@ -1083,11 +1232,12 @@ static int mdt_rename_unpack(struct mdt_thread_info *info) if (rec == NULL) RETURN(-EFAULT); - uc->mu_fsuid = rec->rn_fsuid; - uc->mu_fsgid = rec->rn_fsgid; - uc->mu_cap = rec->rn_cap; - uc->mu_suppgids[0] = rec->rn_suppgid1; - uc->mu_suppgids[1] = rec->rn_suppgid2; + /* This prior initialization is needed for old_init_ucred_reint() */ + uc->uc_fsuid = rec->rn_fsuid; + uc->uc_fsgid = rec->rn_fsgid; + uc->uc_cap = rec->rn_cap; + uc->uc_suppgids[0] = rec->rn_suppgid1; + uc->uc_suppgids[1] = rec->rn_suppgid2; attr->la_uid = rec->rn_fsuid; attr->la_gid = rec->rn_fsgid; @@ -1106,13 +1256,13 @@ static int mdt_rename_unpack(struct mdt_thread_info *info) mdt_set_capainfo(info, 1, rr->rr_fid2, req_capsule_client_get(pill, &RMF_CAPA2)); - rr->rr_name = req_capsule_client_get(pill, &RMF_NAME); - rr->rr_tgt = req_capsule_client_get(pill, &RMF_SYMTGT); - if (rr->rr_name == NULL || rr->rr_tgt == NULL) - RETURN(-EFAULT); - rr->rr_namelen = req_capsule_get_size(pill, &RMF_NAME, RCL_CLIENT) - 1; - rr->rr_tgtlen = req_capsule_get_size(pill, &RMF_SYMTGT, RCL_CLIENT) - 1; - LASSERT(rr->rr_namelen > 0 && rr->rr_tgtlen > 0); + rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0); + if (rc < 0) + RETURN(rc); + + rc = mdt_name_unpack(pill, &RMF_SYMTGT, &rr->rr_tgt_name, 0); + if (rc < 0) + RETURN(rc); if (rec->rn_bias & MDS_VTX_BYPASS) ma->ma_attr_flags |= MDS_VTX_BYPASS; @@ -1121,8 +1271,10 @@ static int mdt_rename_unpack(struct mdt_thread_info *info) info->mti_spec.no_create = !!req_is_replay(mdt_info_req(info)); - rc = mdt_dlmreq_unpack(info); - RETURN(rc); + + rc = mdt_dlmreq_unpack(info); + + RETURN(rc); } /* @@ -1151,7 +1303,7 @@ static void mdt_fix_lov_magic(struct mdt_thread_info *info) static int mdt_open_unpack(struct mdt_thread_info *info) { - struct md_ucred *uc = mdt_ucred(info); + struct lu_ucred *uc = mdt_ucred(info); struct mdt_rec_create *rec; struct lu_attr *attr = &info->mti_attr.ma_attr; struct req_capsule *pill = info->mti_pill; @@ -1165,12 +1317,13 @@ static int mdt_open_unpack(struct mdt_thread_info *info) if (rec == NULL) RETURN(-EFAULT); - uc->mu_fsuid = rec->cr_fsuid; - uc->mu_fsgid = rec->cr_fsgid; - uc->mu_cap = rec->cr_cap; - uc->mu_suppgids[0] = rec->cr_suppgid1; - uc->mu_suppgids[1] = rec->cr_suppgid2; - uc->mu_umask = rec->cr_umask; + /* This prior initialization is needed for old_init_ucred_reint() */ + uc->uc_fsuid = rec->cr_fsuid; + uc->uc_fsgid = rec->cr_fsgid; + uc->uc_cap = rec->cr_cap; + uc->uc_suppgids[0] = rec->cr_suppgid1; + uc->uc_suppgids[1] = rec->cr_suppgid2; + uc->uc_umask = rec->cr_umask; rr->rr_fid1 = &rec->cr_fid1; rr->rr_fid2 = &rec->cr_fid2; @@ -1211,10 +1364,7 @@ static int mdt_open_unpack(struct mdt_thread_info *info) #endif } - rr->rr_name = req_capsule_client_get(pill, &RMF_NAME); - if (rr->rr_name == NULL) - RETURN(-EFAULT); - rr->rr_namelen = req_capsule_get_size(pill, &RMF_NAME, RCL_CLIENT) - 1; + mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, MNF_FIX_ANON); if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) { rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA, @@ -1243,12 +1393,13 @@ static int mdt_open_unpack(struct mdt_thread_info *info) static int mdt_setxattr_unpack(struct mdt_thread_info *info) { - struct mdt_reint_record *rr = &info->mti_rr; - struct md_ucred *uc = mdt_ucred(info); - struct lu_attr *attr = &info->mti_attr.ma_attr; - struct req_capsule *pill = info->mti_pill; - struct mdt_rec_setxattr *rec; - ENTRY; + struct mdt_reint_record *rr = &info->mti_rr; + struct lu_ucred *uc = mdt_ucred(info); + struct lu_attr *attr = &info->mti_attr.ma_attr; + struct req_capsule *pill = info->mti_pill; + struct mdt_rec_setxattr *rec; + int rc; + ENTRY; CLASSERT(sizeof(struct mdt_rec_setxattr) == @@ -1258,11 +1409,12 @@ static int mdt_setxattr_unpack(struct mdt_thread_info *info) if (rec == NULL) RETURN(-EFAULT); - uc->mu_fsuid = rec->sx_fsuid; - uc->mu_fsgid = rec->sx_fsgid; - uc->mu_cap = rec->sx_cap; - uc->mu_suppgids[0] = rec->sx_suppgid1; - uc->mu_suppgids[1] = -1; + /* This prior initialization is needed for old_init_ucred_reint() */ + uc->uc_fsuid = rec->sx_fsuid; + uc->uc_fsgid = rec->sx_fsgid; + uc->uc_cap = rec->sx_cap; + uc->uc_suppgids[0] = rec->sx_suppgid1; + uc->uc_suppgids[1] = -1; rr->rr_opcode = rec->sx_opcode; rr->rr_fid1 = &rec->sx_fid; @@ -1277,11 +1429,9 @@ static int mdt_setxattr_unpack(struct mdt_thread_info *info) else mdt_set_capainfo(info, 0, rr->rr_fid1, BYPASS_CAPA); - rr->rr_name = req_capsule_client_get(pill, &RMF_NAME); - if (rr->rr_name == NULL) - RETURN(-EFAULT); - rr->rr_namelen = req_capsule_get_size(pill, &RMF_NAME, RCL_CLIENT) - 1; - LASSERT(rr->rr_namelen > 0); + rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0); + if (rc < 0) + RETURN(rc); if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) { rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA, @@ -1299,6 +1449,9 @@ static int mdt_setxattr_unpack(struct mdt_thread_info *info) RETURN(-EFAULT); } + if (mdt_dlmreq_unpack(info) < 0) + RETURN(-EPROTO); + RETURN(0); } @@ -1306,13 +1459,15 @@ static int mdt_setxattr_unpack(struct mdt_thread_info *info) typedef int (*reint_unpacker)(struct mdt_thread_info *info); static reint_unpacker mdt_reint_unpackers[REINT_MAX] = { - [REINT_SETATTR] = mdt_setattr_unpack, - [REINT_CREATE] = mdt_create_unpack, - [REINT_LINK] = mdt_link_unpack, - [REINT_UNLINK] = mdt_unlink_unpack, - [REINT_RENAME] = mdt_rename_unpack, - [REINT_OPEN] = mdt_open_unpack, - [REINT_SETXATTR] = mdt_setxattr_unpack + [REINT_SETATTR] = mdt_setattr_unpack, + [REINT_CREATE] = mdt_create_unpack, + [REINT_LINK] = mdt_link_unpack, + [REINT_UNLINK] = mdt_unlink_unpack, + [REINT_RENAME] = mdt_rename_unpack, + [REINT_OPEN] = mdt_open_unpack, + [REINT_SETXATTR] = mdt_setxattr_unpack, + [REINT_RMENTRY] = mdt_rmentry_unpack, + [REINT_MIGRATE] = mdt_rename_unpack, }; int mdt_reint_unpack(struct mdt_thread_info *info, __u32 op)