From 981093fea1d9d012cfec97e68770b90170d5861a Mon Sep 17 00:00:00 2001 From: huanghua Date: Thu, 15 Jun 2006 09:17:04 +0000 Subject: [PATCH] added xattr support. --- lustre/include/lustre_req_layout.h | 5 + lustre/include/md_object.h | 24 ++++ lustre/mdt/Makefile.in | 2 +- lustre/mdt/mdt_handler.c | 14 +-- lustre/mdt/mdt_internal.h | 2 + lustre/mdt/mdt_xattr.c | 247 +++++++++++++++++++++++++++++++++++++ lustre/ptlrpc/layout.c | 39 ++++++ 7 files changed, 320 insertions(+), 13 deletions(-) create mode 100644 lustre/mdt/mdt_xattr.c diff --git a/lustre/include/lustre_req_layout.h b/lustre/include/lustre_req_layout.h index 44a379a..52877a0 100644 --- a/lustre/include/lustre_req_layout.h +++ b/lustre/include/lustre_req_layout.h @@ -69,6 +69,9 @@ const void *req_capsule_other_get(const struct req_capsule *pill, void req_capsule_set_size(const struct req_capsule *pill, const struct req_msg_field *field, enum req_location loc, int size); +int req_capsule_get_size(const struct req_capsule *pill, + const struct req_msg_field *field, + enum req_location loc); void req_capsule_extend(struct req_capsule *pill, const struct req_format *fmt); int req_capsule_has_field(const struct req_capsule *pill, @@ -83,6 +86,8 @@ extern const struct req_format RQF_SEQ_QUERY; extern const struct req_format RQF_FLD_QUERY; extern const struct req_format RQF_MDS_GETSTATUS; extern const struct req_format RQF_MDS_STATFS; +extern const struct req_format RQF_MDS_GETXATTR; +extern const struct req_format RQF_MDS_SETXATTR; extern const struct req_format RQF_MDS_GETATTR; extern const struct req_format RQF_MDS_CONNECT; extern const struct req_format RQF_MDS_DISCONNECT; diff --git a/lustre/include/md_object.h b/lustre/include/md_object.h index 4d1fd9f..3a767f0 100644 --- a/lustre/include/md_object.h +++ b/lustre/include/md_object.h @@ -190,6 +190,30 @@ static inline int mo_xattr_get(const struct lu_context *cx, LASSERT(m->mo_ops->moo_xattr_get); return m->mo_ops->moo_xattr_get(cx, m, buf, buf_len, name); } +static inline int mo_xattr_del(const struct lu_context *cx, + struct md_object *m, + const char *name) +{ + LASSERT(m->mo_ops->moo_xattr_set); + /*NULL buffer & zero length for set? or we need a new interface*/ + return m->mo_ops->moo_xattr_set(cx, m, NULL, 0, name); +} + +static inline int mo_xattr_set(const struct lu_context *cx, + struct md_object *m, + void *buf, int buf_len, const char *name) +{ + LASSERT(m->mo_ops->moo_xattr_set); + return m->mo_ops->moo_xattr_set(cx, m, buf, buf_len, name); +} +static inline int mo_xattr_list(const struct lu_context *cx, + struct md_object *m, + void *buf, int buf_len) +{ + LASSERT(m->mo_ops->moo_xattr_get); + /*NULL name for get? or we need a new interface*/ + return m->mo_ops->moo_xattr_get(cx, m, buf, buf_len, NULL); +} static inline int mo_open(const struct lu_context *cx, struct md_object *m) diff --git a/lustre/mdt/Makefile.in b/lustre/mdt/Makefile.in index 846af6e..26c17e2 100644 --- a/lustre/mdt/Makefile.in +++ b/lustre/mdt/Makefile.in @@ -1,4 +1,4 @@ MODULES := mdt -mdt-objs := mdt_handler.o mdt_lib.o mdt_reint.o +mdt-objs := mdt_handler.o mdt_lib.o mdt_reint.o mdt_xattr.o @INCLUDE_RULES@ diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 2e792f6..662e9f9 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -304,16 +304,6 @@ static int mdt_disconnect(struct mdt_thread_info *info) return target_handle_disconnect(mdt_info_req(info)); } -static int mdt_setxattr(struct mdt_thread_info *info) -{ - return -EOPNOTSUPP; -} - -static int mdt_getxattr(struct mdt_thread_info *info) -{ - return -EOPNOTSUPP; -} - static int mdt_readpage(struct mdt_thread_info *info) { return -EOPNOTSUPP; @@ -2285,8 +2275,8 @@ DEF_MDT_HNDL_F(0, DISCONNECT, mdt_disconnect), DEF_MDT_HNDL_F(0 |HABEO_REFERO, GETSTATUS, mdt_getstatus), DEF_MDT_HNDL_F(HABEO_CORPUS|HABEO_REFERO, GETATTR, mdt_getattr), DEF_MDT_HNDL_F(HABEO_CORPUS|HABEO_REFERO, GETATTR_NAME, mdt_getattr_name), -DEF_MDT_HNDL_0(HABEO_CORPUS, SETXATTR, mdt_setxattr), -DEF_MDT_HNDL_0(HABEO_CORPUS, GETXATTR, mdt_getxattr), +DEF_MDT_HNDL_F(HABEO_CORPUS, SETXATTR, mdt_setxattr), +DEF_MDT_HNDL_F(HABEO_CORPUS, GETXATTR, mdt_getxattr), DEF_MDT_HNDL_F(0 |HABEO_REFERO, STATFS, mdt_statfs), DEF_MDT_HNDL_0(HABEO_CORPUS, READPAGE, mdt_readpage), DEF_MDT_HNDL_F(0, REINT, mdt_reint), diff --git a/lustre/mdt/mdt_internal.h b/lustre/mdt/mdt_internal.h index 22106e5..90918ae 100644 --- a/lustre/mdt/mdt_internal.h +++ b/lustre/mdt/mdt_internal.h @@ -220,6 +220,8 @@ int mdt_reint_rec(struct mdt_thread_info *); void mdt_pack_attr2body(struct mdt_body *b, struct lu_attr *attr); const struct lu_fid *mdt_object_fid(struct mdt_object *o); struct ptlrpc_request *mdt_info_req (struct mdt_thread_info *info); +int mdt_getxattr(struct mdt_thread_info *info); +int mdt_setxattr(struct mdt_thread_info *info); #endif /* __KERNEL__ */ #endif /* _MDT_H */ diff --git a/lustre/mdt/mdt_xattr.c b/lustre/mdt/mdt_xattr.c new file mode 100644 index 0000000..566bfba --- /dev/null +++ b/lustre/mdt/mdt_xattr.c @@ -0,0 +1,247 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * linux/mdt/mdt_reint.c + * Lustre Metadata Target (mdt) reintegration routines + * + * Copyright (C) 2002-2006 Cluster File Systems, Inc. + * Author: Peter Braam + * Author: Andreas Dilger + * Author: Phil Schwan + * Author: Huang Hua + * + * This file is part of the Lustre file system, http://www.lustre.org + * Lustre is a trademark of Cluster File Systems, Inc. + * + * 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. + * + * 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. + * + * 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. + */ + +#ifndef EXPORT_SYMTAB +# define EXPORT_SYMTAB +#endif +#define DEBUG_SUBSYSTEM S_MDS + +#include "mdt_internal.h" + + +/* return EADATA length to the caller. negative value means error */ +static int mdt_getxattr_pack_reply(struct mdt_thread_info * info) +{ + char *xattr_name; + int rc = -EOPNOTSUPP, rc2; + struct req_capsule *pill; + struct ptlrpc_request *req = mdt_info_req(info); + + pill = &info->mti_pill; + + /* Imagine how many bytes we need */ + if (info->mti_body->valid & OBD_MD_FLXATTR) { + xattr_name = req_capsule_client_get(pill, &RMF_NAME); + if (!xattr_name) { + CERROR("can't extract xattr name for getxattr\n"); + return -EFAULT; + } + + if (!(req->rq_export->exp_connect_flags & OBD_CONNECT_XATTR) && + (strncmp(xattr_name, "user.", 5) == 0)) + return -EOPNOTSUPP; + + rc = mo_xattr_get(info->mti_ctxt, + mdt_object_child(info->mti_object), + NULL, 0, xattr_name); + } else if (info->mti_body->valid & OBD_MD_FLXATTRLS) { + rc = mo_xattr_list(info->mti_ctxt, + mdt_object_child(info->mti_object), + NULL, 0); + } else { + CERROR("valid bits: "LPX64"\n", info->mti_body->valid); + return -EINVAL; + } + + if (rc < 0) { + if (rc != -ENODATA && rc != -EOPNOTSUPP) + CWARN("get EA size error: %d\n", rc); + /* return empty to client */ + req_capsule_extend(&info->mti_pill, &RQF_MDS_SETXATTR); + } else { + rc = min_t(int, info->mti_body->eadatasize, rc); + req_capsule_set_size(pill, &RMF_EADATA, RCL_SERVER, rc); + } + + if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETXATTR_PACK)) { + CERROR("failed MDS_GETXATTR_PACK test\n"); + req->rq_status = -ENOMEM; + return -ENOMEM; + } + + rc2 = req_capsule_pack(pill); + if (rc2) + return rc2; + + if (rc < 0) + req->rq_status = rc; + return rc; +} + + +int mdt_getxattr(struct mdt_thread_info *info) +{ + int rc; + struct md_object *next; + char *buf; + int buflen; + struct mdt_body *rep_body; + + ENTRY; + + LASSERT(info->mti_object != NULL); + LASSERT(lu_object_exists(info->mti_ctxt, + &info->mti_object->mot_obj.mo_lu)); + ENTRY; + + if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETXATTR_PACK)) { + CERROR(LUSTRE_MDT0_NAME": getxattr lustre_pack_reply failed\n"); + RETURN(rc = -ENOMEM); + } + + next = mdt_object_child(info->mti_object); + + buflen = mdt_getxattr_pack_reply(info); + if (buflen < 0) + RETURN(rc = buflen); + buf = req_capsule_server_get(&info->mti_pill, + &RMF_EADATA); + rep_body = req_capsule_server_get(&info->mti_pill, + &RMF_MDT_BODY); + + if (info->mti_body->valid & OBD_MD_FLXATTR) { + char *xattr_name = req_capsule_client_get(&info->mti_pill, + &RMF_NAME); + CDEBUG(S_MDS, "getxattr %s\n", xattr_name); + + rc = mo_xattr_get(info->mti_ctxt, next, + buf, buflen, xattr_name); + + if (rc < 0 && rc != -ENODATA && rc != -EOPNOTSUPP && + rc != -ERANGE) + CDEBUG(S_MDS, "getxattr failed: %d\n", rc); + } else if (info->mti_body->valid & OBD_MD_FLXATTRLS) { + CDEBUG(S_MDS, "listxattr\n"); + + rc = mo_xattr_list(info->mti_ctxt, next, buf, buflen); + if (rc < 0) + CDEBUG(D_OTHER, "listxattr failed: %d\n", rc); + } else + LBUG(); + + if (rc >= 0) { + rep_body->eadatasize = rc; + rc = 0; + } + + RETURN(rc); + return 0; +} + + +int mdt_setxattr(struct mdt_thread_info *info) +{ + int rc; + char *xattr_name; + int xattr_len; + struct ptlrpc_request *req = mdt_info_req(info); + __u64 lockpart; + struct mdt_lock_handle *lh; + ENTRY; + + lh = &info->mti_lh[MDT_LH_PARENT]; + lh->mlh_mode = LCK_EX; + +/* if (req->rq_reqmsg->bufcount < 2) + * RETURN(-EFAULT); + */ + DEBUG_REQ(D_INODE, req, "setxattr "DFID3, + PFID3(&info->mti_body->fid1)); + +/* MDS_CHECK_RESENT(req, mds_reconstruct_generic(req)); */ + + lockpart = MDS_INODELOCK_UPDATE; + + /* various sanity check for xattr name */ + xattr_name = req_capsule_client_get(&info->mti_pill, &RMF_NAME); + if (!xattr_name) { + CERROR("can't extract xattr name\n"); + GOTO(out, rc = -EPROTO); + } + + CDEBUG(D_INODE, "%sxattr %s\n", + info->mti_body->valid & OBD_MD_FLXATTR ? "set" : "remove", + xattr_name); + + if (strncmp(xattr_name, "trusted.", 8) == 0) { + if (strcmp(xattr_name + 8, "lov") == 0) + GOTO(out, rc = -EACCES); + } + + if (!(req->rq_export->exp_connect_flags & OBD_CONNECT_XATTR) && + (strncmp(xattr_name, "user.", 5) == 0)) { + GOTO(out, rc = -EOPNOTSUPP); + } + +#define XATTR_NAME_ACL_ACCESS "system.posix_acl_access" + + if (!strcmp(xattr_name, XATTR_NAME_ACL_ACCESS)) + lockpart |= MDS_INODELOCK_LOOKUP; + + rc = mdt_object_lock(info->mti_mdt->mdt_namespace, info->mti_object, + lh, lockpart); + if (rc != 0) + GOTO(out, rc); + + + if (info->mti_body->valid & OBD_MD_FLXATTR) { + char * xattr; + if (!req_capsule_field_present(&info->mti_pill, &RMF_EADATA)) { + CERROR("no xattr data supplied\n"); + GOTO(out_unlock, rc = -EFAULT); + } + + xattr_len = req_capsule_get_size(&info->mti_pill, + &RMF_EADATA, RCL_CLIENT); + if (xattr_len) + { + xattr = req_capsule_client_get(&info->mti_pill, + &RMF_EADATA); + + rc = mo_xattr_set(info->mti_ctxt, + mdt_object_child(info->mti_object), + xattr, xattr_len, xattr_name); + } + } else if (info->mti_body->valid & OBD_MD_FLXATTRRM) { + rc = mo_xattr_del(info->mti_ctxt, + mdt_object_child(info->mti_object), + xattr_name); + } else { + CERROR("valid bits: "LPX64"\n", info->mti_body->valid); + rc = -EINVAL; + } + +out_unlock: + mdt_object_unlock(info->mti_mdt->mdt_namespace, + info->mti_object, lh); +out: + return rc; +} diff --git a/lustre/ptlrpc/layout.c b/lustre/ptlrpc/layout.c index efba55d..f46e7c7 100644 --- a/lustre/ptlrpc/layout.c +++ b/lustre/ptlrpc/layout.c @@ -169,6 +169,22 @@ static const struct req_msg_field *ldlm_intent_unlink_client[] = { &RMF_NAME }; +static const struct req_msg_field * mds_getxattr_client[] = { + &RMF_MDT_BODY, + &RMF_NAME +}; + +static const struct req_msg_field * mds_getxattr_server[] = { + &RMF_MDT_BODY, + &RMF_EADATA +}; + +static const struct req_msg_field * mds_setxattr_client[] = { + &RMF_MDT_BODY, + &RMF_NAME + &RMF_EADATA +}; + static const struct req_format *req_formats[] = { &RQF_MDS_CONNECT, &RQF_MDS_DISCONNECT, @@ -189,6 +205,8 @@ static const struct req_format *req_formats[] = { &RQF_LDLM_INTENT_UNLINK, &RQF_SEQ_QUERY, &RQF_FLD_QUERY, + &RQF_MDS_GETXATTR, + &RQF_MDS_SETXATTR }; struct req_msg_field { @@ -385,6 +403,14 @@ const struct req_format RQF_MDS_GETATTR = DEFINE_REQ_FMT0("MDS_GETATTR", mdt_body_only, mdt_body_only); EXPORT_SYMBOL(RQF_MDS_GETATTR); +const struct req_format RQF_MDS_GETXATTR = + DEFINE_REQ_FMT0("MDS_GETXATTR", mds_getxattr_client, mds_getxattr_server); +EXPORT_SYMBOL(RQF_MDS_GETATTR); + +const struct req_format RQF_MDS_SETXATTR = + DEFINE_REQ_FMT0("MDS_SETXATTR", mds_setxattr_client, empty); +EXPORT_SYMBOL(RQF_MDS_GETATTR); + const struct req_format RQF_MDS_GETATTR_NAME = DEFINE_REQ_FMT0("MDS_GETATTR_NAME", mds_getattr_name_client, mdt_body_only); @@ -649,6 +675,19 @@ void req_capsule_set_size(const struct req_capsule *pill, } EXPORT_SYMBOL(req_capsule_set_size); +int req_capsule_get_size(const struct req_capsule *pill, + const struct req_msg_field *field, + enum req_location loc) +{ + LASSERT(location == RCL_SERVER || location == RCL_CLIENT); + if (loc == RCL_SERVER) + return pill->rc_area[__req_capsule_offset(pill, field, loc)]; + /* else */ + return lustre_msg_buflen(__req_msg(pill, loc), + __req_capsule_offset(pill, field, loc)); +} +EXPORT_SYMBOL(req_capsule_get_size); + #define FMT_FIELD(fmt, i, j) (fmt)->rf_fields[(i)].d[(j)] void req_capsule_extend(struct req_capsule *pill, const struct req_format *fmt) -- 1.8.3.1