#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 | \
* 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
#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
#include <stdint.h>
#include <lustre/lustre_user.h>
+#ifndef LL_MAXQUOTAS
+#define LL_MAXQUOTAS 2
+#endif
+
extern bool liblustreapi_initialized;
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)
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;
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;
}
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));
}
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;
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)
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)
}
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 */
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);
}
}
/* 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",
* - 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
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;
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,
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;
}
/**
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)
};
#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);
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);
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.
*/
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];
}
/**
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;
}
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++;
}
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,
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)
{
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 {
/**
* 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;
}
/**
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;
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
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);
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:
*
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;
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");
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 */
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,
#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)
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
*/
#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 */
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.
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);
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));
}
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 */
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));
}
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);
}
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;
}
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);
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));
&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);
}
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);
}
}
&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);
}
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);
}
#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);
"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,
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) {
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;
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);
}
}
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.
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;
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;
}
/* 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) {
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) {
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);
}
}
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),
*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)
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') {
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;
{"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",
}
}
- if (qctl.qc_type == UGQUOTA) {
+ if (qctl.qc_type == ALLQUOTA) {
fprintf(stderr, "error: neither -u nor -g specified\n");
return CMD_HELP;
}
};
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 "
"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");
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:
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",
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;
}
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;
}
/* 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 = "<unknown>";
- /* 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 = "<unknown>";
+ 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];
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");
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! */