int lst_group_del_ioctl(lstio_group_del_args_t *args) { int rc; char *name; if (args->lstio_grp_key != console_session.ses_key) return -EACCES; if (args->lstio_grp_namep == NULL || args->lstio_grp_nmlen <= 0 || args->lstio_grp_nmlen > LST_NAME_SIZE) return -EINVAL; LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1); if (name == NULL) return -ENOMEM; if (cfs_copy_from_user(name, args->lstio_grp_namep, args->lstio_grp_nmlen)) { LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); return -EFAULT; } name[args->lstio_grp_nmlen] = 0; rc = lstcon_group_del(name); LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); return rc; }
static int osc_wd_checksum_type(struct file *file, const char *buffer, unsigned long count, void *data) { struct obd_device *obd = data; int i; DECLARE_CKSUM_NAME; char kernbuf[10]; if (obd == NULL) return 0; if (count > sizeof(kernbuf) - 1) return -EINVAL; if (cfs_copy_from_user(kernbuf, buffer, count)) return -EFAULT; if (count > 0 && kernbuf[count - 1] == '\n') kernbuf[count - 1] = '\0'; else kernbuf[count] = '\0'; for (i = 0; i < ARRAY_SIZE(cksum_name); i++) { if (((1 << i) & obd->u.cli.cl_supp_cksum_types) == 0) continue; if (!strcmp(kernbuf, cksum_name[i])) { obd->u.cli.cl_cksum_type = 1 << i; return count; } } return -EINVAL; }
static int lprocfs_wr_changelog_mask(struct file *file, const char *buffer, unsigned long count, void *data) { struct mdd_device *mdd = data; char *kernbuf; int rc; ENTRY; if (count >= CFS_PAGE_SIZE) RETURN(-EINVAL); OBD_ALLOC(kernbuf, CFS_PAGE_SIZE); if (kernbuf == NULL) RETURN(-ENOMEM); if (cfs_copy_from_user(kernbuf, buffer, count)) GOTO(out, rc = -EFAULT); kernbuf[count] = 0; rc = cfs_str2mask(kernbuf, changelog_type2str, &mdd->mdd_cl.mc_mask, CHANGELOG_MINMASK, CHANGELOG_ALLMASK); if (rc == 0) rc = count; out: OBD_FREE(kernbuf, CFS_PAGE_SIZE); return rc; }
int lst_batch_stop_ioctl(lstio_batch_stop_args_t *args) { int rc; char *name; if (args->lstio_bat_key != console_session.ses_key) return -EACCES; if (args->lstio_bat_resultp == NULL || args->lstio_bat_namep == NULL || args->lstio_bat_nmlen <= 0 || args->lstio_bat_nmlen > LST_NAME_SIZE) return -EINVAL; LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1); if (name == NULL) return -ENOMEM; if (cfs_copy_from_user(name, args->lstio_bat_namep, args->lstio_bat_nmlen)) { LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); return -EFAULT; } name[args->lstio_bat_nmlen] = 0; rc = lstcon_batch_stop(name, args->lstio_bat_force, args->lstio_bat_resultp); LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); return rc; }
int lst_group_update_ioctl(lstio_group_update_args_t *args) { int rc; char *name; if (args->lstio_grp_key != console_session.ses_key) return -EACCES; if (args->lstio_grp_resultp == NULL || args->lstio_grp_namep == NULL || args->lstio_grp_nmlen <= 0 || args->lstio_grp_nmlen > LST_NAME_SIZE) return -EINVAL; LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1); if (name == NULL) return -ENOMEM; if (cfs_copy_from_user(name, args->lstio_grp_namep, args->lstio_grp_nmlen)) { LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); return -EFAULT; } name[args->lstio_grp_nmlen] = 0; switch (args->lstio_grp_opc) { case LST_GROUP_CLEAN: rc = lstcon_group_clean(name, args->lstio_grp_args); break; case LST_GROUP_REFRESH: rc = lstcon_group_refresh(name, args->lstio_grp_resultp); break; case LST_GROUP_RMND: if (args->lstio_grp_count <= 0 || args->lstio_grp_idsp == NULL) { rc = -EINVAL; break; } rc = lstcon_nodes_remove(name, args->lstio_grp_count, args->lstio_grp_idsp, args->lstio_grp_resultp); break; default: rc = -EINVAL; break; } LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); return rc; }
int lprocfs_quota_wr_type(struct file *file, const char *buffer, unsigned long count, void *data) { struct obd_device *obd = (struct obd_device *)data; struct obd_device_target *obt; int type = 0, is_mds; unsigned long i; char stype[MAX_STYPE_SIZE + 1] = ""; LASSERT(obd != NULL); obt = &obd->u.obt; is_mds = !strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME); if (count > MAX_STYPE_SIZE) return -EINVAL; if (cfs_copy_from_user(stype, buffer, count)) return -EFAULT; for (i = 0 ; i < count ; i++) { switch (stype[i]) { case 'u' : type |= USER_QUOTA; break; case 'g' : type |= GROUP_QUOTA; break; case '1' : case '2' : CWARN("quota_type options 1 and 2 are obsolete, " "they will be ignored\n"); break; case '3' : /* the only valid version spec, do nothing */ default : /* just skip stray symbols like \n */ break; } } if (type != 0) { int rc = auto_quota_on(obd, type - 1); if (rc && rc != -EALREADY && rc != -ENOENT) return rc; } return count; }
int lst_stat_query_ioctl(lstio_stat_args_t *args) { int rc; char *name; /* TODO: not finished */ if (args->lstio_sta_key != console_session.ses_key) return -EACCES; if (args->lstio_sta_resultp == NULL || (args->lstio_sta_namep == NULL && args->lstio_sta_idsp == NULL) || args->lstio_sta_nmlen <= 0 || args->lstio_sta_nmlen > LST_NAME_SIZE) return -EINVAL; if (args->lstio_sta_idsp != NULL && args->lstio_sta_count <= 0) return -EINVAL; LIBCFS_ALLOC(name, args->lstio_sta_nmlen + 1); if (name == NULL) return -ENOMEM; if (cfs_copy_from_user(name, args->lstio_sta_namep, args->lstio_sta_nmlen)) { LIBCFS_FREE(name, args->lstio_sta_nmlen + 1); return -EFAULT; } if (args->lstio_sta_idsp == NULL) { rc = lstcon_group_stat(name, args->lstio_sta_timeout, args->lstio_sta_resultp); } else { rc = lstcon_nodes_stat(args->lstio_sta_count, args->lstio_sta_idsp, args->lstio_sta_timeout, args->lstio_sta_resultp); } LIBCFS_FREE(name, args->lstio_sta_nmlen + 1); return rc; }
int lst_batch_query_ioctl(lstio_batch_query_args_t *args) { char *name; int rc; if (args->lstio_bat_key != console_session.ses_key) return -EACCES; if (args->lstio_bat_resultp == NULL || args->lstio_bat_namep == NULL || args->lstio_bat_nmlen <= 0 || args->lstio_bat_nmlen > LST_NAME_SIZE) return -EINVAL; if (args->lstio_bat_testidx < 0) return -EINVAL; LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1); if (name == NULL) return -ENOMEM; if (cfs_copy_from_user(name, args->lstio_bat_namep, args->lstio_bat_nmlen)) { LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); return -EFAULT; } name[args->lstio_bat_nmlen] = 0; rc = lstcon_test_batch_query(name, args->lstio_bat_testidx, args->lstio_bat_client, args->lstio_bat_timeout, args->lstio_bat_resultp); LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); return rc; }
static int lprocfs_wr_atime_diff(struct file *file, const char *buffer, unsigned long count, void *data) { struct mdd_device *mdd = data; char kernbuf[20], *end; unsigned long diff = 0; if (count > (sizeof(kernbuf) - 1)) return -EINVAL; if (cfs_copy_from_user(kernbuf, buffer, count)) return -EFAULT; kernbuf[count] = '\0'; diff = simple_strtoul(kernbuf, &end, 0); if (kernbuf == end) return -EINVAL; mdd->mdd_atime_diff = diff; return count; }
int lst_nodes_add_ioctl(lstio_group_nodes_args_t *args) { int rc; char *name; if (args->lstio_grp_key != console_session.ses_key) return -EACCES; if (args->lstio_grp_idsp == NULL || /* array of ids */ args->lstio_grp_count <= 0 || args->lstio_grp_resultp == NULL || args->lstio_grp_namep == NULL || args->lstio_grp_nmlen <= 0 || args->lstio_grp_nmlen > LST_NAME_SIZE) return -EINVAL; LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1); if (name == NULL) return -ENOMEM; if (cfs_copy_from_user(name, args->lstio_grp_namep, args->lstio_grp_nmlen)) { LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); return -EFAULT; } name[args->lstio_grp_nmlen] = 0; rc = lstcon_nodes_add(name, args->lstio_grp_count, args->lstio_grp_idsp, args->lstio_grp_resultp); LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); return rc; }
int lst_session_new_ioctl(lstio_session_new_args_t *args) { char *name; int rc; if (args->lstio_ses_idp == NULL || /* address for output sid */ args->lstio_ses_key == 0 || /* no key is specified */ args->lstio_ses_namep == NULL || /* session name */ args->lstio_ses_nmlen <= 0 || args->lstio_ses_nmlen > LST_NAME_SIZE) return -EINVAL; LIBCFS_ALLOC(name, args->lstio_ses_nmlen + 1); if (name == NULL) return -ENOMEM; if (cfs_copy_from_user(name, args->lstio_ses_namep, args->lstio_ses_nmlen)) { LIBCFS_FREE(name, args->lstio_ses_nmlen + 1); return -EFAULT; } name[args->lstio_ses_nmlen] = 0; rc = lstcon_session_new(name, args->lstio_ses_key, args->lstio_ses_timeout, args->lstio_ses_force, args->lstio_ses_idp); LIBCFS_FREE(name, args->lstio_ses_nmlen + 1); return rc; }
int lst_batch_info_ioctl(lstio_batch_info_args_t *args) { char *name; int rc; int index; int ndent; if (args->lstio_bat_key != console_session.ses_key) return -EACCES; if (args->lstio_bat_namep == NULL || /* batch name */ args->lstio_bat_nmlen <= 0 || args->lstio_bat_nmlen > LST_NAME_SIZE) return -EINVAL; if (args->lstio_bat_entp == NULL && /* output: batch entry */ args->lstio_bat_dentsp == NULL) /* output: node entry */ return -EINVAL; if (args->lstio_bat_dentsp != NULL) { /* have node entry */ if (args->lstio_bat_idxp == NULL || /* node index */ args->lstio_bat_ndentp == NULL) /* # of node entry */ return -EINVAL; if (cfs_copy_from_user(&index, args->lstio_bat_idxp, sizeof(index)) || cfs_copy_from_user(&ndent, args->lstio_bat_ndentp, sizeof(ndent))) return -EFAULT; if (ndent <= 0 || index < 0) return -EINVAL; } LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1); if (name == NULL) return -ENOMEM; if (cfs_copy_from_user(name, args->lstio_bat_namep, args->lstio_bat_nmlen)) { LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); return -EFAULT; } name[args->lstio_bat_nmlen] = 0; rc = lstcon_batch_info(name, args->lstio_bat_entp, args->lstio_bat_server, args->lstio_bat_testidx, &index, &ndent, args->lstio_bat_dentsp); LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); if (rc != 0) return rc; if (args->lstio_bat_dentsp != NULL && (cfs_copy_to_user(args->lstio_bat_idxp, &index, sizeof(index)) || cfs_copy_to_user(args->lstio_bat_ndentp, &ndent, sizeof(ndent)))) rc = -EFAULT; return rc; }
static int mgs_iocontrol_pool(struct obd_device *obd, struct obd_ioctl_data *data) { int rc; 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 (cfs_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); } 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); }
/* from mdt_iocontrol */ int mgs_iocontrol(unsigned int cmd, struct obd_export *exp, int len, void *karg, void *uarg) { struct obd_device *obd = exp->exp_obd; struct obd_ioctl_data *data = karg; struct lvfs_run_ctxt saved; int rc = 0; ENTRY; CDEBUG(D_IOCTL, "handling ioctl cmd %#x\n", cmd); switch (cmd) { case OBD_IOC_PARAM: { struct lustre_cfg *lcfg; struct llog_rec_hdr rec; char fsname[MTI_NAME_MAXLEN]; 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); RETURN(-EINVAL); } OBD_ALLOC(lcfg, data->ioc_plen1); if (lcfg == NULL) RETURN(-ENOMEM); if (cfs_copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1)) GOTO(out_free, rc = -EFAULT); if (lcfg->lcfg_bufcount < 1) GOTO(out_free, rc = -EINVAL); rc = mgs_setparam(obd, lcfg, fsname); if (rc) { CERROR("setparam err %d\n", rc); GOTO(out_free, rc); } out_free: OBD_FREE(lcfg, data->ioc_plen1); RETURN(rc); } case OBD_IOC_POOL: { RETURN(mgs_iocontrol_pool(obd, data)); } case OBD_IOC_DUMP_LOG: { struct llog_ctxt *ctxt; ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT); push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); rc = class_config_dump_llog(ctxt, data->ioc_inlbuf1, NULL); pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); llog_ctxt_put(ctxt); RETURN(rc); } case OBD_IOC_LLOG_CHECK: case OBD_IOC_LLOG_INFO: case OBD_IOC_LLOG_PRINT: { struct llog_ctxt *ctxt; ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT); push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL); rc = llog_ioctl(ctxt, cmd, data); pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL); llog_ctxt_put(ctxt); RETURN(rc); } default: CDEBUG(D_INFO, "unknown command %x\n", cmd); RETURN(-EINVAL); } RETURN(0); }
static int lprocfs_wr_lru_size(struct file *file, const char *buffer, unsigned long count, void *data) { struct ldlm_namespace *ns = data; char dummy[MAX_STRING_SIZE + 1], *end; unsigned long tmp; int lru_resize; dummy[MAX_STRING_SIZE] = '\0'; if (cfs_copy_from_user(dummy, buffer, MAX_STRING_SIZE)) return -EFAULT; if (strncmp(dummy, "clear", 5) == 0) { CDEBUG(D_DLMTRACE, "dropping all unused locks from namespace %s\n", ldlm_ns_name(ns)); if (ns_connect_lru_resize(ns)) { int canceled, unused = ns->ns_nr_unused; /* Try to cancel all @ns_nr_unused locks. */ canceled = ldlm_cancel_lru(ns, unused, LDLM_SYNC, LDLM_CANCEL_PASSED); if (canceled < unused) { CDEBUG(D_DLMTRACE, "not all requested locks are canceled, " "requested: %d, canceled: %d\n", unused, canceled); return -EINVAL; } } else { tmp = ns->ns_max_unused; ns->ns_max_unused = 0; ldlm_cancel_lru(ns, 0, LDLM_SYNC, LDLM_CANCEL_PASSED); ns->ns_max_unused = tmp; } return count; } tmp = simple_strtoul(dummy, &end, 0); if (dummy == end) { CERROR("invalid value written\n"); return -EINVAL; } lru_resize = (tmp == 0); if (ns_connect_lru_resize(ns)) { if (!lru_resize) ns->ns_max_unused = (unsigned int)tmp; if (tmp > ns->ns_nr_unused) tmp = ns->ns_nr_unused; tmp = ns->ns_nr_unused - tmp; CDEBUG(D_DLMTRACE, "changing namespace %s unused locks from %u to %u\n", ldlm_ns_name(ns), ns->ns_nr_unused, (unsigned int)tmp); ldlm_cancel_lru(ns, tmp, LDLM_ASYNC, LDLM_CANCEL_PASSED); if (!lru_resize) { CDEBUG(D_DLMTRACE, "disable lru_resize for namespace %s\n", ldlm_ns_name(ns)); ns->ns_connect_flags &= ~OBD_CONNECT_LRU_RESIZE; } } else { CDEBUG(D_DLMTRACE, "changing namespace %s max_unused from %u to %u\n", ldlm_ns_name(ns), ns->ns_max_unused, (unsigned int)tmp); ns->ns_max_unused = (unsigned int)tmp; ldlm_cancel_lru(ns, 0, LDLM_ASYNC, LDLM_CANCEL_PASSED); /* Make sure that LRU resize was originally supported before * turning it on here. */ if (lru_resize && (ns->ns_orig_connect_flags & OBD_CONNECT_LRU_RESIZE)) { CDEBUG(D_DLMTRACE, "enable lru_resize for namespace %s\n", ldlm_ns_name(ns)); ns->ns_connect_flags |= OBD_CONNECT_LRU_RESIZE; } } return count; }
int lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_data *data) { char *buf; int opc = data->ioc_u32[0]; int rc; if (cmd != IOC_LIBCFS_LNETST) return -EINVAL; if (data->ioc_plen1 > CFS_PAGE_SIZE) return -EINVAL; LIBCFS_ALLOC(buf, data->ioc_plen1); if (buf == NULL) return -ENOMEM; /* copy in parameter */ if (cfs_copy_from_user(buf, data->ioc_pbuf1, data->ioc_plen1)) { LIBCFS_FREE(buf, data->ioc_plen1); return -EFAULT; } cfs_mutex_down(&console_session.ses_mutex); console_session.ses_laststamp = cfs_time_current_sec(); if (console_session.ses_shutdown) { rc = -ESHUTDOWN; goto out; } if (console_session.ses_expired) lstcon_session_end(); if (opc != LSTIO_SESSION_NEW && console_session.ses_state == LST_SESSION_NONE) { CDEBUG(D_NET, "LST no active session\n"); rc = -ESRCH; goto out; } memset(&console_session.ses_trans_stat, 0, sizeof(lstcon_trans_stat_t)); switch (opc) { case LSTIO_SESSION_NEW: rc = lst_session_new_ioctl((lstio_session_new_args_t *)buf); break; case LSTIO_SESSION_END: rc = lst_session_end_ioctl((lstio_session_end_args_t *)buf); break; case LSTIO_SESSION_INFO: rc = lst_session_info_ioctl((lstio_session_info_args_t *)buf); break; case LSTIO_DEBUG: rc = lst_debug_ioctl((lstio_debug_args_t *)buf); break; case LSTIO_GROUP_ADD: rc = lst_group_add_ioctl((lstio_group_add_args_t *)buf); break; case LSTIO_GROUP_DEL: rc = lst_group_del_ioctl((lstio_group_del_args_t *)buf); break; case LSTIO_GROUP_UPDATE: rc = lst_group_update_ioctl((lstio_group_update_args_t *)buf); break; case LSTIO_NODES_ADD: rc = lst_nodes_add_ioctl((lstio_group_nodes_args_t *)buf); break; case LSTIO_GROUP_LIST: rc = lst_group_list_ioctl((lstio_group_list_args_t *)buf); break; case LSTIO_GROUP_INFO: rc = lst_group_info_ioctl((lstio_group_info_args_t *)buf); break; case LSTIO_BATCH_ADD: rc = lst_batch_add_ioctl((lstio_batch_add_args_t *)buf); break; case LSTIO_BATCH_START: rc = lst_batch_run_ioctl((lstio_batch_run_args_t *)buf); break; case LSTIO_BATCH_STOP: rc = lst_batch_stop_ioctl((lstio_batch_stop_args_t *)buf); break; case LSTIO_BATCH_QUERY: rc = lst_batch_query_ioctl((lstio_batch_query_args_t *)buf); break; case LSTIO_BATCH_LIST: rc = lst_batch_list_ioctl((lstio_batch_list_args_t *)buf); break; case LSTIO_BATCH_INFO: rc = lst_batch_info_ioctl((lstio_batch_info_args_t *)buf); break; case LSTIO_TEST_ADD: rc = lst_test_add_ioctl((lstio_test_args_t *)buf); break; case LSTIO_STAT_QUERY: rc = lst_stat_query_ioctl((lstio_stat_args_t *)buf); break; default: rc = -EINVAL; } if (cfs_copy_to_user(data->ioc_pbuf2, &console_session.ses_trans_stat, sizeof(lstcon_trans_stat_t))) rc = -EFAULT; out: cfs_mutex_up(&console_session.ses_mutex); LIBCFS_FREE(buf, data->ioc_plen1); return rc; }
int lst_test_add_ioctl(lstio_test_args_t *args) { char *name; char *srcgrp = NULL; char *dstgrp = NULL; void *param = NULL; int ret = 0; int rc = -ENOMEM; if (args->lstio_tes_resultp == NULL || args->lstio_tes_retp == NULL || args->lstio_tes_bat_name == NULL || /* no specified batch */ args->lstio_tes_bat_nmlen <= 0 || args->lstio_tes_bat_nmlen > LST_NAME_SIZE || args->lstio_tes_sgrp_name == NULL || /* no source group */ args->lstio_tes_sgrp_nmlen <= 0 || args->lstio_tes_sgrp_nmlen > LST_NAME_SIZE || args->lstio_tes_dgrp_name == NULL || /* no target group */ args->lstio_tes_dgrp_nmlen <= 0 || args->lstio_tes_dgrp_nmlen > LST_NAME_SIZE) return -EINVAL; /* have parameter, check if parameter length is valid */ if (args->lstio_tes_param != NULL && (args->lstio_tes_param_len <= 0 || args->lstio_tes_param_len > CFS_PAGE_SIZE - sizeof(lstcon_test_t))) return -EINVAL; LIBCFS_ALLOC(name, args->lstio_tes_bat_nmlen + 1); if (name == NULL) return rc; LIBCFS_ALLOC(srcgrp, args->lstio_tes_sgrp_nmlen + 1); if (srcgrp == NULL) goto out; LIBCFS_ALLOC(dstgrp, args->lstio_tes_dgrp_nmlen + 1); if (srcgrp == NULL) goto out; if (args->lstio_tes_param != NULL) { LIBCFS_ALLOC(param, args->lstio_tes_param_len); if (param == NULL) goto out; } rc = -EFAULT; if (cfs_copy_from_user(name, args->lstio_tes_bat_name, args->lstio_tes_bat_nmlen) || cfs_copy_from_user(srcgrp, args->lstio_tes_sgrp_name, args->lstio_tes_sgrp_nmlen) || cfs_copy_from_user(dstgrp, args->lstio_tes_dgrp_name, args->lstio_tes_dgrp_nmlen) || cfs_copy_from_user(param, args->lstio_tes_param, args->lstio_tes_param_len)) goto out; rc = lstcon_test_add(name, args->lstio_tes_type, args->lstio_tes_loop, args->lstio_tes_concur, args->lstio_tes_dist, args->lstio_tes_span, srcgrp, dstgrp, param, args->lstio_tes_param_len, &ret, args->lstio_tes_resultp); if (ret != 0) rc = (cfs_copy_to_user(args->lstio_tes_retp, &ret, sizeof(ret))) ? -EFAULT : 0; out: if (name != NULL) LIBCFS_FREE(name, args->lstio_tes_bat_nmlen + 1); if (srcgrp != NULL) LIBCFS_FREE(srcgrp, args->lstio_tes_sgrp_nmlen + 1); if (dstgrp != NULL) LIBCFS_FREE(dstgrp, args->lstio_tes_dgrp_nmlen + 1); if (param != NULL) LIBCFS_FREE(param, args->lstio_tes_param_len); return rc; }
int lst_debug_ioctl(lstio_debug_args_t *args) { char *name = NULL; int client = 1; int rc; if (args->lstio_dbg_key != console_session.ses_key) return -EACCES; if (args->lstio_dbg_resultp == NULL) return -EINVAL; if (args->lstio_dbg_namep != NULL && /* name of batch/group */ (args->lstio_dbg_nmlen <= 0 || args->lstio_dbg_nmlen > LST_NAME_SIZE)) return -EINVAL; if (args->lstio_dbg_namep != NULL) { LIBCFS_ALLOC(name, args->lstio_dbg_nmlen + 1); if (name == NULL) return -ENOMEM; if (cfs_copy_from_user(name, args->lstio_dbg_namep, args->lstio_dbg_nmlen)) { LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1); return -EFAULT; } name[args->lstio_dbg_nmlen] = 0; } rc = -EINVAL; switch (args->lstio_dbg_type) { case LST_OPC_SESSION: rc = lstcon_session_debug(args->lstio_dbg_timeout, args->lstio_dbg_resultp); break; case LST_OPC_BATCHSRV: client = 0; case LST_OPC_BATCHCLI: if (name == NULL) goto out; rc = lstcon_batch_debug(args->lstio_dbg_timeout, name, client, args->lstio_dbg_resultp); break; case LST_OPC_GROUP: if (name == NULL) goto out; rc = lstcon_group_debug(args->lstio_dbg_timeout, name, args->lstio_dbg_resultp); break; case LST_OPC_NODES: if (args->lstio_dbg_count <= 0 || args->lstio_dbg_idsp == NULL) goto out; rc = lstcon_nodes_debug(args->lstio_dbg_timeout, args->lstio_dbg_count, args->lstio_dbg_idsp, args->lstio_dbg_resultp); break; default: break; } out: if (name != NULL) LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1); return rc; }
static int ctx_init_pack_request(struct obd_import *imp, struct ptlrpc_request *req, int lustre_srv, uid_t uid, gid_t gid, long token_size, char __user *token) { struct lustre_msg *msg = req->rq_reqbuf; struct gss_sec *gsec; struct gss_header *ghdr; struct ptlrpc_user_desc *pud; __u32 *p, size, offset = 2; rawobj_t obj; LASSERT(msg->lm_bufcount <= 4); LASSERT(req->rq_cli_ctx); LASSERT(req->rq_cli_ctx->cc_sec); /* gss hdr */ ghdr = lustre_msg_buf(msg, 0, sizeof(*ghdr)); ghdr->gh_version = PTLRPC_GSS_VERSION; ghdr->gh_sp = (__u8) imp->imp_sec->ps_part; ghdr->gh_flags = 0; ghdr->gh_proc = PTLRPC_GSS_PROC_INIT; ghdr->gh_seq = 0; ghdr->gh_svc = SPTLRPC_SVC_NULL; ghdr->gh_handle.len = 0; /* fix the user desc */ if (req->rq_pack_udesc) { ghdr->gh_flags |= LUSTRE_GSS_PACK_USER; pud = lustre_msg_buf(msg, offset, sizeof(*pud)); LASSERT(pud); pud->pud_uid = pud->pud_fsuid = uid; pud->pud_gid = pud->pud_fsgid = gid; pud->pud_cap = 0; pud->pud_ngroups = 0; offset++; } /* security payload */ p = lustre_msg_buf(msg, offset, 0); size = msg->lm_buflens[offset]; LASSERT(p); /* 1. lustre svc type */ LASSERT(size > 4); *p++ = cpu_to_le32(lustre_srv); size -= 4; /* 2. target uuid */ obj.len = strlen(imp->imp_obd->u.cli.cl_target_uuid.uuid) + 1; obj.data = imp->imp_obd->u.cli.cl_target_uuid.uuid; if (rawobj_serialize(&obj, &p, &size)) LBUG(); /* 3. reverse context handle. actually only needed by root user, * but we send it anyway. */ gsec = sec2gsec(req->rq_cli_ctx->cc_sec); obj.len = sizeof(gsec->gs_rvs_hdl); obj.data = (__u8 *) &gsec->gs_rvs_hdl; if (rawobj_serialize(&obj, &p, &size)) LBUG(); /* 4. now the token */ LASSERT(size >= (sizeof(__u32) + token_size)); *p++ = cpu_to_le32(((__u32) token_size)); if (cfs_copy_from_user(p, token, token_size)) { CERROR("can't copy token\n"); return -EFAULT; } size -= sizeof(__u32) + cfs_size_round4(token_size); req->rq_reqdata_len = lustre_shrink_msg(req->rq_reqbuf, offset, msg->lm_buflens[offset] - size, 0); return 0; }
static int __lov_setstripe(struct obd_export *exp, int max_lmm_size, struct lov_stripe_md **lsmp, struct lov_user_md *lump) { struct obd_device *obd = class_exp2obd(exp); struct lov_obd *lov = &obd->u.lov; char buffer[sizeof(struct lov_user_md_v3)]; struct lov_user_md_v3 *lumv3 = (struct lov_user_md_v3 *)&buffer[0]; struct lov_user_md_v1 *lumv1 = (struct lov_user_md_v1 *)&buffer[0]; int lmm_magic; int stripe_count; int rc; ENTRY; if (cfs_copy_from_user(lumv3, lump, sizeof(struct lov_user_md_v1))) RETURN(-EFAULT); lmm_magic = lumv1->lmm_magic; if (lmm_magic == __swab32(LOV_USER_MAGIC_V1)) { lustre_swab_lov_user_md_v1(lumv1); lmm_magic = LOV_USER_MAGIC_V1; } else if (lmm_magic == LOV_USER_MAGIC_V3) { if (cfs_copy_from_user(lumv3, lump, sizeof(*lumv3))) RETURN(-EFAULT); } else if (lmm_magic == __swab32(LOV_USER_MAGIC_V3)) { if (cfs_copy_from_user(lumv3, lump, sizeof(*lumv3))) RETURN(-EFAULT); lustre_swab_lov_user_md_v3(lumv3); lmm_magic = LOV_USER_MAGIC_V3; } else if (lmm_magic != LOV_USER_MAGIC_V1) { CDEBUG(D_IOCTL, "bad userland LOV MAGIC: %#08x != %#08x nor %#08x\n", lmm_magic, LOV_USER_MAGIC_V1, LOV_USER_MAGIC_V3); RETURN(-EINVAL); } /* in the rest of the tests, as *lumv1 and lumv3 have the same * fields, we use lumv1 to avoid code duplication */ if (lumv1->lmm_pattern == 0) { lumv1->lmm_pattern = lov->desc.ld_pattern ? lov->desc.ld_pattern : LOV_PATTERN_RAID0; } if (lumv1->lmm_pattern != LOV_PATTERN_RAID0) { CDEBUG(D_IOCTL, "bad userland stripe pattern: %#x\n", lumv1->lmm_pattern); RETURN(-EINVAL); } /* 64kB is the largest common page size we see (ia64), and matches the * check in lfs */ if (lumv1->lmm_stripe_size & (LOV_MIN_STRIPE_SIZE - 1)) { CDEBUG(D_IOCTL, "stripe size %u not multiple of %u, fixing\n", lumv1->lmm_stripe_size, LOV_MIN_STRIPE_SIZE); lumv1->lmm_stripe_size = LOV_MIN_STRIPE_SIZE; } if ((lumv1->lmm_stripe_offset >= lov->desc.ld_tgt_count) && (lumv1->lmm_stripe_offset != (typeof(lumv1->lmm_stripe_offset))(-1))) { CDEBUG(D_IOCTL, "stripe offset %u > number of OSTs %u\n", lumv1->lmm_stripe_offset, lov->desc.ld_tgt_count); RETURN(-EINVAL); } stripe_count = lov_get_stripecnt(lov, lumv1->lmm_stripe_count); if (max_lmm_size) { int max_stripes = (max_lmm_size - lov_mds_md_size(0, lmm_magic)) / sizeof(struct lov_ost_data_v1); if (unlikely(max_stripes < stripe_count)) { CDEBUG(D_IOCTL, "stripe count reset from %d to %d\n", stripe_count, max_stripes); stripe_count = max_stripes; } } if (lmm_magic == LOV_USER_MAGIC_V3) { struct pool_desc *pool; pool = lov_find_pool(lov, lumv3->lmm_pool_name); if (pool != NULL) { if (lumv3->lmm_stripe_offset != (typeof(lumv3->lmm_stripe_offset))(-1)) { rc = lov_check_index_in_pool( lumv3->lmm_stripe_offset, pool); if (rc < 0) { lov_pool_putref(pool); RETURN(-EINVAL); } } if (stripe_count > pool_tgt_count(pool)) stripe_count = pool_tgt_count(pool); lov_pool_putref(pool); } } rc = lov_alloc_memmd(lsmp, stripe_count, lumv1->lmm_pattern, lmm_magic); if (rc >= 0) { (*lsmp)->lsm_oinfo[0]->loi_ost_idx = lumv1->lmm_stripe_offset; (*lsmp)->lsm_stripe_size = lumv1->lmm_stripe_size; if (lmm_magic == LOV_USER_MAGIC_V3) strncpy((*lsmp)->lsm_pool_name, lumv3->lmm_pool_name, LOV_MAXPOOLNAME); rc = 0; } RETURN(rc); }
/* Retrieve object striping information. * * @lump is a pointer to an in-core struct with lmm_ost_count indicating * the maximum number of OST indices which will fit in the user buffer. * lmm_magic must be LOV_USER_MAGIC. */ int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm, struct lov_user_md *lump) { /* * XXX huge struct allocated on stack. */ /* we use lov_user_md_v3 because it is larger than lov_user_md_v1 */ struct lov_user_md_v3 lum; struct lov_mds_md *lmmk = NULL; int rc, lmm_size; int lum_size; mm_segment_t seg; ENTRY; if (!lsm) RETURN(-ENODATA); /* * "Switch to kernel segment" to allow copying from kernel space by * copy_{to,from}_user(). */ seg = get_fs(); set_fs(KERNEL_DS); /* we only need the header part from user space to get lmm_magic and * lmm_stripe_count, (the header part is common to v1 and v3) */ lum_size = sizeof(struct lov_user_md_v1); if (cfs_copy_from_user(&lum, lump, lum_size)) GOTO(out_set, rc = -EFAULT); else if ((lum.lmm_magic != LOV_USER_MAGIC) && (lum.lmm_magic != LOV_USER_MAGIC_V3)) GOTO(out_set, rc = -EINVAL); if (lum.lmm_stripe_count && (lum.lmm_stripe_count < lsm->lsm_stripe_count)) { /* Return right size of stripe to user */ lum.lmm_stripe_count = lsm->lsm_stripe_count; rc = cfs_copy_to_user(lump, &lum, lum_size); GOTO(out_set, rc = -EOVERFLOW); } rc = lov_packmd(exp, &lmmk, lsm); if (rc < 0) GOTO(out_set, rc); lmm_size = rc; rc = 0; /* FIXME: Bug 1185 - copy fields properly when structs change */ /* struct lov_user_md_v3 and struct lov_mds_md_v3 must be the same */ CLASSERT(sizeof(lum) == sizeof(struct lov_mds_md_v3)); CLASSERT(sizeof lum.lmm_objects[0] == sizeof lmmk->lmm_objects[0]); if ((cpu_to_le32(LOV_MAGIC) != LOV_MAGIC) && ((lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) || (lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)))) { lustre_swab_lov_mds_md(lmmk); lustre_swab_lov_user_md_objects( (struct lov_user_ost_data*)lmmk->lmm_objects, lmmk->lmm_stripe_count); } if (lum.lmm_magic == LOV_USER_MAGIC) { /* User request for v1, we need skip lmm_pool_name */ if (lmmk->lmm_magic == LOV_MAGIC_V3) { memmove((char*)(&lmmk->lmm_stripe_count) + sizeof(lmmk->lmm_stripe_count), ((struct lov_mds_md_v3*)lmmk)->lmm_objects, lmmk->lmm_stripe_count * sizeof(struct lov_ost_data_v1)); lmm_size -= LOV_MAXPOOLNAME; } } else { /* if v3 we just have to update the lum_size */ lum_size = sizeof(struct lov_user_md_v3); } /* User wasn't expecting this many OST entries */ if (lum.lmm_stripe_count == 0) lmm_size = lum_size; else if (lum.lmm_stripe_count < lmmk->lmm_stripe_count) GOTO(out_set, rc = -EOVERFLOW); /* * Have a difference between lov_mds_md & lov_user_md. * So we have to re-order the data before copy to user. */ lum.lmm_stripe_count = lmmk->lmm_stripe_count; ((struct lov_user_md*)lmmk)->lmm_stripe_offset = 0; ((struct lov_user_md*)lmmk)->lmm_stripe_count = lum.lmm_stripe_count; if (cfs_copy_to_user(lump, lmmk, lmm_size)) rc = -EFAULT; obd_free_diskmd(exp, &lmmk); out_set: set_fs(seg); RETURN(rc); }
int gss_do_ctx_init_rpc(__user char *buffer, unsigned long count) { struct obd_import *imp; struct ptlrpc_request *req; struct lgssd_ioctl_param param; struct obd_device *obd; char obdname[64]; long lsize; int rc; if (count != sizeof(param)) { CERROR("ioctl size %lu, expect %lu, please check lgss_keyring " "version\n", count, (unsigned long) sizeof(param)); RETURN(-EINVAL); } if (cfs_copy_from_user(¶m, buffer, sizeof(param))) { CERROR("failed copy data from lgssd\n"); RETURN(-EFAULT); } if (param.version != GSSD_INTERFACE_VERSION) { CERROR("gssd interface version %d (expect %d)\n", param.version, GSSD_INTERFACE_VERSION); RETURN(-EINVAL); } /* take name */ if (strncpy_from_user(obdname, param.uuid, sizeof(obdname)) <= 0) { CERROR("Invalid obdname pointer\n"); RETURN(-EFAULT); } obd = class_name2obd(obdname); if (!obd) { CERROR("no such obd %s\n", obdname); RETURN(-EINVAL); } if (unlikely(!obd->obd_set_up)) { CERROR("obd %s not setup\n", obdname); RETURN(-EINVAL); } cfs_spin_lock(&obd->obd_dev_lock); if (obd->obd_stopping) { CERROR("obd %s has stopped\n", obdname); cfs_spin_unlock(&obd->obd_dev_lock); RETURN(-EINVAL); } if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) && strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) && strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) { CERROR("obd %s is not a client device\n", obdname); cfs_spin_unlock(&obd->obd_dev_lock); RETURN(-EINVAL); } cfs_spin_unlock(&obd->obd_dev_lock); cfs_down_read(&obd->u.cli.cl_sem); if (obd->u.cli.cl_import == NULL) { CERROR("obd %s: import has gone\n", obd->obd_name); cfs_up_read(&obd->u.cli.cl_sem); RETURN(-EINVAL); } imp = class_import_get(obd->u.cli.cl_import); cfs_up_read(&obd->u.cli.cl_sem); if (imp->imp_deactive) { CERROR("import has been deactivated\n"); class_import_put(imp); RETURN(-EINVAL); } req = ptlrpc_request_alloc_pack(imp, &RQF_SEC_CTX, LUSTRE_OBD_VERSION, SEC_CTX_INIT); if (req == NULL) { param.status = -ENOMEM; goto out_copy; } if (req->rq_cli_ctx->cc_sec->ps_id != param.secid) { CWARN("original secid %d, now has changed to %d, " "cancel this negotiation\n", param.secid, req->rq_cli_ctx->cc_sec->ps_id); param.status = -EINVAL; goto out_copy; } /* get token */ rc = ctx_init_pack_request(imp, req, param.lustre_svc, param.uid, param.gid, param.send_token_size, param.send_token); if (rc) { param.status = rc; goto out_copy; } ptlrpc_request_set_replen(req); rc = ptlrpc_queue_wait(req); if (rc) { /* If any _real_ denial be made, we expect server return * -EACCES reply or return success but indicate gss error * inside reply messsage. All other errors are treated as * timeout, caller might try the negotiation repeatedly, * leave recovery decisions to general ptlrpc layer. * * FIXME maybe some other error code shouldn't be treated * as timeout. */ param.status = rc; if (rc != -EACCES) param.status = -ETIMEDOUT; goto out_copy; } LASSERT(req->rq_repdata); lsize = ctx_init_parse_reply(req->rq_repdata, ptlrpc_rep_need_swab(req), param.reply_buf, param.reply_buf_size); if (lsize < 0) { param.status = (int) lsize; goto out_copy; } param.status = 0; param.reply_length = lsize; out_copy: if (cfs_copy_to_user(buffer, ¶m, sizeof(param))) rc = -EFAULT; else rc = 0; class_import_put(imp); ptlrpc_req_finished(req); RETURN(rc); }