Whamcloud - gitweb
LU-8827 mdt: bypass quota enforcement for HSM release 20/23720/2
authorJohn L. Hammond <john.hammond@intel.com>
Wed, 10 Feb 2016 15:45:00 +0000 (09:45 -0600)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 9 Mar 2017 06:12:54 +0000 (06:12 +0000)
In mdt_hsm_release() create the orphan object with root ownership to
bypass potential quota restrictions on the user and group of the file
to be released.

Signed-off-by: John L. Hammond <john.hammond@intel.com>
Change-Id: I2f238bf39339e67e07a48743ccd2072a40ea7f0a
Reviewed-on: https://review.whamcloud.com/23720
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Niu Yawei <yawei.niu@intel.com>
Reviewed-by: Faccini Bruno <bruno.faccini@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/mdd/mdd_object.c
lustre/mdt/mdt_open.c

index 1d44816..36de98f 100644 (file)
@@ -1311,13 +1311,15 @@ static int mdd_xattr_hsm_replace(const struct lu_env *env,
  *  the rules are:
  *  - only normal FIDs or non-system IGIFs
  *  - same type of objects
- *  - same owner/group (so quotas are still valid)
+ *  - same owner/group (so quotas are still valid) unless this is from HSM
+ *    release.
  */
 static int mdd_layout_swap_allowed(const struct lu_env *env,
                                   struct mdd_object *o1,
                                   const struct lu_attr *attr1,
                                   struct mdd_object *o2,
-                                  const struct lu_attr *attr2)
+                                  const struct lu_attr *attr2,
+                                  __u64 flags)
 {
        const struct lu_fid     *fid1, *fid2;
        ENTRY;
@@ -1341,6 +1343,9 @@ static int mdd_layout_swap_allowed(const struct lu_env *env,
                RETURN(-EBADF);
        }
 
+       if (flags & SWAP_LAYOUTS_MDS_HSM)
+               RETURN(0);
+
        if ((attr1->la_uid != attr2->la_uid) ||
            (attr1->la_gid != attr2->la_gid))
                RETURN(-EPERM);
@@ -1394,7 +1399,7 @@ static int mdd_swap_layouts(const struct lu_env *env, struct md_object *obj1,
                RETURN(rc);
 
        /* check if layout swapping is allowed */
-       rc = mdd_layout_swap_allowed(env, fst_o, fst_la, snd_o, snd_la);
+       rc = mdd_layout_swap_allowed(env, fst_o, fst_la, snd_o, snd_la, flags);
        if (rc != 0)
                RETURN(rc);
 
index f9ca9a3..a6a1846 100644 (file)
@@ -1666,11 +1666,13 @@ static int mdt_hsm_release(struct mdt_thread_info *info, struct mdt_object *o,
                           struct md_attr *ma)
 {
        struct mdt_lock_handle *lh = &info->mti_lh[MDT_LH_LAYOUT];
+       struct lu_ucred        *uc = mdt_ucred(info);
        struct close_data      *data;
        struct ldlm_lock       *lease;
        struct mdt_object      *orphan;
        struct md_attr         *orp_ma;
        struct lu_buf          *buf;
+       cfs_cap_t               cap;
        bool                    lease_broken;
        int                     rc;
        int                     rc2;
@@ -1769,8 +1771,10 @@ static int mdt_hsm_release(struct mdt_thread_info *info, struct mdt_object *o,
 
        orp_ma = &info->mti_u.hsm.attr;
        orp_ma->ma_attr.la_mode = S_IFREG | S_IWUSR;
-       orp_ma->ma_attr.la_uid = ma->ma_attr.la_uid;
-       orp_ma->ma_attr.la_gid = ma->ma_attr.la_gid;
+       /* We use root ownership to bypass potential quota
+        * restrictions on the user and group of the file. */
+       orp_ma->ma_attr.la_uid = 0;
+       orp_ma->ma_attr.la_gid = 0;
        orp_ma->ma_attr.la_valid = LA_MODE | LA_UID | LA_GID;
        orp_ma->ma_lmm = ma->ma_lmm;
        orp_ma->ma_lmm_size = ma->ma_lmm_size;
@@ -1799,20 +1803,25 @@ static int mdt_hsm_release(struct mdt_thread_info *info, struct mdt_object *o,
        if (rc != 0)
                GOTO(out_close, rc);
 
+       /* The orphan has root ownership so we need to raise
+        * CAP_FOWNER to set the HSM attributes. */
+       cap = uc->uc_cap;
+       uc->uc_cap |= MD_CAP_TO_MASK(CFS_CAP_FOWNER);
        rc = mo_xattr_set(info->mti_env, mdt_object_child(orphan), buf,
                          XATTR_NAME_HSM, 0);
+       uc->uc_cap = cap;
+       if (rc != 0)
+               GOTO(out_layout_lock, rc);
 
-       if (rc == 0)
-               /* Swap layout with orphan object */
-               rc = mo_swap_layouts(info->mti_env, mdt_object_child(o),
-                                    mdt_object_child(orphan),
-                                    SWAP_LAYOUTS_MDS_HSM);
+       /* Swap layout with orphan objects. */
+       rc = mo_swap_layouts(info->mti_env, mdt_object_child(o),
+                            mdt_object_child(orphan),
+                            SWAP_LAYOUTS_MDS_HSM);
+       EXIT;
 
+out_layout_lock:
        /* Release exclusive LL */
        mdt_object_unlock(info, o, lh, 1);
-
-       EXIT;
-
 out_close:
        /* Close orphan object anyway */
        rc2 = mo_close(info->mti_env, mdt_object_child(orphan), orp_ma,