size_t count, loff_t *off)
{
struct lu_server_seq *seq = ((struct seq_file *)file->private_data)->private;
- int rc, val;
+ int rc;
+ __s64 val;
ENTRY;
LASSERT(seq != NULL);
mutex_lock(&seq->lss_mutex);
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc != 0) {
- CERROR("%s: invalid width.\n", seq->lss_name);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc) {
+ CERROR("%s: invalid FID sequence width: rc = %d\n",
+ seq->lss_name, rc);
GOTO(out_unlock, count = rc);
}
+ if (val < 0) {
+ CERROR("%s: invalid FID sequence width: rc = %d\n",
+ seq->lss_name, -ERANGE);
+ GOTO(out_unlock, count = -ERANGE);
+ }
+
seq->lss_width = val;
CDEBUG(D_INFO, "%s: Width: "LPU64"\n",
size_t count, loff_t *off)
{
struct lu_client_seq *seq = ((struct seq_file *)file->private_data)->private;
- __u64 max;
- int rc, val;
+ __u64 max;
+ int rc;
+ __s64 val;
ENTRY;
LASSERT(seq != NULL);
mutex_lock(&seq->lcs_mutex);
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc) {
- mutex_unlock(&seq->lcs_mutex);
- RETURN(rc);
+ GOTO(out_unlock, count = rc);
}
if (seq->lcs_type == LUSTRE_SEQ_DATA)
CDEBUG(D_INFO, "%s: Sequence size: "LPU64"\n",
seq->lcs_name, seq->lcs_width);
+ } else {
+ GOTO(out_unlock, count = -ERANGE);
}
- mutex_unlock(&seq->lcs_mutex);
+out_unlock:
+ mutex_unlock(&seq->lcs_mutex);
RETURN(count);
}
extern int lprocfs_filestotal_seq_show(struct seq_file *m, void *data);
extern int lprocfs_filesfree_seq_show(struct seq_file *m, void *data);
-extern int lprocfs_write_helper(const char __user *buffer, unsigned long count,
- int *val);
-extern int lprocfs_write_frac_helper(const char __user *buffer,
- unsigned long count,
- int *val, int mult);
extern int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult);
extern int lprocfs_read_frac_helper(char *buffer, unsigned long count,
long val, int mult);
-extern int lprocfs_write_u64_helper(const char __user *buffer,
- unsigned long count, __u64 *val);
-extern int lprocfs_write_frac_u64_helper(const char __user *buffer,
- unsigned long count,
- __u64 *val, int mult);
+extern int lprocfs_str_to_s64(const char __user *buffer, unsigned long count,
+ __s64 *val);
+extern int lprocfs_str_with_units_to_s64(const char __user *buffer,
+ unsigned long count, __s64 *val,
+ char defunit);
char *lprocfs_find_named_value(const char *buffer, const char *name,
size_t *count);
void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value);
struct lfsck_query *que);
int lfsck_get_speed(struct seq_file *m, struct dt_device *key);
-int lfsck_set_speed(struct dt_device *key, int val);
+int lfsck_set_speed(struct dt_device *key, __u32 val);
int lfsck_get_windows(struct seq_file *m, struct dt_device *key);
int lfsck_set_windows(struct dt_device *key, int val);
const char __user *buffer, size_t count,
loff_t *off)
{
+ __s64 value;
__u64 watermark;
__u64 *data = ((struct seq_file *)file->private_data)->private;
bool wm_low = (data == &ldlm_reclaim_threshold_mb) ? true : false;
int rc;
- rc = lprocfs_write_frac_u64_helper(buffer, count, &watermark, 1 << 20);
+ rc = lprocfs_str_with_units_to_s64(buffer, count, &value, 'M');
if (rc) {
CERROR("Failed to set %s, rc = %d.\n",
wm_low ? "lock_reclaim_threshold_mb" : "lock_limit_mb",
rc);
return rc;
- } else if (watermark != 0 && watermark < (1 << 20)) {
+ } else if (value != 0 && value < (1 << 20)) {
CERROR("%s should be greater than 1MB.\n",
wm_low ? "lock_reclaim_threshold_mb" : "lock_limit_mb");
return -EINVAL;
}
- watermark >>= 20;
+ watermark = value >> 20;
if (wm_low) {
if (ldlm_lock_limit_mb != 0 && watermark > ldlm_lock_limit_mb) {
}
EXPORT_SYMBOL(lfsck_get_speed);
-int lfsck_set_speed(struct dt_device *key, int val)
+int lfsck_set_speed(struct dt_device *key, __u32 val)
{
struct lu_env env;
struct lfsck_instance *lfsck;
{
struct seq_file *m = file->private_data;
struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private);
- int val, rc;
+ __s64 val;
+ int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
struct seq_file *m = file->private_data;
struct super_block *sb = m->private;
struct ll_sb_info *sbi = ll_s2sbi(sb);
- __u64 val;
- long pages_number;
- int pages_shift;
+ __s64 pages_number;
int rc;
- pages_shift = 20 - PAGE_CACHE_SHIFT;
- rc = lprocfs_write_frac_u64_helper(buffer, count, &val,
- 1 << pages_shift);
+ rc = lprocfs_str_with_units_to_s64(buffer, count, &pages_number, 'M');
if (rc)
return rc;
- if (val > LONG_MAX)
- return -ERANGE;
- pages_number = (long)val;
+ pages_number >>= PAGE_CACHE_SHIFT;
if (pages_number < 0 || pages_number > totalram_pages / 2) {
/* 1/2 of RAM */
CERROR("%s: can't set max_readahead_mb=%lu > %luMB\n",
- ll_get_fsname(sb, NULL, 0), pages_number >> pages_shift,
- totalram_pages >> (pages_shift + 1));
+ ll_get_fsname(sb, NULL, 0),
+ (unsigned long)pages_number >> (20 - PAGE_CACHE_SHIFT),
+ totalram_pages >> (20 - PAGE_CACHE_SHIFT + 1));
return -ERANGE;
}
struct seq_file *m = file->private_data;
struct super_block *sb = m->private;
struct ll_sb_info *sbi = ll_s2sbi(sb);
- int pages_shift, rc, pages_number;
+ int rc;
+ __s64 pages_number;
- pages_shift = 20 - PAGE_CACHE_SHIFT;
- rc = lprocfs_write_frac_helper(buffer, count, &pages_number,
- 1 << pages_shift);
+ rc = lprocfs_str_with_units_to_s64(buffer, count, &pages_number, 'M');
if (rc)
return rc;
+ pages_number >>= PAGE_CACHE_SHIFT;
+
if (pages_number < 0 || pages_number > sbi->ll_ra_info.ra_max_pages) {
- CERROR("%s: can't set max_readahead_per_file_mb=%u > "
+ CERROR("%s: can't set max_readahead_per_file_mb=%lu > "
"max_read_ahead_mb=%lu\n", ll_get_fsname(sb, NULL, 0),
- pages_number >> pages_shift,
- sbi->ll_ra_info.ra_max_pages >> pages_shift);
+ (unsigned long)pages_number >> (20 - PAGE_CACHE_SHIFT),
+ sbi->ll_ra_info.ra_max_pages >> (20 - PAGE_CACHE_SHIFT));
return -ERANGE;
}
struct seq_file *m = file->private_data;
struct super_block *sb = m->private;
struct ll_sb_info *sbi = ll_s2sbi(sb);
- int pages_shift, rc, pages_number;
+ int rc;
+ __s64 pages_number;
- pages_shift = 20 - PAGE_CACHE_SHIFT;
- rc = lprocfs_write_frac_helper(buffer, count, &pages_number,
- 1 << pages_shift);
+ rc = lprocfs_str_with_units_to_s64(buffer, count, &pages_number, 'M');
if (rc)
return rc;
+ pages_number >>= PAGE_CACHE_SHIFT;
+
/* Cap this at the current max readahead window size, the readahead
* algorithm does this anyway so it's pointless to set it larger. */
if (pages_number < 0 ||
pages_number > sbi->ll_ra_info.ra_max_pages_per_file) {
- CERROR("%s: can't set max_read_ahead_whole_mb=%u > "
+ int pages_shift = 20 - PAGE_CACHE_SHIFT;
+ CERROR("%s: can't set max_read_ahead_whole_mb=%lu > "
"max_read_ahead_per_file_mb=%lu\n",
ll_get_fsname(sb, NULL, 0),
- pages_number >> pages_shift,
+ (unsigned long)pages_number >> pages_shift,
sbi->ll_ra_info.ra_max_pages_per_file >> pages_shift);
return -ERANGE;
}
struct ll_sb_info *sbi = ll_s2sbi(sb);
struct cl_client_cache *cache = sbi->ll_cache;
struct lu_env *env;
- __u64 val;
long diff = 0;
long nrpages = 0;
- long pages_number;
__u16 refcheck;
- int mult;
+ __s64 pages_number;
long rc;
char kernbuf[128];
ENTRY;
RETURN(-EFAULT);
kernbuf[count] = 0;
- mult = 1 << (20 - PAGE_CACHE_SHIFT);
buffer += lprocfs_find_named_value(kernbuf, "max_cached_mb:", &count) -
kernbuf;
- rc = lprocfs_write_frac_u64_helper(buffer, count, &val, mult);
+ rc = lprocfs_str_with_units_to_s64(buffer, count, &pages_number, 'M');
if (rc)
RETURN(rc);
- if (val > LONG_MAX)
- return -ERANGE;
- pages_number = (long)val;
+ pages_number >>= PAGE_CACHE_SHIFT;
if (pages_number < 0 || pages_number > totalram_pages) {
CERROR("%s: can't set max cache more than %lu MB\n",
{
struct seq_file *m = file->private_data;
struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private);
- int val, rc;
+ int rc;
+ __s64 val;
- if (!sbi->ll_dt_exp)
- /* Not set up yet */
- return -EAGAIN;
+ if (!sbi->ll_dt_exp)
+ /* Not set up yet */
+ return -EAGAIN;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc)
- return rc;
- if (val)
- sbi->ll_flags |= LL_SBI_CHECKSUM;
- else
- sbi->ll_flags &= ~LL_SBI_CHECKSUM;
-
- rc = obd_set_info_async(NULL, sbi->ll_dt_exp, sizeof(KEY_CHECKSUM),
- KEY_CHECKSUM, sizeof(val), &val, NULL);
- if (rc)
- CWARN("Failed to set OSC checksum flags: %d\n", rc);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
+ if (val)
+ sbi->ll_flags |= LL_SBI_CHECKSUM;
+ else
+ sbi->ll_flags &= ~LL_SBI_CHECKSUM;
- return count;
+ rc = obd_set_info_async(NULL, sbi->ll_dt_exp, sizeof(KEY_CHECKSUM),
+ KEY_CHECKSUM, sizeof(val), &val, NULL);
+ if (rc)
+ CWARN("Failed to set OSC checksum flags: %d\n", rc);
+
+ return count;
}
LPROC_SEQ_FOPS(ll_checksum);
void *data, enum stats_track_type type)
{
struct super_block *sb = data;
- int rc, pid;
+ int rc;
+ __s64 pid;
- rc = lprocfs_write_helper(buffer, count, &pid);
- if (rc)
- return rc;
- ll_s2sbi(sb)->ll_stats_track_id = pid;
- if (pid == 0)
- ll_s2sbi(sb)->ll_stats_track_type = STATS_TRACK_ALL;
- else
- ll_s2sbi(sb)->ll_stats_track_type = type;
- lprocfs_clear_stats(ll_s2sbi(sb)->ll_stats);
- return count;
+ rc = lprocfs_str_to_s64(buffer, count, &pid);
+ if (rc)
+ return rc;
+ if (pid > INT_MAX || pid < 0)
+ return -ERANGE;
+
+ ll_s2sbi(sb)->ll_stats_track_id = pid;
+ if (pid == 0)
+ ll_s2sbi(sb)->ll_stats_track_type = STATS_TRACK_ALL;
+ else
+ ll_s2sbi(sb)->ll_stats_track_type = type;
+ lprocfs_clear_stats(ll_s2sbi(sb)->ll_stats);
+ return count;
}
static int ll_track_pid_seq_show(struct seq_file *m, void *v)
{
struct seq_file *m = file->private_data;
struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private);
- int val, rc;
+ int rc;
+ __s64 val;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc)
- return rc;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
- if (val >= 0 && val <= LL_SA_RPC_MAX)
- sbi->ll_sa_max = val;
- else
- CERROR("Bad statahead_max value %d. Valid values are in the "
- "range [0, %d]\n", val, LL_SA_RPC_MAX);
+ if (val >= 0 && val <= LL_SA_RPC_MAX)
+ sbi->ll_sa_max = val;
+ else
+ CERROR("Bad statahead_max value "LPD64". Valid values are in "
+ "the range [0, %d]\n", val, LL_SA_RPC_MAX);
- return count;
+ return count;
}
LPROC_SEQ_FOPS(ll_statahead_max);
{
struct seq_file *m = file->private_data;
struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private);
- int val, rc;
+ int rc;
+ __s64 val;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc)
- return rc;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
- if (val)
- sbi->ll_flags |= LL_SBI_AGL_ENABLED;
- else
- sbi->ll_flags &= ~LL_SBI_AGL_ENABLED;
+ if (val)
+ sbi->ll_flags |= LL_SBI_AGL_ENABLED;
+ else
+ sbi->ll_flags &= ~LL_SBI_AGL_ENABLED;
- return count;
+ return count;
}
LPROC_SEQ_FOPS(ll_statahead_agl);
{
struct seq_file *m = file->private_data;
struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)m->private);
- int val, rc;
+ int rc;
+ __s64 val;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc)
- return rc;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
- if (val)
- sbi->ll_flags |= LL_SBI_LAZYSTATFS;
- else
- sbi->ll_flags &= ~LL_SBI_LAZYSTATFS;
+ if (val)
+ sbi->ll_flags |= LL_SBI_LAZYSTATFS;
+ else
+ sbi->ll_flags &= ~LL_SBI_LAZYSTATFS;
- return count;
+ return count;
}
LPROC_SEQ_FOPS(ll_lazystatfs);
const char __user *buffer,
size_t count, loff_t *unused)
{
- struct seq_file *seq = file->private_data;
- struct super_block *sb = (struct super_block *)seq->private;
- struct ll_sb_info *sbi = ll_s2sbi(sb);
- int val;
- int rc;
+ struct seq_file *seq = file->private_data;
+ struct super_block *sb = (struct super_block *)seq->private;
+ struct ll_sb_info *sbi = ll_s2sbi(sb);
+ __s64 val;
+ int rc;
if (count == 0)
return 0;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc < 0)
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
return rc;
+ if (val < 0 || val > INT_MAX)
+ return -ERANGE;
rc = ll_set_default_mdsize(sbi, val);
if (rc)
struct seq_file *seq = file->private_data;
struct ll_sb_info *sbi = ll_s2sbi((struct super_block *)seq->private);
char kernbuf[128];
- int val, rc;
+ int rc;
+ __s64 val;
if (count == 0)
return 0;
buffer += lprocfs_find_named_value(kernbuf, "unstable_check:", &count) -
kernbuf;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc < 0)
return rc;
struct ll_sb_info *sbi = seq->private;
struct ll_rw_extents_info *io_extents = &sbi->ll_rw_extents_info;
int i;
- int value = 1, rc = 0;
+ __s64 value = 1;
+ int rc = 0;
if (len == 0)
return -EINVAL;
- rc = lprocfs_write_helper(buf, len, &value);
+ rc = lprocfs_str_to_s64(buf, len, &value);
if (rc < 0 && len < 16) {
char kernbuf[16];
struct ll_sb_info *sbi = seq->private;
struct ll_rw_extents_info *io_extents = &sbi->ll_rw_extents_info;
int i;
- int value = 1, rc = 0;
+ __s64 value = 1;
+ int rc = 0;
if (len == 0)
return -EINVAL;
- rc = lprocfs_write_helper(buf, len, &value);
+ rc = lprocfs_str_to_s64(buf, len, &value);
if (rc < 0 && len < 16) {
char kernbuf[16];
struct ll_sb_info *sbi = seq->private;
struct ll_rw_process_info *process_info = sbi->ll_rw_process_info;
struct ll_rw_process_info *offset_info = sbi->ll_rw_offset_info;
- int value = 1, rc = 0;
+ __s64 value = 1;
+ int rc = 0;
if (len == 0)
return -EINVAL;
- rc = lprocfs_write_helper(buf, len, &value);
+ rc = lprocfs_str_to_s64(buf, len, &value);
if (rc < 0 && len < 16) {
char kernbuf[16];
lod_stripesize_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
+ struct seq_file *m = file->private_data;
struct obd_device *dev = m->private;
struct lod_device *lod;
- __u64 val;
+ __s64 val;
int rc;
LASSERT(dev != NULL);
lod = lu2lod_dev(dev->obd_lu_dev);
- rc = lprocfs_write_u64_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
+ if (val < 0)
+ return -ERANGE;
lod_fix_desc_stripe_size(&val);
lod->lod_desc.ld_default_stripe_size = val;
+
return count;
}
LPROC_SEQ_FOPS(lod_stripesize);
lod_stripeoffset_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
+ struct seq_file *m = file->private_data;
struct obd_device *dev = m->private;
struct lod_device *lod;
- __u64 val;
+ __s64 val;
int rc;
LASSERT(dev != NULL);
lod = lu2lod_dev(dev->obd_lu_dev);
- rc = lprocfs_write_u64_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
+ if (val < 0)
+ return -ERANGE;
lod->lod_desc.ld_default_stripe_offset = val;
+
return count;
}
LPROC_SEQ_FOPS(lod_stripeoffset);
lod_stripetype_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
+ struct seq_file *m = file->private_data;
struct obd_device *dev = m->private;
struct lod_device *lod;
- int val, rc;
+ int rc;
+ __u32 pattern;
+ __s64 val;
LASSERT(dev != NULL);
lod = lu2lod_dev(dev->obd_lu_dev);
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
+ if (val < 0)
+ return -ERANGE;
+
+ pattern = val;
+ lod_fix_desc_pattern(&pattern);
+ lod->lod_desc.ld_pattern = pattern;
- lod_fix_desc_pattern(&val);
- lod->lod_desc.ld_pattern = val;
return count;
}
LPROC_SEQ_FOPS(lod_stripetype);
lod_stripecount_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
+ struct seq_file *m = file->private_data;
struct obd_device *dev = m->private;
struct lod_device *lod;
- int val, rc;
+ int rc;
+ __s64 val;
+ __u32 stripe_count;
LASSERT(dev != NULL);
lod = lu2lod_dev(dev->obd_lu_dev);
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
+ if (val < 0)
+ return -ERANGE;
+
+ stripe_count = val;
+ lod_fix_desc_stripe_count(&stripe_count);
+ lod->lod_desc.ld_default_stripe_count = stripe_count;
- lod_fix_desc_stripe_count(&val);
- lod->lod_desc.ld_default_stripe_count = val;
return count;
}
LPROC_SEQ_FOPS(lod_stripecount);
lod_qos_priofree_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
+ struct seq_file *m = file->private_data;
struct obd_device *dev = m->private;
struct lod_device *lod;
- int val, rc;
+ int rc;
+ __s64 val;
LASSERT(dev != NULL);
lod = lu2lod_dev(dev->obd_lu_dev);
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
- if (val > 100)
+ if (val < 0 || val > 100)
return -EINVAL;
lod->lod_qos.lq_prio_free = (val << 8) / 100;
lod->lod_qos.lq_dirty = 1;
lod->lod_qos.lq_reset = 1;
+
return count;
}
LPROC_SEQ_FOPS(lod_qos_priofree);
lod_qos_thresholdrr_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
+ struct seq_file *m = file->private_data;
struct obd_device *dev = m->private;
struct lod_device *lod;
- int val, rc;
+ int rc;
+ __s64 val;
LASSERT(dev != NULL);
lod = lu2lod_dev(dev->obd_lu_dev);
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_with_units_to_s64(buffer, count, &val, '%');
if (rc)
return rc;
lod->lod_qos.lq_threshold_rr = (val << 8) / 100;
lod->lod_qos.lq_dirty = 1;
+
return count;
}
LPROC_SEQ_FOPS(lod_qos_thresholdrr);
lod_qos_maxage_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *dev = m->private;
- struct lustre_cfg_bufs bufs;
- struct lod_device *lod;
- struct lu_device *next;
- struct lustre_cfg *lcfg;
- char str[32];
- unsigned int i;
- int val, rc;
+ struct seq_file *m = file->private_data;
+ struct obd_device *dev = m->private;
+ struct lustre_cfg_bufs bufs;
+ struct lod_device *lod;
+ struct lu_device *next;
+ struct lustre_cfg *lcfg;
+ char str[32];
+ unsigned int i;
+ int rc;
+ __s64 val;
LASSERT(dev != NULL);
lod = lu2lod_dev(dev->obd_lu_dev);
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
* propogate the value down to OSPs
*/
lustre_cfg_bufs_reset(&bufs, NULL);
- sprintf(str, "%smaxage=%d", PARAM_OSP, val);
+ snprintf(str, 32, "%smaxage=%u", PARAM_OSP, (__u32)val);
lustre_cfg_bufs_set_string(&bufs, 1, str);
lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
if (lcfg == NULL)
lod_lmv_failout_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *dev = m->private;
- struct lod_device *lod;
- int val = 0;
- int rc;
+ struct seq_file *m = file->private_data;
+ struct obd_device *dev = m->private;
+ struct lod_device *lod;
+ __s64 val = 0;
+ int rc;
LASSERT(dev != NULL);
lod = lu2lod_dev(dev->obd_lu_dev);
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc != 0)
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
return rc;
- if (val != 0)
- lod->lod_lmv_failout = 1;
- else
- lod->lod_lmv_failout = 0;
+ lod->lod_lmv_failout = !!val;
return count;
}
size_t count, loff_t *off)
{
struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
- struct lov_desc *desc;
- __u64 val;
- int rc;
-
- LASSERT(dev != NULL);
- desc = &dev->u.lov.desc;
- rc = lprocfs_write_u64_helper(buffer, count, &val);
- if (rc)
- return rc;
-
- lov_fix_desc_stripe_size(&val);
- desc->ld_default_stripe_size = val;
- return count;
+ struct lov_desc *desc;
+ __s64 val;
+ int rc;
+
+ LASSERT(dev != NULL);
+ desc = &dev->u.lov.desc;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
+ if (val < 0)
+ return -ERANGE;
+
+ lov_fix_desc_stripe_size(&val);
+ desc->ld_default_stripe_size = val;
+
+ return count;
}
LPROC_SEQ_FOPS(lov_stripesize);
size_t count, loff_t *off)
{
struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
- struct lov_desc *desc;
- __u64 val;
- int rc;
-
- LASSERT(dev != NULL);
- desc = &dev->u.lov.desc;
- rc = lprocfs_write_u64_helper(buffer, count, &val);
- if (rc)
- return rc;
-
- desc->ld_default_stripe_offset = val;
- return count;
+ struct lov_desc *desc;
+ __s64 val;
+ int rc;
+
+ LASSERT(dev != NULL);
+ desc = &dev->u.lov.desc;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
+ if (val < 0)
+ return -ERANGE;
+
+ desc->ld_default_stripe_offset = val;
+
+ return count;
}
LPROC_SEQ_FOPS(lov_stripeoffset);
size_t count, loff_t *off)
{
struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
- struct lov_desc *desc;
- int val, rc;
-
- LASSERT(dev != NULL);
- desc = &dev->u.lov.desc;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc)
- return rc;
-
- lov_fix_desc_pattern(&val);
- desc->ld_pattern = val;
- return count;
+ struct lov_desc *desc;
+ int pattern, rc;
+ __s64 val;
+
+ LASSERT(dev != NULL);
+ desc = &dev->u.lov.desc;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
+ if (val < INT_MIN || val > INT_MAX)
+ return -ERANGE;
+
+ pattern = val;
+ lov_fix_desc_pattern(&pattern);
+ desc->ld_pattern = pattern;
+
+ return count;
}
LPROC_SEQ_FOPS(lov_stripetype);
size_t count, loff_t *off)
{
struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
- struct lov_desc *desc;
- int val, rc;
-
- LASSERT(dev != NULL);
- desc = &dev->u.lov.desc;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc)
- return rc;
-
- lov_fix_desc_stripe_count(&val);
- desc->ld_default_stripe_count = val;
- return count;
+ struct lov_desc *desc;
+ int rc;
+ __u32 stripe_count;
+ __s64 val;
+
+ LASSERT(dev != NULL);
+ desc = &dev->u.lov.desc;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
+ if (val < 0)
+ return -ERANGE;
+
+ stripe_count = val;
+ lov_fix_desc_stripe_count(&stripe_count);
+ desc->ld_default_stripe_count = stripe_count;
+
+ return count;
}
LPROC_SEQ_FOPS(lov_stripecount);
size_t count, loff_t *off)
{
struct obd_device *dev;
- int val, rc;
+ int rc;
+ __s64 val;
dev = ((struct seq_file *)file->private_data)->private;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
if (val < 0 || val > 1)
if (dev->u.cli.cl_import->imp_deactive == val)
rc = ptlrpc_set_import_active(dev->u.cli.cl_import, val);
else
- CDEBUG(D_CONFIG, "activate %d: ignoring repeat request\n", val);
+ CDEBUG(D_CONFIG, "activate "LPD64": ignoring repeat request\n",
+ val);
return count;
}
loff_t *off)
{
struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
- int val;
+ __s64 val;
int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc == 0)
- rc = obd_set_max_rpcs_in_flight(&dev->u.cli, val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
- if (rc != 0)
- count = rc;
+ if (val < 0 || val > UINT_MAX)
+ return -ERANGE;
+
+ rc = obd_set_max_rpcs_in_flight(&dev->u.cli, val);
+ if (rc)
+ return rc;
return count;
}
{
struct obd_device *dev =
((struct seq_file *)file->private_data)->private;
- int val;
+ __s64 val;
int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc != 0)
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
return rc;
if (val < 0 || val > USHRT_MAX)
return -ERANGE;
rc = obd_set_max_mod_rpcs_in_flight(&dev->u.cli, val);
- if (rc != 0)
+ if (rc)
count = rc;
return count;
{
struct seq_file *m = file->private_data;
struct mdd_device *mdd = m->private;
- int val, rc;
+ int rc;
+ __s64 val;
- LASSERT(mdd != NULL);
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc)
- return rc;
+ LASSERT(mdd != NULL);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
- mdd->mdd_sync_permission = !!val;
- return count;
+ mdd->mdd_sync_permission = !!val;
+
+ return count;
}
LPROC_SEQ_FOPS(mdd_sync_perm);
{
struct seq_file *m = file->private_data;
struct mdd_device *mdd = m->private;
- __u32 val;
+ __s64 val;
int rc;
LASSERT(mdd != NULL);
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc != 0)
return rc;
+ if (val < 0 || val > INT_MAX)
+ return -ERANGE;
rc = lfsck_set_speed(mdd->mdd_bottom, val);
return rc != 0 ? rc : count;
{
struct seq_file *m = file->private_data;
struct mdd_device *mdd = m->private;
- __u32 val;
+ __s64 val;
int rc;
LASSERT(mdd != NULL);
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc == 0)
- rc = lfsck_set_windows(mdd->mdd_bottom, val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
+ if (val < 0 || val > INT_MAX)
+ return -ERANGE;
+
+ rc = lfsck_set_windows(mdd->mdd_bottom, val);
return rc != 0 ? rc : count;
}
struct seq_file *m = file->private_data; \
struct mdt_device *mdt = m->private; \
struct coordinator *cdt = &mdt->mdt_coordinator; \
- int val; \
+ __s64 val; \
int rc; \
ENTRY; \
\
- rc = lprocfs_write_helper(buffer, count, &val); \
+ rc = lprocfs_str_to_s64(buffer, count, &val); \
if (rc) \
RETURN(rc); \
- if (val > 0) { \
+ if (val > 0 && val < INT_MAX) { \
cdt->VAR = val; \
RETURN(count); \
} \
struct seq_file *m = file->private_data;
struct obd_device *obd = m->private;
struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
- int rc, val;
+ int rc;
+ __s64 val;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
+ if (val < 0 || val > INT_MAX)
+ return -ERANGE;
mdt->mdt_identity_cache->uc_entry_expire = val;
+
return count;
}
LPROC_SEQ_FOPS(mdt_identity_expire);
struct seq_file *m = file->private_data;
struct obd_device *obd = m->private;
struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
- int rc, val;
+ int rc;
+ __s64 val;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
+ if (val < 0 || val > INT_MAX)
+ return -ERANGE;
mdt->mdt_identity_cache->uc_acquire_expire = val;
+
return count;
}
LPROC_SEQ_FOPS(mdt_identity_acquire_expire);
struct seq_file *m = file->private_data;
struct obd_device *obd = m->private;
struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
- int rc, uid;
+ int rc;
+ __s64 uid;
- rc = lprocfs_write_helper(buffer, count, &uid);
+ rc = lprocfs_str_to_s64(buffer, count, &uid);
if (rc)
return rc;
+ if (uid < INT_MIN || uid > INT_MAX)
+ return -ERANGE;
mdt_flush_identity(mdt->mdt_identity_cache, uid);
return count;
struct seq_file *m = file->private_data;
struct obd_device *obd = m->private;
struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
- int val, rc;
+ __s64 val;
+ int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
mdt->mdt_opts.mo_evict_tgt_nids = !!val;
struct seq_file *m = file->private_data;
struct obd_device *obd = m->private;
struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
- int val, rc;
+ int rc;
+ __s64 val;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc)
- return rc;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
- if (val > LUSTRE_SEC_ALL || val < LUSTRE_SEC_NONE)
- return -EINVAL;
+ if (val > LUSTRE_SEC_ALL || val < LUSTRE_SEC_NONE)
+ return -EINVAL;
- if (val == LUSTRE_SEC_SPECIFY) {
- CWARN("security level %d will be supported in future.\n",
- LUSTRE_SEC_SPECIFY);
- return -EINVAL;
- }
+ if (val == LUSTRE_SEC_SPECIFY) {
+ CWARN("security level %d will be supported in future.\n",
+ LUSTRE_SEC_SPECIFY);
+ return -EINVAL;
+ }
mdt->mdt_lut.lut_sec_level = val;
+
return count;
}
LPROC_SEQ_FOPS(mdt_sec_level);
struct seq_file *m = file->private_data;
struct obd_device *obd = m->private;
struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
- int val, rc;
+ int rc;
+ __s64 val;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
+ if (val < INT_MIN || val > INT_MAX)
+ return -ERANGE;
+
mdt_enable_cos(mdt, val);
return count;
}
struct seq_file *m = file->private_data;
struct obd_device *obd = m->private;
struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
- __u32 val;
+ __s64 val;
int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
- if (val > 1)
+ if (val > 1 || val < 0)
return -ERANGE;
mdt->mdt_enable_remote_dir = val;
struct seq_file *m = file->private_data;
struct obd_device *obd = m->private;
struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
- __u32 val;
+ __s64 val;
int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
struct seq_file *m = file->private_data;
struct obd_device *obd = m->private;
struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
- int val;
+ __s64 val;
int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
+ if (val < INT_MIN || val > INT_MAX)
+ return -ERANGE;
+
atomic_set(&mdt->mdt_async_commit_count, val);
return count;
struct seq_file *m = file->private_data;
struct obd_device *obd = m->private;
struct lu_target *tgt = obd->u.obt.obt_lut;
- int val;
+ __s64 val;
int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
+ if (val < INT_MIN || val > INT_MAX)
+ return -ERANGE;
+
atomic_set(&tgt->lut_sync_count, val);
return count;
proc_max_dirty_pages_in_mb(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
- __u64 val;
+ __s64 val;
int rc = 0;
if (!table->data || !table->maxlen || !*lenp || (*ppos && !write)) {
return 0;
}
if (write) {
- rc = lprocfs_write_frac_u64_helper(buffer, *lenp, &val,
- 1 << (20 - PAGE_CACHE_SHIFT));
+ rc = lprocfs_str_with_units_to_s64(buffer, *lenp, &val, 'M');
+ if (rc)
+ return rc;
+
+ if (val < 0)
+ return -ERANGE;
+
+ val >>= PAGE_CACHE_SHIFT;
/* Don't allow them to let dirty pages exceed 90% of system
* memory and set a hard minimum of 4MB. */
if (val > ((totalram_pages / 10) * 9)) {
- CERROR("Refusing to set max dirty pages to "LPU64", "
+ CERROR("Refusing to set max dirty pages to "LPD64", "
"which is more than 90%% of available RAM; "
"setting to %lu\n", val,
((totalram_pages / 10) * 9));
{
struct obd_device *obd;
struct obd_job_stats *stats;
- int val, rc;
+ int rc;
+ __s64 val;
obd = ((struct seq_file *)file->private_data)->private;
if (obd == NULL)
stats = &obd->u.obt.obt_jobstats;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
+ if (val < 0 || val > UINT_MAX)
+ return -ERANGE;
stats->ojs_cleanup_interval = val;
lprocfs_job_cleanup(stats, stats->ojs_cleanup_interval);
size_t count, loff_t *off)
{
int *data = ((struct seq_file *)file->private_data)->private;
- int val = 0, rc;
+ int rc;
+ __s64 val = 0;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc < 0)
return rc;
size_t count, loff_t *off)
{
atomic_t *atm = ((struct seq_file *)file->private_data)->private;
- int val = 0;
+ __s64 val = 0;
int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc < 0)
return rc;
- if (val <= 0)
+ if (val <= 0 || val > INT_MAX)
return -ERANGE;
atomic_set(atm, val);
}
EXPORT_SYMBOL(lprocfs_read_helper);
-int lprocfs_write_helper(const char __user *buffer, unsigned long count,
- int *val)
-{
- return lprocfs_write_frac_helper(buffer, count, val, 1);
-}
-EXPORT_SYMBOL(lprocfs_write_helper);
-
-int lprocfs_write_frac_helper(const char __user *buffer, unsigned long count,
- int *val, int mult)
-{
- char kernbuf[20], *end, *pbuf;
-
- if (count > (sizeof(kernbuf) - 1))
- return -EINVAL;
-
- if (copy_from_user(kernbuf, buffer, count))
- return -EFAULT;
-
- kernbuf[count] = '\0';
- pbuf = kernbuf;
- if (*pbuf == '-') {
- mult = -mult;
- pbuf++;
- }
-
- *val = (int)simple_strtoul(pbuf, &end, 10) * mult;
- if (pbuf == end)
- return -EINVAL;
-
- if (end != NULL && *end == '.') {
- int temp_val, pow = 1;
- int i;
-
- pbuf = end + 1;
- if (strlen(pbuf) > 5)
- pbuf[5] = '\0'; /*only allow 5bits fractional*/
-
- temp_val = (int)simple_strtoul(pbuf, &end, 10) * mult;
-
- if (pbuf < end) {
- for (i = 0; i < (end - pbuf); i++)
- pow *= 10;
-
- *val += temp_val / pow;
- }
- }
- return 0;
-}
-EXPORT_SYMBOL(lprocfs_write_frac_helper);
-
int lprocfs_read_frac_helper(char *buffer, unsigned long count, long val,
int mult)
{
}
EXPORT_SYMBOL(lprocfs_seq_read_frac_helper);
-int lprocfs_write_u64_helper(const char __user *buffer, unsigned long count,
- __u64 *val)
+/* Obtains the conversion factor for the unit specified */
+static int get_mult(char unit, __u64 *mult)
+{
+ __u64 units = 1;
+
+ switch (unit) {
+ /* peta, tera, giga, mega, and kilo */
+ case 'p':
+ case 'P':
+ units <<= 10;
+ case 't':
+ case 'T':
+ units <<= 10;
+ case 'g':
+ case 'G':
+ units <<= 10;
+ case 'm':
+ case 'M':
+ units <<= 10;
+ case 'k':
+ case 'K':
+ units <<= 10;
+ break;
+ /* some tests expect % to be accepted */
+ case '%':
+ units = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ *mult = units;
+
+ return 0;
+}
+
+/*
+ * Ensures the numeric string is valid. The function provides the final
+ * multiplier in the case a unit exists at the end of the string. It also
+ * locates the start of the whole and fractional parts (if any). This
+ * function modifies the string so kstrtoull can be used to parse both
+ * the whole and fraction portions. This function also figures out
+ * the base of the number.
+ */
+static int preprocess_numeric_str(char *buffer, __u64 *mult, __u64 def_mult,
+ bool allow_units, char **whole, char **frac,
+ unsigned int *base)
{
- return lprocfs_write_frac_u64_helper(buffer, count, val, 1);
+ bool hit_decimal = false;
+ bool hit_unit = false;
+ int rc = 0;
+ char *start;
+ *mult = def_mult;
+ *whole = NULL;
+ *frac = NULL;
+ *base = 10;
+
+ /* a hex string if it starts with "0x" */
+ if (buffer[0] == '0' && tolower(buffer[1]) == 'x') {
+ *base = 16;
+ buffer += 2;
+ }
+
+ start = buffer;
+
+ while (*buffer) {
+ /* any chars after our unit indicates a malformed string */
+ if (hit_unit)
+ return -EINVAL;
+
+ /* ensure we only hit one decimal */
+ if (*buffer == '.') {
+ if (hit_decimal)
+ return -EINVAL;
+
+ /* if past start, there's a whole part */
+ if (start != buffer)
+ *whole = start;
+
+ *buffer = '\0';
+ start = buffer + 1;
+ hit_decimal = true;
+ } else if (!isdigit(*buffer) &&
+ !(*base == 16 && isxdigit(*buffer))) {
+ if (allow_units) {
+ /* if we allow units, attempt to get mult */
+ hit_unit = true;
+ rc = get_mult(*buffer, mult);
+ if (rc)
+ return rc;
+
+ /* string stops here, but keep processing */
+ *buffer = '\0';
+ } else {
+ /* bad string */
+ return -EINVAL;
+ }
+ }
+
+ buffer++;
+ }
+
+ if (hit_decimal) {
+ /* hit a decimal, make sure there's a fractional part */
+ if (!*start)
+ return -EINVAL;
+
+ *frac = start;
+ } else {
+ /* didn't hit a decimal, but may have a whole part */
+ if (start != buffer && *start)
+ *whole = start;
+ }
+
+ /* malformed string if we didn't get anything */
+ if (!*frac && !*whole)
+ return -EINVAL;
+
+ return 0;
}
-EXPORT_SYMBOL(lprocfs_write_u64_helper);
-int lprocfs_write_frac_u64_helper(const char __user *buffer,
- unsigned long count,
- __u64 *val, int mult)
+/*
+ * Parses a numeric string which can contain a whole and fraction portion
+ * into a __u64. Accepts a multiplier to apply to the value parsed. Also
+ * allows the string to have a unit at the end. The function handles
+ * wrapping of the final unsigned value.
+ */
+static int str_to_u64_parse(char *buffer, unsigned long count,
+ __u64 *val, __u64 def_mult, bool allow_units)
{
- char kernbuf[22], *end, *pbuf;
- __u64 whole, frac = 0, units;
- unsigned frac_d = 1;
+ __u64 whole = 0;
+ __u64 frac = 0;
+ unsigned int frac_d = 1;
+ __u64 wrap_indicator = ULLONG_MAX;
+ int rc = 0;
+ __u64 mult;
+ char *strwhole;
+ char *strfrac;
+ unsigned int base = 10;
- if (count > (sizeof(kernbuf) - 1))
- return -EINVAL;
+ rc = preprocess_numeric_str(buffer, &mult, def_mult, allow_units,
+ &strwhole, &strfrac, &base);
- if (copy_from_user(kernbuf, buffer, count))
- return -EFAULT;
+ if (rc)
+ return rc;
- kernbuf[count] = '\0';
- pbuf = kernbuf;
- if (*pbuf == '-') {
- mult = -mult;
- pbuf++;
- }
+ if (mult == 0) {
+ *val = 0;
+ return 0;
+ }
- whole = simple_strtoull(pbuf, &end, 10);
- if (pbuf == end)
- return -EINVAL;
+ /* the multiplier limits how large the value can be */
+ wrap_indicator /= mult;
- if (end != NULL && *end == '.') {
- int i;
- pbuf = end + 1;
+ if (strwhole) {
+ rc = kstrtoull(strwhole, base, &whole);
+ if (rc)
+ return rc;
- /* need to limit frac_d to a __u32 */
- if (strlen(pbuf) > 10)
- pbuf[10] = '\0';
+ if (whole > wrap_indicator)
+ return -ERANGE;
- frac = simple_strtoull(pbuf, &end, 10);
- /* count decimal places */
- for (i = 0; i < (end - pbuf); i++)
- frac_d *= 10;
- }
+ whole *= mult;
+ }
+
+ if (strfrac) {
+ if (strlen(strfrac) > 10)
+ strfrac[10] = '\0';
- units = 1;
- if (end != NULL) {
- switch (*end) {
- case 'p': case 'P':
- units <<= 10;
- case 't': case 'T':
- units <<= 10;
- case 'g': case 'G':
- units <<= 10;
- case 'm': case 'M':
- units <<= 10;
- case 'k': case 'K':
- units <<= 10;
+ rc = kstrtoull(strfrac, base, &frac);
+ if (rc)
+ return rc;
+
+ /* determine power of fractional portion */
+ while (*strfrac) {
+ frac_d *= base;
+ strfrac++;
}
+
+ /* fractional portion is too large to perform calculation */
+ if (frac > wrap_indicator)
+ return -ERANGE;
+
+ frac *= mult;
+ do_div(frac, frac_d);
}
- /* Specified units override the multiplier */
- if (units > 1)
- mult = mult < 0 ? -units : units;
- frac *= mult;
- do_div(frac, frac_d);
- *val = whole * mult + frac;
- return 0;
+ /* check that the sum of whole and fraction fits in u64 */
+ if (whole > (ULLONG_MAX - frac))
+ return -ERANGE;
+
+ *val = whole + frac;
+
+ return 0;
+}
+
+/*
+ * This function parses numeric/hex strings into __s64. It accepts a multiplier
+ * which will apply to the value parsed. It also can allow the string to
+ * have a unit as the last character. The function handles overflow/underflow
+ * of the signed integer.
+ */
+static int str_to_s64_internal(const char __user *buffer, unsigned long count,
+ __s64 *val, __u64 def_mult, bool allow_units)
+{
+ char kernbuf[22];
+ __u64 tmp;
+ unsigned int offset = 0;
+ int signed sign = 1;
+ __u64 max = LLONG_MAX;
+ int rc = 0;
+
+ if (count > (sizeof(kernbuf) - 1))
+ return -EINVAL;
+
+ if (copy_from_user(kernbuf, buffer, count))
+ return -EFAULT;
+
+ kernbuf[count] = '\0';
+
+ /* keep track of our sign */
+ if (*kernbuf == '-') {
+ sign = -1;
+ offset++;
+ /* equivalent to max = -LLONG_MIN, avoids overflow */
+ max++;
+ }
+
+ rc = str_to_u64_parse(kernbuf + offset, count - offset,
+ &tmp, def_mult, allow_units);
+ if (rc)
+ return rc;
+
+ /* check for overflow/underflow */
+ if (max < tmp)
+ return -ERANGE;
+
+ *val = (__s64)tmp * sign;
+
+ return 0;
+}
+
+/**
+ * Convert a user string into a signed 64 bit number. This function produces
+ * an error when the value parsed from the string underflows or
+ * overflows. This function accepts strings which contain digits and
+ * optionally a decimal or hex strings which are prefixed with "0x".
+ *
+ * \param[in] buffer string consisting of numbers and optionally a decimal
+ * \param[in] count buffer length
+ * \param[in] val if successful, the value represented by the string
+ *
+ * \retval 0 on success
+ * \retval negative number on error
+ */
+int lprocfs_str_to_s64(const char __user *buffer, unsigned long count,
+ __s64 *val)
+{
+ return str_to_s64_internal(buffer, count, val, 1, false);
+}
+EXPORT_SYMBOL(lprocfs_str_to_s64);
+
+/**
+ * Convert a user string into a signed 64 bit number. This function produces
+ * an error when the value parsed from the string times multiplier underflows or
+ * overflows. This function only accepts strings that contains digits, an
+ * optional decimal, and a char representing a unit at the end. If a unit is
+ * specified in the string, the multiplier provided by the caller is ignored.
+ * This function can also accept hexadecimal strings which are prefixed with
+ * "0x".
+ *
+ * \param[in] buffer string consisting of numbers, a decimal, and a unit
+ * \param[in] count buffer length
+ * \param[in] val if successful, the value represented by the string
+ * \param[in] defunit default unit if string doesn't contain one
+ *
+ * \retval 0 on success
+ * \retval negative number on error
+ */
+int lprocfs_str_with_units_to_s64(const char __user *buffer,
+ unsigned long count, __s64 *val, char defunit)
+{
+ __u64 mult;
+ int rc;
+
+ rc = get_mult(defunit, &mult);
+ if (rc)
+ return rc;
+
+ return str_to_s64_internal(buffer, count, val, mult, true);
}
-EXPORT_SYMBOL(lprocfs_write_frac_u64_helper);
+EXPORT_SYMBOL(lprocfs_str_with_units_to_s64);
static char *lprocfs_strnstr(const char *s1, const char *s2, size_t len)
{
{
struct seq_file *m = file->private_data;
struct obd_device *obd = m->private;
- int val, rc;
+ int rc;
+ __s64 val;
LASSERT(obd != NULL);
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
{
struct seq_file *m = file->private_data;
struct obd_device *obd = m->private;
- int val, rc;
+ int rc;
+ __s64 val;
LASSERT(obd != NULL);
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
+ if (val < 0 || val > INT_MAX)
+ return -ERANGE;
obd->obd_recovery_timeout = val;
return count;
{
struct seq_file *m = file->private_data;
struct obd_device *obd = m->private;
- int val, rc;
+ int rc;
+ __s64 val;
LASSERT(obd != NULL);
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
+ if (val < 0 || val > INT_MAX)
+ return -ERANGE;
obd->obd_recovery_time_hard = val;
return count;
ofd_precreate_batch_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
+ struct seq_file *m = file->private_data;
struct obd_device *obd = m->private;
struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
- int val;
+ __s64 val;
int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
- if (val < 1)
+ if (val < 1 || val > INT_MAX)
return -EINVAL;
spin_lock(&ofd->ofd_batch_lock);
ofd_fmd_max_num_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *obd = m->private;
- struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
- int val;
- int rc;
+ struct seq_file *m = file->private_data;
+ struct obd_device *obd = m->private;
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ __s64 val;
+ int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
struct seq_file *m = file->private_data;
struct obd_device *obd = m->private;
struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
- int val;
+ __s64 val;
int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
ofd_degraded_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *obd = m->private;
- struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
- int val, rc;
+ struct seq_file *m = file->private_data;
+ struct obd_device *obd = m->private;
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ int rc;
+ __s64 val;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
ofd_syncjournal_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *obd = m->private;
- struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
- int val;
- int rc;
+ struct seq_file *m = file->private_data;
+ struct obd_device *obd = m->private;
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ __s64 val;
+ int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
ofd_brw_size_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *obd = m->private;
- struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
- int val;
- int rc;
+ struct seq_file *m = file->private_data;
+ struct obd_device *obd = m->private;
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ __s64 val;
+ int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
ofd_sync_lock_cancel_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *obd = m->private;
- struct lu_target *tgt = obd->u.obt.obt_lut;
- char kernbuf[SYNC_STATES_MAXLEN];
- int val = -1;
- int i;
+ struct seq_file *m = file->private_data;
+ struct obd_device *obd = m->private;
+ struct lu_target *tgt = obd->u.obt.obt_lut;
+ char kernbuf[SYNC_STATES_MAXLEN];
+ __s64 val = -1;
+ int i;
if (count == 0 || count >= sizeof(kernbuf))
return -EINVAL;
/* Legacy numeric codes */
if (val == -1) {
- int rc;
-
- /* Safe to use userspace buffer as lprocfs_write_helper will
- * use copy from user for parsing */
- rc = lprocfs_write_helper(buffer, count, &val);
+ int rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
}
const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *obd = m->private;
- struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
- int val;
- int rc;
+ struct seq_file *m = file->private_data;
+ struct obd_device *obd = m->private;
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ __s64 val;
+ int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
ofd_lfsck_speed_limit_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *obd = m->private;
- struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
- __u32 val;
- int rc;
+ struct seq_file *m = file->private_data;
+ struct obd_device *obd = m->private;
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ __s64 val;
+ int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc != 0)
return rc;
+ if (val < 0)
+ return -ERANGE;
+
rc = lfsck_set_speed(ofd->ofd_osd, val);
return rc != 0 ? rc : count;
ofd_lfsck_verify_pfid_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *obd = m->private;
- struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
- __u32 val;
- int rc;
+ struct seq_file *m = file->private_data;
+ struct obd_device *obd = m->private;
+ struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
+ __s64 val;
+ int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc != 0)
return rc;
size_t count, loff_t *off)
{
struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
- int val, rc;
+ int rc;
+ __s64 val;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc)
- return rc;
- if (val < 0 || val > 1)
- return -ERANGE;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
+ if (val < 0 || val > 1)
+ return -ERANGE;
- /* opposite senses */
- if (dev->u.cli.cl_import->imp_deactive == val)
- rc = ptlrpc_set_import_active(dev->u.cli.cl_import, val);
- else
- CDEBUG(D_CONFIG, "activate %d: ignoring repeat request\n", val);
+ /* opposite senses */
+ if (dev->u.cli.cl_import->imp_deactive == val)
+ rc = ptlrpc_set_import_active(dev->u.cli.cl_import, val);
+ else
+ CDEBUG(D_CONFIG, "activate %d: ignoring repeat request\n",
+ (int)val);
- return count;
+ return count;
}
LPROC_SEQ_FOPS(osc_active);
size_t count, loff_t *off)
{
struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
- struct client_obd *cli = &dev->u.cli;
- int val, rc;
+ struct client_obd *cli = &dev->u.cli;
+ int rc;
int adding, added, req_count;
+ __s64 val;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc)
- return rc;
-
- if (val < 1 || val > OSC_MAX_RIF_MAX)
- return -ERANGE;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
+ if (val < 1 || val > OSC_MAX_RIF_MAX)
+ return -ERANGE;
- LPROCFS_CLIMP_CHECK(dev);
+ LPROCFS_CLIMP_CHECK(dev);
- adding = val - cli->cl_max_rpcs_in_flight;
+ adding = (int)val - cli->cl_max_rpcs_in_flight;
req_count = atomic_read(&osc_pool_req_count);
if (adding > 0 && req_count < osc_reqpool_maxreqcount) {
/*
{
struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
struct client_obd *cli = &dev->u.cli;
- int pages_number, mult, rc;
+ int rc;
+ __s64 pages_number;
- mult = 1 << (20 - PAGE_CACHE_SHIFT);
- rc = lprocfs_write_frac_helper(buffer, count, &pages_number, mult);
+ rc = lprocfs_str_with_units_to_s64(buffer, count, &pages_number, 'M');
if (rc)
return rc;
+ pages_number >>= PAGE_CACHE_SHIFT;
+
if (pages_number <= 0 ||
pages_number >= OSC_MAX_DIRTY_MB_MAX << (20 - PAGE_CACHE_SHIFT) ||
pages_number > totalram_pages / 4) /* 1/4 of RAM */
{
struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
struct client_obd *cli = &dev->u.cli;
- __u64 val;
- long pages_number;
+ __s64 pages_number;
long rc;
- int mult;
char kernbuf[128];
if (count >= sizeof(kernbuf))
return -EFAULT;
kernbuf[count] = 0;
- mult = 1 << (20 - PAGE_CACHE_SHIFT);
buffer += lprocfs_find_named_value(kernbuf, "used_mb:", &count) -
kernbuf;
- rc = lprocfs_write_frac_u64_helper(buffer, count, &val, mult);
-
+ rc = lprocfs_str_with_units_to_s64(buffer, count, &pages_number, 'M');
if (rc)
return rc;
- if (val > LONG_MAX)
- return -ERANGE;
- pages_number = (long)val;
+ pages_number >>= PAGE_CACHE_SHIFT;
if (pages_number < 0)
return -ERANGE;
size_t count, loff_t *off)
{
struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
- struct client_obd *cli = &obd->u.cli;
- int rc;
- __u64 val;
+ struct client_obd *cli = &obd->u.cli;
+ int rc;
+ __s64 val;
- if (obd == NULL)
- return 0;
+ if (obd == NULL)
+ return 0;
- rc = lprocfs_write_u64_helper(buffer, count, &val);
- if (rc)
- return rc;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
+ if (val < 0)
+ return -ERANGE;
- /* this is only for shrinking grant */
+ /* this is only for shrinking grant */
spin_lock(&cli->cl_loi_list_lock);
if (val >= cli->cl_avail_grant) {
spin_unlock(&cli->cl_loi_list_lock);
spin_unlock(&cli->cl_loi_list_lock);
- LPROCFS_CLIMP_CHECK(obd);
- if (cli->cl_import->imp_state == LUSTRE_IMP_FULL)
- rc = osc_shrink_grant_to_target(cli, val);
- LPROCFS_CLIMP_EXIT(obd);
- if (rc)
- return rc;
- return count;
+ LPROCFS_CLIMP_CHECK(obd);
+ if (cli->cl_import->imp_state == LUSTRE_IMP_FULL)
+ rc = osc_shrink_grant_to_target(cli, val);
+ LPROCFS_CLIMP_EXIT(obd);
+ if (rc)
+ return rc;
+ return count;
}
LPROC_SEQ_FOPS(osc_cur_grant_bytes);
size_t count, loff_t *off)
{
struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
- int val, rc;
+ int rc;
+ __s64 val;
if (obd == NULL)
return 0;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc)
- return rc;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
- if (val <= 0)
- return -ERANGE;
+ if (val <= 0 || val > INT_MAX)
+ return -ERANGE;
- obd->u.cli.cl_grant_shrink_interval = val;
+ obd->u.cli.cl_grant_shrink_interval = val;
- return count;
+ return count;
}
LPROC_SEQ_FOPS(osc_grant_shrink_interval);
size_t count, loff_t *off)
{
struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
- int val, rc;
+ int rc;
+ __s64 val;
- if (obd == NULL)
- return 0;
+ if (obd == NULL)
+ return 0;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc)
- return rc;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
- obd->u.cli.cl_checksum = (val ? 1 : 0);
+ obd->u.cli.cl_checksum = !!val;
- return count;
+ return count;
}
LPROC_SEQ_FOPS(osc_checksum);
size_t count, loff_t *off)
{
struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
- int val, rc;
+ int rc;
+ __s64 val;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
- if (val < 0)
+ if (val < 0 || val > INT_MAX)
return -EINVAL;
atomic_set(&obd->u.cli.cl_resends, val);
{
struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
struct osc_device *od = obd2osc_dev(obd);
+ int rc;
+ __s64 val;
- return lprocfs_write_helper(buffer, count, &od->od_contention_time) ?: count;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
+ if (val < 0 || val > INT_MAX)
+ return -ERANGE;
+
+ od->od_contention_time = val;
+
+ return count;
}
LPROC_SEQ_FOPS(osc_contention_seconds);
{
struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
struct osc_device *od = obd2osc_dev(obd);
+ int rc;
+ __s64 val;
- return lprocfs_write_helper(buffer, count, &od->od_lockless_truncate) ?:
- count;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc)
+ return rc;
+ if (val < 0)
+ return -ERANGE;
+
+ od->od_lockless_truncate = !!val;
+
+ return count;
}
LPROC_SEQ_FOPS(osc_lockless_truncate);
struct client_obd *cli = &dev->u.cli;
struct obd_connect_data *ocd = &cli->cl_import->imp_connect_data;
int chunk_mask, rc;
- __u64 val;
+ __s64 val;
- rc = lprocfs_write_u64_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
+ if (val < 0)
+ return -ERANGE;
/* if the max_pages is specified in bytes, convert to pages */
if (val >= ONE_MB_BRW_SIZE)
ldiskfs_osd_cache_seq_write(struct file *file, const char *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct dt_device *dt = m->private;
+ struct seq_file *m = file->private_data;
+ struct dt_device *dt = m->private;
struct osd_device *osd = osd_dt_dev(dt);
- int val, rc;
+ int rc;
+ __s64 val;
LASSERT(osd != NULL);
if (unlikely(osd->od_mnt == NULL))
return -EINPROGRESS;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
ldiskfs_osd_wcache_seq_write(struct file *file, const char *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct dt_device *dt = m->private;
+ struct seq_file *m = file->private_data;
+ struct dt_device *dt = m->private;
struct osd_device *osd = osd_dt_dev(dt);
- int val, rc;
+ int rc;
+ __s64 val;
LASSERT(osd != NULL);
if (unlikely(osd->od_mnt == NULL))
return -EINPROGRESS;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
ldiskfs_osd_pdo_seq_write(struct file *file, const char *buffer,
size_t count, loff_t *off)
{
- int pdo, rc;
+ int rc;
+ __s64 pdo;
- rc = lprocfs_write_helper(buffer, count, &pdo);
- if (rc != 0)
- return rc;
+ rc = lprocfs_str_to_s64(buffer, count, &pdo);
+ if (rc != 0)
+ return rc;
- ldiskfs_pdo = !!pdo;
+ ldiskfs_pdo = !!pdo;
- return count;
+ return count;
}
LPROC_SEQ_FOPS(ldiskfs_osd_pdo);
ldiskfs_osd_auto_scrub_seq_write(struct file *file, const char *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct dt_device *dt = m->private;
+ struct seq_file *m = file->private_data;
+ struct dt_device *dt = m->private;
struct osd_device *dev = osd_dt_dev(dt);
- int val, rc;
+ int rc;
+ __s64 val;
LASSERT(dev != NULL);
if (unlikely(dev->od_mnt == NULL))
return -EINPROGRESS;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
ldiskfs_osd_full_scrub_ratio_seq_write(struct file *file, const char *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct dt_device *dt = m->private;
+ struct seq_file *m = file->private_data;
+ struct dt_device *dt = m->private;
struct osd_device *dev = osd_dt_dev(dt);
- int val, rc;
+ int rc;
+ __s64 val;
LASSERT(dev != NULL);
if (unlikely(dev->od_mnt == NULL))
return -EINPROGRESS;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc != 0)
return rc;
const char *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct dt_device *dt = m->private;
+ struct seq_file *m = file->private_data;
+ struct dt_device *dt = m->private;
struct osd_device *dev = osd_dt_dev(dt);
- int val, rc;
+ int rc;
+ __s64 val;
LASSERT(dev != NULL);
if (unlikely(dev->od_mnt == NULL))
return -EINPROGRESS;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc != 0)
return rc;
const char *buffer,
size_t count, loff_t *off)
{
- int track_declares_assert;
- int rc;
+ __s64 track_declares_assert;
+ int rc;
- rc = lprocfs_write_helper(buffer, count, &track_declares_assert);
+ rc = lprocfs_str_to_s64(buffer, count, &track_declares_assert);
if (rc != 0)
return rc;
ldiskfs_osd_readcache_seq_write(struct file *file, const char *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct dt_device *dt = m->private;
+ struct seq_file *m = file->private_data;
+ struct dt_device *dt = m->private;
struct osd_device *osd = osd_dt_dev(dt);
- __u64 val;
- int rc;
+ __s64 val;
+ int rc;
LASSERT(osd != NULL);
if (unlikely(osd->od_mnt == NULL))
return -EINPROGRESS;
- rc = lprocfs_write_u64_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
+ if (val < 0)
+ return -ERANGE;
osd->od_readcache_max_filesize = val > OSD_MAX_CACHE_SIZE ?
OSD_MAX_CACHE_SIZE : val;
ldiskfs_osd_index_in_idif_seq_write(struct file *file, const char *buffer,
size_t count, loff_t *off)
{
- struct lu_env env;
- struct seq_file *m = file->private_data;
- struct dt_device *dt = m->private;
- struct osd_device *dev = osd_dt_dev(dt);
- struct lu_target *tgt;
- int val;
- int rc;
+ struct lu_env env;
+ struct seq_file *m = file->private_data;
+ struct dt_device *dt = m->private;
+ struct osd_device *dev = osd_dt_dev(dt);
+ struct lu_target *tgt;
+ __s64 val;
+ int rc;
LASSERT(dev != NULL);
if (unlikely(dev->od_mnt == NULL))
return -EINPROGRESS;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc != 0)
return rc;
zfs_osd_iused_est_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct dt_device *dt = m->private;
+ struct seq_file *m = file->private_data;
+ struct dt_device *dt = m->private;
struct osd_device *osd = osd_dt_dev(dt);
- int rc, val;
+ int rc;
+ __s64 val;
LASSERT(osd != NULL);
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
osp_active_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
+ struct seq_file *m = file->private_data;
struct obd_device *dev = m->private;
- int val, rc;
+ int rc;
+ __s64 val;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
if (val < 0 || val > 1)
if (dev->u.cli.cl_import->imp_deactive == val)
rc = ptlrpc_set_import_active(dev->u.cli.cl_import, val);
else
- CDEBUG(D_CONFIG, "activate %d: ignoring repeat request\n",
+ CDEBUG(D_CONFIG, "activate "LPD64": ignoring repeat request\n",
val);
LPROCFS_CLIMP_EXIT(dev);
osp_max_rpcs_in_flight_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *dev = m->private;
- struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
- int val, rc;
+ struct seq_file *m = file->private_data;
+ struct obd_device *dev = m->private;
+ struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
+ int rc;
+ __s64 val;
if (osp == NULL)
return -EINVAL;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
- if (val < 1)
+ if (val < 1 || val > INT_MAX)
return -ERANGE;
osp->opd_syn_max_rpc_in_flight = val;
osp_max_rpcs_in_prog_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *dev = m->private;
- struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
- int val, rc;
+ struct seq_file *m = file->private_data;
+ struct obd_device *dev = m->private;
+ struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
+ int rc;
+ __s64 val;
if (osp == NULL)
return -EINVAL;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
- if (val < 1)
+ if (val < 1 || val > INT_MAX)
return -ERANGE;
osp->opd_syn_max_rpc_in_progress = val;
osp_create_count_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *obd = m->private;
- struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
- int val, rc, i;
+ struct seq_file *m = file->private_data;
+ struct obd_device *obd = m->private;
+ struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
+ int rc, i;
+ __s64 val;
if (osp == NULL || osp->opd_pre == NULL)
return 0;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
osp_max_create_count_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *obd = m->private;
- struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
- int val, rc;
+ struct seq_file *m = file->private_data;
+ struct obd_device *obd = m->private;
+ struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
+ int rc;
+ __s64 val;
if (osp == NULL || osp->opd_pre == NULL)
return 0;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
- if (val < 0)
+ if (val < 0 || val > INT_MAX)
return -ERANGE;
if (val > OST_MAX_PRECREATE)
return -ERANGE;
osp_maxage_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *dev = m->private;
- struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
- int val, rc;
+ struct seq_file *m = file->private_data;
+ struct obd_device *dev = m->private;
+ struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
+ int rc;
+ __s64 val;
if (osp == NULL)
return -EINVAL;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc)
return rc;
- if (val < 1)
+ if (val < 1 || val > INT_MAX)
return -ERANGE;
osp->opd_statfs_maxage = val;
{
struct seq_file *m = file->private_data;
struct obd_device *dev = m->private;
- int val;
+ __s64 val;
int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc == 0)
- rc = obd_set_max_rpcs_in_flight(&dev->u.cli, val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc == 0) {
+ if (val < 0)
+ return -ERANGE;
- if (rc != 0)
+ rc = obd_set_max_rpcs_in_flight(&dev->u.cli, val);
+ } else {
count = rc;
+ }
return count;
}
gss_lk_proc_dl_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- int val, rc;
+ int rc;
+ __s64 val;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc < 0)
- return rc;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc < 0)
+ return rc;
+
+ if (val < 0 || val > 4)
+ return -ERANGE;
- if (val < 0 || val > 4)
- return -ERANGE;
+ gss_lk_debug_level = val;
- gss_lk_debug_level = val;
- return count;
+ return count;
}
LPROC_SEQ_FOPS(gss_lk_proc_dl);
const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct ptlrpc_service *svc = m->private;
- int bufpages;
- int val;
- int rc;
+ struct seq_file *m = file->private_data;
+ struct ptlrpc_service *svc = m->private;
+ int bufpages;
+ __s64 val;
+ int rc;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc < 0)
- return rc;
+ rc = lprocfs_str_to_s64(buffer, count, &val);
+ if (rc < 0)
+ return rc;
- if (val < 0)
- return -ERANGE;
+ if (val < 0 || val > INT_MAX)
+ return -ERANGE;
- /* This sanity check is more of an insanity check; we can still
- * hose a kernel by allowing the request history to grow too
- * far. */
+ /* This sanity check is more of an insanity check; we can still
+ * hose a kernel by allowing the request history to grow too
+ * far. */
bufpages = (svc->srv_buf_size + PAGE_CACHE_SIZE - 1) >>
PAGE_CACHE_SHIFT;
if (val > totalram_pages/(2 * bufpages))
- return -ERANGE;
+ return -ERANGE;
spin_lock(&svc->srv_lock);
if (val == 0)
svc->srv_hist_nrqbds_cpt_max = 0;
else
- svc->srv_hist_nrqbds_cpt_max = max(1, (val / svc->srv_ncpts));
+ svc->srv_hist_nrqbds_cpt_max =
+ max(1, ((int)val / svc->srv_ncpts));
spin_unlock(&svc->srv_lock);
const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct ptlrpc_service *svc = m->private;
- int val;
- int rc = lprocfs_write_helper(buffer, count, &val);
+ struct seq_file *m = file->private_data;
+ struct ptlrpc_service *svc = m->private;
+ __s64 val;
+ int rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc < 0)
return rc;
return -ERANGE;
}
- svc->srv_nthrs_cpt_init = val / svc->srv_ncpts;
+ svc->srv_nthrs_cpt_init = (int)val / svc->srv_ncpts;
spin_unlock(&svc->srv_lock);
const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct ptlrpc_service *svc = m->private;
- int val;
- int rc = lprocfs_write_helper(buffer, count, &val);
+ struct seq_file *m = file->private_data;
+ struct ptlrpc_service *svc = m->private;
+ __s64 val;
+ int rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc < 0)
return rc;
return -ERANGE;
}
- svc->srv_nthrs_cpt_limit = val / svc->srv_ncpts;
+ svc->srv_nthrs_cpt_limit = (int)val / svc->srv_ncpts;
spin_unlock(&svc->srv_lock);
ptlrpc_lprocfs_hp_ratio_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct ptlrpc_service *svc = m->private;
- int rc;
- int val;
+ struct seq_file *m = file->private_data;
+ struct ptlrpc_service *svc = m->private;
+ int rc;
+ __s64 val;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc < 0)
return rc;
- if (val < 0)
+ if (val < 0 || val > INT_MAX)
return -ERANGE;
spin_lock(&svc->srv_lock);
lprocfs_pinger_recov_seq_write(struct file *file, const char __user *buffer,
size_t count, loff_t *off)
{
- struct seq_file *m = file->private_data;
- struct obd_device *obd = m->private;
- struct client_obd *cli = &obd->u.cli;
- struct obd_import *imp = cli->cl_import;
- int rc, val;
+ struct seq_file *m = file->private_data;
+ struct obd_device *obd = m->private;
+ struct client_obd *cli = &obd->u.cli;
+ struct obd_import *imp = cli->cl_import;
+ int rc;
+ __s64 val;
- rc = lprocfs_write_helper(buffer, count, &val);
+ rc = lprocfs_str_to_s64(buffer, count, &val);
if (rc < 0)
return rc;
size_t count, loff_t *off)
{
struct qsd_instance *qsd = ((struct seq_file *)file->private_data)->private;
- int timeout, rc;
+ int rc;
+ __s64 timeout;
LASSERT(qsd != NULL);
- rc = lprocfs_write_helper(buffer, count, &timeout);
+ rc = lprocfs_str_to_s64(buffer, count, &timeout);
if (rc)
return rc;
- if (timeout < 0)
+ if (timeout < 0 || timeout > INT_MAX)
return -EINVAL;
qsd->qsd_timeout = timeout;