- cmd = qctl->qc_cmd;
- type = qctl->qc_type;
- id = qctl->qc_id;
- valid = qctl->qc_valid;
-
- switch (cmd) {
- case LUSTRE_Q_INVALIDATE:
- case LUSTRE_Q_FINVALIDATE:
- case Q_QUOTAON:
- case Q_QUOTAOFF:
- case Q_SETQUOTA:
- case Q_SETINFO:
- if (!cfs_capable(CFS_CAP_SYS_ADMIN) ||
- sbi->ll_flags & LL_SBI_RMT_CLIENT)
- GOTO(out_quotactl, rc = -EPERM);
- break;
- case Q_GETQUOTA:
- if (((type == USRQUOTA && cfs_curproc_euid() != id) ||
- (type == GRPQUOTA && !in_egroup_p(id))) &&
- (!cfs_capable(CFS_CAP_SYS_ADMIN) ||
- sbi->ll_flags & LL_SBI_RMT_CLIENT))
- GOTO(out_quotactl, rc = -EPERM);
- break;
- case Q_GETINFO:
- break;
- default:
- CERROR("unsupported quotactl op: %#x\n", cmd);
- GOTO(out_quotactl, rc = -ENOTTY);
- }
-
- if (valid != QC_GENERAL) {
- if (sbi->ll_flags & LL_SBI_RMT_CLIENT)
- GOTO(out_quotactl, rc = -EOPNOTSUPP);
-
- if (cmd == Q_GETINFO)
- qctl->qc_cmd = Q_GETOINFO;
- else if (cmd == Q_GETQUOTA)
- qctl->qc_cmd = Q_GETOQUOTA;
- else
- GOTO(out_quotactl, rc = -EINVAL);
-
- switch (valid) {
- case QC_MDTIDX:
- rc = obd_iocontrol(OBD_IOC_QUOTACTL,
- sbi->ll_md_exp,
- sizeof(*qctl), qctl, NULL);
- break;
- case QC_OSTIDX:
- rc = obd_iocontrol(OBD_IOC_QUOTACTL,
- sbi->ll_dt_exp,
- sizeof(*qctl), qctl, NULL);
- break;
- case QC_UUID:
- rc = obd_iocontrol(OBD_IOC_QUOTACTL,
- sbi->ll_md_exp,
- sizeof(*qctl), qctl, NULL);
- if (rc == -EAGAIN)
- rc = obd_iocontrol(OBD_IOC_QUOTACTL,
- sbi->ll_dt_exp,
- sizeof(*qctl), qctl,
- NULL);
- break;
- default:
- rc = -EINVAL;
- break;
- }
-
- if (rc)
- GOTO(out_quotactl, rc);
- else
- qctl->qc_cmd = cmd;
- } else {
- struct obd_quotactl *oqctl;
-
- OBD_ALLOC_PTR(oqctl);
- if (!oqctl)
- GOTO(out_quotactl, rc = -ENOMEM);
-
- QCTL_COPY(oqctl, qctl);
- rc = obd_quotactl(sbi->ll_md_exp, oqctl);
- if (rc) {
- if (rc != -EALREADY && cmd == Q_QUOTAON) {
- oqctl->qc_cmd = Q_QUOTAOFF;
- obd_quotactl(sbi->ll_md_exp, oqctl);
- }
- OBD_FREE_PTR(oqctl);
- GOTO(out_quotactl, rc);
- } else {
- QCTL_COPY(qctl, oqctl);
- OBD_FREE_PTR(oqctl);
- }
- }