mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	sysctl: add proc_dou8vec_minmax()
Networking has many sysctls that could fit in one u8. This patch adds proc_dou8vec_minmax() for this purpose. Note that the .extra1 and .extra2 fields are pointing to integers, because it makes conversions easier. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									d54e1348d8
								
							
						
					
					
						commit
						cb94441306
					
				
					 3 changed files with 73 additions and 0 deletions
				
			
		| 
						 | 
					@ -1108,6 +1108,11 @@ static int sysctl_check_table_array(const char *path, struct ctl_table *table)
 | 
				
			||||||
			err |= sysctl_err(path, table, "array not allowed");
 | 
								err |= sysctl_err(path, table, "array not allowed");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (table->proc_handler == proc_dou8vec_minmax) {
 | 
				
			||||||
 | 
							if (table->maxlen != sizeof(u8))
 | 
				
			||||||
 | 
								err |= sysctl_err(path, table, "array not allowed");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1123,6 +1128,7 @@ static int sysctl_check_table(const char *path, struct ctl_table *table)
 | 
				
			||||||
		    (table->proc_handler == proc_douintvec) ||
 | 
							    (table->proc_handler == proc_douintvec) ||
 | 
				
			||||||
		    (table->proc_handler == proc_douintvec_minmax) ||
 | 
							    (table->proc_handler == proc_douintvec_minmax) ||
 | 
				
			||||||
		    (table->proc_handler == proc_dointvec_minmax) ||
 | 
							    (table->proc_handler == proc_dointvec_minmax) ||
 | 
				
			||||||
 | 
							    (table->proc_handler == proc_dou8vec_minmax) ||
 | 
				
			||||||
		    (table->proc_handler == proc_dointvec_jiffies) ||
 | 
							    (table->proc_handler == proc_dointvec_jiffies) ||
 | 
				
			||||||
		    (table->proc_handler == proc_dointvec_userhz_jiffies) ||
 | 
							    (table->proc_handler == proc_dointvec_userhz_jiffies) ||
 | 
				
			||||||
		    (table->proc_handler == proc_dointvec_ms_jiffies) ||
 | 
							    (table->proc_handler == proc_dointvec_ms_jiffies) ||
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,6 +53,8 @@ int proc_douintvec(struct ctl_table *, int, void *, size_t *, loff_t *);
 | 
				
			||||||
int proc_dointvec_minmax(struct ctl_table *, int, void *, size_t *, loff_t *);
 | 
					int proc_dointvec_minmax(struct ctl_table *, int, void *, size_t *, loff_t *);
 | 
				
			||||||
int proc_douintvec_minmax(struct ctl_table *table, int write, void *buffer,
 | 
					int proc_douintvec_minmax(struct ctl_table *table, int write, void *buffer,
 | 
				
			||||||
		size_t *lenp, loff_t *ppos);
 | 
							size_t *lenp, loff_t *ppos);
 | 
				
			||||||
 | 
					int proc_dou8vec_minmax(struct ctl_table *table, int write, void *buffer,
 | 
				
			||||||
 | 
								size_t *lenp, loff_t *ppos);
 | 
				
			||||||
int proc_dointvec_jiffies(struct ctl_table *, int, void *, size_t *, loff_t *);
 | 
					int proc_dointvec_jiffies(struct ctl_table *, int, void *, size_t *, loff_t *);
 | 
				
			||||||
int proc_dointvec_userhz_jiffies(struct ctl_table *, int, void *, size_t *,
 | 
					int proc_dointvec_userhz_jiffies(struct ctl_table *, int, void *, size_t *,
 | 
				
			||||||
		loff_t *);
 | 
							loff_t *);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1034,6 +1034,65 @@ int proc_douintvec_minmax(struct ctl_table *table, int write,
 | 
				
			||||||
				 do_proc_douintvec_minmax_conv, ¶m);
 | 
									 do_proc_douintvec_minmax_conv, ¶m);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * proc_dou8vec_minmax - read a vector of unsigned chars with min/max values
 | 
				
			||||||
 | 
					 * @table: the sysctl table
 | 
				
			||||||
 | 
					 * @write: %TRUE if this is a write to the sysctl file
 | 
				
			||||||
 | 
					 * @buffer: the user buffer
 | 
				
			||||||
 | 
					 * @lenp: the size of the user buffer
 | 
				
			||||||
 | 
					 * @ppos: file position
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Reads/writes up to table->maxlen/sizeof(u8) unsigned chars
 | 
				
			||||||
 | 
					 * values from/to the user buffer, treated as an ASCII string. Negative
 | 
				
			||||||
 | 
					 * strings are not allowed.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This routine will ensure the values are within the range specified by
 | 
				
			||||||
 | 
					 * table->extra1 (min) and table->extra2 (max).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Returns 0 on success or an error on write when the range check fails.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int proc_dou8vec_minmax(struct ctl_table *table, int write,
 | 
				
			||||||
 | 
								void *buffer, size_t *lenp, loff_t *ppos)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct ctl_table tmp;
 | 
				
			||||||
 | 
						unsigned int min = 0, max = 255U, val;
 | 
				
			||||||
 | 
						u8 *data = table->data;
 | 
				
			||||||
 | 
						struct do_proc_douintvec_minmax_conv_param param = {
 | 
				
			||||||
 | 
							.min = &min,
 | 
				
			||||||
 | 
							.max = &max,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Do not support arrays yet. */
 | 
				
			||||||
 | 
						if (table->maxlen != sizeof(u8))
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (table->extra1) {
 | 
				
			||||||
 | 
							min = *(unsigned int *) table->extra1;
 | 
				
			||||||
 | 
							if (min > 255U)
 | 
				
			||||||
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (table->extra2) {
 | 
				
			||||||
 | 
							max = *(unsigned int *) table->extra2;
 | 
				
			||||||
 | 
							if (max > 255U)
 | 
				
			||||||
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp = *table;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tmp.maxlen = sizeof(val);
 | 
				
			||||||
 | 
						tmp.data = &val;
 | 
				
			||||||
 | 
						val = *data;
 | 
				
			||||||
 | 
						res = do_proc_douintvec(&tmp, write, buffer, lenp, ppos,
 | 
				
			||||||
 | 
									do_proc_douintvec_minmax_conv, ¶m);
 | 
				
			||||||
 | 
						if (res)
 | 
				
			||||||
 | 
							return res;
 | 
				
			||||||
 | 
						if (write)
 | 
				
			||||||
 | 
							*data = val;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(proc_dou8vec_minmax);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int do_proc_dopipe_max_size_conv(unsigned long *lvalp,
 | 
					static int do_proc_dopipe_max_size_conv(unsigned long *lvalp,
 | 
				
			||||||
					unsigned int *valp,
 | 
										unsigned int *valp,
 | 
				
			||||||
					int write, void *data)
 | 
										int write, void *data)
 | 
				
			||||||
| 
						 | 
					@ -1582,6 +1641,12 @@ int proc_douintvec_minmax(struct ctl_table *table, int write,
 | 
				
			||||||
	return -ENOSYS;
 | 
						return -ENOSYS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int proc_dou8vec_minmax(struct ctl_table *table, int write,
 | 
				
			||||||
 | 
								void *buffer, size_t *lenp, loff_t *ppos)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return -ENOSYS;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int proc_dointvec_jiffies(struct ctl_table *table, int write,
 | 
					int proc_dointvec_jiffies(struct ctl_table *table, int write,
 | 
				
			||||||
		    void *buffer, size_t *lenp, loff_t *ppos)
 | 
							    void *buffer, size_t *lenp, loff_t *ppos)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue