+ }
+ case OBD_IOC_QUOTACHECK: {
+ struct obd_quotactl *oqctl;
+ int error = 0;
+
+ if (!cfs_capable(CFS_CAP_SYS_ADMIN) ||
+ sbi->ll_flags & LL_SBI_RMT_CLIENT)
+ RETURN(-EPERM);
+
+ OBD_ALLOC_PTR(oqctl);
+ if (!oqctl)
+ RETURN(-ENOMEM);
+ oqctl->qc_type = arg;
+ rc = obd_quotacheck(sbi->ll_md_exp, oqctl);
+ if (rc < 0) {
+ CDEBUG(D_INFO, "md_quotacheck failed: rc %d\n", rc);
+ error = rc;
+ }
+
+ rc = obd_quotacheck(sbi->ll_dt_exp, oqctl);
+ if (rc < 0)
+ CDEBUG(D_INFO, "obd_quotacheck failed: rc %d\n", rc);
+
+ OBD_FREE_PTR(oqctl);
+ return error ?: rc;
+ }
+ case OBD_IOC_POLL_QUOTACHECK: {
+ struct if_quotacheck *check;
+
+ if (!cfs_capable(CFS_CAP_SYS_ADMIN) ||
+ sbi->ll_flags & LL_SBI_RMT_CLIENT)
+ RETURN(-EPERM);
+
+ OBD_ALLOC_PTR(check);
+ if (!check)
+ RETURN(-ENOMEM);
+
+ rc = obd_iocontrol(cmd, sbi->ll_md_exp, 0, (void *)check,
+ NULL);
+ if (rc) {
+ CDEBUG(D_QUOTA, "mdc ioctl %d failed: %d\n", cmd, rc);
+ if (cfs_copy_to_user((void *)arg, check,
+ sizeof(*check)))
+ CDEBUG(D_QUOTA, "cfs_copy_to_user failed\n");
+ GOTO(out_poll, rc);
+ }
+
+ rc = obd_iocontrol(cmd, sbi->ll_dt_exp, 0, (void *)check,
+ NULL);
+ if (rc) {
+ CDEBUG(D_QUOTA, "osc ioctl %d failed: %d\n", cmd, rc);
+ if (cfs_copy_to_user((void *)arg, check,
+ sizeof(*check)))
+ CDEBUG(D_QUOTA, "cfs_copy_to_user failed\n");
+ GOTO(out_poll, rc);
+ }
+ out_poll:
+ OBD_FREE_PTR(check);
+ RETURN(rc);
+ }
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2,7,50,0)
+ case LL_IOC_QUOTACTL_18: {
+ /* copy the old 1.x quota struct for internal use, then copy
+ * back into old format struct. For 1.8 compatibility. */
+ struct if_quotactl_18 *qctl_18;
+ struct if_quotactl *qctl_20;
+
+ OBD_ALLOC_PTR(qctl_18);
+ if (!qctl_18)
+ RETURN(-ENOMEM);
+
+ OBD_ALLOC_PTR(qctl_20);
+ if (!qctl_20)
+ GOTO(out_quotactl_18, rc = -ENOMEM);
+
+ if (cfs_copy_from_user(qctl_18, (void *)arg, sizeof(*qctl_18)))
+ GOTO(out_quotactl_20, rc = -ENOMEM);
+
+ QCTL_COPY(qctl_20, qctl_18);
+ qctl_20->qc_idx = 0;
+
+ /* XXX: dqb_valid was borrowed as a flag to mark that
+ * only mds quota is wanted */
+ if (qctl_18->qc_cmd == Q_GETQUOTA &&
+ qctl_18->qc_dqblk.dqb_valid) {
+ qctl_20->qc_valid = QC_MDTIDX;
+ qctl_20->qc_dqblk.dqb_valid = 0;
+ } else if (qctl_18->obd_uuid.uuid[0] != '\0') {
+ qctl_20->qc_valid = QC_UUID;
+ qctl_20->obd_uuid = qctl_18->obd_uuid;
+ } else {
+ qctl_20->qc_valid = QC_GENERAL;
+ }
+
+ rc = quotactl_ioctl(sbi, qctl_20);
+
+ if (rc == 0) {
+ QCTL_COPY(qctl_18, qctl_20);
+ qctl_18->obd_uuid = qctl_20->obd_uuid;
+
+ if (cfs_copy_to_user((void *)arg, qctl_18,
+ sizeof(*qctl_18)))
+ rc = -EFAULT;
+ }
+
+ out_quotactl_20:
+ OBD_FREE_PTR(qctl_20);
+ out_quotactl_18:
+ OBD_FREE_PTR(qctl_18);
+ RETURN(rc);
+ }
+#else
+#warning "remove old LL_IOC_QUOTACTL_18 compatibility code"
+#endif /* LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2,7,50,0) */
+ case LL_IOC_QUOTACTL: {
+ struct if_quotactl *qctl;
+
+ OBD_ALLOC_PTR(qctl);
+ if (!qctl)
+ RETURN(-ENOMEM);
+
+ if (cfs_copy_from_user(qctl, (void *)arg, sizeof(*qctl)))
+ GOTO(out_quotactl, rc = -EFAULT);
+
+ rc = quotactl_ioctl(sbi, qctl);
+
+ if (rc == 0 && cfs_copy_to_user((void *)arg,qctl,sizeof(*qctl)))
+ rc = -EFAULT;
+
+ out_quotactl:
+ OBD_FREE_PTR(qctl);
+ RETURN(rc);
+ }
+ case OBD_IOC_GETNAME: {
+ struct obd_device *obd = class_exp2obd(sbi->ll_dt_exp);
+ if (!obd)
+ RETURN(-EFAULT);
+ if (cfs_copy_to_user((void *)arg, obd->obd_name,
+ strlen(obd->obd_name) + 1))
+ RETURN (-EFAULT);
+ RETURN(0);
+ }
+ case LL_IOC_FLUSHCTX:
+ RETURN(ll_flush_ctx(inode));
+#ifdef CONFIG_FS_POSIX_ACL
+ case LL_IOC_RMTACL: {
+ if (sbi->ll_flags & LL_SBI_RMT_CLIENT &&
+ inode == inode->i_sb->s_root->d_inode) {
+ struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
+
+ LASSERT(fd != NULL);
+ rc = rct_add(&sbi->ll_rct, cfs_curproc_pid(), arg);
+ if (!rc)
+ fd->fd_flags |= LL_FILE_RMTACL;
+ RETURN(rc);
+ } else
+ RETURN(0);
+ }
+#endif
+ case LL_IOC_GETOBDCOUNT: {
+ int count, vallen;
+ struct obd_export *exp;
+
+ if (cfs_copy_from_user(&count, (int *)arg, sizeof(int)))
+ RETURN(-EFAULT);
+
+ /* get ost count when count is zero, get mdt count otherwise */
+ exp = count ? sbi->ll_md_exp : sbi->ll_dt_exp;
+ vallen = sizeof(count);
+ rc = obd_get_info(exp, sizeof(KEY_TGT_COUNT), KEY_TGT_COUNT,
+ &vallen, &count, NULL);
+ if (rc) {
+ CERROR("get target count failed: %d\n", rc);
+ RETURN(rc);
+ }
+
+ if (cfs_copy_to_user((int *)arg, &count, sizeof(int)))
+ RETURN(-EFAULT);
+
+ RETURN(0);
+ }
+ case LL_IOC_PATH2FID:
+ if (cfs_copy_to_user((void *)arg, ll_inode2fid(inode),
+ sizeof(struct lu_fid)))
+ RETURN(-EFAULT);
+ RETURN(0);
+ case LL_IOC_GET_CONNECT_FLAGS: {
+ RETURN(obd_iocontrol(cmd, sbi->ll_md_exp, 0, NULL, (void*)arg));
+ }
+ case OBD_IOC_CHANGELOG_SEND:
+ case OBD_IOC_CHANGELOG_CLEAR:
+ rc = copy_and_ioctl(cmd, sbi->ll_md_exp, (void *)arg,
+ sizeof(struct ioc_changelog));
+ RETURN(rc);
+ case OBD_IOC_FID2PATH:
+ RETURN(ll_fid2path(ll_i2mdexp(inode), (void *)arg));
+ case LL_IOC_HSM_CT_START:
+ rc = copy_and_ioctl(cmd, sbi->ll_md_exp, (void *)arg,
+ sizeof(struct lustre_kernelcomm));
+ RETURN(rc);
+