Whamcloud - gitweb
added xattr support.
authorhuanghua <huanghua>
Thu, 15 Jun 2006 09:17:04 +0000 (09:17 +0000)
committerhuanghua <huanghua>
Thu, 15 Jun 2006 09:17:04 +0000 (09:17 +0000)
lustre/include/lustre_req_layout.h
lustre/include/md_object.h
lustre/mdt/Makefile.in
lustre/mdt/mdt_handler.c
lustre/mdt/mdt_internal.h
lustre/mdt/mdt_xattr.c [new file with mode: 0644]
lustre/ptlrpc/layout.c

index 44a379a..52877a0 100644 (file)
@@ -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;
index 4d1fd9f..3a767f0 100644 (file)
@@ -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)
index 846af6e..26c17e2 100644 (file)
@@ -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@
index 2e792f6..662e9f9 100644 (file)
@@ -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),
index 22106e5..90918ae 100644 (file)
@@ -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 (file)
index 0000000..566bfba
--- /dev/null
@@ -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 <braam@clusterfs.com>
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *   Author: Phil Schwan <phil@clusterfs.com>
+ *   Author: Huang Hua <huanghua@clusterfs.com>
+ *
+ *   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;
+}
index efba55d..f46e7c7 100644 (file)
@@ -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)