/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
- * lustre/mdt/mdt_lib.c
- * Lustre Metadata Target (mdt) request unpacking helper.
+ * GPL HEADER START
*
- * Copyright (c) 2006 Cluster File Systems, Inc.
- * Author: Peter Braam <braam@clusterfs.com>
- * Author: Andreas Dilger <adilger@clusterfs.com>
- * Author: Phil Schwan <phil@clusterfs.com>
- * Author: Mike Shaver <shaver@clusterfs.com>
- * Author: Nikita Danilov <nikita@clusterfs.com>
- * Author: Huang Hua <huanghua@clusterfs.com>
- * Author: Fan Yong <fanyong@clusterfs.com>
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
*
- * This file is part of the Lustre file system, http://www.lustre.org
- * Lustre is a trademark of Cluster File Systems, Inc.
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
*
- * You may have signed or agreed to another license before downloading
- * this software. If so, you are bound by the terms and conditions
- * of that agreement, and the following does not apply to you. See the
- * LICENSE file included with this distribution for more information.
+ * 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
*
- * If you did not agree to a different license, then this copy of Lustre
- * is open source software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
+ * 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.
*
- * In either case, Lustre is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * license text for more details.
+ * GPL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/mdt/mdt_lib.c
+ *
+ * Lustre Metadata Target (mdt) request unpacking helper.
+ *
+ * Author: Peter Braam <braam@clusterfs.com>
+ * Author: Andreas Dilger <adilger@clusterfs.com>
+ * Author: Phil Schwan <phil@clusterfs.com>
+ * Author: Mike Shaver <shaver@clusterfs.com>
+ * Author: Nikita Danilov <nikita@clusterfs.com>
+ * Author: Huang Hua <huanghua@clusterfs.com>
+ * Author: Fan Yong <fanyong@clusterfs.com>
*/
struct mdt_device *mdt = info->mti_mdt;
struct ptlrpc_user_desc *pud = req->rq_user_desc;
struct md_ucred *ucred = mdt_ucred(info);
- lnet_nid_t peernid = req->rq_peer.nid;
+ lnet_nid_t peernid = req->rq_peer.nid;
__u32 perm = 0;
- int setuid;
- int setgid;
- int rc = 0;
+ int setuid;
+ int setgid;
+ int rc = 0;
ENTRY;
LASSERT(req->rq_auth_gss);
LASSERT(!req->rq_auth_usr_mdt);
LASSERT(req->rq_user_desc);
-
+
ucred->mu_valid = UCRED_INVALID;
ucred->mu_o_uid = pud->pud_uid;
/* sanity check: we expect the uid which client claimed is true */
if (med->med_rmtclient) {
if (req->rq_auth_mapped_uid == INVALID_UID) {
- CWARN("remote user not mapped, deny access!\n");
+ CDEBUG(D_SEC, "remote user not mapped, deny access!\n");
RETURN(-EACCES);
}
RETURN(-EACCES);
if (req->rq_auth_mapped_uid != pud->pud_uid) {
- CERROR("remote client "LPU64": auth/mapped uid %u/%u "
- "while client claim %u:%u/%u:%u\n",
- peernid, req->rq_auth_uid,
+ CDEBUG(D_SEC, "remote client %s: auth/mapped uid %u/%u "
+ "while client claims %u:%u/%u:%u\n",
+ libcfs_nid2str(peernid), req->rq_auth_uid,
req->rq_auth_mapped_uid,
pud->pud_uid, pud->pud_gid,
pud->pud_fsuid, pud->pud_fsgid);
}
} else {
if (req->rq_auth_uid != pud->pud_uid) {
- CERROR("local client "LPU64": auth uid %u "
- "while client claim %u:%u/%u:%u\n",
- peernid, req->rq_auth_uid, pud->pud_uid,
- pud->pud_gid, pud->pud_fsuid, pud->pud_fsgid);
+ CDEBUG(D_SEC, "local client %s: auth uid %u "
+ "while client claims %u:%u/%u:%u\n",
+ libcfs_nid2str(peernid), req->rq_auth_uid,
+ pud->pud_uid, pud->pud_gid,
+ pud->pud_fsuid, pud->pud_fsgid);
RETURN(-EACCES);
}
}
if (is_identity_get_disabled(mdt->mdt_identity_cache)) {
if (med->med_rmtclient) {
- CERROR("remote client must run with identity_get "
+ CDEBUG(D_SEC, "remote client must run with identity_get "
"enabled!\n");
RETURN(-EACCES);
} else {
CFS_SETGRP_PERM;
}
} else {
- ucred->mu_identity = mdt_identity_get(mdt->mdt_identity_cache,
- pud->pud_uid);
- if (!ucred->mu_identity) {
- CERROR("Deny access without identity: uid %d\n",
- pud->pud_uid);
- RETURN(-EACCES);
+ struct md_identity *identity;
+
+ identity = mdt_identity_get(mdt->mdt_identity_cache,
+ pud->pud_uid);
+ if (IS_ERR(identity)) {
+ if (unlikely(PTR_ERR(identity) == -EREMCHG &&
+ !med->med_rmtclient)) {
+ ucred->mu_identity = NULL;
+ perm = CFS_SETUID_PERM | CFS_SETGID_PERM |
+ CFS_SETGRP_PERM;
+ } else {
+ CDEBUG(D_SEC, "Deny access without identity: uid %u\n",
+ pud->pud_uid);
+ RETURN(-EACCES);
+ }
} else {
+ ucred->mu_identity = identity;
perm = mdt_identity_get_perm(ucred->mu_identity,
- med->med_rmtclient,
- peernid);
+ med->med_rmtclient,
+ peernid);
}
}
/* check permission of setuid */
if (setuid && !(perm & CFS_SETUID_PERM)) {
- CWARN("mdt blocked setuid attempt (%u -> %u) from "
- LPX64"\n", pud->pud_uid, pud->pud_fsuid, peernid);
+ CDEBUG(D_SEC, "mdt blocked setuid attempt (%u -> %u) from %s\n",
+ pud->pud_uid, pud->pud_fsuid, libcfs_nid2str(peernid));
GOTO(out, rc = -EACCES);
}
/* check permission of setgid */
if (setgid && !(perm & CFS_SETGID_PERM)) {
- CWARN("mdt blocked setgid attempt (%u:%u/%u:%u -> %u) "
- "from "LPX64"\n", pud->pud_uid, pud->pud_gid,
- pud->pud_fsuid, pud->pud_fsgid,
- ucred->mu_identity->mi_gid, peernid);
+ 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);
}
*/
if (!med->med_rmtclient && perm & CFS_SETGRP_PERM) {
if (pud->pud_ngroups) {
- /* setgroups for local client */
+ /* setgroups for local client */
ucred->mu_ginfo = groups_alloc(pud->pud_ngroups);
if (!ucred->mu_ginfo) {
- CERROR("failed to alloc %d groups\n",
- pud->pud_ngroups);
- GOTO(out, rc = -ENOMEM);
- }
+ 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_ginfo = NULL;
+ }
} else {
ucred->mu_suppgids[0] = -1;
ucred->mu_suppgids[1] = -1;
/* remove fs privilege for non-root user */
if (ucred->mu_fsuid)
- ucred->mu_cap = pud->pud_cap & ~CAP_FS_MASK;
+ ucred->mu_cap = pud->pud_cap & ~CFS_CAP_FS_MASK;
else
ucred->mu_cap = pud->pud_cap;
ucred->mu_valid = UCRED_NEW;
struct ptlrpc_user_desc *pud = req->rq_user_desc;
struct md_ucred *ucred = mdt_ucred(info);
struct md_identity *identity = NULL;
- lnet_nid_t peernid = req->rq_peer.nid;
+ lnet_nid_t peernid = req->rq_peer.nid;
__u32 perm = 0;
int setuid;
int setgid;
/* sanity check: if we use strong authentication, we expect the
* uid which client claimed is true */
- if (med->med_rmtclient) {
- if (req->rq_auth_mapped_uid == INVALID_UID) {
- CWARN("remote user not mapped, deny access!\n");
- RETURN(-EACCES);
- }
+ if (med->med_rmtclient) {
+ if (req->rq_auth_mapped_uid == INVALID_UID) {
+ 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) {
- CERROR("remote client "LPU64": auth/mapped uid %u/%u "
- "while client claim %u:%u/%u:%u\n",
- peernid, req->rq_auth_uid,
+ if (req->rq_auth_mapped_uid != pud->pud_uid) {
+ CDEBUG(D_SEC, "remote client %s: auth/mapped uid %u/%u "
+ "while client claims %u:%u/%u:%u\n",
+ libcfs_nid2str(peernid), req->rq_auth_uid,
req->rq_auth_mapped_uid,
pud->pud_uid, pud->pud_gid,
pud->pud_fsuid, pud->pud_fsgid);
- RETURN(-EACCES);
- }
- } else {
- if (req->rq_auth_uid != pud->pud_uid) {
- CERROR("local client "LPU64": auth uid %u "
- "while client claim %u:%u/%u:%u\n",
- peernid, req->rq_auth_uid, pud->pud_uid,
- pud->pud_gid, pud->pud_fsuid,
- pud->pud_fsgid);
- RETURN(-EACCES);
- }
+ RETURN(-EACCES);
+ }
+ } else {
+ if (req->rq_auth_uid != pud->pud_uid) {
+ CDEBUG(D_SEC, "local client %s: auth uid %u "
+ "while client claims %u:%u/%u:%u\n",
+ libcfs_nid2str(peernid), req->rq_auth_uid,
+ pud->pud_uid, pud->pud_gid,
+ pud->pud_fsuid, pud->pud_fsgid);
+ RETURN(-EACCES);
}
+ }
if (is_identity_get_disabled(mdt->mdt_identity_cache)) {
if (med->med_rmtclient) {
- CERROR("remote client must run with identity_get "
+ CDEBUG(D_SEC, "remote client must run with identity_get "
"enabled!\n");
RETURN(-EACCES);
}
}
identity = mdt_identity_get(mdt->mdt_identity_cache, pud->pud_uid);
- if (!identity) {
- CERROR("Deny access without identity: uid %d\n", pud->pud_uid);
- RETURN(-EACCES);
+ if (IS_ERR(identity)) {
+ if (unlikely(PTR_ERR(identity) == -EREMCHG &&
+ !med->med_rmtclient)) {
+ RETURN(0);
+ } else {
+ CDEBUG(D_SEC, "Deny access without identity: uid %u\n",
+ pud->pud_uid);
+ RETURN(-EACCES);
+ }
}
perm = mdt_identity_get_perm(identity, med->med_rmtclient, peernid);
/* check permission of setuid */
if (setuid && !(perm & CFS_SETUID_PERM)) {
- CWARN("mdt blocked setuid attempt (%u -> %u) from "
- LPX64"\n", pud->pud_uid, pud->pud_fsuid, peernid);
+ CDEBUG(D_SEC, "mdt blocked setuid attempt (%u -> %u) from %s\n",
+ pud->pud_uid, pud->pud_fsuid, libcfs_nid2str(peernid));
GOTO(out, rc = -EACCES);
}
/* check permission of setgid */
if (setgid && !(perm & CFS_SETGID_PERM)) {
- CWARN("mdt blocked setgid attempt (%u:%u/%u:%u -> %u) "
- "from "LPX64"\n", pud->pud_uid, pud->pud_gid,
- pud->pud_fsuid, pud->pud_fsgid, identity->mi_gid,
- peernid);
+ 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, identity->mi_gid,
+ libcfs_nid2str(peernid));
GOTO(out, rc = -EACCES);
}
if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
identity = mdt_identity_get(mdt->mdt_identity_cache,
uc->mu_fsuid);
- if (!identity) {
- CERROR("Deny access without identity: uid %d\n",
- uc->mu_fsuid);
- RETURN(-EACCES);
+ 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;
/* remove fs privilege for non-root user */
if (uc->mu_fsuid)
- uc->mu_cap = body->capability & ~CAP_FS_MASK;
+ uc->mu_cap = body->capability & ~CFS_CAP_FS_MASK;
else
uc->mu_cap = body->capability;
uc->mu_valid = UCRED_OLD;
if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
identity = mdt_identity_get(mdt->mdt_identity_cache,
uc->mu_fsuid);
- if (!identity) {
- CERROR("Deny access without identity: uid %d\n",
- uc->mu_fsuid);
- RETURN(-EACCES);
- }
+ 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;
/* remove fs privilege for non-root user */
if (uc->mu_fsuid)
- uc->mu_cap &= ~CAP_FS_MASK;
+ uc->mu_cap &= ~CFS_CAP_FS_MASK;
uc->mu_valid = UCRED_OLD;
RETURN(0);
void mdt_shrink_reply(struct mdt_thread_info *info)
{
- struct req_capsule *pill = &info->mti_pill;
- struct mdt_body *body;
- int acl_size, md_size, adjust = 0;
+ struct req_capsule *pill = info->mti_pill;
+ struct mdt_body *body;
+ int md_size;
+ int acl_size;
ENTRY;
body = req_capsule_server_get(pill, &RMF_MDT_BODY);
acl_size = body->aclsize;
- CDEBUG(D_INFO, "Shrink to md_size = %d cookie/acl_size = %d"
- " MDSCAPA = %d, OSSCAPA = %d\n",
+ CDEBUG(D_INFO, "Shrink to md_size = %d cookie/acl_size = %d"
+ " MDSCAPA = "LPX64", OSSCAPA = "LPX64"\n",
md_size, acl_size,
- (int)(body->valid & OBD_MD_FLMDSCAPA),
- (int)(body->valid & OBD_MD_FLOSSCAPA));
+ body->valid & OBD_MD_FLMDSCAPA,
+ body->valid & OBD_MD_FLOSSCAPA);
/*
&RMF_MDT_BODY,
&RMF_MDT_MD,
(optional) &RMF_CAPA2,
(optional) something else
*/
- adjust += req_capsule_shrink(pill, &RMF_MDT_MD,
- md_size, adjust, 1);
+ if (req_capsule_has_field(pill, &RMF_MDT_MD, RCL_SERVER))
+ req_capsule_shrink(pill, &RMF_MDT_MD, md_size,
+ RCL_SERVER);
if (req_capsule_has_field(pill, &RMF_ACL, RCL_SERVER))
- adjust += req_capsule_shrink(pill, &RMF_ACL,
- acl_size, adjust, 1);
+ req_capsule_shrink(pill, &RMF_ACL, acl_size, RCL_SERVER);
else if (req_capsule_has_field(pill, &RMF_LOGCOOKIES, RCL_SERVER))
- adjust += req_capsule_shrink(pill, &RMF_LOGCOOKIES,
- acl_size, adjust, 1);
-
- /* RMF_CAPA1 on server-side maybe for OBD_MD_FLMDSCAPA or
- * OBD_MD_FLOSSCAPA. If RMF_CAPA2 exist also, RMF_CAPA1 is
- * for OBD_MD_FLMDSCAPA only. */
- if (req_capsule_has_field(pill, &RMF_CAPA1, RCL_SERVER)) {
- if ((req_capsule_has_field(pill, &RMF_CAPA2, RCL_SERVER) &&
- !(body->valid & OBD_MD_FLMDSCAPA)) ||
- (!req_capsule_has_field(pill, &RMF_CAPA2, RCL_SERVER) &&
- !(body->valid & OBD_MD_FLMDSCAPA) &&
- !(body->valid & OBD_MD_FLOSSCAPA)))
- adjust += req_capsule_shrink(pill, &RMF_CAPA1,
- 0, adjust, 1);
- }
+ req_capsule_shrink(pill, &RMF_LOGCOOKIES,
+ 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);
- /* RMF_CAPA2 on server-side is for OBD_MD_FLOSSCAPA only. */
- if ((req_capsule_has_field(pill, &RMF_CAPA2, RCL_SERVER) &&
- !(body->valid & OBD_MD_FLOSSCAPA)))
- adjust += req_capsule_shrink(pill, &RMF_CAPA2, 0, adjust, 0);
+ if (req_capsule_has_field(pill, &RMF_CAPA2, RCL_SERVER) &&
+ !(body->valid & OBD_MD_FLOSSCAPA))
+ req_capsule_shrink(pill, &RMF_CAPA2, 0, RCL_SERVER);
/*
* Some more field should be shrinked if needed.
const struct lu_attr *la = &ma->ma_attr;
ENTRY;
- repbody = req_capsule_server_get(&info->mti_pill, &RMF_MDT_BODY);
+ repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
LASSERT(repbody != NULL);
if (ma->ma_valid & MA_INODE)
out |= LA_FLAGS;
if (in & MDS_OPEN_OWNEROVERRIDE)
- out |= MDS_OPEN_OWNEROVERRIDE;
+ ma->ma_attr_flags |= MDS_OPEN_OWNEROVERRIDE;
+
+ if (in & (ATTR_KILL_SUID|ATTR_KILL_SGID))
+ ma->ma_attr_flags |= MDS_PERM_BYPASS;
/*XXX need ATTR_RAW?*/
in &= ~(ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_BLOCKS|
struct md_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;
+ struct req_capsule *pill = info->mti_pill;
struct mdt_reint_record *rr = &info->mti_rr;
struct mdt_rec_setattr *rec;
ENTRY;
- rec = req_capsule_client_get(pill, &RMF_REC_SETATTR);
+ CLASSERT(sizeof(struct mdt_rec_setattr)== sizeof(struct mdt_rec_reint));
+ rec = req_capsule_client_get(pill, &RMF_REC_REINT);
if (rec == NULL)
RETURN(-EFAULT);
static int mdt_epoch_unpack(struct mdt_thread_info *info)
{
- struct req_capsule *pill = &info->mti_pill;
+ struct req_capsule *pill = info->mti_pill;
ENTRY;
if (req_capsule_get_size(pill, &RMF_MDT_EPOCH, RCL_CLIENT))
}
static inline int mdt_dlmreq_unpack(struct mdt_thread_info *info) {
- struct req_capsule *pill = &info->mti_pill;
+ struct req_capsule *pill = info->mti_pill;
if (req_capsule_get_size(pill, &RMF_DLM_REQ, RCL_CLIENT)) {
info->mti_dlm_req = req_capsule_client_get(pill, &RMF_DLM_REQ);
if (info->mti_dlm_req == NULL)
RETURN(-EFAULT);
}
-
+
RETURN(0);
}
static int mdt_setattr_unpack(struct mdt_thread_info *info)
{
struct md_attr *ma = &info->mti_attr;
- struct req_capsule *pill = &info->mti_pill;
+ struct req_capsule *pill = info->mti_pill;
int rc;
ENTRY;
struct mdt_rec_create *rec;
struct lu_attr *attr = &info->mti_attr.ma_attr;
struct mdt_reint_record *rr = &info->mti_rr;
- struct req_capsule *pill = &info->mti_pill;
+ struct req_capsule *pill = info->mti_pill;
struct md_op_spec *sp = &info->mti_spec;
int rc;
ENTRY;
- rec = req_capsule_client_get(pill, &RMF_REC_CREATE);
+ CLASSERT(sizeof(struct mdt_rec_create) == sizeof(struct mdt_rec_reint));
+ rec = req_capsule_client_get(pill, &RMF_REC_REINT);
if (rec == NULL)
RETURN(-EFAULT);
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_namelen > 0);
-
+ LASSERT(rr->rr_name && rr->rr_namelen > 0);
+
#ifdef CONFIG_FS_POSIX_ACL
if (sp->sp_cr_flags & MDS_CREATE_RMT_ACL) {
if (S_ISDIR(attr->la_mode))
RCL_CLIENT));
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);
+ RCL_CLIENT);
sp->u.sp_ea.fid = rr->rr_fid1;
RETURN(0);
}
struct mdt_rec_link *rec;
struct lu_attr *attr = &info->mti_attr.ma_attr;
struct mdt_reint_record *rr = &info->mti_rr;
- struct req_capsule *pill = &info->mti_pill;
+ struct req_capsule *pill = info->mti_pill;
int rc;
ENTRY;
- rec = req_capsule_client_get(pill, &RMF_REC_LINK);
+ CLASSERT(sizeof(struct mdt_rec_link) == sizeof(struct mdt_rec_reint));
+ rec = req_capsule_client_get(pill, &RMF_REC_REINT);
if (rec == NULL)
RETURN(-EFAULT);
struct md_attr *ma = &info->mti_attr;
struct lu_attr *attr = &info->mti_attr.ma_attr;
struct mdt_reint_record *rr = &info->mti_rr;
- struct req_capsule *pill = &info->mti_pill;
+ struct req_capsule *pill = info->mti_pill;
int rc;
ENTRY;
- rec = req_capsule_client_get(pill, &RMF_REC_UNLINK);
+ CLASSERT(sizeof(struct mdt_rec_unlink) == sizeof(struct mdt_rec_reint));
+ rec = req_capsule_client_get(pill, &RMF_REC_REINT);
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_suppgid;
+ uc->mu_suppgids[0] = rec->ul_suppgid1;
uc->mu_suppgids[1] = -1;
attr->la_uid = rec->ul_fsuid;
struct md_attr *ma = &info->mti_attr;
struct lu_attr *attr = &info->mti_attr.ma_attr;
struct mdt_reint_record *rr = &info->mti_rr;
- struct req_capsule *pill = &info->mti_pill;
+ struct req_capsule *pill = info->mti_pill;
int rc;
ENTRY;
- rec = req_capsule_client_get(pill, &RMF_REC_RENAME);
+ CLASSERT(sizeof(struct mdt_rec_rename) == sizeof(struct mdt_rec_reint));
+ rec = req_capsule_client_get(pill, &RMF_REC_REINT);
if (rec == NULL)
RETURN(-EFAULT);
struct md_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;
+ struct req_capsule *pill = info->mti_pill;
struct mdt_reint_record *rr = &info->mti_rr;
struct ptlrpc_request *req = mdt_info_req(info);
struct md_op_spec *sp = &info->mti_spec;
ENTRY;
- rec = req_capsule_client_get(pill, &RMF_REC_CREATE);
+ CLASSERT(sizeof(struct mdt_rec_create) == sizeof(struct mdt_rec_reint));
+ rec = req_capsule_client_get(pill, &RMF_REC_REINT);
if (rec == NULL)
RETURN(-EFAULT);
RETURN(0);
}
+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;
+
+
+ CLASSERT(sizeof(struct mdt_rec_setxattr) ==
+ sizeof(struct mdt_rec_reint));
+
+ rec = req_capsule_client_get(pill, &RMF_REC_REINT);
+ 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;
+
+ rr->rr_opcode = rec->sx_opcode;
+ rr->rr_fid1 = &rec->sx_fid;
+ attr->la_valid = rec->sx_valid;
+ attr->la_ctime = rec->sx_time;
+ attr->la_size = rec->sx_size;
+ attr->la_flags = rec->sx_flags;
+
+ 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));
+ 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);
+
+ rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA, RCL_CLIENT);
+ if (rr->rr_eadatalen > 0) {
+ rr->rr_eadata = req_capsule_client_get(pill, &RMF_EADATA);
+ if (rr->rr_eadata == NULL)
+ RETURN(-EFAULT);
+ }
+
+ RETURN(0);
+}
+
+
typedef int (*reint_unpacker)(struct mdt_thread_info *info);
static reint_unpacker mdt_reint_unpackers[REINT_MAX] = {
[REINT_LINK] = mdt_link_unpack,
[REINT_UNLINK] = mdt_unlink_unpack,
[REINT_RENAME] = mdt_rename_unpack,
- [REINT_OPEN] = mdt_open_unpack
+ [REINT_OPEN] = mdt_open_unpack,
+ [REINT_SETXATTR] = mdt_setxattr_unpack
};
int mdt_reint_unpack(struct mdt_thread_info *info, __u32 op)