it is still possible to lock or unlock encrypted directories,
as these operations only need read access to fscrypt metadata.
.br
+- ignore_root_prjquota, so that project quota is not enforced for the root user.
+.br
- quota_ops, to allow quota modifications.
.br
- server_upcall, to define which identity upcall to use. If set, identity upcall
/* whether ignore quota */
th_ignore_quota:1,
/* whether restart transaction */
- th_restart_tran:1;
+ th_restart_tran:1,
+ /* enforce project quota for root */
+ th_ignore_root_proj_quota:1;
};
/*
{ NODEMAP_RBAC_CHLG_OPS, "chlg_ops" },
{ NODEMAP_RBAC_FSCRYPT_ADMIN, "fscrypt_admin" },
{ NODEMAP_RBAC_SERVER_UPCALL, "server_upcall" },
+ { NODEMAP_RBAC_IGN_ROOT_PRJQUOTA, "ignore_root_prjquota" },
};
struct nodemap_pde {
/* whether we are reporting blocks or inodes */
bool lqi_is_blk;
+ /* enforce project quota for root */
+ bool lqi_ignore_root_proj_quota;
};
/* With the DoM, both inode quota in meta pool and block quota in data pool
int uc_rbac_chlg_ops:1;
int uc_rbac_fscrypt_admin:1;
int uc_rbac_server_upcall:1;
+ int uc_rbac_ignore_root_prjquota:1;
};
struct lu_ucred *lu_ucred(const struct lu_env *env);
NODEMAP_RBAC_CHLG_OPS = 0x00000010,
NODEMAP_RBAC_FSCRYPT_ADMIN = 0x00000020,
NODEMAP_RBAC_SERVER_UPCALL = 0x00000040,
+ NODEMAP_RBAC_IGN_ROOT_PRJQUOTA = 0x00000080,
NODEMAP_RBAC_NONE = (__u32)~(NODEMAP_RBAC_FILE_PERMS |
NODEMAP_RBAC_DNE_OPS |
NODEMAP_RBAC_QUOTA_OPS |
NODEMAP_RBAC_BYFID_OPS |
NODEMAP_RBAC_CHLG_OPS |
NODEMAP_RBAC_FSCRYPT_ADMIN |
- NODEMAP_RBAC_SERVER_UPCALL),
+ NODEMAP_RBAC_SERVER_UPCALL |
+ NODEMAP_RBAC_IGN_ROOT_PRJQUOTA),
NODEMAP_RBAC_ALL = 0xFFFFFFFF, /* future caps ON by default */
};
tth = container_of(th, struct top_thandle, tt_super);
tth->tt_master_sub_thandle->th_ignore_quota = th->th_ignore_quota;
+ tth->tt_master_sub_thandle->th_ignore_root_proj_quota =
+ th->th_ignore_root_proj_quota;
/* local object must be mdt object, Note: during ost object
* creation, FID is not assigned until osp_create(),
if (IS_ERR(sub_th))
RETURN(sub_th);
sub_th->th_ignore_quota = th->th_ignore_quota;
+ sub_th->th_ignore_root_proj_quota = th->th_ignore_root_proj_quota;
if (tth->tt_multiple_thandle != NULL && record_update != NULL &&
th->th_result == 0)
return ERR_PTR(-EINPROGRESS);
th = mdd_child_ops(mdd)->dt_trans_create(env, mdd->mdd_child);
- if (!IS_ERR(th) && uc)
+ if (IS_ERR(th)) {
+ barrier_exit(mdd->mdd_bottom);
+ goto out;
+ }
+
+ if (uc)
th->th_ignore_quota = !!cap_raised(uc->uc_cap, CAP_SYS_RESOURCE);
- if (IS_ERR(th))
- barrier_exit(mdd->mdd_bottom);
+ th->th_ignore_root_proj_quota =
+ uc ? uc->uc_rbac_ignore_root_prjquota : 1;
+out:
return th;
}
uc->uc_rbac_chlg_ops = 1;
uc->uc_rbac_fscrypt_admin = 1;
uc->uc_rbac_server_upcall = 1;
+ uc->uc_rbac_ignore_root_prjquota = 1;
RETURN(0);
}
mdt_ucred(info)->uc_rbac_chlg_ops = 1;
mdt_ucred(info)->uc_rbac_fscrypt_admin = 1;
mdt_ucred(info)->uc_rbac_server_upcall = 1;
+ mdt_ucred(info)->uc_rbac_ignore_root_prjquota = 1;
rc = mdt_add_dirty_flag(info, mfd->mfd_object, &info->mti_attr);
lu_context_exit(&ses);
uc->uc_rbac_chlg_ops = !!(rbac & NODEMAP_RBAC_CHLG_OPS);
uc->uc_rbac_fscrypt_admin = !!(rbac & NODEMAP_RBAC_FSCRYPT_ADMIN);
uc->uc_rbac_server_upcall = !!(rbac & NODEMAP_RBAC_SERVER_UPCALL);
+ uc->uc_rbac_ignore_root_prjquota =
+ !!(rbac & NODEMAP_RBAC_IGN_ROOT_PRJQUOTA);
}
static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
uc->uc_rbac_chlg_ops = 1;
uc->uc_rbac_fscrypt_admin = 1;
uc->uc_rbac_server_upcall = 1;
+ uc->uc_rbac_ignore_root_prjquota = 1;
task = kthread_create(mdt_restriper_main, info, "mdt_restriper_%03d",
mdt_seq_site(mdt)->ss_node_id);
ucred->uc_rbac_chlg_ops = 1;
ucred->uc_rbac_fscrypt_admin = 1;
ucred->uc_rbac_server_upcall = 1;
+ ucred->uc_rbac_ignore_root_prjquota = 1;
}
static void echo_ucred_fini(struct lu_env *env)
#define DEBUG_SUBSYSTEM S_FILTER
+#include <obd_class.h>
+#include <lustre_nodemap.h>
#include "ofd_internal.h"
/**
if (IS_ERR(th))
return th;
- /* export can require sync operations */
- if (info->fti_exp != NULL)
+ if (info->fti_exp != NULL) {
+ struct lu_nodemap *nodemap;
+
+ /* export can require sync operations */
th->th_sync |= info->fti_exp->exp_need_sync;
+
+ nodemap = nodemap_get_from_exp(info->fti_exp);
+ if (!IS_ERR_OR_NULL(nodemap)) {
+ th->th_ignore_root_proj_quota = !!(nodemap->nmf_rbac &
+ NODEMAP_RBAC_IGN_ROOT_PRJQUOTA);
+ nodemap_putref(nodemap);
+ } else {
+ th->th_ignore_root_proj_quota = 1;
+ }
+ }
+
return th;
}
int rc;
struct osd_thread_info *info = osd_oti_get(env);
struct lquota_id_info *qi = &info->oti_qi;
+ struct thandle *th = &oh->ot_super;
qi->lqi_type = type;
/* inode accounting */
qi->lqi_is_blk = false;
+ qi->lqi_ignore_root_proj_quota = th->th_ignore_root_proj_quota;
/* one more inode for the new id ... */
qi->lqi_id.qid_uid = new_id;
/* and now project quota */
qi->lqi_id.qid_projid = projid;
+ qi->lqi_ignore_root_proj_quota = th->th_ignore_root_proj_quota;
qi->lqi_type = PRJQUOTA;
rcp = osd_declare_qid(env, oh, qi, obj, true, local_flags);
if (!zpl_is_valid_projid(attr->la_projid))
GOTO(out, rc = -EINVAL);
+ info->oti_qi.lqi_ignore_root_proj_quota =
+ handle->th_ignore_root_proj_quota;
rc = qsd_transfer(env, osd_def_qsd(osd),
&oh->ot_quota_trans, PRJQUOTA,
obj->oo_attr.la_projid,
/* for project quota */
if (osd->od_projectused_dn) {
qi->lqi_id.qid_projid = projid;
+ qi->lqi_ignore_root_proj_quota = th->th_ignore_root_proj_quota;
qi->lqi_type = PRJQUOTA;
rcp = qsd_op_begin(env, qsd, &oh->ot_quota_trans, qi,
local_flags);
(unsigned)NODEMAP_RBAC_FSCRYPT_ADMIN);
LASSERTF(NODEMAP_RBAC_SERVER_UPCALL == 0x00000040UL, "found 0x%.8xUL\n",
(unsigned)NODEMAP_RBAC_SERVER_UPCALL);
- LASSERTF(NODEMAP_RBAC_NONE == 0xffffff80UL, "found 0x%.8xUL\n",
- (unsigned)NODEMAP_RBAC_NONE);
+ LASSERTF(NODEMAP_RBAC_IGN_ROOT_PRJQUOTA == 0x00000080UL, "found 0x%.8xUL\n",
+ (unsigned)NODEMAP_RBAC_IGN_ROOT_PRJQUOTA);
+ LASSERTF(NODEMAP_RBAC_NONE == 0xffffff00UL, "found 0x%.8xUL\n",
+ (unsigned)NODEMAP_RBAC_NONE);
LASSERTF(NODEMAP_RBAC_ALL == 0xffffffffUL, "found 0x%.8xUL\n",
(unsigned)NODEMAP_RBAC_ALL);
(qsd->qsd_type_array[qi->lqi_type])->qqi_acct_failed)
RETURN(0);
- if (local_flags && qi->lqi_id.qid_projid && qsd->qsd_root_prj_enable)
+ if (local_flags && qi->lqi_id.qid_projid &&
+ (qsd->qsd_root_prj_enable || !qi->lqi_ignore_root_proj_quota))
*local_flags |= QUOTA_FL_ROOT_PRJQUOTA;
LASSERTF(trans->lqt_id_cnt <= QUOTA_MAX_TRANSIDS, "id_cnt=%d\n",
local testf="$DIR/$tdir/$tfile-0"
local testf1="$DIR/$tdir/$tfile-1"
local testf2="$DIR/$tdir/$tfile-2"
+ local client_ip=$(host_nids_address $HOSTNAME $NETTYPE)
+ local client_nid=$(h2nettype $client_ip)
+ local nm=test_1j
(( $OST1_VERSION >= $(version_code 2.14.0.74) )) ||
skip "need OST at least 2.14.0.74"
do_facet ost2 $LCTL set_param $procf=0 ||
error "disable root quotas for project failed"
+ if (( $OST1_VERSION >= $(version_code 2.16.50) )); then
+ do_facet mgs $LCTL nodemap_modify --name default \
+ --property admin --value 1
+ do_facet mgs $LCTL nodemap_modify --name default \
+ --property trusted --value 1
+ do_facet mgs $LCTL nodemap_add $nm
+ stack_trap "do_facet mgs $LCTL nodemap_del $nm || true"
+ do_facet mgs $LCTL nodemap_add_range \
+ --name $nm --range $client_nid
+ do_facet mgs $LCTL nodemap_modify --name $nm \
+ --property admin --value 1
+ do_facet mgs $LCTL nodemap_modify --name $nm \
+ --property trusted --value 1
+ # do not set ignore_root_prjquota rbac role
+ do_facet mgs $LCTL nodemap_modify --name $nm --property rbac \
+ --value file_perms,dne_ops,quota_ops,byfid_ops,chlg_ops
+ do_facet mgs $LCTL nodemap_activate 1
+ stack_trap "do_facet mgs $LCTL nodemap_activate 0"
+ wait_nm_sync active
+ wait_nm_sync default admin_nodemap
+ wait_nm_sync default trusted_nodemap
+ wait_nm_sync $nm admin_nodemap
+ wait_nm_sync $nm trusted_nodemap
+ wait_nm_sync $nm rbac
+
+ runas -u 0 -g 0 $DD of=$testf count=$((limit/2)) \
+ seek=$limit oflag=direct &&
+ quota_error "project" $TSTPRJID "root write should fail"
+
+ do_facet mgs $LCTL nodemap_activate 0
+ wait_nm_sync active
+ fi
+
runas -u 0 -g 0 $DD of=$testf count=$limit seek=$limit oflag=direct ||
quota_error "project" $TSTPRJID "root write to project failed"
CHECK_VALUE_X(NODEMAP_RBAC_CHLG_OPS);
CHECK_VALUE_X(NODEMAP_RBAC_FSCRYPT_ADMIN);
CHECK_VALUE_X(NODEMAP_RBAC_SERVER_UPCALL);
+ CHECK_VALUE_X(NODEMAP_RBAC_IGN_ROOT_PRJQUOTA);
CHECK_VALUE_X(NODEMAP_RBAC_NONE);
CHECK_VALUE_X(NODEMAP_RBAC_ALL);
}
(unsigned)NODEMAP_RBAC_FSCRYPT_ADMIN);
LASSERTF(NODEMAP_RBAC_SERVER_UPCALL == 0x00000040UL, "found 0x%.8xUL\n",
(unsigned)NODEMAP_RBAC_SERVER_UPCALL);
- LASSERTF(NODEMAP_RBAC_NONE == 0xffffff80UL, "found 0x%.8xUL\n",
- (unsigned)NODEMAP_RBAC_NONE);
+ LASSERTF(NODEMAP_RBAC_IGN_ROOT_PRJQUOTA == 0x00000080UL, "found 0x%.8xUL\n",
+ (unsigned)NODEMAP_RBAC_IGN_ROOT_PRJQUOTA);
+ LASSERTF(NODEMAP_RBAC_NONE == 0xffffff00UL, "found 0x%.8xUL\n",
+ (unsigned)NODEMAP_RBAC_NONE);
LASSERTF(NODEMAP_RBAC_ALL == 0xffffffffUL, "found 0x%.8xUL\n",
(unsigned)NODEMAP_RBAC_ALL);