+static int mgs_iocontrol_pool(struct obd_device *obd,
+ struct obd_ioctl_data *data)
+{
+ int rc;
+ struct lustre_handle lockh;
+ struct lustre_cfg *lcfg = NULL;
+ struct llog_rec_hdr rec;
+ char *fsname = NULL;
+ char *poolname = NULL;
+ ENTRY;
+
+ OBD_ALLOC(fsname, MTI_NAME_MAXLEN);
+ if (fsname == NULL)
+ RETURN(-ENOMEM);
+
+ OBD_ALLOC(poolname, LOV_MAXPOOLNAME + 1);
+ if (poolname == NULL) {
+ rc = -ENOMEM;
+ GOTO(out_pool, rc);
+ }
+ rec.lrh_len = llog_data_len(data->ioc_plen1);
+
+ if (data->ioc_type == LUSTRE_CFG_TYPE) {
+ rec.lrh_type = OBD_CFG_REC;
+ } else {
+ CERROR("unknown cfg record type:%d \n", data->ioc_type);
+ rc = -EINVAL;
+ GOTO(out_pool, rc);
+ }
+
+ if (data->ioc_plen1 > CFS_PAGE_SIZE) {
+ rc = -E2BIG;
+ GOTO(out_pool, rc);
+ }
+
+ OBD_ALLOC(lcfg, data->ioc_plen1);
+ if (lcfg == NULL)
+ GOTO(out_pool, rc = -ENOMEM);
+
+ if (copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1))
+ GOTO(out_pool, rc = -EFAULT);
+
+ if (lcfg->lcfg_bufcount < 2) {
+ GOTO(out_pool, rc = -EFAULT);
+ }
+
+ /* first arg is always <fsname>.<poolname> */
+ mgs_extract_fs_pool(lustre_cfg_string(lcfg, 1), fsname,
+ poolname);
+
+ switch (lcfg->lcfg_command) {
+ case LCFG_POOL_NEW: {
+ if (lcfg->lcfg_bufcount != 2)
+ RETURN(-EINVAL);
+ rc = mgs_pool_cmd(obd, LCFG_POOL_NEW, fsname,
+ poolname, NULL);
+ break;
+ }
+ case LCFG_POOL_ADD: {
+ if (lcfg->lcfg_bufcount != 3)
+ RETURN(-EINVAL);
+ rc = mgs_pool_cmd(obd, LCFG_POOL_ADD, fsname, poolname,
+ lustre_cfg_string(lcfg, 2));
+ break;
+ }
+ case LCFG_POOL_REM: {
+ if (lcfg->lcfg_bufcount != 3)
+ RETURN(-EINVAL);
+ rc = mgs_pool_cmd(obd, LCFG_POOL_REM, fsname, poolname,
+ lustre_cfg_string(lcfg, 2));
+ break;
+ }
+ case LCFG_POOL_DEL: {
+ if (lcfg->lcfg_bufcount != 2)
+ RETURN(-EINVAL);
+ rc = mgs_pool_cmd(obd, LCFG_POOL_DEL, fsname,
+ poolname, NULL);
+ break;
+ }
+ default: {
+ rc = -EINVAL;
+ GOTO(out_pool, rc);
+ }
+ }
+
+ if (rc) {
+ CERROR("OBD_IOC_POOL err %d, cmd %X for pool %s.%s\n",
+ rc, lcfg->lcfg_command, fsname, poolname);
+ GOTO(out_pool, rc);
+ }
+
+ /* request for update */
+ mgs_revoke_lock(obd, fsname, &lockh);
+
+out_pool:
+ if (lcfg != NULL)
+ OBD_FREE(lcfg, data->ioc_plen1);
+
+ if (fsname != NULL)
+ OBD_FREE(fsname, MTI_NAME_MAXLEN);
+
+ if (poolname != NULL)
+ OBD_FREE(poolname, LOV_MAXPOOLNAME + 1);
+
+ RETURN(rc);
+}
+