From a00a07567d4909251e58900a9e5ea27157960fd4 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Sat, 8 Apr 2017 14:11:42 -0400 Subject: [PATCH] LU-4017 quota: cleanup codes of quota for new type This patch cleanups codes of quota to prepare for new type other than USRQUOTA/GRPQUOTA. Signed-off-by: Li Xi Signed-off-by: Wang Shilong Signed-off-by: Oleg Drokin Change-Id: I5b6fadf4eead957c8c94c91a4993de8798d87d3d Reviewed-on: https://review.whamcloud.com/18894 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Niu Yawei --- lustre/include/lustre/lustre_idl.h | 4 + lustre/include/lustre/lustre_user.h | 12 +- lustre/include/lustre/lustreapi.h | 4 + lustre/include/lustre_fid.h | 14 +- lustre/llite/dir.c | 20 ++- lustre/mdt/mdt_handler.c | 11 +- lustre/ofd/ofd_io.c | 2 +- lustre/osc/osc_quota.c | 40 +++-- lustre/osc/osc_request.c | 4 +- lustre/osd-ldiskfs/osd_internal.h | 4 +- lustre/osd-ldiskfs/osd_io.c | 2 +- lustre/osd-ldiskfs/osd_quota.c | 39 ++-- lustre/osd-zfs/osd_internal.h | 2 +- lustre/osd-zfs/osd_oi.c | 18 +- lustre/osd-zfs/osd_quota.c | 29 ++- lustre/quota/lproc_quota.c | 19 +- lustre/quota/lquota_disk.c | 11 +- lustre/quota/lquota_internal.h | 41 ++++- lustre/quota/lquota_lib.c | 75 +++++--- lustre/quota/qmt_pool.c | 32 ++-- lustre/quota/qsd_entry.c | 2 +- lustre/quota/qsd_handler.c | 14 +- lustre/quota/qsd_lib.c | 45 +++-- lustre/quota/qsd_lock.c | 2 +- lustre/utils/lfs.c | 349 ++++++++++++++++++------------------ 25 files changed, 491 insertions(+), 304 deletions(-) diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index df22acd..7e94d97 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -1199,6 +1199,8 @@ lov_mds_md_max_stripe_count(size_t buf_size, __u32 lmm_magic) #define OBD_MD_DEFAULT_MEA (0x0040000000000000ULL) /* default MEA */ #define OBD_MD_FLOSTLAYOUT (0x0080000000000000ULL) /* contain ost_layout */ +#define OBD_MD_FLALLQUOTA (OBD_MD_FLUSRQUOTA | OBD_MD_FLGRPQUOTA) + #define OBD_MD_FLGETATTR (OBD_MD_FLID | OBD_MD_FLATIME | OBD_MD_FLMTIME | \ OBD_MD_FLCTIME | OBD_MD_FLSIZE | OBD_MD_FLBLKSZ | \ OBD_MD_FLMODE | OBD_MD_FLTYPE | OBD_MD_FLUID | \ @@ -1246,6 +1248,8 @@ struct hsm_state_set { * space for unstable pages; asking * it to sync quickly */ +#define OBD_BRW_OVER_ALLQUOTA (OBD_BRW_OVER_USRQUOTA | OBD_BRW_OVER_GRPQUOTA) + #define OBD_OBJECT_EOF LUSTRE_EOF #define OST_MIN_PRECREATE 32 diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index a3dcbe4..5a2fc74 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -701,7 +701,17 @@ static inline __u64 lustre_stoqb(size_t space) #define LUSTRE_Q_INVALIDATE 0x80000b /* deprecated as of 2.4 */ #define LUSTRE_Q_FINVALIDATE 0x80000c /* deprecated as of 2.4 */ -#define UGQUOTA 2 /* set both USRQUOTA and GRPQUOTA */ +#define ALLQUOTA 255 /* set all quota */ +static inline char *qtype_name(int qtype) +{ + switch (qtype) { + case USRQUOTA: + return "usr"; + case GRPQUOTA: + return "grp"; + } + return "unknown"; +} #define IDENTITY_DOWNCALL_MAGIC 0x6d6dd629 diff --git a/lustre/include/lustre/lustreapi.h b/lustre/include/lustre/lustreapi.h index f2da938..e8d895a 100644 --- a/lustre/include/lustre/lustreapi.h +++ b/lustre/include/lustre/lustreapi.h @@ -42,6 +42,10 @@ #include #include +#ifndef LL_MAXQUOTAS +#define LL_MAXQUOTAS 2 +#endif + extern bool liblustreapi_initialized; diff --git a/lustre/include/lustre_fid.h b/lustre/include/lustre_fid.h index f85449a..37baa62 100644 --- a/lustre/include/lustre_fid.h +++ b/lustre/include/lustre_fid.h @@ -278,11 +278,21 @@ static inline int fid_is_otable_it(const struct lu_fid *fid) fid_oid(fid) == OTABLE_IT_OID); } +static inline int fid_oid_is_quota(const struct lu_fid *fid) +{ + switch (fid_oid(fid)) { + case ACCT_USER_OID: + case ACCT_GROUP_OID: + return 1; + default: + return 0; + } +} + static inline int fid_is_acct(const struct lu_fid *fid) { return fid_seq(fid) == FID_SEQ_LOCAL_FILE && - (fid_oid(fid) == ACCT_USER_OID || - fid_oid(fid) == ACCT_GROUP_OID); + fid_oid_is_quota(fid); } static inline int fid_is_quota(const struct lu_fid *fid) diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index ad4acfd..c6a59cd 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -985,6 +985,21 @@ out: return rc; } +static inline int check_owner(int type, int id) +{ + switch (type) { + case USRQUOTA: + if (!uid_eq(current_euid(), make_kuid(&init_user_ns, id))) + return -EPERM; + break; + case GRPQUOTA: + if (!in_egroup_p(make_kgid(&init_user_ns, id))) + return -EPERM; + break; + } + return 0; +} + static int quotactl_ioctl(struct ll_sb_info *sbi, struct if_quotactl *qctl) { int cmd = qctl->qc_cmd; @@ -1001,10 +1016,7 @@ static int quotactl_ioctl(struct ll_sb_info *sbi, struct if_quotactl *qctl) RETURN(-EPERM); break; case Q_GETQUOTA: - if (((type == USRQUOTA && - !uid_eq(current_euid(), make_kuid(&init_user_ns, id))) || - (type == GRPQUOTA && - !in_egroup_p(make_kgid(&init_user_ns, id)))) && + if (check_owner(type, id) && (!cfs_capable(CFS_CAP_SYS_ADMIN))) RETURN(-EPERM); break; diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 657966d..b41b70e 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -2137,13 +2137,18 @@ static int mdt_quotactl(struct tgt_session_info *tsi) } id = oqctl->qc_id; - if (oqctl->qc_type == USRQUOTA) + switch (oqctl->qc_type) { + case USRQUOTA: id = nodemap_map_id(nodemap, NODEMAP_UID, NODEMAP_CLIENT_TO_FS, id); - else if (oqctl->qc_type == GRPQUOTA) + break; + case GRPQUOTA: id = nodemap_map_id(nodemap, NODEMAP_UID, NODEMAP_CLIENT_TO_FS, id); - + break; + default: + GOTO(out_nodemap, rc = -EOPNOTSUPP); + } repoqc = req_capsule_server_get(pill, &RMF_OBD_QUOTACTL); if (repoqc == NULL) GOTO(out_nodemap, rc = err_serious(-EFAULT)); diff --git a/lustre/ofd/ofd_io.c b/lustre/ofd/ofd_io.c index 11cd6ce..5129ae9 100644 --- a/lustre/ofd/ofd_io.c +++ b/lustre/ofd/ofd_io.c @@ -1250,7 +1250,7 @@ int ofd_commitrw(const struct lu_env *env, int cmd, struct obd_export *exp, } oa->o_valid |= OBD_MD_FLFLAGS; - oa->o_valid |= OBD_MD_FLUSRQUOTA | OBD_MD_FLGRPQUOTA; + oa->o_valid |= OBD_MD_FLALLQUOTA; } } else if (cmd == OBD_BRW_READ) { struct ldlm_namespace *ns = ofd->ofd_namespace; diff --git a/lustre/osc/osc_quota.c b/lustre/osc/osc_quota.c index f259f49..d817953 100644 --- a/lustre/osc/osc_quota.c +++ b/lustre/osc/osc_quota.c @@ -66,16 +66,36 @@ int osc_quota_chkdq(struct client_obd *cli, const unsigned int qid[]) RETURN(QUOTA_OK); } -#define MD_QUOTA_FLAG(type) ((type == USRQUOTA) ? OBD_MD_FLUSRQUOTA \ - : OBD_MD_FLGRPQUOTA) -#define FL_QUOTA_FLAG(type) ((type == USRQUOTA) ? OBD_FL_NO_USRQUOTA \ - : OBD_FL_NO_GRPQUOTA) +static inline u32 md_quota_flag(int qtype) +{ + switch (qtype) { + case USRQUOTA: + return OBD_MD_FLUSRQUOTA; + case GRPQUOTA: + return OBD_MD_FLGRPQUOTA; + default: + return 0; + } +} + +static inline u32 fl_quota_flag(int qtype) +{ + switch (qtype) { + case USRQUOTA: + return OBD_FL_NO_USRQUOTA; + case GRPQUOTA: + return OBD_FL_NO_GRPQUOTA; + default: + return 0; + } +} int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], u64 valid, u32 flags) { int type; int rc = 0; + ENTRY; if ((valid & (OBD_MD_FLUSRQUOTA | OBD_MD_FLGRPQUOTA)) == 0) @@ -84,12 +104,12 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], for (type = 0; type < LL_MAXQUOTAS; type++) { struct osc_quota_info *oqi; - if ((valid & MD_QUOTA_FLAG(type)) == 0) + if ((valid & md_quota_flag(type)) == 0) continue; /* lookup the ID in the per-type hash table */ oqi = cfs_hash_lookup(cli->cl_quota_hash[type], &qid[type]); - if ((flags & FL_QUOTA_FLAG(type)) != 0) { + if ((flags & fl_quota_flag(type)) != 0) { /* This ID is getting close to its quota limit, let's * switch to sync I/O */ if (oqi != NULL) @@ -110,9 +130,7 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], } CDEBUG(D_QUOTA, "%s: setdq to insert for %s %d (%d)\n", - cli_name(cli), - type == USRQUOTA ? "user" : "group", - qid[type], rc); + cli_name(cli), qtype_name(type), qid[type], rc); } else { /* This ID is now off the hook, let's remove it from * the hash table */ @@ -125,9 +143,7 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], OBD_SLAB_FREE_PTR(oqi, osc_quota_kmem); CDEBUG(D_QUOTA, "%s: setdq to remove for %s %d (%p)\n", - cli_name(cli), - type == USRQUOTA ? "user" : "group", - qid[type], oqi); + cli_name(cli), qtype_name(type), qid[type], oqi); } } diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 4060d23..114b6ce 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -1386,8 +1386,8 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc) /* set/clear over quota flag for a uid/gid */ if (lustre_msg_get_opc(req->rq_reqmsg) == OST_WRITE && - body->oa.o_valid & (OBD_MD_FLUSRQUOTA | OBD_MD_FLGRPQUOTA)) { - unsigned int qid[LL_MAXQUOTAS] = + body->oa.o_valid & (OBD_MD_FLALLQUOTA)) { + unsigned qid[LL_MAXQUOTAS] = {body->oa.o_uid, body->oa.o_gid}; CDEBUG(D_QUOTA, "setdq for [%u %u] with valid %#llx, flags %x\n", diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h index 150c00a..dba78c1 100644 --- a/lustre/osd-ldiskfs/osd_internal.h +++ b/lustre/osd-ldiskfs/osd_internal.h @@ -324,8 +324,6 @@ enum osd_full_scrub_ratio { * - 2 for target child uid & gid (if the target child exists); * - 2 for root uid & gid (last_rcvd, llog, etc); * - * The 0 to (OSD_MAX_UGID_CNT - 1) bits of ot_id_type is for indicating - * the id type of each id in the ot_id_array. */ #define OSD_MAX_UGID_CNT 10 @@ -354,7 +352,7 @@ struct osd_thandle { struct lu_ref_link ot_dev_link; unsigned int ot_credits; unsigned short ot_id_cnt; - unsigned short ot_id_type; + __u8 ot_id_types[OSD_MAX_UGID_CNT]; unsigned int ot_remove_agents:1; uid_t ot_id_array[OSD_MAX_UGID_CNT]; struct lquota_trans *ot_quota_trans; diff --git a/lustre/osd-ldiskfs/osd_io.c b/lustre/osd-ldiskfs/osd_io.c index 25326bf..c6522ae 100644 --- a/lustre/osd-ldiskfs/osd_io.c +++ b/lustre/osd-ldiskfs/osd_io.c @@ -1193,7 +1193,7 @@ static int osd_declare_write_commit(const struct lu_env *env, osd_trans_declare_op(env, oh, OSD_OT_WRITE, credits); /* make sure the over quota flags were not set */ - lnb[0].lnb_flags &= ~(OBD_BRW_OVER_USRQUOTA | OBD_BRW_OVER_GRPQUOTA); + lnb[0].lnb_flags &= ~OBD_BRW_OVER_ALLQUOTA; rc = osd_declare_inode_qid(env, i_uid_read(inode), i_gid_read(inode), quota_space, oh, osd_dt_obj(dt), true, diff --git a/lustre/osd-ldiskfs/osd_quota.c b/lustre/osd-ldiskfs/osd_quota.c index 3e7807a..e4f531c 100644 --- a/lustre/osd-ldiskfs/osd_quota.c +++ b/lustre/osd-ldiskfs/osd_quota.c @@ -38,14 +38,15 @@ static inline int fid2type(const struct lu_fid *fid) { LASSERT(fid_is_acct(fid)); - if (fid_oid(fid) == ACCT_GROUP_OID) + switch (fid_oid(fid)) { + case ACCT_USER_OID: + return USRQUOTA; + case ACCT_GROUP_OID: return GRPQUOTA; - return USRQUOTA; -} + } -static inline int obj2type(struct dt_object *obj) -{ - return fid2type(lu_object_fid(&obj->do_lu)); + LASSERTF(0, "invalid fid for quota type: %u", fid_oid(fid)); + return USRQUOTA; } /** @@ -65,7 +66,7 @@ int osd_acct_obj_lookup(struct osd_thread_info *info, struct osd_device *osd, const struct lu_fid *fid, struct osd_inode_id *id) { struct super_block *sb = osd_sb(osd); - unsigned long qf_inums[2] = { + unsigned long qf_inums[LL_MAXQUOTAS] = { le32_to_cpu(LDISKFS_SB(sb)->s_es->s_usr_quota_inum), le32_to_cpu(LDISKFS_SB(sb)->s_es->s_grp_quota_inum) }; @@ -116,15 +117,17 @@ static int osd_acct_index_lookup(const struct lu_env *env, #ifdef HAVE_DQUOT_KQID struct kqid qid; #endif + int type; ENTRY; + type = fid2type(lu_object_fid(&dtobj->do_lu)); memset(dqblk, 0, sizeof(*dqblk)); #ifdef HAVE_DQUOT_KQID - qid = make_kqid(&init_user_ns, obj2type(dtobj), id); + qid = make_kqid(&init_user_ns, type, id); rc = sb->s_qcop->get_dqblk(sb, qid, dqblk); #else - rc = sb->s_qcop->get_dqblk(sb, obj2type(dtobj), (qid_t)id, dqblk); + rc = sb->s_qcop->get_dqblk(sb, type, (qid_t) id, dqblk); #endif if (rc) RETURN(rc); @@ -221,12 +224,13 @@ static int osd_it_acct_get(const struct lu_env *env, struct dt_it *di, struct osd_it_quota *it = (struct osd_it_quota *)di; const struct lu_fid *fid = lu_object_fid(&it->oiq_obj->oo_dt.do_lu); - int type = fid2type(fid); + int type; qid_t dqid = *(qid_t *)key; loff_t offset; int rc; ENTRY; + type = fid2type(fid); offset = find_tree_dqentry(env, it->oiq_obj, type, dqid, LUSTRE_DQTREEOFF, 0, it); @@ -285,12 +289,14 @@ static int osd_it_acct_next(const struct lu_env *env, struct dt_it *di) struct osd_it_quota *it = (struct osd_it_quota *)di; const struct lu_fid *fid = lu_object_fid(&it->oiq_obj->oo_dt.do_lu); - int type = fid2type(fid); + int type; int depth, rc; uint index; ENTRY; + type = fid2type(fid); + /* Let's first check if there are any remaining valid entry in the * current leaf block. Start with the next entry after the current one. */ @@ -483,12 +489,7 @@ void osd_quota_unpack(struct osd_object *obj, const struct dt_rec *rec) static inline int osd_qid_type(struct osd_thandle *oh, int i) { - return (oh->ot_id_type & (1 << i)) ? GRPQUOTA : USRQUOTA; -} - -static inline void osd_qid_set_type(struct osd_thandle *oh, int i, int type) -{ - oh->ot_id_type |= ((type == GRPQUOTA) ? (1 << i) : 0); + return oh->ot_id_types[i]; } /** @@ -528,7 +529,7 @@ int osd_declare_qid(const struct lu_env *env, struct osd_thandle *oh, for (i = 0; i < oh->ot_id_cnt; i++) { if (oh->ot_id_array[i] == qi->lqi_id.qid_uid && - osd_qid_type(oh, i) == qi->lqi_type) { + oh->ot_id_types[i] == qi->lqi_type) { found = true; break; } @@ -569,7 +570,7 @@ int osd_declare_qid(const struct lu_env *env, struct osd_thandle *oh, osd_trans_declare_op(env, oh, OSD_OT_QUOTA, crd); oh->ot_id_array[i] = qi->lqi_id.qid_uid; - osd_qid_set_type(oh, i, qi->lqi_type); + oh->ot_id_types[i] = qi->lqi_type; oh->ot_id_cnt++; } diff --git a/lustre/osd-zfs/osd_internal.h b/lustre/osd-zfs/osd_internal.h index fb3e47d..b604b21 100644 --- a/lustre/osd-zfs/osd_internal.h +++ b/lustre/osd-zfs/osd_internal.h @@ -375,7 +375,7 @@ struct osd_object { int osd_statfs(const struct lu_env *, struct dt_device *, struct obd_statfs *); extern const struct dt_index_operations osd_acct_index_ops; -uint64_t osd_quota_fid2dmu(const struct lu_fid *fid); +int osd_quota_fid2dmu(const struct lu_fid *fid, uint64_t *oid); extern struct lu_device_operations osd_lu_ops; extern struct dt_index_operations osd_dir_ops; int osd_declare_quota(const struct lu_env *env, struct osd_device *osd, diff --git a/lustre/osd-zfs/osd_oi.c b/lustre/osd-zfs/osd_oi.c index ac2ad46..bad04a4 100644 --- a/lustre/osd-zfs/osd_oi.c +++ b/lustre/osd-zfs/osd_oi.c @@ -481,6 +481,19 @@ static inline int fid_is_fs_root(const struct lu_fid *fid) fid_oid(fid) == OSD_FS_ROOT_OID; } +static inline uint64_t osd_oid(struct osd_device *dev, __u32 local_oid) +{ + switch (local_oid) { + case ACCT_USER_OID: + return dev->od_iusr_oid; + case ACCT_GROUP_OID: + return dev->od_igrp_oid; + } + + LASSERTF(0, "invalid oid: %u for quota type", local_oid); + return dev->od_igrp_oid; +} + int osd_fid_lookup(const struct lu_env *env, struct osd_device *dev, const struct lu_fid *fid, uint64_t *oid) { @@ -494,10 +507,7 @@ int osd_fid_lookup(const struct lu_env *env, struct osd_device *dev, RETURN(-ENOENT); if (unlikely(fid_is_acct(fid))) { - if (fid_oid(fid) == ACCT_USER_OID) - *oid = dev->od_iusr_oid; - else - *oid = dev->od_igrp_oid; + *oid = osd_oid(dev, fid_oid(fid)); } else if (unlikely(fid_is_fs_root(fid))) { *oid = dev->od_root; } else { diff --git a/lustre/osd-zfs/osd_quota.c b/lustre/osd-zfs/osd_quota.c index 4ef1ad5..14ba2cd 100644 --- a/lustre/osd-zfs/osd_quota.c +++ b/lustre/osd-zfs/osd_quota.c @@ -34,12 +34,23 @@ /** * Helper function to retrieve DMU object id from fid for accounting object */ -uint64_t osd_quota_fid2dmu(const struct lu_fid *fid) +inline int osd_quota_fid2dmu(const struct lu_fid *fid, uint64_t *oid) { + int rc = 0; + LASSERT(fid_is_acct(fid)); - if (fid_oid(fid) == ACCT_GROUP_OID) - return DMU_GROUPUSED_OBJECT; - return DMU_USERUSED_OBJECT; + switch (fid_oid(fid)) { + case ACCT_GROUP_OID: + *oid = DMU_GROUPUSED_OBJECT; + break; + case ACCT_USER_OID: + *oid = DMU_USERUSED_OBJECT; + break; + default: + rc = -EINVAL; + break; + } + return rc; } /** @@ -97,7 +108,7 @@ static int osd_acct_index_lookup(const struct lu_env *env, struct osd_object *obj = osd_dt_obj(dtobj); struct osd_device *osd = osd_obj2dev(obj); int rc; - uint64_t oid; + uint64_t oid = 0; ENTRY; rec->bspace = rec->ispace = 0; @@ -106,7 +117,9 @@ static int osd_acct_index_lookup(const struct lu_env *env, snprintf(buf, buflen, "%llx", *((__u64 *)dtkey)); /* fetch DMU object ID (DMU_USERUSED_OBJECT/DMU_GROUPUSED_OBJECT) to be * used */ - oid = osd_quota_fid2dmu(lu_object_fid(&dtobj->do_lu)); + rc = osd_quota_fid2dmu(lu_object_fid(&dtobj->do_lu), &oid); + if (rc) + RETURN(rc); /* disk usage (in bytes) is maintained by DMU. * DMU_USERUSED_OBJECT/DMU_GROUPUSED_OBJECT are special objects which @@ -170,7 +183,9 @@ static struct dt_it *osd_it_acct_init(const struct lu_env *env, RETURN(ERR_PTR(-ENOMEM)); memset(it, 0, sizeof(*it)); - it->oiq_oid = osd_quota_fid2dmu(lu_object_fid(lo)); + rc = osd_quota_fid2dmu(lu_object_fid(lo), &it->oiq_oid); + if (rc) + RETURN(ERR_PTR(rc)); /* initialize zap cursor */ rc = osd_zap_cursor_init(&it->oiq_zc, osd->od_os, it->oiq_oid, 0); diff --git a/lustre/quota/lproc_quota.c b/lustre/quota/lproc_quota.c index 1f2584f..034a269 100644 --- a/lustre/quota/lproc_quota.c +++ b/lustre/quota/lproc_quota.c @@ -165,6 +165,18 @@ static void *lprocfs_quota_seq_next(struct seq_file *p, void *v, loff_t *pos) return NULL; } +static inline const char *oid2name(__u32 oid) +{ + switch (oid) { + case ACCT_USER_OID: + return "usr_accounting"; + case ACCT_GROUP_OID: + return "grp_accounting"; + default: + return "unknown_accounting"; + } +} + /* * Output example: * @@ -195,10 +207,7 @@ static int lprocfs_quota_seq_show(struct seq_file *p, void *v) if (v == SEQ_START_TOKEN) { if (fid_is_acct(fid)) { - if (fid_oid(fid) == ACCT_USER_OID) - seq_printf(p, "usr_accounting:\n"); - else - seq_printf(p, "grp_accounting:\n"); + seq_printf(p, "%s:\n", oid2name(fid_oid(fid))); } else if (fid_seq(fid) == FID_SEQ_QUOTA_GLB) { int poolid, rtype, qtype; @@ -207,7 +216,7 @@ static int lprocfs_quota_seq_show(struct seq_file *p, void *v) return rc; seq_printf(p, "global_pool%d_%s_%s\n", poolid, - RES_NAME(rtype), QTYPE_NAME(qtype)); + RES_NAME(rtype), qtype_name(qtype)); } else if (fid_seq(fid) == FID_SEQ_LOCAL_NAME) { /* global index copy object */ seq_printf(p, "global_index_copy:\n"); diff --git a/lustre/quota/lquota_disk.c b/lustre/quota/lquota_disk.c index af2e299..d97c305 100644 --- a/lustre/quota/lquota_disk.c +++ b/lustre/quota/lquota_disk.c @@ -64,10 +64,10 @@ lquota_disk_find_create(const struct lu_env *env, struct dt_device *dev, const struct dt_index_features *idx_feat, char *name) { - struct lquota_thread_info *qti = lquota_info(env); - struct dt_object *obj; - struct local_oid_storage *los; - int rc; + struct lquota_thread_info *qti = lquota_info(env); + struct dt_object *obj; + struct local_oid_storage *los; + int rc; ENTRY; /* Set up local storage */ @@ -406,8 +406,7 @@ struct dt_object *lquota_disk_slv_find_create(const struct lu_env *env, RETURN(ERR_PTR(rc)); /* use predefined fid in the reserved oid list */ - qti->qti_fid.f_oid = (type == USRQUOTA) ? LQUOTA_USR_OID - : LQUOTA_GRP_OID; + qti->qti_fid.f_oid = qtype2slv_oid(type); slv_idx = local_index_find_or_create_with_fid(env, dev, &qti->qti_fid, diff --git a/lustre/quota/lquota_internal.h b/lustre/quota/lquota_internal.h index 1e9d5d0..19a08cb 100644 --- a/lustre/quota/lquota_internal.h +++ b/lustre/quota/lquota_internal.h @@ -31,7 +31,19 @@ #ifndef _LQUOTA_INTERNAL_H #define _LQUOTA_INTERNAL_H -#define QTYPE_NAME(qtype) ((qtype) == USRQUOTA ? "usr" : "grp") +/* +static inline char *qtype_name(int qtype) +{ + switch (qtype) { + case USRQUOTA: + return "usr"; + case GRPQUOTA: + return "grp"; + } + return "unknown"; +} +*/ + #define RES_NAME(res) ((res) == LQUOTA_RES_MD ? "md" : "dt") #define QIF_IFLAGS (QIF_INODES | QIF_ITIME | QIF_ILIMITS) @@ -50,6 +62,19 @@ enum lquota_local_oid { LQUOTA_GENERATED_OID = 4096UL, }; +static inline __u32 qtype2slv_oid(int qtype) +{ + switch (qtype) { + case USRQUOTA: + return LQUOTA_USR_OID; + case GRPQUOTA: + return LQUOTA_GRP_OID; + } + + LASSERTF(0, "invalid quota type: %d", qtype); + return LQUOTA_USR_OID; +} + /* * lquota_entry support */ @@ -279,8 +304,18 @@ static inline void lqe_read_unlock(struct lquota_entry *lqe) #define LQUOTA_LEAST_QUNIT(type) \ (type == LQUOTA_RES_MD ? (1 << 10) : toqb(OFD_MAX_BRW_SIZE)) -#define LQUOTA_OVER_FL(type) \ - (type == USRQUOTA ? QUOTA_FL_OVER_USRQUOTA : QUOTA_FL_OVER_GRPQUOTA) +static inline int lquota_over_fl(int qtype) +{ + switch (qtype) { + case USRQUOTA: + return QUOTA_FL_OVER_USRQUOTA; + case GRPQUOTA: + return QUOTA_FL_OVER_GRPQUOTA; + } + + LASSERTF(0, "invalid quota type: %d", qtype); + return QUOTA_FL_OVER_USRQUOTA; +} /* Common data shared by quota-level handlers. This is allocated per-thread to * reduce stack consumption */ diff --git a/lustre/quota/lquota_lib.c b/lustre/quota/lquota_lib.c index a9e903b..e89da00 100644 --- a/lustre/quota/lquota_lib.c +++ b/lustre/quota/lquota_lib.c @@ -54,6 +54,18 @@ LU_KEY_INIT_FINI(lquota, struct lquota_thread_info); LU_CONTEXT_KEY_DEFINE(lquota, LCT_MD_THREAD | LCT_DT_THREAD | LCT_LOCAL); LU_KEY_INIT_GENERIC(lquota); +static inline __u32 qtype2acct_oid(int qtype) +{ + switch (qtype) { + case USRQUOTA: + return ACCT_USER_OID; + case GRPQUOTA: + return ACCT_GROUP_OID; + } + + return ACCT_GROUP_OID; +} + /** * Look-up accounting object to collect space usage information for user * or group. @@ -69,8 +81,7 @@ struct dt_object *acct_obj_lookup(const struct lu_env *env, struct dt_object *obj = NULL; ENTRY; - lu_local_obj_fid(&qti->qti_fid, - type == USRQUOTA ? ACCT_USER_OID : ACCT_GROUP_OID); + lu_local_obj_fid(&qti->qti_fid, qtype2acct_oid(type)); /* lookup the accounting object */ obj = dt_locate(env, dev, &qti->qti_fid); @@ -91,7 +102,7 @@ struct dt_object *acct_obj_lookup(const struct lu_env *env, CERROR("%s: failed to set up indexing operations for %s" " acct object rc:%d\n", dev->dd_lu_dev.ld_obd->obd_name, - QTYPE_NAME(type), rc); + qtype_name(type), rc); dt_object_put(env, obj); RETURN(ERR_PTR(rc)); } @@ -114,7 +125,7 @@ static struct dt_object *quota_obj_lookup(const struct lu_env *env, ENTRY; qti->qti_fid.f_seq = FID_SEQ_QUOTA; - qti->qti_fid.f_oid = type == USRQUOTA ? LQUOTA_USR_OID : LQUOTA_GRP_OID; + qti->qti_fid.f_oid = qtype2slv_oid(type); qti->qti_fid.f_ver = 0; /* lookup the quota object */ @@ -137,7 +148,7 @@ static struct dt_object *quota_obj_lookup(const struct lu_env *env, CERROR("%s: failed to set up indexing operations for %s" " slave index object rc:%d\n", dev->dd_lu_dev.ld_obd->obd_name, - QTYPE_NAME(type), rc); + qtype_name(type), rc); dt_object_put(env, obj); RETURN(ERR_PTR(rc)); } @@ -173,7 +184,7 @@ int lquotactl_slv(const struct lu_env *env, struct dt_device *dev, RETURN(-EOPNOTSUPP); } - if (oqctl->qc_type != USRQUOTA && oqctl->qc_type != GRPQUOTA) + if (oqctl->qc_type < 0 || oqctl->qc_type >= MAXQUOTAS) /* no support for directory quota yet */ RETURN(-EOPNOTSUPP); @@ -232,20 +243,42 @@ out: } EXPORT_SYMBOL(lquotactl_slv); +static inline __u8 qtype2lqtype(int qtype) +{ + switch (qtype) { + case USRQUOTA: + return LQUOTA_TYPE_USR; + case GRPQUOTA: + return LQUOTA_TYPE_GRP; + } + + return LQUOTA_TYPE_GRP; +} + +static inline int lqtype2qtype(int lqtype) +{ + switch (lqtype) { + case LQUOTA_TYPE_USR: + return USRQUOTA; + case LQUOTA_TYPE_GRP: + return GRPQUOTA; + } + + return GRPQUOTA; +} + /** * Helper routine returning the FID associated with the global index storing * quota settings for the storage pool \pool_id, resource type \pool_type and * the quota type \quota_type. */ void lquota_generate_fid(struct lu_fid *fid, int pool_id, int pool_type, - int quota_type) + int quota_type) { - __u8 qtype; - - qtype = (quota_type == USRQUOTA) ? LQUOTA_TYPE_USR : LQUOTA_TYPE_GRP; + __u8 lqtype = qtype2lqtype(quota_type); fid->f_seq = FID_SEQ_QUOTA_GLB; - fid->f_oid = (qtype << 24) | (pool_type << 16) | (__u16)pool_id; + fid->f_oid = (lqtype << 24) | (pool_type << 16) | (__u16)pool_id; fid->f_ver = 0; } @@ -256,34 +289,34 @@ void lquota_generate_fid(struct lu_fid *fid, int pool_id, int pool_type, int lquota_extract_fid(const struct lu_fid *fid, int *pool_id, int *pool_type, int *quota_type) { - unsigned int tmp; + unsigned int lqtype; ENTRY; if (fid->f_seq != FID_SEQ_QUOTA_GLB) RETURN(-EINVAL); if (pool_id != NULL) { - tmp = fid->f_oid & 0xffffU; - if (tmp != 0) + lqtype = fid->f_oid & 0xffffU; + if (lqtype != 0) /* we only support pool ID 0 for the time being */ RETURN(-ENOTSUPP); - *pool_id = tmp; + *pool_id = lqtype; } if (pool_type != NULL) { - tmp = (fid->f_oid >> 16) & 0xffU; - if (tmp >= LQUOTA_LAST_RES) + lqtype = (fid->f_oid >> 16) & 0xffU; + if (lqtype >= LQUOTA_LAST_RES) RETURN(-ENOTSUPP); - *pool_type = tmp; + *pool_type = lqtype; } if (quota_type != NULL) { - tmp = fid->f_oid >> 24; - if (tmp >= LQUOTA_TYPE_MAX) + lqtype = fid->f_oid >> 24; + if (lqtype >= LQUOTA_TYPE_MAX) RETURN(-ENOTSUPP); - *quota_type = (tmp == LQUOTA_TYPE_USR) ? USRQUOTA : GRPQUOTA; + *quota_type = lqtype2qtype(lqtype); } RETURN(0); diff --git a/lustre/quota/qmt_pool.c b/lustre/quota/qmt_pool.c index b20658b..679ceeb 100644 --- a/lustre/quota/qmt_pool.c +++ b/lustre/quota/qmt_pool.c @@ -163,7 +163,7 @@ static int qpi_state_seq_show(struct seq_file *m, void *data) seq_printf(m, " %s:\n" " #slv: %d\n" " #lqe: %d\n", - QTYPE_NAME(type), + qtype_name(type), pool->qpi_slv_nr[type], atomic_read(&pool->qpi_site[type]->lqs_hash->hs_count)); @@ -542,9 +542,8 @@ int qmt_pool_prepare(const struct lu_env *env, struct qmt_device *qmt, &qti->qti_fid, false); if (IS_ERR(obj)) { rc = PTR_ERR(obj); - CERROR("%s: failed to create glb index copy for" - " %s type (%d)\n", qmt->qmt_svname, - QTYPE_NAME(qtype), rc); + CERROR("%s: failed to create glb index copy for %s type: rc = %d\n", + qmt->qmt_svname, qtype_name(qtype), rc); RETURN(rc); } @@ -561,19 +560,15 @@ int qmt_pool_prepare(const struct lu_env *env, struct qmt_device *qmt, rc = lquota_disk_write_glb(env, obj, 0, rec); if (rc) { - CERROR("%s: failed to set default " - "grace time for %s type (%d)\n", - qmt->qmt_svname, - QTYPE_NAME(qtype), rc); + CERROR("%s: failed to set default grace time for %s type: rc = %d\n", + qmt->qmt_svname, qtype_name(qtype), rc); RETURN(rc); } rc = lquota_disk_update_ver(env, dev, obj, 1); if (rc) { - CERROR("%s: failed to set initial " - "version for %s type (%d)\n", - qmt->qmt_svname, - QTYPE_NAME(qtype), rc); + CERROR("%s: failed to set initial version for %s type: rc = %d\n", + qmt->qmt_svname, qtype_name(qtype), rc); RETURN(rc); } } @@ -584,9 +579,8 @@ int qmt_pool_prepare(const struct lu_env *env, struct qmt_device *qmt, &qmt_lqe_ops); if (IS_ERR(pool->qpi_site[qtype])) { rc = PTR_ERR(pool->qpi_site[qtype]); - CERROR("%s: failed to create site for %s type " - "(%d)\n", qmt->qmt_svname, - QTYPE_NAME(qtype), rc); + CERROR("%s: failed to create site for %s type: rc = %d\n", + qmt->qmt_svname, qtype_name(qtype), rc); RETURN(rc); } @@ -598,9 +592,8 @@ int qmt_pool_prepare(const struct lu_env *env, struct qmt_device *qmt, qmt_slv_cnt, &pool->qpi_slv_nr[qtype]); if (rc) { - CERROR("%s: failed to scan & count slave " - "indexes for %s type (%d)\n", - qmt->qmt_svname, QTYPE_NAME(qtype), rc); + CERROR("%s: failed to scan & count slave indexes for %s type: rc = %d\n", + qmt->qmt_svname, qtype_name(qtype), rc); RETURN(rc); } @@ -617,7 +610,8 @@ int qmt_pool_prepare(const struct lu_env *env, struct qmt_device *qmt, #ifdef CONFIG_PROC_FS /* add procfs file to dump the global index, mostly for * debugging purpose */ - sprintf(qti->qti_buf, "glb-%s", QTYPE_NAME(qtype)); + snprintf(qti->qti_buf, MTI_NAME_MAXLEN, + "glb-%s", qtype_name(qtype)); rc = lprocfs_seq_create(pool->qpi_proc, qti->qti_buf, 0444, &lprocfs_quota_seq_fops, obj); diff --git a/lustre/quota/qsd_entry.c b/lustre/quota/qsd_entry.c index d0b49f0..eb3f176 100644 --- a/lustre/quota/qsd_entry.c +++ b/lustre/quota/qsd_entry.c @@ -141,7 +141,7 @@ static void qsd_lqe_debug(struct lquota_entry *lqe, void *arg, "qsd:%s qtype:%s id:%llu enforced:%d granted:" "%llu pending:%llu waiting:%llu req:%d usage:" "%llu qunit:%llu qtune:%llu edquot:%d\n", - qqi->qqi_qsd->qsd_svname, QTYPE_NAME(qqi->qqi_qtype), + qqi->qqi_qsd->qsd_svname, qtype_name(qqi->qqi_qtype), lqe->lqe_id.qid_uid, lqe->lqe_enforced, lqe->lqe_granted, lqe->lqe_pending_write, lqe->lqe_waiting_write, lqe->lqe_pending_req, diff --git a/lustre/quota/qsd_handler.c b/lustre/quota/qsd_handler.c index 0982e93..b38a111 100644 --- a/lustre/quota/qsd_handler.c +++ b/lustre/quota/qsd_handler.c @@ -687,9 +687,10 @@ static int qsd_op_begin0(const struct lu_env *env, struct qsd_qtype_info *qqi, struct lquota_id_info *qid, long long space, int *flags) { - struct lquota_entry *lqe; - int rc, ret = -EINPROGRESS; - struct l_wait_info lwi; + struct lquota_entry *lqe; + struct l_wait_info lwi; + int qtype_flag = 0; + int rc, ret = -EINPROGRESS; ENTRY; if (qid->lqi_qentry != NULL) { @@ -772,7 +773,7 @@ static int qsd_op_begin0(const struct lu_env *env, struct qsd_qtype_info *qqi, out_flags: LASSERT(qid->lqi_is_blk); if (rc != 0) { - *flags |= LQUOTA_OVER_FL(qqi->qqi_qtype); + *flags |= lquota_over_fl(qqi->qqi_qtype); } else { __u64 usage; @@ -782,11 +783,12 @@ out_flags: usage += lqe->lqe_waiting_write; usage += qqi->qqi_qsd->qsd_sync_threshold; + qtype_flag = lquota_over_fl(qqi->qqi_qtype); /* if we should notify client to start sync write */ if (usage >= lqe->lqe_granted - lqe->lqe_pending_rel) - *flags |= LQUOTA_OVER_FL(qqi->qqi_qtype); + *flags |= qtype_flag; else - *flags &= ~LQUOTA_OVER_FL(qqi->qqi_qtype); + *flags &= ~qtype_flag; lqe_read_unlock(lqe); } } diff --git a/lustre/quota/qsd_lib.c b/lustre/quota/qsd_lib.c index e10eeae..e1749b6 100644 --- a/lustre/quota/qsd_lib.c +++ b/lustre/quota/qsd_lib.c @@ -343,6 +343,32 @@ static void qsd_qtype_fini(const struct lu_env *env, struct qsd_instance *qsd, EXIT; } +static const char *qtype2acct_name(int qtype) +{ + switch (qtype) { + case USRQUOTA: + return "acct_user"; + case GRPQUOTA: + return "acct_group"; + } + + LASSERTF(0, "invalid quota type: %d", qtype); + return NULL; +} + +static const char *qtype2glb_name(int qtype) +{ + switch (qtype) { + case USRQUOTA: + return "limit_user"; + case GRPQUOTA: + return "limit_group"; + } + + LASSERTF(0, "invalid quota type: %d", qtype); + return NULL; +} + /* * Allocate and initialize a qsd_qtype_info structure for quota type \qtype. * This opens the accounting object and initializes the proc file. @@ -378,8 +404,6 @@ static int qsd_qtype_init(const struct lu_env *env, struct qsd_instance *qsd, qqi->qqi_qsd = qsd; qqi->qqi_qtype = qtype; lu_ref_init(&qqi->qqi_reference); - lquota_generate_fid(&qqi->qqi_fid, qsd->qsd_pool_id, QSD_RES_TYPE(qsd), - qtype); qqi->qqi_glb_uptodate = false; qqi->qqi_slv_uptodate = false; qqi->qqi_reint = false; @@ -387,13 +411,15 @@ static int qsd_qtype_init(const struct lu_env *env, struct qsd_instance *qsd, thread_set_flags(&qqi->qqi_reint_thread, SVC_STOPPED); INIT_LIST_HEAD(&qqi->qqi_deferred_glb); INIT_LIST_HEAD(&qqi->qqi_deferred_slv); + lquota_generate_fid(&qqi->qqi_fid, qsd->qsd_pool_id, + QSD_RES_TYPE(qsd), qtype); /* open accounting object */ LASSERT(qqi->qqi_acct_obj == NULL); qqi->qqi_acct_obj = acct_obj_lookup(env, qsd->qsd_dev, qtype); if (IS_ERR(qqi->qqi_acct_obj)) { - CDEBUG(D_QUOTA, "%s: no %s space accounting support rc:%ld\n", - qsd->qsd_svname, QTYPE_NAME(qtype), + CDEBUG(D_QUOTA, "%s: no %s space accounting support: rc = %ld\n", + qsd->qsd_svname, qtype_name(qtype), PTR_ERR(qqi->qqi_acct_obj)); qqi->qqi_acct_obj = NULL; qsd->qsd_acct_failed = true; @@ -436,8 +462,7 @@ static int qsd_qtype_init(const struct lu_env *env, struct qsd_instance *qsd, } /* register proc entry for accounting & global index copy objects */ - rc = lprocfs_seq_create(qsd->qsd_proc, - qtype == USRQUOTA ? "acct_user" : "acct_group", + rc = lprocfs_seq_create(qsd->qsd_proc, qtype2acct_name(qtype), 0444, &lprocfs_quota_seq_fops, qqi->qqi_acct_obj); if (rc) { @@ -446,8 +471,7 @@ static int qsd_qtype_init(const struct lu_env *env, struct qsd_instance *qsd, GOTO(out, rc); } - rc = lprocfs_seq_create(qsd->qsd_proc, - qtype == USRQUOTA ? "limit_user" : "limit_group", + rc = lprocfs_seq_create(qsd->qsd_proc, qtype2glb_name(qtype), 0444, &lprocfs_quota_seq_fops, qqi->qqi_glb_obj); if (rc) { @@ -723,9 +747,8 @@ int qsd_prepare(const struct lu_env *env, struct qsd_instance *qsd) rc = qsd_start_reint_thread(qqi); if (rc) { - CERROR("%s: failed to start reint thread for type %s " - "(%d)\n", qsd->qsd_svname, QTYPE_NAME(qtype), - rc); + CERROR("%s: failed to start reint thread for type %s: rc = %d\n", + qsd->qsd_svname, qtype_name(qtype), rc); RETURN(rc); } } diff --git a/lustre/quota/qsd_lock.c b/lustre/quota/qsd_lock.c index 1109414..c63a4e3 100644 --- a/lustre/quota/qsd_lock.c +++ b/lustre/quota/qsd_lock.c @@ -212,7 +212,7 @@ static int qsd_glb_blocking_ast(struct ldlm_lock *lock, write_unlock(&qqi->qqi_qsd->qsd_lock); CDEBUG(D_QUOTA, "%s: losing global index lock for %s type\n", - qqi->qqi_qsd->qsd_svname, QTYPE_NAME((qqi->qqi_qtype))); + qqi->qqi_qsd->qsd_svname, qtype_name((qqi->qqi_qtype))); /* kick off reintegration thread if not running already, if * it's just local cancel (for stack clean up or eviction), diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index f522852..53f9437 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -1721,62 +1721,52 @@ static int set_time(time_t *time, time_t *set, char *str) *set = *time - t * 24 * 60 * 60; return res; } - -#define USER 0 -#define GROUP 1 - -static int name2id(unsigned int *id, char *name, int type) +static int name2uid(unsigned int *id, const char *name) { - if (type == USER) { - struct passwd *entry; + struct passwd *passwd; - if (!(entry = getpwnam(name))) { - if (!errno) - errno = ENOENT; - return -1; - } + passwd = getpwnam(name); + if (passwd == NULL) + return -ENOENT; + *id = passwd->pw_uid; - *id = entry->pw_uid; - } else { - struct group *entry; + return 0; +} - if (!(entry = getgrnam(name))) { - if (!errno) - errno = ENOENT; - return -1; - } +static int name2gid(unsigned int *id, const char *name) +{ + struct group *group; - *id = entry->gr_gid; - } + group = getgrnam(name); + if (group == NULL) + return -ENOENT; + *id = group->gr_gid; - return 0; + return 0; } -static int id2name(char **name, unsigned int id, int type) +static int uid2name(char **name, unsigned int id) { - if (type == USER) { - struct passwd *entry; + struct passwd *passwd; - if (!(entry = getpwuid(id))) { - if (!errno) - errno = ENOENT; - return -1; - } + passwd = getpwuid(id); + if (passwd == NULL) + return -ENOENT; + *name = passwd->pw_name; - *name = entry->pw_name; - } else { - struct group *entry; + return 0; +} - if (!(entry = getgrgid(id))) { - if (!errno) - errno = ENOENT; - return -1; - } +static inline int gid2name(char **name, unsigned int id) +{ + struct group *group; - *name = entry->gr_name; - } + group = getgrgid(id); + if (group == NULL) + return -ENOENT; + *name = group->gr_name; - return 0; + return 0; } static int name2layout(__u32 *layout, char *name) @@ -2007,7 +1997,7 @@ static int lfs_find(int argc, char **argv) break; case 'g': case 'G': - rc = name2id(¶m.fp_gid, optarg, GROUP); + rc = name2gid(¶m.fp_gid, optarg); if (rc) { param.fp_gid = strtoul(optarg, &endptr, 10); if (*endptr != '\0') { @@ -2027,13 +2017,13 @@ static int lfs_find(int argc, char **argv) param.fp_exclude_layout = !!neg_opt; param.fp_check_layout = 1; break; - case 'u': - case 'U': - rc = name2id(¶m.fp_uid, optarg, USER); + case 'u': + case 'U': + rc = name2uid(¶m.fp_uid, optarg); if (rc) { param.fp_uid = strtoul(optarg, &endptr, 10); - if (*endptr != '\0') { - fprintf(stderr, "User/UID: %s cannot " + if (*endptr != '\0') { + fprintf(stderr, "User/UID: %s cannot " "be found.\n", optarg); ret = -1; goto err; @@ -3424,22 +3414,28 @@ int lfs_setquota_times(int argc, char **argv) {"user", no_argument, 0, 'u'}, {0, 0, 0, 0} }; + int qtype; - memset(&qctl, 0, sizeof(qctl)); - qctl.qc_cmd = LUSTRE_Q_SETINFO; - qctl.qc_type = UGQUOTA; + memset(&qctl, 0, sizeof(qctl)); + qctl.qc_cmd = LUSTRE_Q_SETINFO; + qctl.qc_type = ALLQUOTA; - while ((c = getopt_long(argc, argv, "b:gi:tu", long_opts, NULL)) != -1) { - switch (c) { - case 'u': - case 'g': - if (qctl.qc_type != UGQUOTA) { - fprintf(stderr, "error: -u and -g can't be used " + while ((c = getopt_long(argc, argv, "b:gi:tu", + long_opts, NULL)) != -1) { + switch (c) { + case 'u': + qtype = USRQUOTA; + goto quota_type; + case 'g': + qtype = GRPQUOTA; +quota_type: + if (qctl.qc_type != ALLQUOTA) { + fprintf(stderr, "error: -u and -g can't be used " "more than once\n"); - return CMD_HELP; - } - qctl.qc_type = (c == 'u') ? USRQUOTA : GRPQUOTA; - break; + return CMD_HELP; + } + qctl.qc_type = qtype; + break; case 'b': if ((dqi->dqi_bgrace = str2sec(optarg)) == ULONG_MAX) { fprintf(stderr, "error: bad block-grace: %s\n", @@ -3463,7 +3459,7 @@ int lfs_setquota_times(int argc, char **argv) } } - if (qctl.qc_type == UGQUOTA) { + if (qctl.qc_type == ALLQUOTA) { fprintf(stderr, "error: neither -u nor -g specified\n"); return CMD_HELP; } @@ -3508,41 +3504,47 @@ int lfs_setquota(int argc, char **argv) }; unsigned limit_mask = 0; char *endptr; + int qtype; - if (has_times_option(argc, argv)) - return lfs_setquota_times(argc, argv); + if (has_times_option(argc, argv)) + return lfs_setquota_times(argc, argv); - memset(&qctl, 0, sizeof(qctl)); - qctl.qc_cmd = LUSTRE_Q_SETQUOTA; - qctl.qc_type = UGQUOTA; /* UGQUOTA makes no sense for setquota, + memset(&qctl, 0, sizeof(qctl)); + qctl.qc_cmd = LUSTRE_Q_SETQUOTA; + qctl.qc_type = ALLQUOTA; /* ALLQUOTA makes no sense for setquota, * so it can be used as a marker that qc_type * isn't reinitialized from command line */ while ((c = getopt_long(argc, argv, "b:B:g:i:I:u:", long_opts, NULL)) != -1) { switch (c) { case 'u': + qtype = USRQUOTA; + rc = name2uid(&qctl.qc_id, optarg); + /* fall through */ case 'g': - if (qctl.qc_type != UGQUOTA) { - fprintf(stderr, "error: -u and -g can't be used" - " more than once\n"); - return CMD_HELP; - } - qctl.qc_type = (c == 'u') ? USRQUOTA : GRPQUOTA; - rc = name2id(&qctl.qc_id, optarg, - (qctl.qc_type == USRQUOTA) ? USER : GROUP); - if (rc) { - qctl.qc_id = strtoul(optarg, &endptr, 10); - if (*endptr != '\0') { - fprintf(stderr, "error: can't find id " - "for name %s\n", optarg); - return CMD_HELP; - } + if (c == 'g') { + qtype = GRPQUOTA; + rc = name2gid(&qctl.qc_id, optarg); + } + if (qctl.qc_type != ALLQUOTA) { + fprintf(stderr, "error: -u and -g can't be used" + " more than once\n"); + return CMD_HELP; } - break; + qctl.qc_type = qtype; + if (rc) { + qctl.qc_id = strtoul(optarg, &endptr, 10); + if (*endptr != '\0') { + fprintf(stderr, "error: can't find id " + "for name %s\n", optarg); + return CMD_HELP; + } + } + break; case 'b': - ARG2ULL(dqb->dqb_bsoftlimit, optarg, 1024); - dqb->dqb_bsoftlimit >>= 10; - limit_mask |= BSLIMIT; + ARG2ULL(dqb->dqb_bsoftlimit, optarg, 1024); + dqb->dqb_bsoftlimit >>= 10; + limit_mask |= BSLIMIT; if (dqb->dqb_bsoftlimit && dqb->dqb_bsoftlimit <= 1024) /* <= 1M? */ fprintf(stderr, "warning: block softlimit is " @@ -3582,14 +3584,14 @@ int lfs_setquota(int argc, char **argv) "Lustre manual for details.\n"); break; default: /* getopt prints error message for us when opterr != 0 */ - return CMD_HELP; - } - } + return CMD_HELP; + } + } - if (qctl.qc_type == UGQUOTA) { - fprintf(stderr, "error: neither -u nor -g was specified\n"); - return CMD_HELP; - } + if (qctl.qc_type == ALLQUOTA) { + fprintf(stderr, "error: neither -u nor -g was specified\n"); + return CMD_HELP; + } if (limit_mask == 0) { fprintf(stderr, "error: at least one limit must be specified\n"); @@ -3654,16 +3656,6 @@ int lfs_setquota(int argc, char **argv) return 0; } -static inline char *type2name(int check_type) -{ - if (check_type == USRQUOTA) - return "user"; - else if (check_type == GRPQUOTA) - return "group"; - else - return "unknown"; -} - /* Converts seconds value into format string * result is returned in buf * Notes: @@ -3723,8 +3715,8 @@ static void print_quota_title(char *name, struct if_quotactl *qctl, bool human_readable) { printf("Disk quotas for %s %s (%cid %u):\n", - type2name(qctl->qc_type), name, - *type2name(qctl->qc_type), qctl->qc_id); + qtype_name(qctl->qc_type), name, + *qtype_name(qctl->qc_type), qctl->qc_id); printf("%15s%8s %7s%8s%8s%8s %7s%8s%8s\n", "Filesystem", human_readable ? "used" : "kbytes", "quota", "limit", "grace", @@ -3875,8 +3867,8 @@ static int print_obd_quota(char *mnt, struct if_quotactl *qctl, int is_mdt, qctl->qc_valid = is_mdt ? QC_MDTIDX : QC_OSTIDX; rc = llapi_quotactl(mnt, qctl); if (rc) { - /* It is remote client case. */ - if (-rc == EOPNOTSUPP) { + /* It is remote client case. */ + if (rc == -EOPNOTSUPP) { rc = 0; goto out; } @@ -3903,32 +3895,32 @@ static int lfs_quota(int argc, char **argv) int c; char *mnt, *name = NULL; struct if_quotactl qctl = { .qc_cmd = LUSTRE_Q_GETQUOTA, - .qc_type = UGQUOTA }; + .qc_type = ALLQUOTA }; char *obd_type = (char *)qctl.obd_type; char *obd_uuid = (char *)qctl.obd_uuid.uuid; - int rc, rc1 = 0, rc2 = 0, rc3 = 0, + int rc = 0, rc1 = 0, rc2 = 0, rc3 = 0, verbose = 0, pass = 0, quiet = 0, inacc; char *endptr; __u32 valid = QC_GENERAL, idx = 0; __u64 total_ialloc = 0, total_balloc = 0; bool human_readable = false; + int qtype; while ((c = getopt(argc, argv, "gi:I:o:qtuvh")) != -1) { - switch (c) { - case 'u': - if (qctl.qc_type != UGQUOTA) { - fprintf(stderr, "error: use either -u or -g\n"); - return CMD_HELP; - } - qctl.qc_type = USRQUOTA; - break; - case 'g': - if (qctl.qc_type != UGQUOTA) { - fprintf(stderr, "error: use either -u or -g\n"); - return CMD_HELP; - } - qctl.qc_type = GRPQUOTA; - break; + switch (c) { + case 'u': + qtype = USRQUOTA; + /* fall through */ + case 'g': + if (c == 'g') + qtype = GRPQUOTA; + + if (qctl.qc_type != ALLQUOTA) { + fprintf(stderr, "error: use either -u or -g\n"); + return CMD_HELP; + } + qctl.qc_type = qtype; + break; case 't': qctl.qc_cmd = LUSTRE_Q_GETINFO; break; @@ -3961,47 +3953,62 @@ static int lfs_quota(int argc, char **argv) } /* current uid/gid info for "lfs quota /path/to/lustre/mount" */ - if (qctl.qc_cmd == LUSTRE_Q_GETQUOTA && qctl.qc_type == UGQUOTA && - optind == argc - 1) { -ug_output: - memset(&qctl, 0, sizeof(qctl)); /* spoiled by print_*_quota */ - qctl.qc_cmd = LUSTRE_Q_GETQUOTA; - qctl.qc_valid = valid; - qctl.qc_idx = idx; - if (pass++ == 0) { - qctl.qc_type = USRQUOTA; - qctl.qc_id = geteuid(); - } else { - qctl.qc_type = GRPQUOTA; - qctl.qc_id = getegid(); - } - rc = id2name(&name, qctl.qc_id, - (qctl.qc_type == USRQUOTA) ? USER : GROUP); - if (rc) - name = ""; - /* lfs quota -u username /path/to/lustre/mount */ - } else if (qctl.qc_cmd == LUSTRE_Q_GETQUOTA) { - /* options should be followed by u/g-name and mntpoint */ - if (optind + 2 != argc || qctl.qc_type == UGQUOTA) { - fprintf(stderr, "error: missing quota argument(s)\n"); - return CMD_HELP; - } + if (qctl.qc_cmd == LUSTRE_Q_GETQUOTA && qctl.qc_type == ALLQUOTA && + optind == argc - 1) { +all_output: + memset(&qctl, 0, sizeof(qctl)); /* spoiled by print_*_quota */ + qctl.qc_cmd = LUSTRE_Q_GETQUOTA; + qctl.qc_valid = valid; + qctl.qc_idx = idx; + qctl.qc_type = pass; + switch (qctl.qc_type) { + case USRQUOTA: + qctl.qc_id = geteuid(); + rc = uid2name(&name, qctl.qc_id); + break; + case GRPQUOTA: + qctl.qc_id = getegid(); + rc = gid2name(&name, qctl.qc_id); + break; + default: + rc = -ENOTSUP; + break; + } + if (rc) + name = ""; + pass++; + /* lfs quota -u username /path/to/lustre/mount */ + } else if (qctl.qc_cmd == LUSTRE_Q_GETQUOTA) { + /* options should be followed by u/g-name and mntpoint */ + if (optind + 2 != argc || qctl.qc_type == ALLQUOTA) { + fprintf(stderr, "error: missing quota argument(s)\n"); + return CMD_HELP; + } - name = argv[optind++]; - rc = name2id(&qctl.qc_id, name, - (qctl.qc_type == USRQUOTA) ? USER : GROUP); - if (rc) { - qctl.qc_id = strtoul(name, &endptr, 10); - if (*endptr != '\0') { - fprintf(stderr, "error: can't find id for name " + name = argv[optind++]; + switch (qctl.qc_type) { + case USRQUOTA: + rc = name2uid(&qctl.qc_id, name); + break; + case GRPQUOTA: + rc = name2gid(&qctl.qc_id, name); + break; + default: + rc = -ENOTSUP; + break; + } + if (rc) { + qctl.qc_id = strtoul(name, &endptr, 10); + if (*endptr != '\0') { + fprintf(stderr, "error: can't find id for name " "%s\n", name); - return CMD_HELP; - } - } - } else if (optind + 1 != argc || qctl.qc_type == UGQUOTA) { - fprintf(stderr, "error: missing quota info argument(s)\n"); - return CMD_HELP; - } + return CMD_HELP; + } + } + } else if (optind + 1 != argc || qctl.qc_type == ALLQUOTA) { + fprintf(stderr, "error: missing quota info argument(s)\n"); + return CMD_HELP; + } mnt = argv[optind]; @@ -4010,7 +4017,7 @@ ug_output: switch (rc1) { case -ESRCH: fprintf(stderr, "%s quotas are not enabled.\n", - qctl.qc_type == USRQUOTA ? "user" : "group"); + qtype_name(qctl.qc_type)); goto out; case -EPERM: fprintf(stderr, "Permission denied.\n"); @@ -4054,16 +4061,16 @@ ug_output: strbuf); } - if (rc1 || rc2 || rc3 || inacc) - printf("Some errors happened when getting quota info. " - "Some devices may be not working or deactivated. " - "The data in \"[]\" is inaccurate.\n"); + if (rc1 || rc2 || rc3 || inacc) + printf("Some errors happened when getting quota info. " + "Some devices may be not working or deactivated. " + "The data in \"[]\" is inaccurate.\n"); out: - if (pass == 1) - goto ug_output; + if (pass > 0 && pass < LL_MAXQUOTAS) + goto all_output; - return rc1; + return rc1; } #endif /* HAVE_SYS_QUOTA_H! */ -- 1.8.3.1