diff options
author | Mark Brown <broonie@linaro.org> | 2013-12-30 08:45:00 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-12-30 08:45:00 -0500 |
commit | 68e67d97e1f91ed11e041b67f3a1336f518c608f (patch) | |
tree | 1de288bc05f1cf1bfec20200a60ffe99dcce77ae /fs/aio.c | |
parent | 9e03d05eee4ca45ed12749ef6c26bf616262cdd2 (diff) | |
parent | 802eee95bde72fd0cd0f3a5b2098375a487d1eda (diff) |
Merge tag 'v3.13-rc6' into spi-rcar
To resolve spurious merge conflicts with fixes.
Linux 3.13-rc6
Diffstat (limited to 'fs/aio.c')
-rw-r--r-- | fs/aio.c | 115 |
1 files changed, 72 insertions, 43 deletions
@@ -244,9 +244,14 @@ static void aio_free_ring(struct kioctx *ctx) | |||
244 | int i; | 244 | int i; |
245 | 245 | ||
246 | for (i = 0; i < ctx->nr_pages; i++) { | 246 | for (i = 0; i < ctx->nr_pages; i++) { |
247 | struct page *page; | ||
247 | pr_debug("pid(%d) [%d] page->count=%d\n", current->pid, i, | 248 | pr_debug("pid(%d) [%d] page->count=%d\n", current->pid, i, |
248 | page_count(ctx->ring_pages[i])); | 249 | page_count(ctx->ring_pages[i])); |
249 | put_page(ctx->ring_pages[i]); | 250 | page = ctx->ring_pages[i]; |
251 | if (!page) | ||
252 | continue; | ||
253 | ctx->ring_pages[i] = NULL; | ||
254 | put_page(page); | ||
250 | } | 255 | } |
251 | 256 | ||
252 | put_aio_ring_file(ctx); | 257 | put_aio_ring_file(ctx); |
@@ -280,18 +285,38 @@ static int aio_migratepage(struct address_space *mapping, struct page *new, | |||
280 | unsigned long flags; | 285 | unsigned long flags; |
281 | int rc; | 286 | int rc; |
282 | 287 | ||
288 | rc = 0; | ||
289 | |||
290 | /* Make sure the old page hasn't already been changed */ | ||
291 | spin_lock(&mapping->private_lock); | ||
292 | ctx = mapping->private_data; | ||
293 | if (ctx) { | ||
294 | pgoff_t idx; | ||
295 | spin_lock_irqsave(&ctx->completion_lock, flags); | ||
296 | idx = old->index; | ||
297 | if (idx < (pgoff_t)ctx->nr_pages) { | ||
298 | if (ctx->ring_pages[idx] != old) | ||
299 | rc = -EAGAIN; | ||
300 | } else | ||
301 | rc = -EINVAL; | ||
302 | spin_unlock_irqrestore(&ctx->completion_lock, flags); | ||
303 | } else | ||
304 | rc = -EINVAL; | ||
305 | spin_unlock(&mapping->private_lock); | ||
306 | |||
307 | if (rc != 0) | ||
308 | return rc; | ||
309 | |||
283 | /* Writeback must be complete */ | 310 | /* Writeback must be complete */ |
284 | BUG_ON(PageWriteback(old)); | 311 | BUG_ON(PageWriteback(old)); |
285 | put_page(old); | 312 | get_page(new); |
286 | 313 | ||
287 | rc = migrate_page_move_mapping(mapping, new, old, NULL, mode); | 314 | rc = migrate_page_move_mapping(mapping, new, old, NULL, mode, 1); |
288 | if (rc != MIGRATEPAGE_SUCCESS) { | 315 | if (rc != MIGRATEPAGE_SUCCESS) { |
289 | get_page(old); | 316 | put_page(new); |
290 | return rc; | 317 | return rc; |
291 | } | 318 | } |
292 | 319 | ||
293 | get_page(new); | ||
294 | |||
295 | /* We can potentially race against kioctx teardown here. Use the | 320 | /* We can potentially race against kioctx teardown here. Use the |
296 | * address_space's private data lock to protect the mapping's | 321 | * address_space's private data lock to protect the mapping's |
297 | * private_data. | 322 | * private_data. |
@@ -303,13 +328,24 @@ static int aio_migratepage(struct address_space *mapping, struct page *new, | |||
303 | spin_lock_irqsave(&ctx->completion_lock, flags); | 328 | spin_lock_irqsave(&ctx->completion_lock, flags); |
304 | migrate_page_copy(new, old); | 329 | migrate_page_copy(new, old); |
305 | idx = old->index; | 330 | idx = old->index; |
306 | if (idx < (pgoff_t)ctx->nr_pages) | 331 | if (idx < (pgoff_t)ctx->nr_pages) { |
307 | ctx->ring_pages[idx] = new; | 332 | /* And only do the move if things haven't changed */ |
333 | if (ctx->ring_pages[idx] == old) | ||
334 | ctx->ring_pages[idx] = new; | ||
335 | else | ||
336 | rc = -EAGAIN; | ||
337 | } else | ||
338 | rc = -EINVAL; | ||
308 | spin_unlock_irqrestore(&ctx->completion_lock, flags); | 339 | spin_unlock_irqrestore(&ctx->completion_lock, flags); |
309 | } else | 340 | } else |
310 | rc = -EBUSY; | 341 | rc = -EBUSY; |
311 | spin_unlock(&mapping->private_lock); | 342 | spin_unlock(&mapping->private_lock); |
312 | 343 | ||
344 | if (rc == MIGRATEPAGE_SUCCESS) | ||
345 | put_page(old); | ||
346 | else | ||
347 | put_page(new); | ||
348 | |||
313 | return rc; | 349 | return rc; |
314 | } | 350 | } |
315 | #endif | 351 | #endif |
@@ -326,7 +362,7 @@ static int aio_setup_ring(struct kioctx *ctx) | |||
326 | struct aio_ring *ring; | 362 | struct aio_ring *ring; |
327 | unsigned nr_events = ctx->max_reqs; | 363 | unsigned nr_events = ctx->max_reqs; |
328 | struct mm_struct *mm = current->mm; | 364 | struct mm_struct *mm = current->mm; |
329 | unsigned long size, populate; | 365 | unsigned long size, unused; |
330 | int nr_pages; | 366 | int nr_pages; |
331 | int i; | 367 | int i; |
332 | struct file *file; | 368 | struct file *file; |
@@ -347,6 +383,20 @@ static int aio_setup_ring(struct kioctx *ctx) | |||
347 | return -EAGAIN; | 383 | return -EAGAIN; |
348 | } | 384 | } |
349 | 385 | ||
386 | ctx->aio_ring_file = file; | ||
387 | nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) | ||
388 | / sizeof(struct io_event); | ||
389 | |||
390 | ctx->ring_pages = ctx->internal_pages; | ||
391 | if (nr_pages > AIO_RING_PAGES) { | ||
392 | ctx->ring_pages = kcalloc(nr_pages, sizeof(struct page *), | ||
393 | GFP_KERNEL); | ||
394 | if (!ctx->ring_pages) { | ||
395 | put_aio_ring_file(ctx); | ||
396 | return -ENOMEM; | ||
397 | } | ||
398 | } | ||
399 | |||
350 | for (i = 0; i < nr_pages; i++) { | 400 | for (i = 0; i < nr_pages; i++) { |
351 | struct page *page; | 401 | struct page *page; |
352 | page = find_or_create_page(file->f_inode->i_mapping, | 402 | page = find_or_create_page(file->f_inode->i_mapping, |
@@ -358,17 +408,14 @@ static int aio_setup_ring(struct kioctx *ctx) | |||
358 | SetPageUptodate(page); | 408 | SetPageUptodate(page); |
359 | SetPageDirty(page); | 409 | SetPageDirty(page); |
360 | unlock_page(page); | 410 | unlock_page(page); |
411 | |||
412 | ctx->ring_pages[i] = page; | ||
361 | } | 413 | } |
362 | ctx->aio_ring_file = file; | 414 | ctx->nr_pages = i; |
363 | nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) | ||
364 | / sizeof(struct io_event); | ||
365 | 415 | ||
366 | ctx->ring_pages = ctx->internal_pages; | 416 | if (unlikely(i != nr_pages)) { |
367 | if (nr_pages > AIO_RING_PAGES) { | 417 | aio_free_ring(ctx); |
368 | ctx->ring_pages = kcalloc(nr_pages, sizeof(struct page *), | 418 | return -EAGAIN; |
369 | GFP_KERNEL); | ||
370 | if (!ctx->ring_pages) | ||
371 | return -ENOMEM; | ||
372 | } | 419 | } |
373 | 420 | ||
374 | ctx->mmap_size = nr_pages * PAGE_SIZE; | 421 | ctx->mmap_size = nr_pages * PAGE_SIZE; |
@@ -377,9 +424,9 @@ static int aio_setup_ring(struct kioctx *ctx) | |||
377 | down_write(&mm->mmap_sem); | 424 | down_write(&mm->mmap_sem); |
378 | ctx->mmap_base = do_mmap_pgoff(ctx->aio_ring_file, 0, ctx->mmap_size, | 425 | ctx->mmap_base = do_mmap_pgoff(ctx->aio_ring_file, 0, ctx->mmap_size, |
379 | PROT_READ | PROT_WRITE, | 426 | PROT_READ | PROT_WRITE, |
380 | MAP_SHARED | MAP_POPULATE, 0, &populate); | 427 | MAP_SHARED, 0, &unused); |
428 | up_write(&mm->mmap_sem); | ||
381 | if (IS_ERR((void *)ctx->mmap_base)) { | 429 | if (IS_ERR((void *)ctx->mmap_base)) { |
382 | up_write(&mm->mmap_sem); | ||
383 | ctx->mmap_size = 0; | 430 | ctx->mmap_size = 0; |
384 | aio_free_ring(ctx); | 431 | aio_free_ring(ctx); |
385 | return -EAGAIN; | 432 | return -EAGAIN; |
@@ -387,27 +434,6 @@ static int aio_setup_ring(struct kioctx *ctx) | |||
387 | 434 | ||
388 | pr_debug("mmap address: 0x%08lx\n", ctx->mmap_base); | 435 | pr_debug("mmap address: 0x%08lx\n", ctx->mmap_base); |
389 | 436 | ||
390 | /* We must do this while still holding mmap_sem for write, as we | ||
391 | * need to be protected against userspace attempting to mremap() | ||
392 | * or munmap() the ring buffer. | ||
393 | */ | ||
394 | ctx->nr_pages = get_user_pages(current, mm, ctx->mmap_base, nr_pages, | ||
395 | 1, 0, ctx->ring_pages, NULL); | ||
396 | |||
397 | /* Dropping the reference here is safe as the page cache will hold | ||
398 | * onto the pages for us. It is also required so that page migration | ||
399 | * can unmap the pages and get the right reference count. | ||
400 | */ | ||
401 | for (i = 0; i < ctx->nr_pages; i++) | ||
402 | put_page(ctx->ring_pages[i]); | ||
403 | |||
404 | up_write(&mm->mmap_sem); | ||
405 | |||
406 | if (unlikely(ctx->nr_pages != nr_pages)) { | ||
407 | aio_free_ring(ctx); | ||
408 | return -EAGAIN; | ||
409 | } | ||
410 | |||
411 | ctx->user_id = ctx->mmap_base; | 437 | ctx->user_id = ctx->mmap_base; |
412 | ctx->nr_events = nr_events; /* trusted copy */ | 438 | ctx->nr_events = nr_events; /* trusted copy */ |
413 | 439 | ||
@@ -645,12 +671,13 @@ static struct kioctx *ioctx_alloc(unsigned nr_events) | |||
645 | aio_nr + nr_events < aio_nr) { | 671 | aio_nr + nr_events < aio_nr) { |
646 | spin_unlock(&aio_nr_lock); | 672 | spin_unlock(&aio_nr_lock); |
647 | err = -EAGAIN; | 673 | err = -EAGAIN; |
648 | goto err; | 674 | goto err_ctx; |
649 | } | 675 | } |
650 | aio_nr += ctx->max_reqs; | 676 | aio_nr += ctx->max_reqs; |
651 | spin_unlock(&aio_nr_lock); | 677 | spin_unlock(&aio_nr_lock); |
652 | 678 | ||
653 | percpu_ref_get(&ctx->users); /* io_setup() will drop this ref */ | 679 | percpu_ref_get(&ctx->users); /* io_setup() will drop this ref */ |
680 | percpu_ref_get(&ctx->reqs); /* free_ioctx_users() will drop this */ | ||
654 | 681 | ||
655 | err = ioctx_add_table(ctx, mm); | 682 | err = ioctx_add_table(ctx, mm); |
656 | if (err) | 683 | if (err) |
@@ -662,6 +689,8 @@ static struct kioctx *ioctx_alloc(unsigned nr_events) | |||
662 | 689 | ||
663 | err_cleanup: | 690 | err_cleanup: |
664 | aio_nr_sub(ctx->max_reqs); | 691 | aio_nr_sub(ctx->max_reqs); |
692 | err_ctx: | ||
693 | aio_free_ring(ctx); | ||
665 | err: | 694 | err: |
666 | free_percpu(ctx->cpu); | 695 | free_percpu(ctx->cpu); |
667 | free_percpu(ctx->reqs.pcpu_count); | 696 | free_percpu(ctx->reqs.pcpu_count); |