Whamcloud - gitweb
LU-11017 quota: ignore quota for CAP_SYS_RESOURCE properly 78/32378/10
authorWang Shilong <wshilong@ddn.com>
Wed, 16 May 2018 02:13:13 +0000 (10:13 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 29 May 2018 04:55:08 +0000 (04:55 +0000)
Currently, lustre quota will ignore this type of quota if
quota id is 0 or we force to ignore.

For write, we have passed CAP_SYS_RESOURCE properly, but
For metadata operations this is not done.

Test-Parameters: testlist=sanity-quota
Change-Id: Ibcdc0e53ad125042d4889ac51a9a9ead4066c0c8
Signed-off-by: Wang Shilong <wshilong@ddn.com>
Reviewed-on: https://review.whamcloud.com/32378
Tested-by: Jenkins
Reviewed-by: Fan Yong <fan.yong@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Yingjin Qian <qian@ddn.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/include/dt_object.h
lustre/lod/lod_sub_object.c
lustre/mdd/mdd_trans.c
lustre/osd-ldiskfs/osd_quota.c
lustre/osd-zfs/osd_quota.c
lustre/tests/sanity-quota.sh

index 2bf129e..35f1ec4 100644 (file)
@@ -1901,7 +1901,9 @@ struct thandle {
                                th_wait_submit:1,
        /* complex transaction which will track updates on all targets,
         * including OSTs */
-                               th_complex:1;
+                               th_complex:1,
+       /* whether ignore quota */
+                               th_ignore_quota:1;
 };
 
 /**
index ee67616..ba97709 100644 (file)
@@ -74,6 +74,7 @@ struct thandle *lod_sub_get_thandle(const struct lu_env *env,
                RETURN(th);
 
        tth = container_of(th, struct top_thandle, tt_super);
+       tth->tt_master_sub_thandle->th_ignore_quota = th->th_ignore_quota;
 
        /* local object must be mdt object, Note: during ost object
         * creation, FID is not assigned until osp_create(),
@@ -103,6 +104,7 @@ struct thandle *lod_sub_get_thandle(const struct lu_env *env,
        sub_th = thandle_get_sub(env, th, sub_obj);
        if (IS_ERR(sub_th))
                RETURN(sub_th);
+       sub_th->th_ignore_quota = th->th_ignore_quota;
 
        if (tth->tt_multiple_thandle != NULL && record_update != NULL &&
            th->th_result == 0)
index 050f397..2004bfc 100644 (file)
@@ -48,6 +48,9 @@
 struct thandle *mdd_trans_create(const struct lu_env *env,
                                  struct mdd_device *mdd)
 {
+       struct thandle *th;
+       struct lu_ucred *uc = lu_ucred_check(env);
+
        /* If blocked by the write barrier, then return "-EINPROGRESS"
         * to the caller. Usually, such error will be forwarded to the
         * client, and the expected behaviour is to re-try such modify
@@ -55,7 +58,11 @@ struct thandle *mdd_trans_create(const struct lu_env *env,
        if (unlikely(!barrier_entry(mdd->mdd_bottom)))
                return ERR_PTR(-EINPROGRESS);
 
-        return mdd_child_ops(mdd)->dt_trans_create(env, mdd->mdd_child);
+       th = mdd_child_ops(mdd)->dt_trans_create(env, mdd->mdd_child);
+       if (!IS_ERR(th) && uc)
+               th->th_ignore_quota = !!md_capable(uc, CFS_CAP_SYS_RESOURCE);
+
+       return th;
 }
 
 int mdd_trans_start(const struct lu_env *env, struct mdd_device *mdd,
index 7e15425..f0fc100 100644 (file)
@@ -634,7 +634,9 @@ int osd_declare_inode_qid(const struct lu_env *env, qid_t uid, qid_t gid,
        struct osd_thread_info  *info = osd_oti_get(env);
        struct lquota_id_info   *qi = &info->oti_qi;
        int rcu, rcg, rcp = 0; /* user & group & project rc */
-       bool force = !!(osd_qid_declare_flags & OSD_QID_FORCE);
+       struct thandle *th = &oh->ot_super;
+       bool force = !!(osd_qid_declare_flags & OSD_QID_FORCE) ||
+                       th->th_ignore_quota;
        ENTRY;
 
        /* let's start with user quota */
index 8db1972..0146a7f 100644 (file)
@@ -522,7 +522,9 @@ int osd_declare_quota(const struct lu_env *env, struct osd_device *osd,
        struct lquota_id_info *qi = &info->oti_qi;
        struct qsd_instance *qsd = osd->od_quota_slave;
        int rcu, rcg, rcp = 0; /* user & group & project rc */
-       bool force = !!(osd_qid_declare_flags & OSD_QID_FORCE);
+       struct thandle *th = &oh->ot_super;
+       bool force = !!(osd_qid_declare_flags & OSD_QID_FORCE) ||
+                       th->th_ignore_quota;
        ENTRY;
 
        if (unlikely(qsd == NULL))
index 0fe27bb..be624ea 100755 (executable)
@@ -3063,6 +3063,34 @@ test_59() {
 }
 run_test 59 "lfs project dosen't crash kernel with project disabled"
 
+test_60() {
+       setup_quota_test || error "setup quota failed with $?"
+       trap cleanup_quota_test EXIT
+       local testfile=$DIR/$tdir/$tfile
+       local limit=100
+
+       set_mdt_qtype "ug" || error "enable mdt quota failed"
+
+       $LFS setquota -g $TSTUSR -b 0 -B 0 -i 0 -I $limit $DIR ||
+               error "set quota failed"
+       quota_show_check a g $TSTUSR
+
+       chown $TSTUSR.$TSTUSR $DIR/$tdir || error "chown $DIR/$tdir failed"
+       chmod g+s $DIR/$tdir || error "chmod g+s failed"
+       $RUNAS createmany -m ${testfile} $((limit-1)) ||
+               error "create many files failed"
+
+       $RUNAS touch $DIR/$tdir/foo && error "regular user should fail"
+
+       # root user can overrun quota
+       runas -u 0 -g 0 touch $DIR/$tdir/foo ||
+               error "root user should succeed"
+
+       cleanup_quota_test
+       resetquota -u $TSTUSR
+}
+run_test 60 "Test quota for root with setgid"
+
 quota_fini()
 {
        do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=-quota"