diff options
author | Jens Axboe <jaxboe@fusionio.com> | 2010-06-03 08:54:39 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-06-03 08:54:39 -0400 |
commit | ff9da691c0498ff81fdd014e7a0731dab2337dac (patch) | |
tree | 429dc9ea36c9927954ed3a32f03d28730e693c8b | |
parent | 419f8367ea37e5adc5d95479e8fd5554b92b49fe (diff) |
pipe: change /proc/sys/fs/pipe-max-pages to byte sized interface
This changes the interface to be based on bytes instead. The API
matches that of F_SETPIPE_SZ in that it rounds up the passed in
size so that the resulting page array is a power-of-2 in size.
The proc file is renamed to /proc/sys/fs/pipe-max-size to
reflect this change.
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
-rw-r--r-- | fs/pipe.c | 54 | ||||
-rw-r--r-- | include/linux/pipe_fs_i.h | 4 | ||||
-rw-r--r-- | kernel/sysctl.c | 8 |
3 files changed, 49 insertions, 17 deletions
@@ -26,9 +26,14 @@ | |||
26 | 26 | ||
27 | /* | 27 | /* |
28 | * The max size that a non-root user is allowed to grow the pipe. Can | 28 | * The max size that a non-root user is allowed to grow the pipe. Can |
29 | * be set by root in /proc/sys/fs/pipe-max-pages | 29 | * be set by root in /proc/sys/fs/pipe-max-size |
30 | */ | 30 | */ |
31 | unsigned int pipe_max_pages = PIPE_DEF_BUFFERS * 16; | 31 | unsigned int pipe_max_size = 1048576; |
32 | |||
33 | /* | ||
34 | * Minimum pipe size, as required by POSIX | ||
35 | */ | ||
36 | unsigned int pipe_min_size = PAGE_SIZE; | ||
32 | 37 | ||
33 | /* | 38 | /* |
34 | * We use a start+len construction, which provides full use of the | 39 | * We use a start+len construction, which provides full use of the |
@@ -1156,6 +1161,35 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages) | |||
1156 | return nr_pages * PAGE_SIZE; | 1161 | return nr_pages * PAGE_SIZE; |
1157 | } | 1162 | } |
1158 | 1163 | ||
1164 | /* | ||
1165 | * Currently we rely on the pipe array holding a power-of-2 number | ||
1166 | * of pages. | ||
1167 | */ | ||
1168 | static inline unsigned int round_pipe_size(unsigned int size) | ||
1169 | { | ||
1170 | unsigned long nr_pages; | ||
1171 | |||
1172 | nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
1173 | return roundup_pow_of_two(nr_pages) << PAGE_SHIFT; | ||
1174 | } | ||
1175 | |||
1176 | /* | ||
1177 | * This should work even if CONFIG_PROC_FS isn't set, as proc_dointvec_minmax | ||
1178 | * will return an error. | ||
1179 | */ | ||
1180 | int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf, | ||
1181 | size_t *lenp, loff_t *ppos) | ||
1182 | { | ||
1183 | int ret; | ||
1184 | |||
1185 | ret = proc_dointvec_minmax(table, write, buf, lenp, ppos); | ||
1186 | if (ret < 0 || !write) | ||
1187 | return ret; | ||
1188 | |||
1189 | pipe_max_size = round_pipe_size(pipe_max_size); | ||
1190 | return ret; | ||
1191 | } | ||
1192 | |||
1159 | long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) | 1193 | long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) |
1160 | { | 1194 | { |
1161 | struct pipe_inode_info *pipe; | 1195 | struct pipe_inode_info *pipe; |
@@ -1169,23 +1203,19 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1169 | 1203 | ||
1170 | switch (cmd) { | 1204 | switch (cmd) { |
1171 | case F_SETPIPE_SZ: { | 1205 | case F_SETPIPE_SZ: { |
1172 | unsigned long nr_pages; | 1206 | unsigned int size, nr_pages; |
1173 | 1207 | ||
1174 | /* | 1208 | size = round_pipe_size(arg); |
1175 | * Currently the array must be a power-of-2 size, so adjust | 1209 | nr_pages = size >> PAGE_SHIFT; |
1176 | * upwards if needed. | ||
1177 | */ | ||
1178 | nr_pages = (arg + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
1179 | nr_pages = roundup_pow_of_two(nr_pages); | ||
1180 | 1210 | ||
1181 | if (!capable(CAP_SYS_RESOURCE) && nr_pages > pipe_max_pages) { | 1211 | if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) { |
1182 | ret = -EPERM; | 1212 | ret = -EPERM; |
1183 | goto out; | 1213 | goto out; |
1184 | } else if (nr_pages < 1) { | 1214 | } else if (nr_pages < PAGE_SIZE) { |
1185 | ret = -EINVAL; | 1215 | ret = -EINVAL; |
1186 | goto out; | 1216 | goto out; |
1187 | } | 1217 | } |
1188 | ret = pipe_set_size(pipe, arg); | 1218 | ret = pipe_set_size(pipe, nr_pages); |
1189 | break; | 1219 | break; |
1190 | } | 1220 | } |
1191 | case F_GETPIPE_SZ: | 1221 | case F_GETPIPE_SZ: |
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 16de3933c45e..445796945ac9 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h | |||
@@ -139,7 +139,9 @@ void pipe_lock(struct pipe_inode_info *); | |||
139 | void pipe_unlock(struct pipe_inode_info *); | 139 | void pipe_unlock(struct pipe_inode_info *); |
140 | void pipe_double_lock(struct pipe_inode_info *, struct pipe_inode_info *); | 140 | void pipe_double_lock(struct pipe_inode_info *, struct pipe_inode_info *); |
141 | 141 | ||
142 | extern unsigned int pipe_max_pages; | 142 | extern unsigned int pipe_max_size, pipe_min_size; |
143 | int pipe_proc_fn(struct ctl_table *, int, void __user *, size_t *, loff_t *); | ||
144 | |||
143 | 145 | ||
144 | /* Drop the inode semaphore and wait for a pipe event, atomically */ | 146 | /* Drop the inode semaphore and wait for a pipe event, atomically */ |
145 | void pipe_wait(struct pipe_inode_info *pipe); | 147 | void pipe_wait(struct pipe_inode_info *pipe); |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 997080f00e0b..d24f761f4876 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -1471,12 +1471,12 @@ static struct ctl_table fs_table[] = { | |||
1471 | }, | 1471 | }, |
1472 | #endif | 1472 | #endif |
1473 | { | 1473 | { |
1474 | .procname = "pipe-max-pages", | 1474 | .procname = "pipe-max-size", |
1475 | .data = &pipe_max_pages, | 1475 | .data = &pipe_max_size, |
1476 | .maxlen = sizeof(int), | 1476 | .maxlen = sizeof(int), |
1477 | .mode = 0644, | 1477 | .mode = 0644, |
1478 | .proc_handler = &proc_dointvec_minmax, | 1478 | .proc_handler = &pipe_proc_fn, |
1479 | .extra1 = &two, | 1479 | .extra1 = &pipe_min_size, |
1480 | }, | 1480 | }, |
1481 | /* | 1481 | /* |
1482 | * NOTE: do not add new entries to this table unless you have read | 1482 | * NOTE: do not add new entries to this table unless you have read |