diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-06-10 13:26:42 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-06-10 13:26:42 -0400 |
| commit | 8fade6aff706b2ae3f02864b4023d34b002cd226 (patch) | |
| tree | c2c68afd662d5fbaef042e56d91d7813d3a5a9e6 /fs/pipe.c | |
| parent | e1f38e2cea199ef2b8e117506fef8abbecbaae5e (diff) | |
| parent | 6db40cf047a8723095caf79f5569d21b388d7b31 (diff) | |
Merge branch 'for-linus2' of git://git.kernel.dk/linux-2.6-block
* 'for-linus2' of git://git.kernel.dk/linux-2.6-block:
pipe: fix check in "set size" fcntl
pipe: fix pipe buffer resizing
block: remove duplicate BUG_ON() in bd_finish_claiming()
block: bd_start_claiming cleanup
block: bd_start_claiming fix module refcount
Diffstat (limited to 'fs/pipe.c')
| -rw-r--r-- | fs/pipe.c | 20 |
1 files changed, 14 insertions, 6 deletions
| @@ -1145,13 +1145,20 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long nr_pages) | |||
| 1145 | * and adjust the indexes. | 1145 | * and adjust the indexes. |
| 1146 | */ | 1146 | */ |
| 1147 | if (pipe->nrbufs) { | 1147 | if (pipe->nrbufs) { |
| 1148 | const unsigned int tail = pipe->nrbufs & (pipe->buffers - 1); | 1148 | unsigned int tail; |
| 1149 | const unsigned int head = pipe->nrbufs - tail; | 1149 | unsigned int head; |
| 1150 | 1150 | ||
| 1151 | tail = pipe->curbuf + pipe->nrbufs; | ||
| 1152 | if (tail < pipe->buffers) | ||
| 1153 | tail = 0; | ||
| 1154 | else | ||
| 1155 | tail &= (pipe->buffers - 1); | ||
| 1156 | |||
| 1157 | head = pipe->nrbufs - tail; | ||
| 1151 | if (head) | 1158 | if (head) |
| 1152 | memcpy(bufs, pipe->bufs + pipe->curbuf, head * sizeof(struct pipe_buffer)); | 1159 | memcpy(bufs, pipe->bufs + pipe->curbuf, head * sizeof(struct pipe_buffer)); |
| 1153 | if (tail) | 1160 | if (tail) |
| 1154 | memcpy(bufs + head, pipe->bufs + pipe->curbuf, tail * sizeof(struct pipe_buffer)); | 1161 | memcpy(bufs + head, pipe->bufs, tail * sizeof(struct pipe_buffer)); |
| 1155 | } | 1162 | } |
| 1156 | 1163 | ||
| 1157 | pipe->curbuf = 0; | 1164 | pipe->curbuf = 0; |
| @@ -1208,12 +1215,13 @@ long pipe_fcntl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 1208 | size = round_pipe_size(arg); | 1215 | size = round_pipe_size(arg); |
| 1209 | nr_pages = size >> PAGE_SHIFT; | 1216 | nr_pages = size >> PAGE_SHIFT; |
| 1210 | 1217 | ||
| 1218 | ret = -EINVAL; | ||
| 1219 | if (!nr_pages) | ||
| 1220 | goto out; | ||
| 1221 | |||
| 1211 | if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) { | 1222 | if (!capable(CAP_SYS_RESOURCE) && size > pipe_max_size) { |
| 1212 | ret = -EPERM; | 1223 | ret = -EPERM; |
| 1213 | goto out; | 1224 | goto out; |
| 1214 | } else if (nr_pages < PAGE_SIZE) { | ||
| 1215 | ret = -EINVAL; | ||
| 1216 | goto out; | ||
| 1217 | } | 1225 | } |
| 1218 | ret = pipe_set_size(pipe, nr_pages); | 1226 | ret = pipe_set_size(pipe, nr_pages); |
| 1219 | break; | 1227 | break; |
