diff options
| author | Jens Axboe <axboe@suse.de> | 2006-04-10 03:03:58 -0400 |
|---|---|---|
| committer | Jens Axboe <axboe@suse.de> | 2006-04-10 03:03:58 -0400 |
| commit | 16c523ddabcce5d3d817f4a2491d628f84dfaaa1 (patch) | |
| tree | 61b26e8d6b774a956fb069efdc62eb275b849c97 | |
| parent | c0bd1f650bd06a43435808d44f1e9520ea806206 (diff) | |
[PATCH] splice: cleanup __generic_file_splice_read()
The whole shadow/pages logic got overly complex, and this simpler
approach is actually faster in testing.
Signed-off-by: Jens Axboe <axboe@suse.de>
| -rw-r--r-- | fs/splice.c | 59 |
1 files changed, 10 insertions, 49 deletions
diff --git a/fs/splice.c b/fs/splice.c index 9f796b1034d1..8b5efcc906dc 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
| @@ -220,10 +220,10 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe, | |||
| 220 | { | 220 | { |
| 221 | struct address_space *mapping = in->f_mapping; | 221 | struct address_space *mapping = in->f_mapping; |
| 222 | unsigned int offset, nr_pages; | 222 | unsigned int offset, nr_pages; |
| 223 | struct page *pages[PIPE_BUFFERS], *shadow[PIPE_BUFFERS]; | 223 | struct page *pages[PIPE_BUFFERS]; |
| 224 | struct page *page; | 224 | struct page *page; |
| 225 | pgoff_t index, pidx; | 225 | pgoff_t index; |
| 226 | int i, j; | 226 | int i; |
| 227 | 227 | ||
| 228 | index = in->f_pos >> PAGE_CACHE_SHIFT; | 228 | index = in->f_pos >> PAGE_CACHE_SHIFT; |
| 229 | offset = in->f_pos & ~PAGE_CACHE_MASK; | 229 | offset = in->f_pos & ~PAGE_CACHE_MASK; |
| @@ -238,41 +238,13 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe, | |||
| 238 | do_page_cache_readahead(mapping, in, index, nr_pages); | 238 | do_page_cache_readahead(mapping, in, index, nr_pages); |
| 239 | 239 | ||
| 240 | /* | 240 | /* |
| 241 | * Get as many pages from the page cache as possible.. | ||
| 242 | * Start IO on the page cache entries we create (we | ||
| 243 | * can assume that any pre-existing ones we find have | ||
| 244 | * already had IO started on them). | ||
| 245 | */ | ||
| 246 | i = find_get_pages(mapping, index, nr_pages, pages); | ||
| 247 | |||
| 248 | /* | ||
| 249 | * common case - we found all pages and they are contiguous, | ||
| 250 | * kick them off | ||
| 251 | */ | ||
| 252 | if (i && (pages[i - 1]->index == index + i - 1)) | ||
| 253 | goto splice_them; | ||
| 254 | |||
| 255 | /* | ||
| 256 | * fill shadow[] with pages at the right locations, so we only | ||
| 257 | * have to fill holes | ||
| 258 | */ | ||
| 259 | memset(shadow, 0, nr_pages * sizeof(struct page *)); | ||
| 260 | for (j = 0; j < i; j++) | ||
| 261 | shadow[pages[j]->index - index] = pages[j]; | ||
| 262 | |||
| 263 | /* | ||
| 264 | * now fill in the holes | 241 | * now fill in the holes |
| 265 | */ | 242 | */ |
| 266 | for (i = 0, pidx = index; i < nr_pages; pidx++, i++) { | 243 | for (i = 0; i < nr_pages; i++, index++) { |
| 267 | int error; | ||
| 268 | |||
| 269 | if (shadow[i]) | ||
| 270 | continue; | ||
| 271 | |||
| 272 | /* | 244 | /* |
| 273 | * no page there, look one up / create it | 245 | * no page there, look one up / create it |
| 274 | */ | 246 | */ |
| 275 | page = find_or_create_page(mapping, pidx, | 247 | page = find_or_create_page(mapping, index, |
| 276 | mapping_gfp_mask(mapping)); | 248 | mapping_gfp_mask(mapping)); |
| 277 | if (!page) | 249 | if (!page) |
| 278 | break; | 250 | break; |
| @@ -280,31 +252,20 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe, | |||
| 280 | if (PageUptodate(page)) | 252 | if (PageUptodate(page)) |
| 281 | unlock_page(page); | 253 | unlock_page(page); |
| 282 | else { | 254 | else { |
| 283 | error = mapping->a_ops->readpage(in, page); | 255 | int error = mapping->a_ops->readpage(in, page); |
| 284 | 256 | ||
| 285 | if (unlikely(error)) { | 257 | if (unlikely(error)) { |
| 286 | page_cache_release(page); | 258 | page_cache_release(page); |
| 287 | break; | 259 | break; |
| 288 | } | 260 | } |
| 289 | } | 261 | } |
| 290 | shadow[i] = page; | 262 | pages[i] = page; |
| 291 | } | ||
| 292 | |||
| 293 | if (!i) { | ||
| 294 | for (i = 0; i < nr_pages; i++) { | ||
| 295 | if (shadow[i]) | ||
| 296 | page_cache_release(shadow[i]); | ||
| 297 | } | ||
| 298 | return 0; | ||
| 299 | } | 263 | } |
| 300 | 264 | ||
| 301 | memcpy(pages, shadow, i * sizeof(struct page *)); | 265 | if (i) |
| 266 | return move_to_pipe(pipe, pages, i, offset, len, flags); | ||
| 302 | 267 | ||
| 303 | /* | 268 | return 0; |
| 304 | * Now we splice them into the pipe.. | ||
| 305 | */ | ||
| 306 | splice_them: | ||
| 307 | return move_to_pipe(pipe, pages, i, offset, len, flags); | ||
| 308 | } | 269 | } |
| 309 | 270 | ||
| 310 | /** | 271 | /** |
