diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/aio.c | 42 | ||||
| -rw-r--r-- | fs/bio-integrity.c | 5 | ||||
| -rw-r--r-- | fs/bio.c | 6 | ||||
| -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/ecryptfs/crypto.c | 51 | ||||
| -rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 4 | ||||
| -rw-r--r-- | fs/ecryptfs/inode.c | 32 | ||||
| -rw-r--r-- | fs/ecryptfs/keystore.c | 3 | ||||
| -rw-r--r-- | fs/ecryptfs/main.c | 5 | ||||
| -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/lockd/clntlock.c | 51 | ||||
| -rw-r--r-- | fs/minix/inode.c | 2 | ||||
| -rw-r--r-- | fs/nfs/client.c | 73 | ||||
| -rw-r--r-- | fs/nfs/dir.c | 8 | ||||
| -rw-r--r-- | fs/nfs/nfs3acl.c | 27 | ||||
| -rw-r--r-- | fs/nfs/nfs3xdr.c | 34 | ||||
| -rw-r--r-- | fs/nfs/nfs4namespace.c | 15 | ||||
| -rw-r--r-- | fs/nfsd/nfs4xdr.c | 1 | ||||
| -rw-r--r-- | fs/ocfs2/alloc.c | 3 | ||||
| -rw-r--r-- | fs/ocfs2/aops.c | 7 | ||||
| -rw-r--r-- | fs/ocfs2/namei.c | 3 | ||||
| -rw-r--r-- | fs/ocfs2/ocfs2_fs.h | 6 | ||||
| -rw-r--r-- | fs/ocfs2/xattr.c | 30 | ||||
| -rw-r--r-- | fs/proc/base.c | 16 | ||||
| -rw-r--r-- | fs/ramfs/file-nommu.c | 4 | ||||
| -rw-r--r-- | fs/ufs/super.c | 2 |
31 files changed, 394 insertions, 144 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/bio-integrity.c b/fs/bio-integrity.c index 549b0144da11..fe2b1aa2464e 100644 --- a/fs/bio-integrity.c +++ b/fs/bio-integrity.c | |||
| @@ -685,19 +685,20 @@ EXPORT_SYMBOL(bio_integrity_split); | |||
| 685 | * bio_integrity_clone - Callback for cloning bios with integrity metadata | 685 | * bio_integrity_clone - Callback for cloning bios with integrity metadata |
| 686 | * @bio: New bio | 686 | * @bio: New bio |
| 687 | * @bio_src: Original bio | 687 | * @bio_src: Original bio |
| 688 | * @gfp_mask: Memory allocation mask | ||
| 688 | * @bs: bio_set to allocate bip from | 689 | * @bs: bio_set to allocate bip from |
| 689 | * | 690 | * |
| 690 | * Description: Called to allocate a bip when cloning a bio | 691 | * Description: Called to allocate a bip when cloning a bio |
| 691 | */ | 692 | */ |
| 692 | int bio_integrity_clone(struct bio *bio, struct bio *bio_src, | 693 | int bio_integrity_clone(struct bio *bio, struct bio *bio_src, |
| 693 | struct bio_set *bs) | 694 | gfp_t gfp_mask, struct bio_set *bs) |
| 694 | { | 695 | { |
| 695 | struct bio_integrity_payload *bip_src = bio_src->bi_integrity; | 696 | struct bio_integrity_payload *bip_src = bio_src->bi_integrity; |
| 696 | struct bio_integrity_payload *bip; | 697 | struct bio_integrity_payload *bip; |
| 697 | 698 | ||
| 698 | BUG_ON(bip_src == NULL); | 699 | BUG_ON(bip_src == NULL); |
| 699 | 700 | ||
| 700 | bip = bio_integrity_alloc_bioset(bio, GFP_NOIO, bip_src->bip_vcnt, bs); | 701 | bip = bio_integrity_alloc_bioset(bio, gfp_mask, bip_src->bip_vcnt, bs); |
| 701 | 702 | ||
| 702 | if (bip == NULL) | 703 | if (bip == NULL) |
| 703 | return -EIO; | 704 | return -EIO; |
| @@ -463,10 +463,12 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask) | |||
| 463 | if (bio_integrity(bio)) { | 463 | if (bio_integrity(bio)) { |
| 464 | int ret; | 464 | int ret; |
| 465 | 465 | ||
| 466 | ret = bio_integrity_clone(b, bio, fs_bio_set); | 466 | ret = bio_integrity_clone(b, bio, gfp_mask, fs_bio_set); |
| 467 | 467 | ||
| 468 | if (ret < 0) | 468 | if (ret < 0) { |
| 469 | bio_put(b); | ||
| 469 | return NULL; | 470 | return NULL; |
| 471 | } | ||
| 470 | } | 472 | } |
| 471 | 473 | ||
| 472 | return b; | 474 | return b; |
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/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index f6caeb1d1106..8b65f289ee00 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
| @@ -946,6 +946,8 @@ static int ecryptfs_copy_mount_wide_sigs_to_inode_sigs( | |||
| 946 | list_for_each_entry(global_auth_tok, | 946 | list_for_each_entry(global_auth_tok, |
| 947 | &mount_crypt_stat->global_auth_tok_list, | 947 | &mount_crypt_stat->global_auth_tok_list, |
| 948 | mount_crypt_stat_list) { | 948 | mount_crypt_stat_list) { |
| 949 | if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_FNEK) | ||
| 950 | continue; | ||
| 949 | rc = ecryptfs_add_keysig(crypt_stat, global_auth_tok->sig); | 951 | rc = ecryptfs_add_keysig(crypt_stat, global_auth_tok->sig); |
| 950 | if (rc) { | 952 | if (rc) { |
| 951 | printk(KERN_ERR "Error adding keysig; rc = [%d]\n", rc); | 953 | printk(KERN_ERR "Error adding keysig; rc = [%d]\n", rc); |
| @@ -1322,14 +1324,13 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max, | |||
| 1322 | } | 1324 | } |
| 1323 | 1325 | ||
| 1324 | static int | 1326 | static int |
| 1325 | ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, | 1327 | ecryptfs_write_metadata_to_contents(struct dentry *ecryptfs_dentry, |
| 1326 | struct dentry *ecryptfs_dentry, | 1328 | char *virt, size_t virt_len) |
| 1327 | char *virt) | ||
| 1328 | { | 1329 | { |
| 1329 | int rc; | 1330 | int rc; |
| 1330 | 1331 | ||
| 1331 | rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt, | 1332 | rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt, |
| 1332 | 0, crypt_stat->num_header_bytes_at_front); | 1333 | 0, virt_len); |
| 1333 | if (rc) | 1334 | if (rc) |
| 1334 | printk(KERN_ERR "%s: Error attempting to write header " | 1335 | printk(KERN_ERR "%s: Error attempting to write header " |
| 1335 | "information to lower file; rc = [%d]\n", __func__, | 1336 | "information to lower file; rc = [%d]\n", __func__, |
| @@ -1339,7 +1340,6 @@ ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, | |||
| 1339 | 1340 | ||
| 1340 | static int | 1341 | static int |
| 1341 | ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, | 1342 | ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, |
| 1342 | struct ecryptfs_crypt_stat *crypt_stat, | ||
| 1343 | char *page_virt, size_t size) | 1343 | char *page_virt, size_t size) |
| 1344 | { | 1344 | { |
| 1345 | int rc; | 1345 | int rc; |
| @@ -1349,6 +1349,17 @@ ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, | |||
| 1349 | return rc; | 1349 | return rc; |
| 1350 | } | 1350 | } |
| 1351 | 1351 | ||
| 1352 | static unsigned long ecryptfs_get_zeroed_pages(gfp_t gfp_mask, | ||
| 1353 | unsigned int order) | ||
| 1354 | { | ||
| 1355 | struct page *page; | ||
| 1356 | |||
| 1357 | page = alloc_pages(gfp_mask | __GFP_ZERO, order); | ||
| 1358 | if (page) | ||
| 1359 | return (unsigned long) page_address(page); | ||
| 1360 | return 0; | ||
| 1361 | } | ||
| 1362 | |||
| 1352 | /** | 1363 | /** |
| 1353 | * ecryptfs_write_metadata | 1364 | * ecryptfs_write_metadata |
| 1354 | * @ecryptfs_dentry: The eCryptfs dentry | 1365 | * @ecryptfs_dentry: The eCryptfs dentry |
| @@ -1365,7 +1376,9 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) | |||
| 1365 | { | 1376 | { |
| 1366 | struct ecryptfs_crypt_stat *crypt_stat = | 1377 | struct ecryptfs_crypt_stat *crypt_stat = |
| 1367 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; | 1378 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; |
| 1379 | unsigned int order; | ||
| 1368 | char *virt; | 1380 | char *virt; |
| 1381 | size_t virt_len; | ||
| 1369 | size_t size = 0; | 1382 | size_t size = 0; |
| 1370 | int rc = 0; | 1383 | int rc = 0; |
| 1371 | 1384 | ||
| @@ -1381,33 +1394,35 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) | |||
| 1381 | rc = -EINVAL; | 1394 | rc = -EINVAL; |
| 1382 | goto out; | 1395 | goto out; |
| 1383 | } | 1396 | } |
| 1397 | virt_len = crypt_stat->num_header_bytes_at_front; | ||
| 1398 | order = get_order(virt_len); | ||
| 1384 | /* Released in this function */ | 1399 | /* Released in this function */ |
| 1385 | virt = (char *)get_zeroed_page(GFP_KERNEL); | 1400 | virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order); |
| 1386 | if (!virt) { | 1401 | if (!virt) { |
| 1387 | printk(KERN_ERR "%s: Out of memory\n", __func__); | 1402 | printk(KERN_ERR "%s: Out of memory\n", __func__); |
| 1388 | rc = -ENOMEM; | 1403 | rc = -ENOMEM; |
| 1389 | goto out; | 1404 | goto out; |
| 1390 | } | 1405 | } |
| 1391 | rc = ecryptfs_write_headers_virt(virt, PAGE_CACHE_SIZE, &size, | 1406 | rc = ecryptfs_write_headers_virt(virt, virt_len, &size, crypt_stat, |
| 1392 | crypt_stat, ecryptfs_dentry); | 1407 | ecryptfs_dentry); |
| 1393 | if (unlikely(rc)) { | 1408 | if (unlikely(rc)) { |
| 1394 | printk(KERN_ERR "%s: Error whilst writing headers; rc = [%d]\n", | 1409 | printk(KERN_ERR "%s: Error whilst writing headers; rc = [%d]\n", |
| 1395 | __func__, rc); | 1410 | __func__, rc); |
| 1396 | goto out_free; | 1411 | goto out_free; |
| 1397 | } | 1412 | } |
| 1398 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | 1413 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
| 1399 | rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, | 1414 | rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, virt, |
| 1400 | crypt_stat, virt, size); | 1415 | size); |
| 1401 | else | 1416 | else |
| 1402 | rc = ecryptfs_write_metadata_to_contents(crypt_stat, | 1417 | rc = ecryptfs_write_metadata_to_contents(ecryptfs_dentry, virt, |
| 1403 | ecryptfs_dentry, virt); | 1418 | virt_len); |
| 1404 | if (rc) { | 1419 | if (rc) { |
| 1405 | printk(KERN_ERR "%s: Error writing metadata out to lower file; " | 1420 | printk(KERN_ERR "%s: Error writing metadata out to lower file; " |
| 1406 | "rc = [%d]\n", __func__, rc); | 1421 | "rc = [%d]\n", __func__, rc); |
| 1407 | goto out_free; | 1422 | goto out_free; |
| 1408 | } | 1423 | } |
| 1409 | out_free: | 1424 | out_free: |
| 1410 | free_page((unsigned long)virt); | 1425 | free_pages((unsigned long)virt, order); |
| 1411 | out: | 1426 | out: |
| 1412 | return rc; | 1427 | return rc; |
| 1413 | } | 1428 | } |
| @@ -2206,17 +2221,19 @@ int ecryptfs_decode_and_decrypt_filename(char **plaintext_name, | |||
| 2206 | struct dentry *ecryptfs_dir_dentry, | 2221 | struct dentry *ecryptfs_dir_dentry, |
| 2207 | const char *name, size_t name_size) | 2222 | const char *name, size_t name_size) |
| 2208 | { | 2223 | { |
| 2224 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | ||
| 2225 | &ecryptfs_superblock_to_private( | ||
| 2226 | ecryptfs_dir_dentry->d_sb)->mount_crypt_stat; | ||
| 2209 | char *decoded_name; | 2227 | char *decoded_name; |
| 2210 | size_t decoded_name_size; | 2228 | size_t decoded_name_size; |
| 2211 | size_t packet_size; | 2229 | size_t packet_size; |
| 2212 | int rc = 0; | 2230 | int rc = 0; |
| 2213 | 2231 | ||
| 2214 | if ((name_size > ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) | 2232 | if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) |
| 2233 | && !(mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) | ||
| 2234 | && (name_size > ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) | ||
| 2215 | && (strncmp(name, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX, | 2235 | && (strncmp(name, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX, |
| 2216 | ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) == 0)) { | 2236 | ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) == 0)) { |
| 2217 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | ||
| 2218 | &ecryptfs_superblock_to_private( | ||
| 2219 | ecryptfs_dir_dentry->d_sb)->mount_crypt_stat; | ||
| 2220 | const char *orig_name = name; | 2237 | const char *orig_name = name; |
| 2221 | size_t orig_name_size = name_size; | 2238 | size_t orig_name_size = name_size; |
| 2222 | 2239 | ||
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index c11fc95714ab..ac749d4d644f 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
| @@ -328,6 +328,7 @@ struct ecryptfs_dentry_info { | |||
| 328 | */ | 328 | */ |
| 329 | struct ecryptfs_global_auth_tok { | 329 | struct ecryptfs_global_auth_tok { |
| 330 | #define ECRYPTFS_AUTH_TOK_INVALID 0x00000001 | 330 | #define ECRYPTFS_AUTH_TOK_INVALID 0x00000001 |
| 331 | #define ECRYPTFS_AUTH_TOK_FNEK 0x00000002 | ||
| 331 | u32 flags; | 332 | u32 flags; |
| 332 | struct list_head mount_crypt_stat_list; | 333 | struct list_head mount_crypt_stat_list; |
| 333 | struct key *global_auth_tok_key; | 334 | struct key *global_auth_tok_key; |
| @@ -619,7 +620,6 @@ int ecryptfs_interpose(struct dentry *hidden_dentry, | |||
| 619 | u32 flags); | 620 | u32 flags); |
| 620 | int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | 621 | int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, |
| 621 | struct dentry *lower_dentry, | 622 | struct dentry *lower_dentry, |
| 622 | struct ecryptfs_crypt_stat *crypt_stat, | ||
| 623 | struct inode *ecryptfs_dir_inode, | 623 | struct inode *ecryptfs_dir_inode, |
| 624 | struct nameidata *ecryptfs_nd); | 624 | struct nameidata *ecryptfs_nd); |
| 625 | int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, | 625 | int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, |
| @@ -696,7 +696,7 @@ ecryptfs_write_header_metadata(char *virt, | |||
| 696 | int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig); | 696 | int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig); |
| 697 | int | 697 | int |
| 698 | ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | 698 | ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, |
| 699 | char *sig); | 699 | char *sig, u32 global_auth_tok_flags); |
| 700 | int ecryptfs_get_global_auth_tok_for_sig( | 700 | int ecryptfs_get_global_auth_tok_for_sig( |
| 701 | struct ecryptfs_global_auth_tok **global_auth_tok, | 701 | struct ecryptfs_global_auth_tok **global_auth_tok, |
| 702 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig); | 702 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig); |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 5697899a168d..55b3145b8072 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
| @@ -246,7 +246,6 @@ out: | |||
| 246 | */ | 246 | */ |
| 247 | int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | 247 | int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, |
| 248 | struct dentry *lower_dentry, | 248 | struct dentry *lower_dentry, |
| 249 | struct ecryptfs_crypt_stat *crypt_stat, | ||
| 250 | struct inode *ecryptfs_dir_inode, | 249 | struct inode *ecryptfs_dir_inode, |
| 251 | struct nameidata *ecryptfs_nd) | 250 | struct nameidata *ecryptfs_nd) |
| 252 | { | 251 | { |
| @@ -254,6 +253,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
| 254 | struct vfsmount *lower_mnt; | 253 | struct vfsmount *lower_mnt; |
| 255 | struct inode *lower_inode; | 254 | struct inode *lower_inode; |
| 256 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | 255 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; |
| 256 | struct ecryptfs_crypt_stat *crypt_stat; | ||
| 257 | char *page_virt = NULL; | 257 | char *page_virt = NULL; |
| 258 | u64 file_size; | 258 | u64 file_size; |
| 259 | int rc = 0; | 259 | int rc = 0; |
| @@ -314,6 +314,11 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
| 314 | goto out_free_kmem; | 314 | goto out_free_kmem; |
| 315 | } | 315 | } |
| 316 | } | 316 | } |
| 317 | crypt_stat = &ecryptfs_inode_to_private( | ||
| 318 | ecryptfs_dentry->d_inode)->crypt_stat; | ||
| 319 | /* TODO: lock for crypt_stat comparison */ | ||
| 320 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) | ||
| 321 | ecryptfs_set_default_sizes(crypt_stat); | ||
| 317 | rc = ecryptfs_read_and_validate_header_region(page_virt, | 322 | rc = ecryptfs_read_and_validate_header_region(page_virt, |
| 318 | ecryptfs_dentry->d_inode); | 323 | ecryptfs_dentry->d_inode); |
| 319 | if (rc) { | 324 | if (rc) { |
| @@ -362,9 +367,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
| 362 | { | 367 | { |
| 363 | char *encrypted_and_encoded_name = NULL; | 368 | char *encrypted_and_encoded_name = NULL; |
| 364 | size_t encrypted_and_encoded_name_size; | 369 | size_t encrypted_and_encoded_name_size; |
| 365 | struct ecryptfs_crypt_stat *crypt_stat = NULL; | ||
| 366 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; | 370 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; |
| 367 | struct ecryptfs_inode_info *inode_info; | ||
| 368 | struct dentry *lower_dir_dentry, *lower_dentry; | 371 | struct dentry *lower_dir_dentry, *lower_dentry; |
| 369 | int rc = 0; | 372 | int rc = 0; |
| 370 | 373 | ||
| @@ -388,26 +391,15 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
| 388 | } | 391 | } |
| 389 | if (lower_dentry->d_inode) | 392 | if (lower_dentry->d_inode) |
| 390 | goto lookup_and_interpose; | 393 | goto lookup_and_interpose; |
| 391 | inode_info = ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); | 394 | mount_crypt_stat = &ecryptfs_superblock_to_private( |
| 392 | if (inode_info) { | 395 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
| 393 | crypt_stat = &inode_info->crypt_stat; | 396 | if (!(mount_crypt_stat |
| 394 | /* TODO: lock for crypt_stat comparison */ | 397 | && (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES))) |
| 395 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) | ||
| 396 | ecryptfs_set_default_sizes(crypt_stat); | ||
| 397 | } | ||
| 398 | if (crypt_stat) | ||
| 399 | mount_crypt_stat = crypt_stat->mount_crypt_stat; | ||
| 400 | else | ||
| 401 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
| 402 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
| 403 | if (!(crypt_stat && (crypt_stat->flags & ECRYPTFS_ENCRYPT_FILENAMES)) | ||
| 404 | && !(mount_crypt_stat && (mount_crypt_stat->flags | ||
| 405 | & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES))) | ||
| 406 | goto lookup_and_interpose; | 398 | goto lookup_and_interpose; |
| 407 | dput(lower_dentry); | 399 | dput(lower_dentry); |
| 408 | rc = ecryptfs_encrypt_and_encode_filename( | 400 | rc = ecryptfs_encrypt_and_encode_filename( |
| 409 | &encrypted_and_encoded_name, &encrypted_and_encoded_name_size, | 401 | &encrypted_and_encoded_name, &encrypted_and_encoded_name_size, |
| 410 | crypt_stat, mount_crypt_stat, ecryptfs_dentry->d_name.name, | 402 | NULL, mount_crypt_stat, ecryptfs_dentry->d_name.name, |
| 411 | ecryptfs_dentry->d_name.len); | 403 | ecryptfs_dentry->d_name.len); |
| 412 | if (rc) { | 404 | if (rc) { |
| 413 | printk(KERN_ERR "%s: Error attempting to encrypt and encode " | 405 | printk(KERN_ERR "%s: Error attempting to encrypt and encode " |
| @@ -426,7 +418,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
| 426 | } | 418 | } |
| 427 | lookup_and_interpose: | 419 | lookup_and_interpose: |
| 428 | rc = ecryptfs_lookup_and_interpose_lower(ecryptfs_dentry, lower_dentry, | 420 | rc = ecryptfs_lookup_and_interpose_lower(ecryptfs_dentry, lower_dentry, |
| 429 | crypt_stat, ecryptfs_dir_inode, | 421 | ecryptfs_dir_inode, |
| 430 | ecryptfs_nd); | 422 | ecryptfs_nd); |
| 431 | goto out; | 423 | goto out; |
| 432 | out_d_drop: | 424 | out_d_drop: |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index ff539420cc6f..e4a6223c3145 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
| @@ -2375,7 +2375,7 @@ struct kmem_cache *ecryptfs_global_auth_tok_cache; | |||
| 2375 | 2375 | ||
| 2376 | int | 2376 | int |
| 2377 | ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | 2377 | ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, |
| 2378 | char *sig) | 2378 | char *sig, u32 global_auth_tok_flags) |
| 2379 | { | 2379 | { |
| 2380 | struct ecryptfs_global_auth_tok *new_auth_tok; | 2380 | struct ecryptfs_global_auth_tok *new_auth_tok; |
| 2381 | int rc = 0; | 2381 | int rc = 0; |
| @@ -2389,6 +2389,7 @@ ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | |||
| 2389 | goto out; | 2389 | goto out; |
| 2390 | } | 2390 | } |
| 2391 | memcpy(new_auth_tok->sig, sig, ECRYPTFS_SIG_SIZE_HEX); | 2391 | memcpy(new_auth_tok->sig, sig, ECRYPTFS_SIG_SIZE_HEX); |
| 2392 | new_auth_tok->flags = global_auth_tok_flags; | ||
| 2392 | new_auth_tok->sig[ECRYPTFS_SIG_SIZE_HEX] = '\0'; | 2393 | new_auth_tok->sig[ECRYPTFS_SIG_SIZE_HEX] = '\0'; |
| 2393 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); | 2394 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); |
| 2394 | list_add(&new_auth_tok->mount_crypt_stat_list, | 2395 | list_add(&new_auth_tok->mount_crypt_stat_list, |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 789cf2e1be1e..aed56c25539b 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
| @@ -319,7 +319,7 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
| 319 | case ecryptfs_opt_ecryptfs_sig: | 319 | case ecryptfs_opt_ecryptfs_sig: |
| 320 | sig_src = args[0].from; | 320 | sig_src = args[0].from; |
| 321 | rc = ecryptfs_add_global_auth_tok(mount_crypt_stat, | 321 | rc = ecryptfs_add_global_auth_tok(mount_crypt_stat, |
| 322 | sig_src); | 322 | sig_src, 0); |
| 323 | if (rc) { | 323 | if (rc) { |
| 324 | printk(KERN_ERR "Error attempting to register " | 324 | printk(KERN_ERR "Error attempting to register " |
| 325 | "global sig; rc = [%d]\n", rc); | 325 | "global sig; rc = [%d]\n", rc); |
| @@ -370,7 +370,8 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
| 370 | ECRYPTFS_SIG_SIZE_HEX] = '\0'; | 370 | ECRYPTFS_SIG_SIZE_HEX] = '\0'; |
| 371 | rc = ecryptfs_add_global_auth_tok( | 371 | rc = ecryptfs_add_global_auth_tok( |
| 372 | mount_crypt_stat, | 372 | mount_crypt_stat, |
| 373 | mount_crypt_stat->global_default_fnek_sig); | 373 | mount_crypt_stat->global_default_fnek_sig, |
| 374 | ECRYPTFS_AUTH_TOK_FNEK); | ||
| 374 | if (rc) { | 375 | if (rc) { |
| 375 | printk(KERN_ERR "Error attempting to register " | 376 | printk(KERN_ERR "Error attempting to register " |
| 376 | "global fnek sig [%s]; rc = [%d]\n", | 377 | "global fnek sig [%s]; rc = [%d]\n", |
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/lockd/clntlock.c b/fs/lockd/clntlock.c index 1f3b0fc0d351..aedc47a264c1 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
| @@ -139,6 +139,55 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout) | |||
| 139 | return 0; | 139 | return 0; |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 143 | static const struct in6_addr *nlmclnt_map_v4addr(const struct sockaddr *sap, | ||
| 144 | struct in6_addr *addr_mapped) | ||
| 145 | { | ||
| 146 | const struct sockaddr_in *sin = (const struct sockaddr_in *)sap; | ||
| 147 | |||
| 148 | switch (sap->sa_family) { | ||
| 149 | case AF_INET6: | ||
| 150 | return &((const struct sockaddr_in6 *)sap)->sin6_addr; | ||
| 151 | case AF_INET: | ||
| 152 | ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, addr_mapped); | ||
| 153 | return addr_mapped; | ||
| 154 | } | ||
| 155 | |||
| 156 | return NULL; | ||
| 157 | } | ||
| 158 | |||
| 159 | /* | ||
| 160 | * If lockd is using a PF_INET6 listener, all incoming requests appear | ||
| 161 | * to come from AF_INET6 remotes. The address of AF_INET remotes are | ||
| 162 | * mapped to AF_INET6 automatically by the network layer. In case the | ||
| 163 | * user passed an AF_INET server address at mount time, ensure both | ||
| 164 | * addresses are AF_INET6 before comparing them. | ||
| 165 | */ | ||
| 166 | static int nlmclnt_cmp_addr(const struct nlm_host *host, | ||
| 167 | const struct sockaddr *sap) | ||
| 168 | { | ||
| 169 | const struct in6_addr *addr1; | ||
| 170 | const struct in6_addr *addr2; | ||
| 171 | struct in6_addr addr1_mapped; | ||
| 172 | struct in6_addr addr2_mapped; | ||
| 173 | |||
| 174 | addr1 = nlmclnt_map_v4addr(nlm_addr(host), &addr1_mapped); | ||
| 175 | if (likely(addr1 != NULL)) { | ||
| 176 | addr2 = nlmclnt_map_v4addr(sap, &addr2_mapped); | ||
| 177 | if (likely(addr2 != NULL)) | ||
| 178 | return ipv6_addr_equal(addr1, addr2); | ||
| 179 | } | ||
| 180 | |||
| 181 | return 0; | ||
| 182 | } | ||
| 183 | #else /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ | ||
| 184 | static int nlmclnt_cmp_addr(const struct nlm_host *host, | ||
| 185 | const struct sockaddr *sap) | ||
| 186 | { | ||
| 187 | return nlm_cmp_addr(nlm_addr(host), sap); | ||
| 188 | } | ||
| 189 | #endif /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ | ||
| 190 | |||
| 142 | /* | 191 | /* |
| 143 | * The server lockd has called us back to tell us the lock was granted | 192 | * The server lockd has called us back to tell us the lock was granted |
| 144 | */ | 193 | */ |
| @@ -166,7 +215,7 @@ __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock) | |||
| 166 | */ | 215 | */ |
| 167 | if (fl_blocked->fl_u.nfs_fl.owner->pid != lock->svid) | 216 | if (fl_blocked->fl_u.nfs_fl.owner->pid != lock->svid) |
| 168 | continue; | 217 | continue; |
| 169 | if (!nlm_cmp_addr(nlm_addr(block->b_host), addr)) | 218 | if (!nlmclnt_cmp_addr(block->b_host, addr)) |
| 170 | continue; | 219 | continue; |
| 171 | if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0) | 220 | if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0) |
| 172 | continue; | 221 | continue; |
diff --git a/fs/minix/inode.c b/fs/minix/inode.c index d1d1eb84679d..618865b3128b 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * Copyright (C) 1991, 1992 Linus Torvalds | 4 | * Copyright (C) 1991, 1992 Linus Torvalds |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 1996 Gertjan van Wingerde (gertjan@cs.vu.nl) | 6 | * Copyright (C) 1996 Gertjan van Wingerde |
| 7 | * Minix V2 fs support. | 7 | * Minix V2 fs support. |
| 8 | * | 8 | * |
| 9 | * Modified for 680x0 by Andreas Schwab | 9 | * Modified for 680x0 by Andreas Schwab |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 9b728f3565a1..574158ae2398 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
| @@ -255,6 +255,32 @@ static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, | |||
| 255 | } | 255 | } |
| 256 | return 0; | 256 | return 0; |
| 257 | } | 257 | } |
| 258 | |||
| 259 | /* | ||
| 260 | * Test if two ip6 socket addresses refer to the same socket by | ||
| 261 | * comparing relevant fields. The padding bytes specifically, are not | ||
| 262 | * compared. sin6_flowinfo is not compared because it only affects QoS | ||
| 263 | * and sin6_scope_id is only compared if the address is "link local" | ||
| 264 | * because "link local" addresses need only be unique to a specific | ||
| 265 | * link. Conversely, ordinary unicast addresses might have different | ||
| 266 | * sin6_scope_id. | ||
| 267 | * | ||
| 268 | * The caller should ensure both socket addresses are AF_INET6. | ||
| 269 | */ | ||
| 270 | static int nfs_sockaddr_cmp_ip6(const struct sockaddr *sa1, | ||
| 271 | const struct sockaddr *sa2) | ||
| 272 | { | ||
| 273 | const struct sockaddr_in6 *saddr1 = (const struct sockaddr_in6 *)sa1; | ||
| 274 | const struct sockaddr_in6 *saddr2 = (const struct sockaddr_in6 *)sa2; | ||
| 275 | |||
| 276 | if (!ipv6_addr_equal(&saddr1->sin6_addr, | ||
| 277 | &saddr1->sin6_addr)) | ||
| 278 | return 0; | ||
| 279 | if (ipv6_addr_scope(&saddr1->sin6_addr) == IPV6_ADDR_SCOPE_LINKLOCAL && | ||
| 280 | saddr1->sin6_scope_id != saddr2->sin6_scope_id) | ||
| 281 | return 0; | ||
| 282 | return saddr1->sin6_port == saddr2->sin6_port; | ||
| 283 | } | ||
| 258 | #else | 284 | #else |
| 259 | static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1, | 285 | static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1, |
| 260 | const struct sockaddr_in *sa2) | 286 | const struct sockaddr_in *sa2) |
| @@ -270,9 +296,52 @@ static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, | |||
| 270 | return nfs_sockaddr_match_ipaddr4((const struct sockaddr_in *)sa1, | 296 | return nfs_sockaddr_match_ipaddr4((const struct sockaddr_in *)sa1, |
| 271 | (const struct sockaddr_in *)sa2); | 297 | (const struct sockaddr_in *)sa2); |
| 272 | } | 298 | } |
| 299 | |||
| 300 | static int nfs_sockaddr_cmp_ip6(const struct sockaddr * sa1, | ||
| 301 | const struct sockaddr * sa2) | ||
| 302 | { | ||
| 303 | return 0; | ||
| 304 | } | ||
| 273 | #endif | 305 | #endif |
| 274 | 306 | ||
| 275 | /* | 307 | /* |
| 308 | * Test if two ip4 socket addresses refer to the same socket, by | ||
| 309 | * comparing relevant fields. The padding bytes specifically, are | ||
| 310 | * not compared. | ||
| 311 | * | ||
| 312 | * The caller should ensure both socket addresses are AF_INET. | ||
| 313 | */ | ||
| 314 | static int nfs_sockaddr_cmp_ip4(const struct sockaddr *sa1, | ||
| 315 | const struct sockaddr *sa2) | ||
| 316 | { | ||
| 317 | const struct sockaddr_in *saddr1 = (const struct sockaddr_in *)sa1; | ||
| 318 | const struct sockaddr_in *saddr2 = (const struct sockaddr_in *)sa2; | ||
| 319 | |||
| 320 | if (saddr1->sin_addr.s_addr != saddr2->sin_addr.s_addr) | ||
| 321 | return 0; | ||
| 322 | return saddr1->sin_port == saddr2->sin_port; | ||
| 323 | } | ||
| 324 | |||
| 325 | /* | ||
| 326 | * Test if two socket addresses represent the same actual socket, | ||
| 327 | * by comparing (only) relevant fields. | ||
| 328 | */ | ||
| 329 | static int nfs_sockaddr_cmp(const struct sockaddr *sa1, | ||
| 330 | const struct sockaddr *sa2) | ||
| 331 | { | ||
| 332 | if (sa1->sa_family != sa2->sa_family) | ||
| 333 | return 0; | ||
| 334 | |||
| 335 | switch (sa1->sa_family) { | ||
| 336 | case AF_INET: | ||
| 337 | return nfs_sockaddr_cmp_ip4(sa1, sa2); | ||
| 338 | case AF_INET6: | ||
| 339 | return nfs_sockaddr_cmp_ip6(sa1, sa2); | ||
| 340 | } | ||
| 341 | return 0; | ||
| 342 | } | ||
| 343 | |||
| 344 | /* | ||
| 276 | * Find a client by IP address and protocol version | 345 | * Find a client by IP address and protocol version |
| 277 | * - returns NULL if no such client | 346 | * - returns NULL if no such client |
| 278 | */ | 347 | */ |
| @@ -344,8 +413,10 @@ struct nfs_client *nfs_find_client_next(struct nfs_client *clp) | |||
| 344 | static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data) | 413 | static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data) |
| 345 | { | 414 | { |
| 346 | struct nfs_client *clp; | 415 | struct nfs_client *clp; |
| 416 | const struct sockaddr *sap = data->addr; | ||
| 347 | 417 | ||
| 348 | list_for_each_entry(clp, &nfs_client_list, cl_share_link) { | 418 | list_for_each_entry(clp, &nfs_client_list, cl_share_link) { |
| 419 | const struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr; | ||
| 349 | /* Don't match clients that failed to initialise properly */ | 420 | /* Don't match clients that failed to initialise properly */ |
| 350 | if (clp->cl_cons_state < 0) | 421 | if (clp->cl_cons_state < 0) |
| 351 | continue; | 422 | continue; |
| @@ -358,7 +429,7 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat | |||
| 358 | continue; | 429 | continue; |
| 359 | 430 | ||
| 360 | /* Match the full socket address */ | 431 | /* Match the full socket address */ |
| 361 | if (memcmp(&clp->cl_addr, data->addr, sizeof(clp->cl_addr)) != 0) | 432 | if (!nfs_sockaddr_cmp(sap, clap)) |
| 362 | continue; | 433 | continue; |
| 363 | 434 | ||
| 364 | atomic_inc(&clp->cl_count); | 435 | atomic_inc(&clp->cl_count); |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index e35c8199f82f..672368f865ca 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -1892,8 +1892,14 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask) | |||
| 1892 | cache.cred = cred; | 1892 | cache.cred = cred; |
| 1893 | cache.jiffies = jiffies; | 1893 | cache.jiffies = jiffies; |
| 1894 | status = NFS_PROTO(inode)->access(inode, &cache); | 1894 | status = NFS_PROTO(inode)->access(inode, &cache); |
| 1895 | if (status != 0) | 1895 | if (status != 0) { |
| 1896 | if (status == -ESTALE) { | ||
| 1897 | nfs_zap_caches(inode); | ||
| 1898 | if (!S_ISDIR(inode->i_mode)) | ||
| 1899 | set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); | ||
| 1900 | } | ||
| 1896 | return status; | 1901 | return status; |
| 1902 | } | ||
| 1897 | nfs_access_add_cache(inode, &cache); | 1903 | nfs_access_add_cache(inode, &cache); |
| 1898 | out: | 1904 | out: |
| 1899 | if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) | 1905 | if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) |
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index cef62557c87d..6bbf0e6daad2 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c | |||
| @@ -292,7 +292,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
| 292 | { | 292 | { |
| 293 | struct nfs_server *server = NFS_SERVER(inode); | 293 | struct nfs_server *server = NFS_SERVER(inode); |
| 294 | struct nfs_fattr fattr; | 294 | struct nfs_fattr fattr; |
| 295 | struct page *pages[NFSACL_MAXPAGES] = { }; | 295 | struct page *pages[NFSACL_MAXPAGES]; |
| 296 | struct nfs3_setaclargs args = { | 296 | struct nfs3_setaclargs args = { |
| 297 | .inode = inode, | 297 | .inode = inode, |
| 298 | .mask = NFS_ACL, | 298 | .mask = NFS_ACL, |
| @@ -303,7 +303,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
| 303 | .rpc_argp = &args, | 303 | .rpc_argp = &args, |
| 304 | .rpc_resp = &fattr, | 304 | .rpc_resp = &fattr, |
| 305 | }; | 305 | }; |
| 306 | int status, count; | 306 | int status; |
| 307 | 307 | ||
| 308 | status = -EOPNOTSUPP; | 308 | status = -EOPNOTSUPP; |
| 309 | if (!nfs_server_capable(inode, NFS_CAP_ACLS)) | 309 | if (!nfs_server_capable(inode, NFS_CAP_ACLS)) |
| @@ -319,6 +319,20 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
| 319 | if (S_ISDIR(inode->i_mode)) { | 319 | if (S_ISDIR(inode->i_mode)) { |
| 320 | args.mask |= NFS_DFACL; | 320 | args.mask |= NFS_DFACL; |
| 321 | args.acl_default = dfacl; | 321 | args.acl_default = dfacl; |
| 322 | args.len = nfsacl_size(acl, dfacl); | ||
| 323 | } else | ||
| 324 | args.len = nfsacl_size(acl, NULL); | ||
| 325 | |||
| 326 | if (args.len > NFS_ACL_INLINE_BUFSIZE) { | ||
| 327 | unsigned int npages = 1 + ((args.len - 1) >> PAGE_SHIFT); | ||
| 328 | |||
| 329 | status = -ENOMEM; | ||
| 330 | do { | ||
| 331 | args.pages[args.npages] = alloc_page(GFP_KERNEL); | ||
| 332 | if (args.pages[args.npages] == NULL) | ||
| 333 | goto out_freepages; | ||
| 334 | args.npages++; | ||
| 335 | } while (args.npages < npages); | ||
| 322 | } | 336 | } |
| 323 | 337 | ||
| 324 | dprintk("NFS call setacl\n"); | 338 | dprintk("NFS call setacl\n"); |
| @@ -329,10 +343,6 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
| 329 | nfs_zap_acl_cache(inode); | 343 | nfs_zap_acl_cache(inode); |
| 330 | dprintk("NFS reply setacl: %d\n", status); | 344 | dprintk("NFS reply setacl: %d\n", status); |
| 331 | 345 | ||
| 332 | /* pages may have been allocated at the xdr layer. */ | ||
| 333 | for (count = 0; count < NFSACL_MAXPAGES && args.pages[count]; count++) | ||
| 334 | __free_page(args.pages[count]); | ||
| 335 | |||
| 336 | switch (status) { | 346 | switch (status) { |
| 337 | case 0: | 347 | case 0: |
| 338 | status = nfs_refresh_inode(inode, &fattr); | 348 | status = nfs_refresh_inode(inode, &fattr); |
| @@ -346,6 +356,11 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
| 346 | case -ENOTSUPP: | 356 | case -ENOTSUPP: |
| 347 | status = -EOPNOTSUPP; | 357 | status = -EOPNOTSUPP; |
| 348 | } | 358 | } |
| 359 | out_freepages: | ||
| 360 | while (args.npages != 0) { | ||
| 361 | args.npages--; | ||
| 362 | __free_page(args.pages[args.npages]); | ||
| 363 | } | ||
| 349 | out: | 364 | out: |
| 350 | return status; | 365 | return status; |
| 351 | } | 366 | } |
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 11cdddec1432..6cdeacffde46 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
| @@ -82,8 +82,10 @@ | |||
| 82 | #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2) | 82 | #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2) |
| 83 | 83 | ||
| 84 | #define ACL3_getaclargs_sz (NFS3_fh_sz+1) | 84 | #define ACL3_getaclargs_sz (NFS3_fh_sz+1) |
| 85 | #define ACL3_setaclargs_sz (NFS3_fh_sz+1+2*(2+5*3)) | 85 | #define ACL3_setaclargs_sz (NFS3_fh_sz+1+ \ |
| 86 | #define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+2*(2+5*3)) | 86 | XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) |
| 87 | #define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+ \ | ||
| 88 | XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) | ||
| 87 | #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz) | 89 | #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz) |
| 88 | 90 | ||
| 89 | /* | 91 | /* |
| @@ -703,28 +705,18 @@ nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p, | |||
| 703 | struct nfs3_setaclargs *args) | 705 | struct nfs3_setaclargs *args) |
| 704 | { | 706 | { |
| 705 | struct xdr_buf *buf = &req->rq_snd_buf; | 707 | struct xdr_buf *buf = &req->rq_snd_buf; |
| 706 | unsigned int base, len_in_head, len = nfsacl_size( | 708 | unsigned int base; |
| 707 | (args->mask & NFS_ACL) ? args->acl_access : NULL, | 709 | int err; |
| 708 | (args->mask & NFS_DFACL) ? args->acl_default : NULL); | ||
| 709 | int count, err; | ||
| 710 | 710 | ||
| 711 | p = xdr_encode_fhandle(p, NFS_FH(args->inode)); | 711 | p = xdr_encode_fhandle(p, NFS_FH(args->inode)); |
| 712 | *p++ = htonl(args->mask); | 712 | *p++ = htonl(args->mask); |
| 713 | base = (char *)p - (char *)buf->head->iov_base; | 713 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); |
| 714 | /* put as much of the acls into head as possible. */ | 714 | base = req->rq_slen; |
| 715 | len_in_head = min_t(unsigned int, buf->head->iov_len - base, len); | 715 | |
| 716 | len -= len_in_head; | 716 | if (args->npages != 0) |
| 717 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p + (len_in_head >> 2)); | 717 | xdr_encode_pages(buf, args->pages, 0, args->len); |
| 718 | 718 | else | |
| 719 | for (count = 0; (count << PAGE_SHIFT) < len; count++) { | 719 | req->rq_slen += args->len; |
| 720 | args->pages[count] = alloc_page(GFP_KERNEL); | ||
| 721 | if (!args->pages[count]) { | ||
| 722 | while (count) | ||
| 723 | __free_page(args->pages[--count]); | ||
| 724 | return -ENOMEM; | ||
| 725 | } | ||
| 726 | } | ||
| 727 | xdr_encode_pages(buf, args->pages, 0, len); | ||
| 728 | 720 | ||
| 729 | err = nfsacl_encode(buf, base, args->inode, | 721 | err = nfsacl_encode(buf, base, args->inode, |
| 730 | (args->mask & NFS_ACL) ? | 722 | (args->mask & NFS_ACL) ? |
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index 30befc39b3c6..2a2a0a7143ad 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c | |||
| @@ -21,7 +21,9 @@ | |||
| 21 | #define NFSDBG_FACILITY NFSDBG_VFS | 21 | #define NFSDBG_FACILITY NFSDBG_VFS |
| 22 | 22 | ||
| 23 | /* | 23 | /* |
| 24 | * Check if fs_root is valid | 24 | * Convert the NFSv4 pathname components into a standard posix path. |
| 25 | * | ||
| 26 | * Note that the resulting string will be placed at the end of the buffer | ||
| 25 | */ | 27 | */ |
| 26 | static inline char *nfs4_pathname_string(const struct nfs4_pathname *pathname, | 28 | static inline char *nfs4_pathname_string(const struct nfs4_pathname *pathname, |
| 27 | char *buffer, ssize_t buflen) | 29 | char *buffer, ssize_t buflen) |
| @@ -99,21 +101,20 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, | |||
| 99 | { | 101 | { |
| 100 | struct vfsmount *mnt = ERR_PTR(-ENOENT); | 102 | struct vfsmount *mnt = ERR_PTR(-ENOENT); |
| 101 | char *mnt_path; | 103 | char *mnt_path; |
| 102 | int page2len; | 104 | unsigned int maxbuflen; |
| 103 | unsigned int s; | 105 | unsigned int s; |
| 104 | 106 | ||
| 105 | mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE); | 107 | mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE); |
| 106 | if (IS_ERR(mnt_path)) | 108 | if (IS_ERR(mnt_path)) |
| 107 | return mnt; | 109 | return mnt; |
| 108 | mountdata->mnt_path = mnt_path; | 110 | mountdata->mnt_path = mnt_path; |
| 109 | page2 += strlen(mnt_path) + 1; | 111 | maxbuflen = mnt_path - 1 - page2; |
| 110 | page2len = PAGE_SIZE - strlen(mnt_path) - 1; | ||
| 111 | 112 | ||
| 112 | for (s = 0; s < location->nservers; s++) { | 113 | for (s = 0; s < location->nservers; s++) { |
| 113 | const struct nfs4_string *buf = &location->servers[s]; | 114 | const struct nfs4_string *buf = &location->servers[s]; |
| 114 | struct sockaddr_storage addr; | 115 | struct sockaddr_storage addr; |
| 115 | 116 | ||
| 116 | if (buf->len <= 0 || buf->len >= PAGE_SIZE) | 117 | if (buf->len <= 0 || buf->len >= maxbuflen) |
| 117 | continue; | 118 | continue; |
| 118 | 119 | ||
| 119 | mountdata->addr = (struct sockaddr *)&addr; | 120 | mountdata->addr = (struct sockaddr *)&addr; |
| @@ -126,8 +127,8 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, | |||
| 126 | continue; | 127 | continue; |
| 127 | nfs_set_port(mountdata->addr, NFS_PORT); | 128 | nfs_set_port(mountdata->addr, NFS_PORT); |
| 128 | 129 | ||
| 129 | strncpy(page2, buf->data, page2len); | 130 | memcpy(page2, buf->data, buf->len); |
| 130 | page2[page2len] = '\0'; | 131 | page2[buf->len] = '\0'; |
| 131 | mountdata->hostname = page2; | 132 | mountdata->hostname = page2; |
| 132 | 133 | ||
| 133 | snprintf(page, PAGE_SIZE, "%s:%s", | 134 | snprintf(page, PAGE_SIZE, "%s:%s", |
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, |
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 3a9e5deed74d..19e3a96aa02c 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
| @@ -176,7 +176,8 @@ static int ocfs2_dinode_insert_check(struct inode *inode, | |||
| 176 | 176 | ||
| 177 | BUG_ON(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL); | 177 | BUG_ON(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL); |
| 178 | mlog_bug_on_msg(!ocfs2_sparse_alloc(osb) && | 178 | mlog_bug_on_msg(!ocfs2_sparse_alloc(osb) && |
| 179 | (OCFS2_I(inode)->ip_clusters != rec->e_cpos), | 179 | (OCFS2_I(inode)->ip_clusters != |
| 180 | le32_to_cpu(rec->e_cpos)), | ||
| 180 | "Device %s, asking for sparse allocation: inode %llu, " | 181 | "Device %s, asking for sparse allocation: inode %llu, " |
| 181 | "cpos %u, clusters %u\n", | 182 | "cpos %u, clusters %u\n", |
| 182 | osb->dev_str, | 183 | osb->dev_str, |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index a067a6cffb01..8e1709a679b7 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
| @@ -227,7 +227,7 @@ int ocfs2_read_inline_data(struct inode *inode, struct page *page, | |||
| 227 | size = i_size_read(inode); | 227 | size = i_size_read(inode); |
| 228 | 228 | ||
| 229 | if (size > PAGE_CACHE_SIZE || | 229 | if (size > PAGE_CACHE_SIZE || |
| 230 | size > ocfs2_max_inline_data(inode->i_sb)) { | 230 | size > ocfs2_max_inline_data_with_xattr(inode->i_sb, di)) { |
| 231 | ocfs2_error(inode->i_sb, | 231 | ocfs2_error(inode->i_sb, |
| 232 | "Inode %llu has with inline data has bad size: %Lu", | 232 | "Inode %llu has with inline data has bad size: %Lu", |
| 233 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 233 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
| @@ -1555,6 +1555,7 @@ static int ocfs2_try_to_write_inline_data(struct address_space *mapping, | |||
| 1555 | int ret, written = 0; | 1555 | int ret, written = 0; |
| 1556 | loff_t end = pos + len; | 1556 | loff_t end = pos + len; |
| 1557 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 1557 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
| 1558 | struct ocfs2_dinode *di = NULL; | ||
| 1558 | 1559 | ||
| 1559 | mlog(0, "Inode %llu, write of %u bytes at off %llu. features: 0x%x\n", | 1560 | mlog(0, "Inode %llu, write of %u bytes at off %llu. features: 0x%x\n", |
| 1560 | (unsigned long long)oi->ip_blkno, len, (unsigned long long)pos, | 1561 | (unsigned long long)oi->ip_blkno, len, (unsigned long long)pos, |
| @@ -1587,7 +1588,9 @@ static int ocfs2_try_to_write_inline_data(struct address_space *mapping, | |||
| 1587 | /* | 1588 | /* |
| 1588 | * Check whether the write can fit. | 1589 | * Check whether the write can fit. |
| 1589 | */ | 1590 | */ |
| 1590 | if (mmap_page || end > ocfs2_max_inline_data(inode->i_sb)) | 1591 | di = (struct ocfs2_dinode *)wc->w_di_bh->b_data; |
| 1592 | if (mmap_page || | ||
| 1593 | end > ocfs2_max_inline_data_with_xattr(inode->i_sb, di)) | ||
| 1591 | return 0; | 1594 | return 0; |
| 1592 | 1595 | ||
| 1593 | do_inline_write: | 1596 | do_inline_write: |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 084aba86c3b2..4b11762f249e 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
| @@ -532,7 +532,8 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
| 532 | 532 | ||
| 533 | fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL); | 533 | fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL); |
| 534 | 534 | ||
| 535 | fe->id2.i_data.id_count = cpu_to_le16(ocfs2_max_inline_data(osb->sb)); | 535 | fe->id2.i_data.id_count = cpu_to_le16( |
| 536 | ocfs2_max_inline_data_with_xattr(osb->sb, fe)); | ||
| 536 | } else { | 537 | } else { |
| 537 | fel = &fe->id2.i_list; | 538 | fel = &fe->id2.i_list; |
| 538 | fel->l_tree_depth = 0; | 539 | fel->l_tree_depth = 0; |
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index c7ae45aaa36c..2332ef740f4f 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h | |||
| @@ -1070,12 +1070,6 @@ static inline int ocfs2_fast_symlink_chars(struct super_block *sb) | |||
| 1070 | offsetof(struct ocfs2_dinode, id2.i_symlink); | 1070 | offsetof(struct ocfs2_dinode, id2.i_symlink); |
| 1071 | } | 1071 | } |
| 1072 | 1072 | ||
| 1073 | static inline int ocfs2_max_inline_data(struct super_block *sb) | ||
| 1074 | { | ||
| 1075 | return sb->s_blocksize - | ||
| 1076 | offsetof(struct ocfs2_dinode, id2.i_data.id_data); | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | static inline int ocfs2_max_inline_data_with_xattr(struct super_block *sb, | 1073 | static inline int ocfs2_max_inline_data_with_xattr(struct super_block *sb, |
| 1080 | struct ocfs2_dinode *di) | 1074 | struct ocfs2_dinode *di) |
| 1081 | { | 1075 | { |
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 4ddd788add67..2563df89fc2a 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
| @@ -547,8 +547,12 @@ int ocfs2_calc_xattr_init(struct inode *dir, | |||
| 547 | * when blocksize = 512, may reserve one more cluser for | 547 | * when blocksize = 512, may reserve one more cluser for |
| 548 | * xattr bucket, otherwise reserve one metadata block | 548 | * xattr bucket, otherwise reserve one metadata block |
| 549 | * for them is ok. | 549 | * for them is ok. |
| 550 | * If this is a new directory with inline data, | ||
| 551 | * we choose to reserve the entire inline area for | ||
| 552 | * directory contents and force an external xattr block. | ||
| 550 | */ | 553 | */ |
| 551 | if (dir->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE || | 554 | if (dir->i_sb->s_blocksize == OCFS2_MIN_BLOCKSIZE || |
| 555 | (S_ISDIR(mode) && ocfs2_supports_inline_data(osb)) || | ||
| 552 | (s_size + a_size) > OCFS2_XATTR_FREE_IN_IBODY) { | 556 | (s_size + a_size) > OCFS2_XATTR_FREE_IN_IBODY) { |
| 553 | ret = ocfs2_reserve_new_metadata_blocks(osb, 1, xattr_ac); | 557 | ret = ocfs2_reserve_new_metadata_blocks(osb, 1, xattr_ac); |
| 554 | if (ret) { | 558 | if (ret) { |
| @@ -4791,19 +4795,33 @@ static int ocfs2_xattr_bucket_set_value_outside(struct inode *inode, | |||
| 4791 | char *val, | 4795 | char *val, |
| 4792 | int value_len) | 4796 | int value_len) |
| 4793 | { | 4797 | { |
| 4794 | int offset; | 4798 | int ret, offset, block_off; |
| 4795 | struct ocfs2_xattr_value_root *xv; | 4799 | struct ocfs2_xattr_value_root *xv; |
| 4796 | struct ocfs2_xattr_entry *xe = xs->here; | 4800 | struct ocfs2_xattr_entry *xe = xs->here; |
| 4801 | struct ocfs2_xattr_header *xh = bucket_xh(xs->bucket); | ||
| 4802 | void *base; | ||
| 4797 | 4803 | ||
| 4798 | BUG_ON(!xs->base || !xe || ocfs2_xattr_is_local(xe)); | 4804 | BUG_ON(!xs->base || !xe || ocfs2_xattr_is_local(xe)); |
| 4799 | 4805 | ||
| 4800 | offset = le16_to_cpu(xe->xe_name_offset) + | 4806 | ret = ocfs2_xattr_bucket_get_name_value(inode, xh, |
| 4801 | OCFS2_XATTR_SIZE(xe->xe_name_len); | 4807 | xe - xh->xh_entries, |
| 4808 | &block_off, | ||
| 4809 | &offset); | ||
| 4810 | if (ret) { | ||
| 4811 | mlog_errno(ret); | ||
| 4812 | goto out; | ||
| 4813 | } | ||
| 4802 | 4814 | ||
| 4803 | xv = (struct ocfs2_xattr_value_root *)(xs->base + offset); | 4815 | base = bucket_block(xs->bucket, block_off); |
| 4816 | xv = (struct ocfs2_xattr_value_root *)(base + offset + | ||
| 4817 | OCFS2_XATTR_SIZE(xe->xe_name_len)); | ||
| 4804 | 4818 | ||
| 4805 | return __ocfs2_xattr_set_value_outside(inode, handle, | 4819 | ret = __ocfs2_xattr_set_value_outside(inode, handle, |
| 4806 | xv, val, value_len); | 4820 | xv, val, value_len); |
| 4821 | if (ret) | ||
| 4822 | mlog_errno(ret); | ||
| 4823 | out: | ||
| 4824 | return ret; | ||
| 4807 | } | 4825 | } |
| 4808 | 4826 | ||
| 4809 | static int ocfs2_rm_xattr_cluster(struct inode *inode, | 4827 | static int ocfs2_rm_xattr_cluster(struct inode *inode, |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 0c9de19a1633..beaa0ce3b82e 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
| @@ -3066,7 +3066,6 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
| 3066 | int retval = -ENOENT; | 3066 | int retval = -ENOENT; |
| 3067 | ino_t ino; | 3067 | ino_t ino; |
| 3068 | int tid; | 3068 | int tid; |
| 3069 | unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */ | ||
| 3070 | struct pid_namespace *ns; | 3069 | struct pid_namespace *ns; |
| 3071 | 3070 | ||
| 3072 | task = get_proc_task(inode); | 3071 | task = get_proc_task(inode); |
| @@ -3083,18 +3082,18 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
| 3083 | goto out_no_task; | 3082 | goto out_no_task; |
| 3084 | retval = 0; | 3083 | retval = 0; |
| 3085 | 3084 | ||
| 3086 | switch (pos) { | 3085 | switch ((unsigned long)filp->f_pos) { |
| 3087 | case 0: | 3086 | case 0: |
| 3088 | ino = inode->i_ino; | 3087 | ino = inode->i_ino; |
| 3089 | if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0) | 3088 | if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) < 0) |
| 3090 | goto out; | 3089 | goto out; |
| 3091 | pos++; | 3090 | filp->f_pos++; |
| 3092 | /* fall through */ | 3091 | /* fall through */ |
| 3093 | case 1: | 3092 | case 1: |
| 3094 | ino = parent_ino(dentry); | 3093 | ino = parent_ino(dentry); |
| 3095 | if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0) | 3094 | if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) < 0) |
| 3096 | goto out; | 3095 | goto out; |
| 3097 | pos++; | 3096 | filp->f_pos++; |
| 3098 | /* fall through */ | 3097 | /* fall through */ |
| 3099 | } | 3098 | } |
| 3100 | 3099 | ||
| @@ -3104,9 +3103,9 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
| 3104 | ns = filp->f_dentry->d_sb->s_fs_info; | 3103 | ns = filp->f_dentry->d_sb->s_fs_info; |
| 3105 | tid = (int)filp->f_version; | 3104 | tid = (int)filp->f_version; |
| 3106 | filp->f_version = 0; | 3105 | filp->f_version = 0; |
| 3107 | for (task = first_tid(leader, tid, pos - 2, ns); | 3106 | for (task = first_tid(leader, tid, filp->f_pos - 2, ns); |
| 3108 | task; | 3107 | task; |
| 3109 | task = next_tid(task), pos++) { | 3108 | task = next_tid(task), filp->f_pos++) { |
| 3110 | tid = task_pid_nr_ns(task, ns); | 3109 | tid = task_pid_nr_ns(task, ns); |
| 3111 | if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { | 3110 | if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { |
| 3112 | /* returning this tgid failed, save it as the first | 3111 | /* returning this tgid failed, save it as the first |
| @@ -3117,7 +3116,6 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
| 3117 | } | 3116 | } |
| 3118 | } | 3117 | } |
| 3119 | out: | 3118 | out: |
| 3120 | filp->f_pos = pos; | ||
| 3121 | put_task_struct(leader); | 3119 | put_task_struct(leader); |
| 3122 | out_no_task: | 3120 | out_no_task: |
| 3123 | return retval; | 3121 | return retval; |
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index b9b567a28376..5d7c7ececa64 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c | |||
| @@ -114,6 +114,9 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) | |||
| 114 | if (!pagevec_add(&lru_pvec, page)) | 114 | if (!pagevec_add(&lru_pvec, page)) |
| 115 | __pagevec_lru_add_file(&lru_pvec); | 115 | __pagevec_lru_add_file(&lru_pvec); |
| 116 | 116 | ||
| 117 | /* prevent the page from being discarded on memory pressure */ | ||
| 118 | SetPageDirty(page); | ||
| 119 | |||
| 117 | unlock_page(page); | 120 | unlock_page(page); |
| 118 | } | 121 | } |
| 119 | 122 | ||
| @@ -126,6 +129,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) | |||
| 126 | return -EFBIG; | 129 | return -EFBIG; |
| 127 | 130 | ||
| 128 | add_error: | 131 | add_error: |
| 132 | pagevec_lru_add_file(&lru_pvec); | ||
| 129 | page_cache_release(pages + loop); | 133 | page_cache_release(pages + loop); |
| 130 | for (loop++; loop < npages; loop++) | 134 | for (loop++; loop < npages; loop++) |
| 131 | __free_page(pages + loop); | 135 | __free_page(pages + loop); |
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index e65212dfb60e..261a1c2f22dd 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | * Stefan Reinauer <stepan@home.culture.mipt.ru> | 41 | * Stefan Reinauer <stepan@home.culture.mipt.ru> |
| 42 | * | 42 | * |
| 43 | * Module usage counts added on 96/04/29 by | 43 | * Module usage counts added on 96/04/29 by |
| 44 | * Gertjan van Wingerde <gertjan@cs.vu.nl> | 44 | * Gertjan van Wingerde <gwingerde@gmail.com> |
| 45 | * | 45 | * |
| 46 | * Clean swab support on 19970406 by | 46 | * Clean swab support on 19970406 by |
| 47 | * Francois-Rene Rideau <fare@tunes.org> | 47 | * Francois-Rene Rideau <fare@tunes.org> |
