Whamcloud - gitweb
xattr support in md/dt stack
[fs/lustre-release.git] / lustre / mdt / mdt_xattr.c
index 566bfba..9b1fe8e 100644 (file)
@@ -1,8 +1,8 @@
 /* -*- 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
+ *  linux/mdt/mdt_xattr.c
+ *  Lustre Metadata Target (mdt) extended attributes management.
  *
  *  Copyright (C) 2002-2006 Cluster File Systems, Inc.
  *   Author: Peter Braam <braam@clusterfs.com>
 #endif
 #define DEBUG_SUBSYSTEM S_MDS
 
+/* prerequisite for linux/xattr.h */
+#include <linux/types.h>
+/* prerequisite for linux/xattr.h */
+#include <linux/fs.h>
+/* XATTR_{REPLACE,CREATE} */
+#include <linux/xattr.h>
+
 #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;
+        struct req_capsule     *pill = &info->mti_pill ;
+        struct ptlrpc_request  *req = mdt_info_req(info);
+        char                   *xattr_name;
+        __u64                   valid = info->mti_body->valid;
+        static const char       user_string[] = "user.";
+        int                     rc;
+
+        if (MDT_FAIL_CHECK(OBD_FAIL_MDS_GETXATTR_PACK))
+                return -ENOMEM;
 
-        /* Imagine how many bytes we need */
-        if (info->mti_body->valid & OBD_MD_FLXATTR) {
+        /* Determine how many bytes we need */
+        if ((valid & OBD_MD_FLXATTR) == OBD_MD_FLXATTR) {
                 xattr_name = req_capsule_client_get(pill, &RMF_NAME);
-                if (!xattr_name) {
-                        CERROR("can't extract xattr name for getxattr\n");
+                if (!xattr_name)
                         return -EFAULT;
-                }
 
                 if (!(req->rq_export->exp_connect_flags & OBD_CONNECT_XATTR) &&
-                    (strncmp(xattr_name, "user.", 5) == 0))
+                    strncmp(xattr_name, user_string,
+                            sizeof(user_string) - 1) == 0)
                         return -EOPNOTSUPP;
 
-                rc = mo_xattr_get(info->mti_ctxt, 
-                                  mdt_object_child(info->mti_object), 
+                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, 
+        } else if ((valid & OBD_MD_FLXATTRLS) == OBD_MD_FLXATTRLS) {
+                rc = mo_xattr_list(info->mti_ctxt,
                                    mdt_object_child(info->mti_object),
                                    NULL, 0);
         } else {
@@ -72,27 +81,17 @@ static int mdt_getxattr_pack_reply(struct mdt_thread_info * info)
         }
 
         if (rc < 0) {
-                if (rc != -ENODATA && rc != -EOPNOTSUPP)
+                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);
+                        return rc;
+                }
+                rc = 0;
         } else {
                 rc =  min_t(int, info->mti_body->eadatasize, rc);
-                req_capsule_set_size(pill, &RMF_EADATA, RCL_SERVER, 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;
+        rc = req_capsule_pack(pill);
         return rc;
 }
 
@@ -108,38 +107,40 @@ int mdt_getxattr(struct mdt_thread_info *info)
         ENTRY;
 
         LASSERT(info->mti_object != NULL);
-        LASSERT(lu_object_exists(info->mti_ctxt,
+        LASSERT(lu_object_assert_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);
-        }
+        CDEBUG(D_INODE, "getxattr "DFID3"\n",
+                        PFID3(&info->mti_body->fid1));
+
+        if (MDT_FAIL_CHECK(OBD_FAIL_MDS_GETXATTR_PACK))
+                RETURN(-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);
+        rc = mdt_getxattr_pack_reply(info);
+        if (rc != 0)
+                RETURN(rc);
+
+        buf = req_capsule_server_get(&info->mti_pill, &RMF_EADATA);
+        rep_body = req_capsule_server_get(&info->mti_pill, &RMF_MDT_BODY);
+        buflen = req_capsule_get_size(&info->mti_pill, &RMF_EADATA, RCL_SERVER);
+        if (buflen == 0)
+                GOTO(no_xattr, rc = 0);
 
         if (info->mti_body->valid & OBD_MD_FLXATTR) {
-                char *xattr_name = req_capsule_client_get(&info->mti_pill, 
+                char *xattr_name = req_capsule_client_get(&info->mti_pill,
                                                           &RMF_NAME);
-                CDEBUG(S_MDS, "getxattr %s\n", xattr_name);
+                CDEBUG(D_INODE, "getxattr %s\n", xattr_name);
 
-                rc = mo_xattr_get(info->mti_ctxt, next, 
-                                   buf, buflen, 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);
+                        CDEBUG(D_INODE, "getxattr failed: %d\n", rc);
         } else if (info->mti_body->valid & OBD_MD_FLXATTRLS) {
-                CDEBUG(S_MDS, "listxattr\n");
+                CDEBUG(D_INODE, "listxattr\n");
 
                 rc = mo_xattr_list(info->mti_ctxt, next, buf, buflen);
                 if (rc < 0)
@@ -148,100 +149,96 @@ int mdt_getxattr(struct mdt_thread_info *info)
                 LBUG();
 
         if (rc >= 0) {
+no_xattr:
                 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 ptlrpc_request  *req = mdt_info_req(info);
+        const char              user_string[] = "user.";
+        const char              trust_string[] = "trusted.";
         struct mdt_lock_handle *lh;
+        struct req_capsule       *pill = &info->mti_pill;
+        struct mdt_object        *obj  = info->mti_object;
+        const struct mdt_body    *body = info->mti_body;
+        const struct lu_context  *ctx  = info->mti_ctxt;
+        struct md_object       *child  = mdt_object_child(obj);
+        __u64                   valid  = body->valid;
+        char                   *xattr_name;
+        int                     xattr_len;
+        __u64                   lockpart;
+        int                     rc;
         ENTRY;
 
-        lh = &info->mti_lh[MDT_LH_PARENT];
-        lh->mlh_mode = LCK_EX;
+        CDEBUG(D_INODE, "setxattr "DFID3"\n", PFID3(&body->fid1));
 
-/*        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;
+        if (MDT_FAIL_CHECK(OBD_FAIL_MDS_SETXATTR))
+                RETURN(-ENOMEM);
 
         /* 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);
-        }
+        xattr_name = req_capsule_client_get(pill, &RMF_NAME);
+        if (!xattr_name)
+                GOTO(out, rc = -EFAULT);
 
-        CDEBUG(D_INODE, "%sxattr %s\n",
-                  info->mti_body->valid & OBD_MD_FLXATTR ? "set" : "remove",
-                  xattr_name);
+        CDEBUG(D_INODE, "%s xattr %s\n",
+                  body->valid & OBD_MD_FLXATTR ? "set" : "remove", xattr_name);
 
-        if (strncmp(xattr_name, "trusted.", 8) == 0) {
-                if (strcmp(xattr_name + 8, "lov") == 0)
+        if (strncmp(xattr_name, trust_string, sizeof(trust_string) - 1) == 0) {
+                if (strcmp(xattr_name + 8, XATTR_NAME_LOV) == 0)
                         GOTO(out, rc = -EACCES);
         }
 
         if (!(req->rq_export->exp_connect_flags & OBD_CONNECT_XATTR) &&
-            (strncmp(xattr_name, "user.", 5) == 0)) {
+            (strncmp(xattr_name, user_string, sizeof(user_string) - 1) == 0)) {
                 GOTO(out, rc = -EOPNOTSUPP);
         }
 
-#define XATTR_NAME_ACL_ACCESS   "system.posix_acl_access"
-
+        lockpart = MDS_INODELOCK_UPDATE;
         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);
+        lh = &info->mti_lh[MDT_LH_PARENT];
+        lh->mlh_mode = LCK_EX;
+        rc = mdt_object_lock(info, obj, 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)) {
+        if ((valid & OBD_MD_FLXATTR) == OBD_MD_FLXATTR) {
+                char * xattr;
+                if (!req_capsule_field_present(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);
+                xattr_len = req_capsule_get_size(pill, &RMF_EADATA, RCL_CLIENT);
+                if (xattr_len) {
+                        int flags = 0;
+                        xattr = req_capsule_client_get(pill, &RMF_EADATA);
 
-                        rc = mo_xattr_set(info->mti_ctxt, 
-                                          mdt_object_child(info->mti_object),
-                                          xattr, xattr_len, xattr_name);
+                        if (body->flags & XATTR_REPLACE)
+                                flags |= LU_XATTR_REPLACE;
+
+                        if (body->flags & XATTR_CREATE)
+                                flags |= LU_XATTR_CREATE;
+
+                        rc = mo_xattr_set(ctx, child, xattr,
+                                          xattr_len, xattr_name, flags);
                 }
-        } 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 if ((valid & OBD_MD_FLXATTRRM) == OBD_MD_FLXATTRRM) {
+                rc = mo_xattr_del(ctx, child, xattr_name);
         } else {
-                CERROR("valid bits: "LPX64"\n", info->mti_body->valid);
+                CERROR("valid bits: "LPX64"\n", body->valid);
                 rc = -EINVAL;
         }
-
+        EXIT;
 out_unlock:
-        mdt_object_unlock(info->mti_mdt->mdt_namespace, 
-                          info->mti_object, lh);
+        mdt_object_unlock(info, obj, lh, rc);
 out:
         return rc;
 }