Whamcloud - gitweb
LU-8551 test: Use mds1 rather than mds to operate on MDT0000
[fs/lustre-release.git] / lustre / mdt / mdt_hsm_cdt_client.c
index ac8da87..63addc9 100644 (file)
@@ -23,6 +23,7 @@
  * (C) Copyright 2012 Commissariat a l'energie atomique et aux energies
  *     alternatives
  *
+ * Copyright (c) 2013, 2014, Intel Corporation.
  */
 /*
  * lustre/mdt/mdt_hsm_cdt_client.c
@@ -39,7 +40,6 @@
 #include <lustre_net.h>
 #include <lustre_export.h>
 #include <obd.h>
-#include <obd_lov.h>
 #include <lprocfs_status.h>
 #include <lustre_log.h>
 #include "mdt_internal.h"
@@ -245,6 +245,43 @@ static bool hal_is_sane(struct hsm_action_list *hal)
        RETURN(true);
 }
 
+static int
+hsm_action_permission(struct mdt_thread_info *mti,
+                     struct mdt_object *obj,
+                     enum hsm_copytool_action hsma)
+{
+       struct coordinator *cdt = &mti->mti_mdt->mdt_coordinator;
+       struct lu_ucred *uc = mdt_ucred(mti);
+       struct md_attr *ma = &mti->mti_attr;
+       const __u64 *mask;
+       int rc;
+       ENTRY;
+
+       if (hsma != HSMA_RESTORE &&
+           exp_connect_flags(mti->mti_exp) & OBD_CONNECT_RDONLY)
+               RETURN(-EROFS);
+
+       if (md_capable(uc, CFS_CAP_SYS_ADMIN))
+               RETURN(0);
+
+       ma->ma_need = MA_INODE;
+       rc = mdt_attr_get_complex(mti, obj, ma);
+       if (rc < 0)
+               RETURN(rc);
+
+       if (uc->uc_fsuid == ma->ma_attr.la_uid)
+               mask = &cdt->cdt_user_request_mask;
+       else if (lustre_in_group_p(uc, ma->ma_attr.la_gid))
+               mask = &cdt->cdt_group_request_mask;
+       else
+               mask = &cdt->cdt_other_request_mask;
+
+       if (!(0 <= hsma && hsma < 8 * sizeof(*mask)))
+               RETURN(-EINVAL);
+
+       RETURN(*mask & (1UL << hsma) ? 0 : -EPERM);
+}
+
 /*
  * Coordinator external API
  */
@@ -253,13 +290,12 @@ static bool hal_is_sane(struct hsm_action_list *hal)
  * register a list of requests
  * \param mti [IN]
  * \param hal [IN] list of requests
- * \param compound_id [OUT] id of the compound request
  * \retval 0 success
  * \retval -ve failure
  * in case of restore, caller must hold layout lock
  */
 int mdt_hsm_add_actions(struct mdt_thread_info *mti,
-                       struct hsm_action_list *hal, __u64 *compound_id)
+                       struct hsm_action_list *hal)
 {
        struct mdt_device       *mdt = mti->mti_mdt;
        struct coordinator      *cdt = &mdt->mdt_coordinator;
@@ -268,6 +304,7 @@ int mdt_hsm_add_actions(struct mdt_thread_info *mti,
        int                      rc = 0, i;
        struct md_hsm            mh;
        bool                     is_restore = false;
+       __u64                    compound_id;
        ENTRY;
 
        /* no coordinator started, so we cannot serve requests */
@@ -277,7 +314,7 @@ int mdt_hsm_add_actions(struct mdt_thread_info *mti,
        if (!hal_is_sane(hal))
                RETURN(-EINVAL);
 
-       *compound_id = atomic_inc_return(&cdt->cdt_compound_id);
+       compound_id = atomic_inc_return(&cdt->cdt_compound_id);
 
        /* search for compatible request, if found hai_cookie is set
         * to the request cookie
@@ -321,23 +358,30 @@ int mdt_hsm_add_actions(struct mdt_thread_info *mti,
                 * if restore, we take the layout lock
                 */
 
-               /* if action is cancel, also no need to check */
-               if (hai->hai_action == HSMA_CANCEL)
-                       goto record;
-
-               /* get HSM attributes */
+               /* Get HSM attributes and check permissions. */
                obj = mdt_hsm_get_md_hsm(mti, &hai->hai_fid, &mh);
-               if (IS_ERR(obj) || obj == NULL) {
-                       /* in case of archive remove, Lustre file
-                        * is not mandatory */
-                       if (hai->hai_action == HSMA_REMOVE)
+               if (IS_ERR(obj)) {
+                       /* In case of REMOVE and CANCEL a Lustre file
+                        * is not mandatory, but restrict this
+                        * exception to admins. */
+                       if (md_capable(mdt_ucred(mti), CFS_CAP_SYS_ADMIN) &&
+                           (hai->hai_action == HSMA_REMOVE ||
+                            hai->hai_action == HSMA_CANCEL))
                                goto record;
-                       if (obj == NULL)
-                               GOTO(out, rc = -ENOENT);
-                       GOTO(out, rc = PTR_ERR(obj));
+                       else
+                               GOTO(out, rc = PTR_ERR(obj));
                }
+
+               rc = hsm_action_permission(mti, obj, hai->hai_action);
                mdt_object_put(mti->mti_env, obj);
 
+               if (rc < 0)
+                       GOTO(out, rc);
+
+               /* if action is cancel, also no need to check */
+               if (hai->hai_action == HSMA_CANCEL)
+                       goto record;
+
                /* Check if an action is needed, compare request
                 * and HSM flags status */
                if (!hsm_action_is_needed(hai, archive_id, flags, &mh))
@@ -408,7 +452,7 @@ int mdt_hsm_add_actions(struct mdt_thread_info *mti,
                }
 record:
                /* record request */
-               rc = mdt_agent_record_add(mti->mti_env, mdt, *compound_id,
+               rc = mdt_agent_record_add(mti->mti_env, mdt, compound_id,
                                          archive_id, flags, hai);
                if (rc)
                        GOTO(out, rc);
@@ -556,4 +600,3 @@ int mdt_hsm_get_actions(struct mdt_thread_info *mti,
 
        RETURN(0);
 }
-