diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/aio.c | 42 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 9 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 45 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 8 | ||||
-rw-r--r-- | fs/buffer.c | 23 | ||||
-rw-r--r-- | fs/ext4/extents.c | 6 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 4 | ||||
-rw-r--r-- | fs/ext4/mballoc.c | 13 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 1 |
9 files changed, 117 insertions, 34 deletions
@@ -443,7 +443,7 @@ static struct kiocb *__aio_get_req(struct kioctx *ctx) | |||
443 | req->private = NULL; | 443 | req->private = NULL; |
444 | req->ki_iovec = NULL; | 444 | req->ki_iovec = NULL; |
445 | INIT_LIST_HEAD(&req->ki_run_list); | 445 | INIT_LIST_HEAD(&req->ki_run_list); |
446 | req->ki_eventfd = ERR_PTR(-EINVAL); | 446 | req->ki_eventfd = NULL; |
447 | 447 | ||
448 | /* Check if the completion queue has enough free space to | 448 | /* Check if the completion queue has enough free space to |
449 | * accept an event from this io. | 449 | * accept an event from this io. |
@@ -485,8 +485,6 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req) | |||
485 | { | 485 | { |
486 | assert_spin_locked(&ctx->ctx_lock); | 486 | assert_spin_locked(&ctx->ctx_lock); |
487 | 487 | ||
488 | if (!IS_ERR(req->ki_eventfd)) | ||
489 | fput(req->ki_eventfd); | ||
490 | if (req->ki_dtor) | 488 | if (req->ki_dtor) |
491 | req->ki_dtor(req); | 489 | req->ki_dtor(req); |
492 | if (req->ki_iovec != &req->ki_inline_vec) | 490 | if (req->ki_iovec != &req->ki_inline_vec) |
@@ -508,8 +506,11 @@ static void aio_fput_routine(struct work_struct *data) | |||
508 | list_del(&req->ki_list); | 506 | list_del(&req->ki_list); |
509 | spin_unlock_irq(&fput_lock); | 507 | spin_unlock_irq(&fput_lock); |
510 | 508 | ||
511 | /* Complete the fput */ | 509 | /* Complete the fput(s) */ |
512 | __fput(req->ki_filp); | 510 | if (req->ki_filp != NULL) |
511 | __fput(req->ki_filp); | ||
512 | if (req->ki_eventfd != NULL) | ||
513 | __fput(req->ki_eventfd); | ||
513 | 514 | ||
514 | /* Link the iocb into the context's free list */ | 515 | /* Link the iocb into the context's free list */ |
515 | spin_lock_irq(&ctx->ctx_lock); | 516 | spin_lock_irq(&ctx->ctx_lock); |
@@ -527,12 +528,14 @@ static void aio_fput_routine(struct work_struct *data) | |||
527 | */ | 528 | */ |
528 | static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) | 529 | static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) |
529 | { | 530 | { |
531 | int schedule_putreq = 0; | ||
532 | |||
530 | dprintk(KERN_DEBUG "aio_put(%p): f_count=%ld\n", | 533 | dprintk(KERN_DEBUG "aio_put(%p): f_count=%ld\n", |
531 | req, atomic_long_read(&req->ki_filp->f_count)); | 534 | req, atomic_long_read(&req->ki_filp->f_count)); |
532 | 535 | ||
533 | assert_spin_locked(&ctx->ctx_lock); | 536 | assert_spin_locked(&ctx->ctx_lock); |
534 | 537 | ||
535 | req->ki_users --; | 538 | req->ki_users--; |
536 | BUG_ON(req->ki_users < 0); | 539 | BUG_ON(req->ki_users < 0); |
537 | if (likely(req->ki_users)) | 540 | if (likely(req->ki_users)) |
538 | return 0; | 541 | return 0; |
@@ -540,10 +543,23 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) | |||
540 | req->ki_cancel = NULL; | 543 | req->ki_cancel = NULL; |
541 | req->ki_retry = NULL; | 544 | req->ki_retry = NULL; |
542 | 545 | ||
543 | /* Must be done under the lock to serialise against cancellation. | 546 | /* |
544 | * Call this aio_fput as it duplicates fput via the fput_work. | 547 | * Try to optimize the aio and eventfd file* puts, by avoiding to |
548 | * schedule work in case it is not __fput() time. In normal cases, | ||
549 | * we would not be holding the last reference to the file*, so | ||
550 | * this function will be executed w/out any aio kthread wakeup. | ||
545 | */ | 551 | */ |
546 | if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) { | 552 | if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) |
553 | schedule_putreq++; | ||
554 | else | ||
555 | req->ki_filp = NULL; | ||
556 | if (req->ki_eventfd != NULL) { | ||
557 | if (unlikely(atomic_long_dec_and_test(&req->ki_eventfd->f_count))) | ||
558 | schedule_putreq++; | ||
559 | else | ||
560 | req->ki_eventfd = NULL; | ||
561 | } | ||
562 | if (unlikely(schedule_putreq)) { | ||
547 | get_ioctx(ctx); | 563 | get_ioctx(ctx); |
548 | spin_lock(&fput_lock); | 564 | spin_lock(&fput_lock); |
549 | list_add(&req->ki_list, &fput_head); | 565 | list_add(&req->ki_list, &fput_head); |
@@ -571,7 +587,7 @@ int aio_put_req(struct kiocb *req) | |||
571 | static struct kioctx *lookup_ioctx(unsigned long ctx_id) | 587 | static struct kioctx *lookup_ioctx(unsigned long ctx_id) |
572 | { | 588 | { |
573 | struct mm_struct *mm = current->mm; | 589 | struct mm_struct *mm = current->mm; |
574 | struct kioctx *ctx = NULL; | 590 | struct kioctx *ctx, *ret = NULL; |
575 | struct hlist_node *n; | 591 | struct hlist_node *n; |
576 | 592 | ||
577 | rcu_read_lock(); | 593 | rcu_read_lock(); |
@@ -579,12 +595,13 @@ static struct kioctx *lookup_ioctx(unsigned long ctx_id) | |||
579 | hlist_for_each_entry_rcu(ctx, n, &mm->ioctx_list, list) { | 595 | hlist_for_each_entry_rcu(ctx, n, &mm->ioctx_list, list) { |
580 | if (ctx->user_id == ctx_id && !ctx->dead) { | 596 | if (ctx->user_id == ctx_id && !ctx->dead) { |
581 | get_ioctx(ctx); | 597 | get_ioctx(ctx); |
598 | ret = ctx; | ||
582 | break; | 599 | break; |
583 | } | 600 | } |
584 | } | 601 | } |
585 | 602 | ||
586 | rcu_read_unlock(); | 603 | rcu_read_unlock(); |
587 | return ctx; | 604 | return ret; |
588 | } | 605 | } |
589 | 606 | ||
590 | /* | 607 | /* |
@@ -1009,7 +1026,7 @@ int aio_complete(struct kiocb *iocb, long res, long res2) | |||
1009 | * eventfd. The eventfd_signal() function is safe to be called | 1026 | * eventfd. The eventfd_signal() function is safe to be called |
1010 | * from IRQ context. | 1027 | * from IRQ context. |
1011 | */ | 1028 | */ |
1012 | if (!IS_ERR(iocb->ki_eventfd)) | 1029 | if (iocb->ki_eventfd != NULL) |
1013 | eventfd_signal(iocb->ki_eventfd, 1); | 1030 | eventfd_signal(iocb->ki_eventfd, 1); |
1014 | 1031 | ||
1015 | put_rq: | 1032 | put_rq: |
@@ -1608,6 +1625,7 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1608 | req->ki_eventfd = eventfd_fget((int) iocb->aio_resfd); | 1625 | req->ki_eventfd = eventfd_fget((int) iocb->aio_resfd); |
1609 | if (IS_ERR(req->ki_eventfd)) { | 1626 | if (IS_ERR(req->ki_eventfd)) { |
1610 | ret = PTR_ERR(req->ki_eventfd); | 1627 | ret = PTR_ERR(req->ki_eventfd); |
1628 | req->ki_eventfd = NULL; | ||
1611 | goto out_put_req; | 1629 | goto out_put_req; |
1612 | } | 1630 | } |
1613 | } | 1631 | } |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 82491ba8fa40..5e1d4e30e9d8 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -784,7 +784,14 @@ struct btrfs_fs_info { | |||
784 | struct list_head dirty_cowonly_roots; | 784 | struct list_head dirty_cowonly_roots; |
785 | 785 | ||
786 | struct btrfs_fs_devices *fs_devices; | 786 | struct btrfs_fs_devices *fs_devices; |
787 | |||
788 | /* | ||
789 | * the space_info list is almost entirely read only. It only changes | ||
790 | * when we add a new raid type to the FS, and that happens | ||
791 | * very rarely. RCU is used to protect it. | ||
792 | */ | ||
787 | struct list_head space_info; | 793 | struct list_head space_info; |
794 | |||
788 | spinlock_t delalloc_lock; | 795 | spinlock_t delalloc_lock; |
789 | spinlock_t new_trans_lock; | 796 | spinlock_t new_trans_lock; |
790 | u64 delalloc_bytes; | 797 | u64 delalloc_bytes; |
@@ -1797,6 +1804,8 @@ int btrfs_cleanup_reloc_trees(struct btrfs_root *root); | |||
1797 | int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len); | 1804 | int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len); |
1798 | u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags); | 1805 | u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags); |
1799 | void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde); | 1806 | void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde); |
1807 | void btrfs_clear_space_info_full(struct btrfs_fs_info *info); | ||
1808 | |||
1800 | int btrfs_check_metadata_free_space(struct btrfs_root *root); | 1809 | int btrfs_check_metadata_free_space(struct btrfs_root *root); |
1801 | int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, | 1810 | int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, |
1802 | u64 bytes); | 1811 | u64 bytes); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 9abf81f71c46..fefe83ad2059 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/writeback.h> | 20 | #include <linux/writeback.h> |
21 | #include <linux/blkdev.h> | 21 | #include <linux/blkdev.h> |
22 | #include <linux/sort.h> | 22 | #include <linux/sort.h> |
23 | #include <linux/rcupdate.h> | ||
23 | #include "compat.h" | 24 | #include "compat.h" |
24 | #include "hash.h" | 25 | #include "hash.h" |
25 | #include "crc32c.h" | 26 | #include "crc32c.h" |
@@ -330,13 +331,33 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, | |||
330 | { | 331 | { |
331 | struct list_head *head = &info->space_info; | 332 | struct list_head *head = &info->space_info; |
332 | struct btrfs_space_info *found; | 333 | struct btrfs_space_info *found; |
333 | list_for_each_entry(found, head, list) { | 334 | |
334 | if (found->flags == flags) | 335 | rcu_read_lock(); |
336 | list_for_each_entry_rcu(found, head, list) { | ||
337 | if (found->flags == flags) { | ||
338 | rcu_read_unlock(); | ||
335 | return found; | 339 | return found; |
340 | } | ||
336 | } | 341 | } |
342 | rcu_read_unlock(); | ||
337 | return NULL; | 343 | return NULL; |
338 | } | 344 | } |
339 | 345 | ||
346 | /* | ||
347 | * after adding space to the filesystem, we need to clear the full flags | ||
348 | * on all the space infos. | ||
349 | */ | ||
350 | void btrfs_clear_space_info_full(struct btrfs_fs_info *info) | ||
351 | { | ||
352 | struct list_head *head = &info->space_info; | ||
353 | struct btrfs_space_info *found; | ||
354 | |||
355 | rcu_read_lock(); | ||
356 | list_for_each_entry_rcu(found, head, list) | ||
357 | found->full = 0; | ||
358 | rcu_read_unlock(); | ||
359 | } | ||
360 | |||
340 | static u64 div_factor(u64 num, int factor) | 361 | static u64 div_factor(u64 num, int factor) |
341 | { | 362 | { |
342 | if (factor == 10) | 363 | if (factor == 10) |
@@ -1903,7 +1924,6 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, | |||
1903 | if (!found) | 1924 | if (!found) |
1904 | return -ENOMEM; | 1925 | return -ENOMEM; |
1905 | 1926 | ||
1906 | list_add(&found->list, &info->space_info); | ||
1907 | INIT_LIST_HEAD(&found->block_groups); | 1927 | INIT_LIST_HEAD(&found->block_groups); |
1908 | init_rwsem(&found->groups_sem); | 1928 | init_rwsem(&found->groups_sem); |
1909 | spin_lock_init(&found->lock); | 1929 | spin_lock_init(&found->lock); |
@@ -1917,6 +1937,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, | |||
1917 | found->full = 0; | 1937 | found->full = 0; |
1918 | found->force_alloc = 0; | 1938 | found->force_alloc = 0; |
1919 | *space_info = found; | 1939 | *space_info = found; |
1940 | list_add_rcu(&found->list, &info->space_info); | ||
1920 | return 0; | 1941 | return 0; |
1921 | } | 1942 | } |
1922 | 1943 | ||
@@ -6320,6 +6341,7 @@ out: | |||
6320 | int btrfs_free_block_groups(struct btrfs_fs_info *info) | 6341 | int btrfs_free_block_groups(struct btrfs_fs_info *info) |
6321 | { | 6342 | { |
6322 | struct btrfs_block_group_cache *block_group; | 6343 | struct btrfs_block_group_cache *block_group; |
6344 | struct btrfs_space_info *space_info; | ||
6323 | struct rb_node *n; | 6345 | struct rb_node *n; |
6324 | 6346 | ||
6325 | spin_lock(&info->block_group_cache_lock); | 6347 | spin_lock(&info->block_group_cache_lock); |
@@ -6341,6 +6363,23 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) | |||
6341 | spin_lock(&info->block_group_cache_lock); | 6363 | spin_lock(&info->block_group_cache_lock); |
6342 | } | 6364 | } |
6343 | spin_unlock(&info->block_group_cache_lock); | 6365 | spin_unlock(&info->block_group_cache_lock); |
6366 | |||
6367 | /* now that all the block groups are freed, go through and | ||
6368 | * free all the space_info structs. This is only called during | ||
6369 | * the final stages of unmount, and so we know nobody is | ||
6370 | * using them. We call synchronize_rcu() once before we start, | ||
6371 | * just to be on the safe side. | ||
6372 | */ | ||
6373 | synchronize_rcu(); | ||
6374 | |||
6375 | while(!list_empty(&info->space_info)) { | ||
6376 | space_info = list_entry(info->space_info.next, | ||
6377 | struct btrfs_space_info, | ||
6378 | list); | ||
6379 | |||
6380 | list_del(&space_info->list); | ||
6381 | kfree(space_info); | ||
6382 | } | ||
6344 | return 0; | 6383 | return 0; |
6345 | } | 6384 | } |
6346 | 6385 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 1316139bf9e8..dd06e18e5aac 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1374,6 +1374,12 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1374 | ret = btrfs_add_device(trans, root, device); | 1374 | ret = btrfs_add_device(trans, root, device); |
1375 | } | 1375 | } |
1376 | 1376 | ||
1377 | /* | ||
1378 | * we've got more storage, clear any full flags on the space | ||
1379 | * infos | ||
1380 | */ | ||
1381 | btrfs_clear_space_info_full(root->fs_info); | ||
1382 | |||
1377 | unlock_chunks(root); | 1383 | unlock_chunks(root); |
1378 | btrfs_commit_transaction(trans, root); | 1384 | btrfs_commit_transaction(trans, root); |
1379 | 1385 | ||
@@ -1459,6 +1465,8 @@ static int __btrfs_grow_device(struct btrfs_trans_handle *trans, | |||
1459 | device->fs_devices->total_rw_bytes += diff; | 1465 | device->fs_devices->total_rw_bytes += diff; |
1460 | 1466 | ||
1461 | device->total_bytes = new_size; | 1467 | device->total_bytes = new_size; |
1468 | btrfs_clear_space_info_full(device->dev_root->fs_info); | ||
1469 | |||
1462 | return btrfs_update_device(trans, device); | 1470 | return btrfs_update_device(trans, device); |
1463 | } | 1471 | } |
1464 | 1472 | ||
diff --git a/fs/buffer.c b/fs/buffer.c index 9f697419ed8e..891e1c78e4f1 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -760,15 +760,9 @@ EXPORT_SYMBOL(mark_buffer_dirty_inode); | |||
760 | * If warn is true, then emit a warning if the page is not uptodate and has | 760 | * If warn is true, then emit a warning if the page is not uptodate and has |
761 | * not been truncated. | 761 | * not been truncated. |
762 | */ | 762 | */ |
763 | static int __set_page_dirty(struct page *page, | 763 | static void __set_page_dirty(struct page *page, |
764 | struct address_space *mapping, int warn) | 764 | struct address_space *mapping, int warn) |
765 | { | 765 | { |
766 | if (unlikely(!mapping)) | ||
767 | return !TestSetPageDirty(page); | ||
768 | |||
769 | if (TestSetPageDirty(page)) | ||
770 | return 0; | ||
771 | |||
772 | spin_lock_irq(&mapping->tree_lock); | 766 | spin_lock_irq(&mapping->tree_lock); |
773 | if (page->mapping) { /* Race with truncate? */ | 767 | if (page->mapping) { /* Race with truncate? */ |
774 | WARN_ON_ONCE(warn && !PageUptodate(page)); | 768 | WARN_ON_ONCE(warn && !PageUptodate(page)); |
@@ -785,8 +779,6 @@ static int __set_page_dirty(struct page *page, | |||
785 | } | 779 | } |
786 | spin_unlock_irq(&mapping->tree_lock); | 780 | spin_unlock_irq(&mapping->tree_lock); |
787 | __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); | 781 | __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); |
788 | |||
789 | return 1; | ||
790 | } | 782 | } |
791 | 783 | ||
792 | /* | 784 | /* |
@@ -816,6 +808,7 @@ static int __set_page_dirty(struct page *page, | |||
816 | */ | 808 | */ |
817 | int __set_page_dirty_buffers(struct page *page) | 809 | int __set_page_dirty_buffers(struct page *page) |
818 | { | 810 | { |
811 | int newly_dirty; | ||
819 | struct address_space *mapping = page_mapping(page); | 812 | struct address_space *mapping = page_mapping(page); |
820 | 813 | ||
821 | if (unlikely(!mapping)) | 814 | if (unlikely(!mapping)) |
@@ -831,9 +824,12 @@ int __set_page_dirty_buffers(struct page *page) | |||
831 | bh = bh->b_this_page; | 824 | bh = bh->b_this_page; |
832 | } while (bh != head); | 825 | } while (bh != head); |
833 | } | 826 | } |
827 | newly_dirty = !TestSetPageDirty(page); | ||
834 | spin_unlock(&mapping->private_lock); | 828 | spin_unlock(&mapping->private_lock); |
835 | 829 | ||
836 | return __set_page_dirty(page, mapping, 1); | 830 | if (newly_dirty) |
831 | __set_page_dirty(page, mapping, 1); | ||
832 | return newly_dirty; | ||
837 | } | 833 | } |
838 | EXPORT_SYMBOL(__set_page_dirty_buffers); | 834 | EXPORT_SYMBOL(__set_page_dirty_buffers); |
839 | 835 | ||
@@ -1262,8 +1258,11 @@ void mark_buffer_dirty(struct buffer_head *bh) | |||
1262 | return; | 1258 | return; |
1263 | } | 1259 | } |
1264 | 1260 | ||
1265 | if (!test_set_buffer_dirty(bh)) | 1261 | if (!test_set_buffer_dirty(bh)) { |
1266 | __set_page_dirty(bh->b_page, page_mapping(bh->b_page), 0); | 1262 | struct page *page = bh->b_page; |
1263 | if (!TestSetPageDirty(page)) | ||
1264 | __set_page_dirty(page, page_mapping(page), 0); | ||
1265 | } | ||
1267 | } | 1266 | } |
1268 | 1267 | ||
1269 | /* | 1268 | /* |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index e2eab196875f..e0aa4fe4f596 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -1122,7 +1122,8 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path, | |||
1122 | struct ext4_extent_idx *ix; | 1122 | struct ext4_extent_idx *ix; |
1123 | struct ext4_extent *ex; | 1123 | struct ext4_extent *ex; |
1124 | ext4_fsblk_t block; | 1124 | ext4_fsblk_t block; |
1125 | int depth, ee_len; | 1125 | int depth; /* Note, NOT eh_depth; depth from top of tree */ |
1126 | int ee_len; | ||
1126 | 1127 | ||
1127 | BUG_ON(path == NULL); | 1128 | BUG_ON(path == NULL); |
1128 | depth = path->p_depth; | 1129 | depth = path->p_depth; |
@@ -1179,7 +1180,8 @@ got_index: | |||
1179 | if (bh == NULL) | 1180 | if (bh == NULL) |
1180 | return -EIO; | 1181 | return -EIO; |
1181 | eh = ext_block_hdr(bh); | 1182 | eh = ext_block_hdr(bh); |
1182 | if (ext4_ext_check_header(inode, eh, depth)) { | 1183 | /* subtract from p_depth to get proper eh_depth */ |
1184 | if (ext4_ext_check_header(inode, eh, path->p_depth - depth)) { | ||
1183 | put_bh(bh); | 1185 | put_bh(bh); |
1184 | return -EIO; | 1186 | return -EIO; |
1185 | } | 1187 | } |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 627f8c3337a3..2d2b3585ee91 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -698,6 +698,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) | |||
698 | struct inode *ret; | 698 | struct inode *ret; |
699 | ext4_group_t i; | 699 | ext4_group_t i; |
700 | int free = 0; | 700 | int free = 0; |
701 | static int once = 1; | ||
701 | ext4_group_t flex_group; | 702 | ext4_group_t flex_group; |
702 | 703 | ||
703 | /* Cannot create files in a deleted directory */ | 704 | /* Cannot create files in a deleted directory */ |
@@ -719,7 +720,8 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) | |||
719 | ret2 = find_group_flex(sb, dir, &group); | 720 | ret2 = find_group_flex(sb, dir, &group); |
720 | if (ret2 == -1) { | 721 | if (ret2 == -1) { |
721 | ret2 = find_group_other(sb, dir, &group); | 722 | ret2 = find_group_other(sb, dir, &group); |
722 | if (ret2 == 0 && printk_ratelimit()) | 723 | if (ret2 == 0 && once) |
724 | once = 0; | ||
723 | printk(KERN_NOTICE "ext4: find_group_flex " | 725 | printk(KERN_NOTICE "ext4: find_group_flex " |
724 | "failed, fallback succeeded dir %lu\n", | 726 | "failed, fallback succeeded dir %lu\n", |
725 | dir->i_ino); | 727 | dir->i_ino); |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 4415beeb0b62..9f61e62f435f 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -1447,7 +1447,7 @@ static void ext4_mb_measure_extent(struct ext4_allocation_context *ac, | |||
1447 | struct ext4_free_extent *gex = &ac->ac_g_ex; | 1447 | struct ext4_free_extent *gex = &ac->ac_g_ex; |
1448 | 1448 | ||
1449 | BUG_ON(ex->fe_len <= 0); | 1449 | BUG_ON(ex->fe_len <= 0); |
1450 | BUG_ON(ex->fe_len >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); | 1450 | BUG_ON(ex->fe_len > EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); |
1451 | BUG_ON(ex->fe_start >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); | 1451 | BUG_ON(ex->fe_start >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); |
1452 | BUG_ON(ac->ac_status != AC_STATUS_CONTINUE); | 1452 | BUG_ON(ac->ac_status != AC_STATUS_CONTINUE); |
1453 | 1453 | ||
@@ -3292,7 +3292,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, | |||
3292 | } | 3292 | } |
3293 | BUG_ON(start + size <= ac->ac_o_ex.fe_logical && | 3293 | BUG_ON(start + size <= ac->ac_o_ex.fe_logical && |
3294 | start > ac->ac_o_ex.fe_logical); | 3294 | start > ac->ac_o_ex.fe_logical); |
3295 | BUG_ON(size <= 0 || size >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); | 3295 | BUG_ON(size <= 0 || size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); |
3296 | 3296 | ||
3297 | /* now prepare goal request */ | 3297 | /* now prepare goal request */ |
3298 | 3298 | ||
@@ -3589,6 +3589,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, | |||
3589 | struct super_block *sb, struct ext4_prealloc_space *pa) | 3589 | struct super_block *sb, struct ext4_prealloc_space *pa) |
3590 | { | 3590 | { |
3591 | ext4_group_t grp; | 3591 | ext4_group_t grp; |
3592 | ext4_fsblk_t grp_blk; | ||
3592 | 3593 | ||
3593 | if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0) | 3594 | if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0) |
3594 | return; | 3595 | return; |
@@ -3603,8 +3604,12 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, | |||
3603 | pa->pa_deleted = 1; | 3604 | pa->pa_deleted = 1; |
3604 | spin_unlock(&pa->pa_lock); | 3605 | spin_unlock(&pa->pa_lock); |
3605 | 3606 | ||
3606 | /* -1 is to protect from crossing allocation group */ | 3607 | grp_blk = pa->pa_pstart; |
3607 | ext4_get_group_no_and_offset(sb, pa->pa_pstart - 1, &grp, NULL); | 3608 | /* If linear, pa_pstart may be in the next group when pa is used up */ |
3609 | if (pa->pa_linear) | ||
3610 | grp_blk--; | ||
3611 | |||
3612 | ext4_get_group_no_and_offset(sb, grp_blk, &grp, NULL); | ||
3608 | 3613 | ||
3609 | /* | 3614 | /* |
3610 | * possible race: | 3615 | * possible race: |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index f65953be39c0..9250067943d8 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -2596,6 +2596,7 @@ static nfsd4_enc nfsd4_enc_ops[] = { | |||
2596 | [OP_LOOKUPP] = (nfsd4_enc)nfsd4_encode_noop, | 2596 | [OP_LOOKUPP] = (nfsd4_enc)nfsd4_encode_noop, |
2597 | [OP_NVERIFY] = (nfsd4_enc)nfsd4_encode_noop, | 2597 | [OP_NVERIFY] = (nfsd4_enc)nfsd4_encode_noop, |
2598 | [OP_OPEN] = (nfsd4_enc)nfsd4_encode_open, | 2598 | [OP_OPEN] = (nfsd4_enc)nfsd4_encode_open, |
2599 | [OP_OPENATTR] = (nfsd4_enc)nfsd4_encode_noop, | ||
2599 | [OP_OPEN_CONFIRM] = (nfsd4_enc)nfsd4_encode_open_confirm, | 2600 | [OP_OPEN_CONFIRM] = (nfsd4_enc)nfsd4_encode_open_confirm, |
2600 | [OP_OPEN_DOWNGRADE] = (nfsd4_enc)nfsd4_encode_open_downgrade, | 2601 | [OP_OPEN_DOWNGRADE] = (nfsd4_enc)nfsd4_encode_open_downgrade, |
2601 | [OP_PUTFH] = (nfsd4_enc)nfsd4_encode_noop, | 2602 | [OP_PUTFH] = (nfsd4_enc)nfsd4_encode_noop, |