diff options
Diffstat (limited to 'fs')
89 files changed, 1636 insertions, 591 deletions
diff --git a/fs/Makefile b/fs/Makefile index 38bc735c67ad..dc20db348679 100644 --- a/fs/Makefile +++ b/fs/Makefile | |||
| @@ -69,10 +69,12 @@ obj-$(CONFIG_DLM) += dlm/ | |||
| 69 | # Do not add any filesystems before this line | 69 | # Do not add any filesystems before this line |
| 70 | obj-$(CONFIG_REISERFS_FS) += reiserfs/ | 70 | obj-$(CONFIG_REISERFS_FS) += reiserfs/ |
| 71 | obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3 | 71 | obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3 |
| 72 | obj-$(CONFIG_EXT4_FS) += ext4/ # Before ext2 so root fs can be ext4 | 72 | obj-$(CONFIG_EXT2_FS) += ext2/ |
| 73 | # We place ext4 after ext2 so plain ext2 root fs's are mounted using ext2 | ||
| 74 | # unless explicitly requested by rootfstype | ||
| 75 | obj-$(CONFIG_EXT4_FS) += ext4/ | ||
| 73 | obj-$(CONFIG_JBD) += jbd/ | 76 | obj-$(CONFIG_JBD) += jbd/ |
| 74 | obj-$(CONFIG_JBD2) += jbd2/ | 77 | obj-$(CONFIG_JBD2) += jbd2/ |
| 75 | obj-$(CONFIG_EXT2_FS) += ext2/ | ||
| 76 | obj-$(CONFIG_CRAMFS) += cramfs/ | 78 | obj-$(CONFIG_CRAMFS) += cramfs/ |
| 77 | obj-$(CONFIG_SQUASHFS) += squashfs/ | 79 | obj-$(CONFIG_SQUASHFS) += squashfs/ |
| 78 | obj-y += ramfs/ | 80 | obj-y += ramfs/ |
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; |
| @@ -302,9 +302,10 @@ void bio_init(struct bio *bio) | |||
| 302 | struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) | 302 | struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) |
| 303 | { | 303 | { |
| 304 | struct bio *bio = NULL; | 304 | struct bio *bio = NULL; |
| 305 | void *uninitialized_var(p); | ||
| 305 | 306 | ||
| 306 | if (bs) { | 307 | if (bs) { |
| 307 | void *p = mempool_alloc(bs->bio_pool, gfp_mask); | 308 | p = mempool_alloc(bs->bio_pool, gfp_mask); |
| 308 | 309 | ||
| 309 | if (p) | 310 | if (p) |
| 310 | bio = p + bs->front_pad; | 311 | bio = p + bs->front_pad; |
| @@ -329,7 +330,7 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) | |||
| 329 | } | 330 | } |
| 330 | if (unlikely(!bvl)) { | 331 | if (unlikely(!bvl)) { |
| 331 | if (bs) | 332 | if (bs) |
| 332 | mempool_free(bio, bs->bio_pool); | 333 | mempool_free(p, bs->bio_pool); |
| 333 | else | 334 | else |
| 334 | kfree(bio); | 335 | kfree(bio); |
| 335 | bio = NULL; | 336 | bio = NULL; |
| @@ -462,10 +463,12 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask) | |||
| 462 | if (bio_integrity(bio)) { | 463 | if (bio_integrity(bio)) { |
| 463 | int ret; | 464 | int ret; |
| 464 | 465 | ||
| 465 | ret = bio_integrity_clone(b, bio, fs_bio_set); | 466 | ret = bio_integrity_clone(b, bio, gfp_mask, fs_bio_set); |
| 466 | 467 | ||
| 467 | if (ret < 0) | 468 | if (ret < 0) { |
| 469 | bio_put(b); | ||
| 468 | return NULL; | 470 | return NULL; |
| 471 | } | ||
| 469 | } | 472 | } |
| 470 | 473 | ||
| 471 | return b; | 474 | return b; |
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index a8c9693b75ac..72677ce2b74f 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h | |||
| @@ -66,6 +66,9 @@ struct btrfs_inode { | |||
| 66 | */ | 66 | */ |
| 67 | struct list_head delalloc_inodes; | 67 | struct list_head delalloc_inodes; |
| 68 | 68 | ||
| 69 | /* the space_info for where this inode's data allocations are done */ | ||
| 70 | struct btrfs_space_info *space_info; | ||
| 71 | |||
| 69 | /* full 64 bit generation number, struct vfs_inode doesn't have a big | 72 | /* full 64 bit generation number, struct vfs_inode doesn't have a big |
| 70 | * enough field for this. | 73 | * enough field for this. |
| 71 | */ | 74 | */ |
| @@ -94,6 +97,11 @@ struct btrfs_inode { | |||
| 94 | */ | 97 | */ |
| 95 | u64 delalloc_bytes; | 98 | u64 delalloc_bytes; |
| 96 | 99 | ||
| 100 | /* total number of bytes that may be used for this inode for | ||
| 101 | * delalloc | ||
| 102 | */ | ||
| 103 | u64 reserved_bytes; | ||
| 104 | |||
| 97 | /* | 105 | /* |
| 98 | * the size of the file stored in the metadata on disk. data=ordered | 106 | * the size of the file stored in the metadata on disk. data=ordered |
| 99 | * means the in-memory i_size might be larger than the size on disk | 107 | * means the in-memory i_size might be larger than the size on disk |
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 35443cc4b9a9..37f31b5529aa 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
| @@ -38,19 +38,12 @@ static int balance_node_right(struct btrfs_trans_handle *trans, | |||
| 38 | static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 38 | static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
| 39 | struct btrfs_path *path, int level, int slot); | 39 | struct btrfs_path *path, int level, int slot); |
| 40 | 40 | ||
| 41 | inline void btrfs_init_path(struct btrfs_path *p) | ||
| 42 | { | ||
| 43 | memset(p, 0, sizeof(*p)); | ||
| 44 | } | ||
| 45 | |||
| 46 | struct btrfs_path *btrfs_alloc_path(void) | 41 | struct btrfs_path *btrfs_alloc_path(void) |
| 47 | { | 42 | { |
| 48 | struct btrfs_path *path; | 43 | struct btrfs_path *path; |
| 49 | path = kmem_cache_alloc(btrfs_path_cachep, GFP_NOFS); | 44 | path = kmem_cache_zalloc(btrfs_path_cachep, GFP_NOFS); |
| 50 | if (path) { | 45 | if (path) |
| 51 | btrfs_init_path(path); | ||
| 52 | path->reada = 1; | 46 | path->reada = 1; |
| 53 | } | ||
| 54 | return path; | 47 | return path; |
| 55 | } | 48 | } |
| 56 | 49 | ||
| @@ -69,14 +62,38 @@ noinline void btrfs_set_path_blocking(struct btrfs_path *p) | |||
| 69 | 62 | ||
| 70 | /* | 63 | /* |
| 71 | * reset all the locked nodes in the patch to spinning locks. | 64 | * reset all the locked nodes in the patch to spinning locks. |
| 65 | * | ||
| 66 | * held is used to keep lockdep happy, when lockdep is enabled | ||
| 67 | * we set held to a blocking lock before we go around and | ||
| 68 | * retake all the spinlocks in the path. You can safely use NULL | ||
| 69 | * for held | ||
| 72 | */ | 70 | */ |
| 73 | noinline void btrfs_clear_path_blocking(struct btrfs_path *p) | 71 | noinline void btrfs_clear_path_blocking(struct btrfs_path *p, |
| 72 | struct extent_buffer *held) | ||
| 74 | { | 73 | { |
| 75 | int i; | 74 | int i; |
| 76 | for (i = 0; i < BTRFS_MAX_LEVEL; i++) { | 75 | |
| 76 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 77 | /* lockdep really cares that we take all of these spinlocks | ||
| 78 | * in the right order. If any of the locks in the path are not | ||
| 79 | * currently blocking, it is going to complain. So, make really | ||
| 80 | * really sure by forcing the path to blocking before we clear | ||
| 81 | * the path blocking. | ||
| 82 | */ | ||
| 83 | if (held) | ||
| 84 | btrfs_set_lock_blocking(held); | ||
| 85 | btrfs_set_path_blocking(p); | ||
| 86 | #endif | ||
| 87 | |||
| 88 | for (i = BTRFS_MAX_LEVEL - 1; i >= 0; i--) { | ||
| 77 | if (p->nodes[i] && p->locks[i]) | 89 | if (p->nodes[i] && p->locks[i]) |
| 78 | btrfs_clear_lock_blocking(p->nodes[i]); | 90 | btrfs_clear_lock_blocking(p->nodes[i]); |
| 79 | } | 91 | } |
| 92 | |||
| 93 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 94 | if (held) | ||
| 95 | btrfs_clear_lock_blocking(held); | ||
| 96 | #endif | ||
| 80 | } | 97 | } |
| 81 | 98 | ||
| 82 | /* this also releases the path */ | 99 | /* this also releases the path */ |
| @@ -260,7 +277,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
| 260 | if (*cow_ret == buf) | 277 | if (*cow_ret == buf) |
| 261 | unlock_orig = 1; | 278 | unlock_orig = 1; |
| 262 | 279 | ||
| 263 | WARN_ON(!btrfs_tree_locked(buf)); | 280 | btrfs_assert_tree_locked(buf); |
| 264 | 281 | ||
| 265 | if (parent) | 282 | if (parent) |
| 266 | parent_start = parent->start; | 283 | parent_start = parent->start; |
| @@ -286,7 +303,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
| 286 | trans->transid, level, &ins); | 303 | trans->transid, level, &ins); |
| 287 | BUG_ON(ret); | 304 | BUG_ON(ret); |
| 288 | cow = btrfs_init_new_buffer(trans, root, prealloc_dest, | 305 | cow = btrfs_init_new_buffer(trans, root, prealloc_dest, |
| 289 | buf->len); | 306 | buf->len, level); |
| 290 | } else { | 307 | } else { |
| 291 | cow = btrfs_alloc_free_block(trans, root, buf->len, | 308 | cow = btrfs_alloc_free_block(trans, root, buf->len, |
| 292 | parent_start, | 309 | parent_start, |
| @@ -917,9 +934,9 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
| 917 | 934 | ||
| 918 | /* promote the child to a root */ | 935 | /* promote the child to a root */ |
| 919 | child = read_node_slot(root, mid, 0); | 936 | child = read_node_slot(root, mid, 0); |
| 937 | BUG_ON(!child); | ||
| 920 | btrfs_tree_lock(child); | 938 | btrfs_tree_lock(child); |
| 921 | btrfs_set_lock_blocking(child); | 939 | btrfs_set_lock_blocking(child); |
| 922 | BUG_ON(!child); | ||
| 923 | ret = btrfs_cow_block(trans, root, child, mid, 0, &child, 0); | 940 | ret = btrfs_cow_block(trans, root, child, mid, 0, &child, 0); |
| 924 | BUG_ON(ret); | 941 | BUG_ON(ret); |
| 925 | 942 | ||
| @@ -1566,7 +1583,7 @@ cow_done: | |||
| 1566 | if (!p->skip_locking) | 1583 | if (!p->skip_locking) |
| 1567 | p->locks[level] = 1; | 1584 | p->locks[level] = 1; |
| 1568 | 1585 | ||
| 1569 | btrfs_clear_path_blocking(p); | 1586 | btrfs_clear_path_blocking(p, NULL); |
| 1570 | 1587 | ||
| 1571 | /* | 1588 | /* |
| 1572 | * we have a lock on b and as long as we aren't changing | 1589 | * we have a lock on b and as long as we aren't changing |
| @@ -1605,7 +1622,7 @@ cow_done: | |||
| 1605 | 1622 | ||
| 1606 | btrfs_set_path_blocking(p); | 1623 | btrfs_set_path_blocking(p); |
| 1607 | sret = split_node(trans, root, p, level); | 1624 | sret = split_node(trans, root, p, level); |
| 1608 | btrfs_clear_path_blocking(p); | 1625 | btrfs_clear_path_blocking(p, NULL); |
| 1609 | 1626 | ||
| 1610 | BUG_ON(sret > 0); | 1627 | BUG_ON(sret > 0); |
| 1611 | if (sret) { | 1628 | if (sret) { |
| @@ -1625,7 +1642,7 @@ cow_done: | |||
| 1625 | 1642 | ||
| 1626 | btrfs_set_path_blocking(p); | 1643 | btrfs_set_path_blocking(p); |
| 1627 | sret = balance_level(trans, root, p, level); | 1644 | sret = balance_level(trans, root, p, level); |
| 1628 | btrfs_clear_path_blocking(p); | 1645 | btrfs_clear_path_blocking(p, NULL); |
| 1629 | 1646 | ||
| 1630 | if (sret) { | 1647 | if (sret) { |
| 1631 | ret = sret; | 1648 | ret = sret; |
| @@ -1688,13 +1705,13 @@ cow_done: | |||
| 1688 | if (!p->skip_locking) { | 1705 | if (!p->skip_locking) { |
| 1689 | int lret; | 1706 | int lret; |
| 1690 | 1707 | ||
| 1691 | btrfs_clear_path_blocking(p); | 1708 | btrfs_clear_path_blocking(p, NULL); |
| 1692 | lret = btrfs_try_spin_lock(b); | 1709 | lret = btrfs_try_spin_lock(b); |
| 1693 | 1710 | ||
| 1694 | if (!lret) { | 1711 | if (!lret) { |
| 1695 | btrfs_set_path_blocking(p); | 1712 | btrfs_set_path_blocking(p); |
| 1696 | btrfs_tree_lock(b); | 1713 | btrfs_tree_lock(b); |
| 1697 | btrfs_clear_path_blocking(p); | 1714 | btrfs_clear_path_blocking(p, b); |
| 1698 | } | 1715 | } |
| 1699 | } | 1716 | } |
| 1700 | } else { | 1717 | } else { |
| @@ -1706,7 +1723,7 @@ cow_done: | |||
| 1706 | btrfs_set_path_blocking(p); | 1723 | btrfs_set_path_blocking(p); |
| 1707 | sret = split_leaf(trans, root, key, | 1724 | sret = split_leaf(trans, root, key, |
| 1708 | p, ins_len, ret == 0); | 1725 | p, ins_len, ret == 0); |
| 1709 | btrfs_clear_path_blocking(p); | 1726 | btrfs_clear_path_blocking(p, NULL); |
| 1710 | 1727 | ||
| 1711 | BUG_ON(sret > 0); | 1728 | BUG_ON(sret > 0); |
| 1712 | if (sret) { | 1729 | if (sret) { |
| @@ -2348,7 +2365,7 @@ static int push_leaf_right(struct btrfs_trans_handle *trans, struct btrfs_root | |||
| 2348 | if (slot >= btrfs_header_nritems(upper) - 1) | 2365 | if (slot >= btrfs_header_nritems(upper) - 1) |
| 2349 | return 1; | 2366 | return 1; |
| 2350 | 2367 | ||
| 2351 | WARN_ON(!btrfs_tree_locked(path->nodes[1])); | 2368 | btrfs_assert_tree_locked(path->nodes[1]); |
| 2352 | 2369 | ||
| 2353 | right = read_node_slot(root, upper, slot + 1); | 2370 | right = read_node_slot(root, upper, slot + 1); |
| 2354 | btrfs_tree_lock(right); | 2371 | btrfs_tree_lock(right); |
| @@ -2545,7 +2562,7 @@ static int push_leaf_left(struct btrfs_trans_handle *trans, struct btrfs_root | |||
| 2545 | if (right_nritems == 0) | 2562 | if (right_nritems == 0) |
| 2546 | return 1; | 2563 | return 1; |
| 2547 | 2564 | ||
| 2548 | WARN_ON(!btrfs_tree_locked(path->nodes[1])); | 2565 | btrfs_assert_tree_locked(path->nodes[1]); |
| 2549 | 2566 | ||
| 2550 | left = read_node_slot(root, path->nodes[1], slot - 1); | 2567 | left = read_node_slot(root, path->nodes[1], slot - 1); |
| 2551 | btrfs_tree_lock(left); | 2568 | btrfs_tree_lock(left); |
| @@ -3926,7 +3943,6 @@ find_next_key: | |||
| 3926 | btrfs_release_path(root, path); | 3943 | btrfs_release_path(root, path); |
| 3927 | goto again; | 3944 | goto again; |
| 3928 | } else { | 3945 | } else { |
| 3929 | btrfs_clear_path_blocking(path); | ||
| 3930 | goto out; | 3946 | goto out; |
| 3931 | } | 3947 | } |
| 3932 | } | 3948 | } |
| @@ -3946,7 +3962,7 @@ find_next_key: | |||
| 3946 | path->locks[level - 1] = 1; | 3962 | path->locks[level - 1] = 1; |
| 3947 | path->nodes[level - 1] = cur; | 3963 | path->nodes[level - 1] = cur; |
| 3948 | unlock_up(path, level, 1); | 3964 | unlock_up(path, level, 1); |
| 3949 | btrfs_clear_path_blocking(path); | 3965 | btrfs_clear_path_blocking(path, NULL); |
| 3950 | } | 3966 | } |
| 3951 | out: | 3967 | out: |
| 3952 | if (ret == 0) | 3968 | if (ret == 0) |
| @@ -4085,7 +4101,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
| 4085 | 4101 | ||
| 4086 | next = read_node_slot(root, c, slot); | 4102 | next = read_node_slot(root, c, slot); |
| 4087 | if (!path->skip_locking) { | 4103 | if (!path->skip_locking) { |
| 4088 | WARN_ON(!btrfs_tree_locked(c)); | 4104 | btrfs_assert_tree_locked(c); |
| 4089 | btrfs_tree_lock(next); | 4105 | btrfs_tree_lock(next); |
| 4090 | btrfs_set_lock_blocking(next); | 4106 | btrfs_set_lock_blocking(next); |
| 4091 | } | 4107 | } |
| @@ -4110,7 +4126,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
| 4110 | reada_for_search(root, path, level, slot, 0); | 4126 | reada_for_search(root, path, level, slot, 0); |
| 4111 | next = read_node_slot(root, next, 0); | 4127 | next = read_node_slot(root, next, 0); |
| 4112 | if (!path->skip_locking) { | 4128 | if (!path->skip_locking) { |
| 4113 | WARN_ON(!btrfs_tree_locked(path->nodes[level])); | 4129 | btrfs_assert_tree_locked(path->nodes[level]); |
| 4114 | btrfs_tree_lock(next); | 4130 | btrfs_tree_lock(next); |
| 4115 | btrfs_set_lock_blocking(next); | 4131 | btrfs_set_lock_blocking(next); |
| 4116 | } | 4132 | } |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 531db112c8bd..82491ba8fa40 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -43,11 +43,7 @@ struct btrfs_ordered_sum; | |||
| 43 | 43 | ||
| 44 | #define BTRFS_ACL_NOT_CACHED ((void *)-1) | 44 | #define BTRFS_ACL_NOT_CACHED ((void *)-1) |
| 45 | 45 | ||
| 46 | #ifdef CONFIG_LOCKDEP | 46 | #define BTRFS_MAX_LEVEL 8 |
| 47 | # define BTRFS_MAX_LEVEL 7 | ||
| 48 | #else | ||
| 49 | # define BTRFS_MAX_LEVEL 8 | ||
| 50 | #endif | ||
| 51 | 47 | ||
| 52 | /* holds pointers to all of the tree roots */ | 48 | /* holds pointers to all of the tree roots */ |
| 53 | #define BTRFS_ROOT_TREE_OBJECTID 1ULL | 49 | #define BTRFS_ROOT_TREE_OBJECTID 1ULL |
| @@ -600,13 +596,27 @@ struct btrfs_block_group_item { | |||
| 600 | 596 | ||
| 601 | struct btrfs_space_info { | 597 | struct btrfs_space_info { |
| 602 | u64 flags; | 598 | u64 flags; |
| 603 | u64 total_bytes; | 599 | |
| 604 | u64 bytes_used; | 600 | u64 total_bytes; /* total bytes in the space */ |
| 605 | u64 bytes_pinned; | 601 | u64 bytes_used; /* total bytes used on disk */ |
| 606 | u64 bytes_reserved; | 602 | u64 bytes_pinned; /* total bytes pinned, will be freed when the |
| 607 | u64 bytes_readonly; | 603 | transaction finishes */ |
| 608 | int full; | 604 | u64 bytes_reserved; /* total bytes the allocator has reserved for |
| 609 | int force_alloc; | 605 | current allocations */ |
| 606 | u64 bytes_readonly; /* total bytes that are read only */ | ||
| 607 | |||
| 608 | /* delalloc accounting */ | ||
| 609 | u64 bytes_delalloc; /* number of bytes reserved for allocation, | ||
| 610 | this space is not necessarily reserved yet | ||
| 611 | by the allocator */ | ||
| 612 | u64 bytes_may_use; /* number of bytes that may be used for | ||
| 613 | delalloc */ | ||
| 614 | |||
| 615 | int full; /* indicates that we cannot allocate any more | ||
| 616 | chunks for this space */ | ||
| 617 | int force_alloc; /* set if we need to force a chunk alloc for | ||
| 618 | this space */ | ||
| 619 | |||
| 610 | struct list_head list; | 620 | struct list_head list; |
| 611 | 621 | ||
| 612 | /* for block groups in our same type */ | 622 | /* for block groups in our same type */ |
| @@ -1715,7 +1725,8 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
| 1715 | u64 empty_size); | 1725 | u64 empty_size); |
| 1716 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | 1726 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, |
| 1717 | struct btrfs_root *root, | 1727 | struct btrfs_root *root, |
| 1718 | u64 bytenr, u32 blocksize); | 1728 | u64 bytenr, u32 blocksize, |
| 1729 | int level); | ||
| 1719 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | 1730 | int btrfs_alloc_extent(struct btrfs_trans_handle *trans, |
| 1720 | struct btrfs_root *root, | 1731 | struct btrfs_root *root, |
| 1721 | u64 num_bytes, u64 parent, u64 min_bytes, | 1732 | u64 num_bytes, u64 parent, u64 min_bytes, |
| @@ -1785,6 +1796,16 @@ int btrfs_add_dead_reloc_root(struct btrfs_root *root); | |||
| 1785 | int btrfs_cleanup_reloc_trees(struct btrfs_root *root); | 1796 | int btrfs_cleanup_reloc_trees(struct btrfs_root *root); |
| 1786 | int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len); | 1797 | int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len); |
| 1787 | u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags); | 1798 | 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); | ||
| 1800 | int btrfs_check_metadata_free_space(struct btrfs_root *root); | ||
| 1801 | int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, | ||
| 1802 | u64 bytes); | ||
| 1803 | void btrfs_free_reserved_data_space(struct btrfs_root *root, | ||
| 1804 | struct inode *inode, u64 bytes); | ||
| 1805 | void btrfs_delalloc_reserve_space(struct btrfs_root *root, struct inode *inode, | ||
| 1806 | u64 bytes); | ||
| 1807 | void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode, | ||
| 1808 | u64 bytes); | ||
| 1788 | /* ctree.c */ | 1809 | /* ctree.c */ |
| 1789 | int btrfs_previous_item(struct btrfs_root *root, | 1810 | int btrfs_previous_item(struct btrfs_root *root, |
| 1790 | struct btrfs_path *path, u64 min_objectid, | 1811 | struct btrfs_path *path, u64 min_objectid, |
| @@ -1834,9 +1855,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, | |||
| 1834 | void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p); | 1855 | void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p); |
| 1835 | struct btrfs_path *btrfs_alloc_path(void); | 1856 | struct btrfs_path *btrfs_alloc_path(void); |
| 1836 | void btrfs_free_path(struct btrfs_path *p); | 1857 | void btrfs_free_path(struct btrfs_path *p); |
| 1837 | void btrfs_init_path(struct btrfs_path *p); | ||
| 1838 | void btrfs_set_path_blocking(struct btrfs_path *p); | 1858 | void btrfs_set_path_blocking(struct btrfs_path *p); |
| 1839 | void btrfs_clear_path_blocking(struct btrfs_path *p); | ||
| 1840 | void btrfs_unlock_up_safe(struct btrfs_path *p, int level); | 1859 | void btrfs_unlock_up_safe(struct btrfs_path *p, int level); |
| 1841 | 1860 | ||
| 1842 | int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 1861 | int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
| @@ -2032,8 +2051,6 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset, | |||
| 2032 | unsigned long btrfs_force_ra(struct address_space *mapping, | 2051 | unsigned long btrfs_force_ra(struct address_space *mapping, |
| 2033 | struct file_ra_state *ra, struct file *file, | 2052 | struct file_ra_state *ra, struct file *file, |
| 2034 | pgoff_t offset, pgoff_t last_index); | 2053 | pgoff_t offset, pgoff_t last_index); |
| 2035 | int btrfs_check_free_space(struct btrfs_root *root, u64 num_required, | ||
| 2036 | int for_del); | ||
| 2037 | int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page); | 2054 | int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page); |
| 2038 | int btrfs_readpage(struct file *file, struct page *page); | 2055 | int btrfs_readpage(struct file *file, struct page *page); |
| 2039 | void btrfs_delete_inode(struct inode *inode); | 2056 | void btrfs_delete_inode(struct inode *inode); |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 5aebddd71193..3e18175248e0 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -75,6 +75,40 @@ struct async_submit_bio { | |||
| 75 | struct btrfs_work work; | 75 | struct btrfs_work work; |
| 76 | }; | 76 | }; |
| 77 | 77 | ||
| 78 | /* These are used to set the lockdep class on the extent buffer locks. | ||
| 79 | * The class is set by the readpage_end_io_hook after the buffer has | ||
| 80 | * passed csum validation but before the pages are unlocked. | ||
| 81 | * | ||
| 82 | * The lockdep class is also set by btrfs_init_new_buffer on freshly | ||
| 83 | * allocated blocks. | ||
| 84 | * | ||
| 85 | * The class is based on the level in the tree block, which allows lockdep | ||
| 86 | * to know that lower nodes nest inside the locks of higher nodes. | ||
| 87 | * | ||
| 88 | * We also add a check to make sure the highest level of the tree is | ||
| 89 | * the same as our lockdep setup here. If BTRFS_MAX_LEVEL changes, this | ||
| 90 | * code needs update as well. | ||
| 91 | */ | ||
| 92 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 93 | # if BTRFS_MAX_LEVEL != 8 | ||
| 94 | # error | ||
| 95 | # endif | ||
| 96 | static struct lock_class_key btrfs_eb_class[BTRFS_MAX_LEVEL + 1]; | ||
| 97 | static const char *btrfs_eb_name[BTRFS_MAX_LEVEL + 1] = { | ||
| 98 | /* leaf */ | ||
| 99 | "btrfs-extent-00", | ||
| 100 | "btrfs-extent-01", | ||
| 101 | "btrfs-extent-02", | ||
| 102 | "btrfs-extent-03", | ||
| 103 | "btrfs-extent-04", | ||
| 104 | "btrfs-extent-05", | ||
| 105 | "btrfs-extent-06", | ||
| 106 | "btrfs-extent-07", | ||
| 107 | /* highest possible level */ | ||
| 108 | "btrfs-extent-08", | ||
| 109 | }; | ||
| 110 | #endif | ||
| 111 | |||
| 78 | /* | 112 | /* |
| 79 | * extents on the btree inode are pretty simple, there's one extent | 113 | * extents on the btree inode are pretty simple, there's one extent |
| 80 | * that covers the entire device | 114 | * that covers the entire device |
| @@ -347,6 +381,15 @@ static int check_tree_block_fsid(struct btrfs_root *root, | |||
| 347 | return ret; | 381 | return ret; |
| 348 | } | 382 | } |
| 349 | 383 | ||
| 384 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 385 | void btrfs_set_buffer_lockdep_class(struct extent_buffer *eb, int level) | ||
| 386 | { | ||
| 387 | lockdep_set_class_and_name(&eb->lock, | ||
| 388 | &btrfs_eb_class[level], | ||
| 389 | btrfs_eb_name[level]); | ||
| 390 | } | ||
| 391 | #endif | ||
| 392 | |||
| 350 | static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, | 393 | static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, |
| 351 | struct extent_state *state) | 394 | struct extent_state *state) |
| 352 | { | 395 | { |
| @@ -392,6 +435,8 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, | |||
| 392 | } | 435 | } |
| 393 | found_level = btrfs_header_level(eb); | 436 | found_level = btrfs_header_level(eb); |
| 394 | 437 | ||
| 438 | btrfs_set_buffer_lockdep_class(eb, found_level); | ||
| 439 | |||
| 395 | ret = csum_tree_block(root, eb, 1); | 440 | ret = csum_tree_block(root, eb, 1); |
| 396 | if (ret) | 441 | if (ret) |
| 397 | ret = -EIO; | 442 | ret = -EIO; |
| @@ -812,7 +857,7 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
| 812 | struct inode *btree_inode = root->fs_info->btree_inode; | 857 | struct inode *btree_inode = root->fs_info->btree_inode; |
| 813 | if (btrfs_header_generation(buf) == | 858 | if (btrfs_header_generation(buf) == |
| 814 | root->fs_info->running_transaction->transid) { | 859 | root->fs_info->running_transaction->transid) { |
| 815 | WARN_ON(!btrfs_tree_locked(buf)); | 860 | btrfs_assert_tree_locked(buf); |
| 816 | 861 | ||
| 817 | /* ugh, clear_extent_buffer_dirty can be expensive */ | 862 | /* ugh, clear_extent_buffer_dirty can be expensive */ |
| 818 | btrfs_set_lock_blocking(buf); | 863 | btrfs_set_lock_blocking(buf); |
| @@ -1777,7 +1822,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1777 | ret = find_and_setup_root(tree_root, fs_info, | 1822 | ret = find_and_setup_root(tree_root, fs_info, |
| 1778 | BTRFS_DEV_TREE_OBJECTID, dev_root); | 1823 | BTRFS_DEV_TREE_OBJECTID, dev_root); |
| 1779 | dev_root->track_dirty = 1; | 1824 | dev_root->track_dirty = 1; |
| 1780 | |||
| 1781 | if (ret) | 1825 | if (ret) |
| 1782 | goto fail_extent_root; | 1826 | goto fail_extent_root; |
| 1783 | 1827 | ||
| @@ -2317,7 +2361,7 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) | |||
| 2317 | 2361 | ||
| 2318 | btrfs_set_lock_blocking(buf); | 2362 | btrfs_set_lock_blocking(buf); |
| 2319 | 2363 | ||
| 2320 | WARN_ON(!btrfs_tree_locked(buf)); | 2364 | btrfs_assert_tree_locked(buf); |
| 2321 | if (transid != root->fs_info->generation) { | 2365 | if (transid != root->fs_info->generation) { |
| 2322 | printk(KERN_CRIT "btrfs transid mismatch buffer %llu, " | 2366 | printk(KERN_CRIT "btrfs transid mismatch buffer %llu, " |
| 2323 | "found %llu running %llu\n", | 2367 | "found %llu running %llu\n", |
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 494a56eb2986..95029db227be 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h | |||
| @@ -101,4 +101,14 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, | |||
| 101 | int btrfs_add_log_tree(struct btrfs_trans_handle *trans, | 101 | int btrfs_add_log_tree(struct btrfs_trans_handle *trans, |
| 102 | struct btrfs_root *root); | 102 | struct btrfs_root *root); |
| 103 | int btree_lock_page_hook(struct page *page); | 103 | int btree_lock_page_hook(struct page *page); |
| 104 | |||
| 105 | |||
| 106 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 107 | void btrfs_set_buffer_lockdep_class(struct extent_buffer *eb, int level); | ||
| 108 | #else | ||
| 109 | static inline void btrfs_set_buffer_lockdep_class(struct extent_buffer *eb, | ||
| 110 | int level) | ||
| 111 | { | ||
| 112 | } | ||
| 113 | #endif | ||
| 104 | #endif | 114 | #endif |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 7527523c2d2d..9abf81f71c46 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -60,6 +60,10 @@ static int update_block_group(struct btrfs_trans_handle *trans, | |||
| 60 | u64 bytenr, u64 num_bytes, int alloc, | 60 | u64 bytenr, u64 num_bytes, int alloc, |
| 61 | int mark_free); | 61 | int mark_free); |
| 62 | 62 | ||
| 63 | static int do_chunk_alloc(struct btrfs_trans_handle *trans, | ||
| 64 | struct btrfs_root *extent_root, u64 alloc_bytes, | ||
| 65 | u64 flags, int force); | ||
| 66 | |||
| 63 | static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits) | 67 | static int block_group_bits(struct btrfs_block_group_cache *cache, u64 bits) |
| 64 | { | 68 | { |
| 65 | return (cache->flags & bits) == bits; | 69 | return (cache->flags & bits) == bits; |
| @@ -1323,8 +1327,25 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | |||
| 1323 | int btrfs_extent_post_op(struct btrfs_trans_handle *trans, | 1327 | int btrfs_extent_post_op(struct btrfs_trans_handle *trans, |
| 1324 | struct btrfs_root *root) | 1328 | struct btrfs_root *root) |
| 1325 | { | 1329 | { |
| 1326 | finish_current_insert(trans, root->fs_info->extent_root, 1); | 1330 | u64 start; |
| 1327 | del_pending_extents(trans, root->fs_info->extent_root, 1); | 1331 | u64 end; |
| 1332 | int ret; | ||
| 1333 | |||
| 1334 | while(1) { | ||
| 1335 | finish_current_insert(trans, root->fs_info->extent_root, 1); | ||
| 1336 | del_pending_extents(trans, root->fs_info->extent_root, 1); | ||
| 1337 | |||
| 1338 | /* is there more work to do? */ | ||
| 1339 | ret = find_first_extent_bit(&root->fs_info->pending_del, | ||
| 1340 | 0, &start, &end, EXTENT_WRITEBACK); | ||
| 1341 | if (!ret) | ||
| 1342 | continue; | ||
| 1343 | ret = find_first_extent_bit(&root->fs_info->extent_ins, | ||
| 1344 | 0, &start, &end, EXTENT_WRITEBACK); | ||
| 1345 | if (!ret) | ||
| 1346 | continue; | ||
| 1347 | break; | ||
| 1348 | } | ||
| 1328 | return 0; | 1349 | return 0; |
| 1329 | } | 1350 | } |
| 1330 | 1351 | ||
| @@ -1892,6 +1913,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, | |||
| 1892 | found->bytes_pinned = 0; | 1913 | found->bytes_pinned = 0; |
| 1893 | found->bytes_reserved = 0; | 1914 | found->bytes_reserved = 0; |
| 1894 | found->bytes_readonly = 0; | 1915 | found->bytes_readonly = 0; |
| 1916 | found->bytes_delalloc = 0; | ||
| 1895 | found->full = 0; | 1917 | found->full = 0; |
| 1896 | found->force_alloc = 0; | 1918 | found->force_alloc = 0; |
| 1897 | *space_info = found; | 1919 | *space_info = found; |
| @@ -1955,6 +1977,233 @@ u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) | |||
| 1955 | return flags; | 1977 | return flags; |
| 1956 | } | 1978 | } |
| 1957 | 1979 | ||
| 1980 | static u64 btrfs_get_alloc_profile(struct btrfs_root *root, u64 data) | ||
| 1981 | { | ||
| 1982 | struct btrfs_fs_info *info = root->fs_info; | ||
| 1983 | u64 alloc_profile; | ||
| 1984 | |||
| 1985 | if (data) { | ||
| 1986 | alloc_profile = info->avail_data_alloc_bits & | ||
| 1987 | info->data_alloc_profile; | ||
| 1988 | data = BTRFS_BLOCK_GROUP_DATA | alloc_profile; | ||
| 1989 | } else if (root == root->fs_info->chunk_root) { | ||
| 1990 | alloc_profile = info->avail_system_alloc_bits & | ||
| 1991 | info->system_alloc_profile; | ||
| 1992 | data = BTRFS_BLOCK_GROUP_SYSTEM | alloc_profile; | ||
| 1993 | } else { | ||
| 1994 | alloc_profile = info->avail_metadata_alloc_bits & | ||
| 1995 | info->metadata_alloc_profile; | ||
| 1996 | data = BTRFS_BLOCK_GROUP_METADATA | alloc_profile; | ||
| 1997 | } | ||
| 1998 | |||
| 1999 | return btrfs_reduce_alloc_profile(root, data); | ||
| 2000 | } | ||
| 2001 | |||
| 2002 | void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *inode) | ||
| 2003 | { | ||
| 2004 | u64 alloc_target; | ||
| 2005 | |||
| 2006 | alloc_target = btrfs_get_alloc_profile(root, 1); | ||
| 2007 | BTRFS_I(inode)->space_info = __find_space_info(root->fs_info, | ||
| 2008 | alloc_target); | ||
| 2009 | } | ||
| 2010 | |||
| 2011 | /* | ||
| 2012 | * for now this just makes sure we have at least 5% of our metadata space free | ||
| 2013 | * for use. | ||
| 2014 | */ | ||
| 2015 | int btrfs_check_metadata_free_space(struct btrfs_root *root) | ||
| 2016 | { | ||
| 2017 | struct btrfs_fs_info *info = root->fs_info; | ||
| 2018 | struct btrfs_space_info *meta_sinfo; | ||
| 2019 | u64 alloc_target, thresh; | ||
| 2020 | int committed = 0, ret; | ||
| 2021 | |||
| 2022 | /* get the space info for where the metadata will live */ | ||
| 2023 | alloc_target = btrfs_get_alloc_profile(root, 0); | ||
| 2024 | meta_sinfo = __find_space_info(info, alloc_target); | ||
| 2025 | |||
| 2026 | again: | ||
| 2027 | spin_lock(&meta_sinfo->lock); | ||
| 2028 | if (!meta_sinfo->full) | ||
| 2029 | thresh = meta_sinfo->total_bytes * 80; | ||
| 2030 | else | ||
| 2031 | thresh = meta_sinfo->total_bytes * 95; | ||
| 2032 | |||
| 2033 | do_div(thresh, 100); | ||
| 2034 | |||
| 2035 | if (meta_sinfo->bytes_used + meta_sinfo->bytes_reserved + | ||
| 2036 | meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly > thresh) { | ||
| 2037 | struct btrfs_trans_handle *trans; | ||
| 2038 | if (!meta_sinfo->full) { | ||
| 2039 | meta_sinfo->force_alloc = 1; | ||
| 2040 | spin_unlock(&meta_sinfo->lock); | ||
| 2041 | |||
| 2042 | trans = btrfs_start_transaction(root, 1); | ||
| 2043 | if (!trans) | ||
| 2044 | return -ENOMEM; | ||
| 2045 | |||
| 2046 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | ||
| 2047 | 2 * 1024 * 1024, alloc_target, 0); | ||
| 2048 | btrfs_end_transaction(trans, root); | ||
| 2049 | goto again; | ||
| 2050 | } | ||
| 2051 | spin_unlock(&meta_sinfo->lock); | ||
| 2052 | |||
| 2053 | if (!committed) { | ||
| 2054 | committed = 1; | ||
| 2055 | trans = btrfs_join_transaction(root, 1); | ||
| 2056 | if (!trans) | ||
| 2057 | return -ENOMEM; | ||
| 2058 | ret = btrfs_commit_transaction(trans, root); | ||
| 2059 | if (ret) | ||
| 2060 | return ret; | ||
| 2061 | goto again; | ||
| 2062 | } | ||
| 2063 | return -ENOSPC; | ||
| 2064 | } | ||
| 2065 | spin_unlock(&meta_sinfo->lock); | ||
| 2066 | |||
| 2067 | return 0; | ||
| 2068 | } | ||
| 2069 | |||
| 2070 | /* | ||
| 2071 | * This will check the space that the inode allocates from to make sure we have | ||
| 2072 | * enough space for bytes. | ||
| 2073 | */ | ||
| 2074 | int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, | ||
| 2075 | u64 bytes) | ||
| 2076 | { | ||
| 2077 | struct btrfs_space_info *data_sinfo; | ||
| 2078 | int ret = 0, committed = 0; | ||
| 2079 | |||
| 2080 | /* make sure bytes are sectorsize aligned */ | ||
| 2081 | bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); | ||
| 2082 | |||
| 2083 | data_sinfo = BTRFS_I(inode)->space_info; | ||
| 2084 | again: | ||
| 2085 | /* make sure we have enough space to handle the data first */ | ||
| 2086 | spin_lock(&data_sinfo->lock); | ||
| 2087 | if (data_sinfo->total_bytes - data_sinfo->bytes_used - | ||
| 2088 | data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved - | ||
| 2089 | data_sinfo->bytes_pinned - data_sinfo->bytes_readonly - | ||
| 2090 | data_sinfo->bytes_may_use < bytes) { | ||
| 2091 | struct btrfs_trans_handle *trans; | ||
| 2092 | |||
| 2093 | /* | ||
| 2094 | * if we don't have enough free bytes in this space then we need | ||
| 2095 | * to alloc a new chunk. | ||
| 2096 | */ | ||
| 2097 | if (!data_sinfo->full) { | ||
| 2098 | u64 alloc_target; | ||
| 2099 | |||
| 2100 | data_sinfo->force_alloc = 1; | ||
| 2101 | spin_unlock(&data_sinfo->lock); | ||
| 2102 | |||
| 2103 | alloc_target = btrfs_get_alloc_profile(root, 1); | ||
| 2104 | trans = btrfs_start_transaction(root, 1); | ||
| 2105 | if (!trans) | ||
| 2106 | return -ENOMEM; | ||
| 2107 | |||
| 2108 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | ||
| 2109 | bytes + 2 * 1024 * 1024, | ||
| 2110 | alloc_target, 0); | ||
| 2111 | btrfs_end_transaction(trans, root); | ||
| 2112 | if (ret) | ||
| 2113 | return ret; | ||
| 2114 | goto again; | ||
| 2115 | } | ||
| 2116 | spin_unlock(&data_sinfo->lock); | ||
| 2117 | |||
| 2118 | /* commit the current transaction and try again */ | ||
| 2119 | if (!committed) { | ||
| 2120 | committed = 1; | ||
| 2121 | trans = btrfs_join_transaction(root, 1); | ||
| 2122 | if (!trans) | ||
| 2123 | return -ENOMEM; | ||
| 2124 | ret = btrfs_commit_transaction(trans, root); | ||
| 2125 | if (ret) | ||
| 2126 | return ret; | ||
| 2127 | goto again; | ||
| 2128 | } | ||
| 2129 | |||
| 2130 | printk(KERN_ERR "no space left, need %llu, %llu delalloc bytes" | ||
| 2131 | ", %llu bytes_used, %llu bytes_reserved, " | ||
| 2132 | "%llu bytes_pinned, %llu bytes_readonly, %llu may use" | ||
| 2133 | "%llu total\n", bytes, data_sinfo->bytes_delalloc, | ||
| 2134 | data_sinfo->bytes_used, data_sinfo->bytes_reserved, | ||
| 2135 | data_sinfo->bytes_pinned, data_sinfo->bytes_readonly, | ||
| 2136 | data_sinfo->bytes_may_use, data_sinfo->total_bytes); | ||
| 2137 | return -ENOSPC; | ||
| 2138 | } | ||
| 2139 | data_sinfo->bytes_may_use += bytes; | ||
| 2140 | BTRFS_I(inode)->reserved_bytes += bytes; | ||
| 2141 | spin_unlock(&data_sinfo->lock); | ||
| 2142 | |||
| 2143 | return btrfs_check_metadata_free_space(root); | ||
| 2144 | } | ||
| 2145 | |||
| 2146 | /* | ||
| 2147 | * if there was an error for whatever reason after calling | ||
| 2148 | * btrfs_check_data_free_space, call this so we can cleanup the counters. | ||
| 2149 | */ | ||
| 2150 | void btrfs_free_reserved_data_space(struct btrfs_root *root, | ||
| 2151 | struct inode *inode, u64 bytes) | ||
| 2152 | { | ||
| 2153 | struct btrfs_space_info *data_sinfo; | ||
| 2154 | |||
| 2155 | /* make sure bytes are sectorsize aligned */ | ||
| 2156 | bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); | ||
| 2157 | |||
| 2158 | data_sinfo = BTRFS_I(inode)->space_info; | ||
| 2159 | spin_lock(&data_sinfo->lock); | ||
| 2160 | data_sinfo->bytes_may_use -= bytes; | ||
| 2161 | BTRFS_I(inode)->reserved_bytes -= bytes; | ||
| 2162 | spin_unlock(&data_sinfo->lock); | ||
| 2163 | } | ||
| 2164 | |||
| 2165 | /* called when we are adding a delalloc extent to the inode's io_tree */ | ||
| 2166 | void btrfs_delalloc_reserve_space(struct btrfs_root *root, struct inode *inode, | ||
| 2167 | u64 bytes) | ||
| 2168 | { | ||
| 2169 | struct btrfs_space_info *data_sinfo; | ||
| 2170 | |||
| 2171 | /* get the space info for where this inode will be storing its data */ | ||
| 2172 | data_sinfo = BTRFS_I(inode)->space_info; | ||
| 2173 | |||
| 2174 | /* make sure we have enough space to handle the data first */ | ||
| 2175 | spin_lock(&data_sinfo->lock); | ||
| 2176 | data_sinfo->bytes_delalloc += bytes; | ||
| 2177 | |||
| 2178 | /* | ||
| 2179 | * we are adding a delalloc extent without calling | ||
| 2180 | * btrfs_check_data_free_space first. This happens on a weird | ||
| 2181 | * writepage condition, but shouldn't hurt our accounting | ||
| 2182 | */ | ||
| 2183 | if (unlikely(bytes > BTRFS_I(inode)->reserved_bytes)) { | ||
| 2184 | data_sinfo->bytes_may_use -= BTRFS_I(inode)->reserved_bytes; | ||
| 2185 | BTRFS_I(inode)->reserved_bytes = 0; | ||
| 2186 | } else { | ||
| 2187 | data_sinfo->bytes_may_use -= bytes; | ||
| 2188 | BTRFS_I(inode)->reserved_bytes -= bytes; | ||
| 2189 | } | ||
| 2190 | |||
| 2191 | spin_unlock(&data_sinfo->lock); | ||
| 2192 | } | ||
| 2193 | |||
| 2194 | /* called when we are clearing an delalloc extent from the inode's io_tree */ | ||
| 2195 | void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode, | ||
| 2196 | u64 bytes) | ||
| 2197 | { | ||
| 2198 | struct btrfs_space_info *info; | ||
| 2199 | |||
| 2200 | info = BTRFS_I(inode)->space_info; | ||
| 2201 | |||
| 2202 | spin_lock(&info->lock); | ||
| 2203 | info->bytes_delalloc -= bytes; | ||
| 2204 | spin_unlock(&info->lock); | ||
| 2205 | } | ||
| 2206 | |||
| 1958 | static int do_chunk_alloc(struct btrfs_trans_handle *trans, | 2207 | static int do_chunk_alloc(struct btrfs_trans_handle *trans, |
| 1959 | struct btrfs_root *extent_root, u64 alloc_bytes, | 2208 | struct btrfs_root *extent_root, u64 alloc_bytes, |
| 1960 | u64 flags, int force) | 2209 | u64 flags, int force) |
| @@ -2211,13 +2460,12 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, | |||
| 2211 | u64 end; | 2460 | u64 end; |
| 2212 | u64 priv; | 2461 | u64 priv; |
| 2213 | u64 search = 0; | 2462 | u64 search = 0; |
| 2214 | u64 skipped = 0; | ||
| 2215 | struct btrfs_fs_info *info = extent_root->fs_info; | 2463 | struct btrfs_fs_info *info = extent_root->fs_info; |
| 2216 | struct btrfs_path *path; | 2464 | struct btrfs_path *path; |
| 2217 | struct pending_extent_op *extent_op, *tmp; | 2465 | struct pending_extent_op *extent_op, *tmp; |
| 2218 | struct list_head insert_list, update_list; | 2466 | struct list_head insert_list, update_list; |
| 2219 | int ret; | 2467 | int ret; |
| 2220 | int num_inserts = 0, max_inserts; | 2468 | int num_inserts = 0, max_inserts, restart = 0; |
| 2221 | 2469 | ||
| 2222 | path = btrfs_alloc_path(); | 2470 | path = btrfs_alloc_path(); |
| 2223 | INIT_LIST_HEAD(&insert_list); | 2471 | INIT_LIST_HEAD(&insert_list); |
| @@ -2233,19 +2481,19 @@ again: | |||
| 2233 | ret = find_first_extent_bit(&info->extent_ins, search, &start, | 2481 | ret = find_first_extent_bit(&info->extent_ins, search, &start, |
| 2234 | &end, EXTENT_WRITEBACK); | 2482 | &end, EXTENT_WRITEBACK); |
| 2235 | if (ret) { | 2483 | if (ret) { |
| 2236 | if (skipped && all && !num_inserts && | 2484 | if (restart && !num_inserts && |
| 2237 | list_empty(&update_list)) { | 2485 | list_empty(&update_list)) { |
| 2238 | skipped = 0; | 2486 | restart = 0; |
| 2239 | search = 0; | 2487 | search = 0; |
| 2240 | continue; | 2488 | continue; |
| 2241 | } | 2489 | } |
| 2242 | mutex_unlock(&info->extent_ins_mutex); | ||
| 2243 | break; | 2490 | break; |
| 2244 | } | 2491 | } |
| 2245 | 2492 | ||
| 2246 | ret = try_lock_extent(&info->extent_ins, start, end, GFP_NOFS); | 2493 | ret = try_lock_extent(&info->extent_ins, start, end, GFP_NOFS); |
| 2247 | if (!ret) { | 2494 | if (!ret) { |
| 2248 | skipped = 1; | 2495 | if (all) |
| 2496 | restart = 1; | ||
| 2249 | search = end + 1; | 2497 | search = end + 1; |
| 2250 | if (need_resched()) { | 2498 | if (need_resched()) { |
| 2251 | mutex_unlock(&info->extent_ins_mutex); | 2499 | mutex_unlock(&info->extent_ins_mutex); |
| @@ -2264,7 +2512,7 @@ again: | |||
| 2264 | list_add_tail(&extent_op->list, &insert_list); | 2512 | list_add_tail(&extent_op->list, &insert_list); |
| 2265 | search = end + 1; | 2513 | search = end + 1; |
| 2266 | if (num_inserts == max_inserts) { | 2514 | if (num_inserts == max_inserts) { |
| 2267 | mutex_unlock(&info->extent_ins_mutex); | 2515 | restart = 1; |
| 2268 | break; | 2516 | break; |
| 2269 | } | 2517 | } |
| 2270 | } else if (extent_op->type == PENDING_BACKREF_UPDATE) { | 2518 | } else if (extent_op->type == PENDING_BACKREF_UPDATE) { |
| @@ -2280,7 +2528,6 @@ again: | |||
| 2280 | * somebody marked this thing for deletion then just unlock it and be | 2528 | * somebody marked this thing for deletion then just unlock it and be |
| 2281 | * done, the free_extents will handle it | 2529 | * done, the free_extents will handle it |
| 2282 | */ | 2530 | */ |
| 2283 | mutex_lock(&info->extent_ins_mutex); | ||
| 2284 | list_for_each_entry_safe(extent_op, tmp, &update_list, list) { | 2531 | list_for_each_entry_safe(extent_op, tmp, &update_list, list) { |
| 2285 | clear_extent_bits(&info->extent_ins, extent_op->bytenr, | 2532 | clear_extent_bits(&info->extent_ins, extent_op->bytenr, |
| 2286 | extent_op->bytenr + extent_op->num_bytes - 1, | 2533 | extent_op->bytenr + extent_op->num_bytes - 1, |
| @@ -2302,6 +2549,10 @@ again: | |||
| 2302 | if (!list_empty(&update_list)) { | 2549 | if (!list_empty(&update_list)) { |
| 2303 | ret = update_backrefs(trans, extent_root, path, &update_list); | 2550 | ret = update_backrefs(trans, extent_root, path, &update_list); |
| 2304 | BUG_ON(ret); | 2551 | BUG_ON(ret); |
| 2552 | |||
| 2553 | /* we may have COW'ed new blocks, so lets start over */ | ||
| 2554 | if (all) | ||
| 2555 | restart = 1; | ||
| 2305 | } | 2556 | } |
| 2306 | 2557 | ||
| 2307 | /* | 2558 | /* |
| @@ -2309,9 +2560,9 @@ again: | |||
| 2309 | * need to make sure everything is cleaned then reset everything and | 2560 | * need to make sure everything is cleaned then reset everything and |
| 2310 | * go back to the beginning | 2561 | * go back to the beginning |
| 2311 | */ | 2562 | */ |
| 2312 | if (!num_inserts && all && skipped) { | 2563 | if (!num_inserts && restart) { |
| 2313 | search = 0; | 2564 | search = 0; |
| 2314 | skipped = 0; | 2565 | restart = 0; |
| 2315 | INIT_LIST_HEAD(&update_list); | 2566 | INIT_LIST_HEAD(&update_list); |
| 2316 | INIT_LIST_HEAD(&insert_list); | 2567 | INIT_LIST_HEAD(&insert_list); |
| 2317 | goto again; | 2568 | goto again; |
| @@ -2368,27 +2619,19 @@ again: | |||
| 2368 | BUG_ON(ret); | 2619 | BUG_ON(ret); |
| 2369 | 2620 | ||
| 2370 | /* | 2621 | /* |
| 2371 | * if we broke out of the loop in order to insert stuff because we hit | 2622 | * if restart is set for whatever reason we need to go back and start |
| 2372 | * the maximum number of inserts at a time we can handle, then loop | 2623 | * searching through the pending list again. |
| 2373 | * back and pick up where we left off | 2624 | * |
| 2625 | * We just inserted some extents, which could have resulted in new | ||
| 2626 | * blocks being allocated, which would result in new blocks needing | ||
| 2627 | * updates, so if all is set we _must_ restart to get the updated | ||
| 2628 | * blocks. | ||
| 2374 | */ | 2629 | */ |
| 2375 | if (num_inserts == max_inserts) { | 2630 | if (restart || all) { |
| 2376 | INIT_LIST_HEAD(&insert_list); | ||
| 2377 | INIT_LIST_HEAD(&update_list); | ||
| 2378 | num_inserts = 0; | ||
| 2379 | goto again; | ||
| 2380 | } | ||
| 2381 | |||
| 2382 | /* | ||
| 2383 | * again, if we need to make absolutely sure there are no more pending | ||
| 2384 | * extent operations left and we know that we skipped some, go back to | ||
| 2385 | * the beginning and do it all again | ||
| 2386 | */ | ||
| 2387 | if (all && skipped) { | ||
| 2388 | INIT_LIST_HEAD(&insert_list); | 2631 | INIT_LIST_HEAD(&insert_list); |
| 2389 | INIT_LIST_HEAD(&update_list); | 2632 | INIT_LIST_HEAD(&update_list); |
| 2390 | search = 0; | 2633 | search = 0; |
| 2391 | skipped = 0; | 2634 | restart = 0; |
| 2392 | num_inserts = 0; | 2635 | num_inserts = 0; |
| 2393 | goto again; | 2636 | goto again; |
| 2394 | } | 2637 | } |
| @@ -2709,6 +2952,8 @@ again: | |||
| 2709 | goto again; | 2952 | goto again; |
| 2710 | } | 2953 | } |
| 2711 | 2954 | ||
| 2955 | if (!err) | ||
| 2956 | finish_current_insert(trans, extent_root, 0); | ||
| 2712 | return err; | 2957 | return err; |
| 2713 | } | 2958 | } |
| 2714 | 2959 | ||
| @@ -2859,7 +3104,8 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
| 2859 | 3104 | ||
| 2860 | if (data & BTRFS_BLOCK_GROUP_METADATA) { | 3105 | if (data & BTRFS_BLOCK_GROUP_METADATA) { |
| 2861 | last_ptr = &root->fs_info->last_alloc; | 3106 | last_ptr = &root->fs_info->last_alloc; |
| 2862 | empty_cluster = 64 * 1024; | 3107 | if (!btrfs_test_opt(root, SSD)) |
| 3108 | empty_cluster = 64 * 1024; | ||
| 2863 | } | 3109 | } |
| 2864 | 3110 | ||
| 2865 | if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) | 3111 | if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) |
| @@ -3091,6 +3337,10 @@ static void dump_space_info(struct btrfs_space_info *info, u64 bytes) | |||
| 3091 | (unsigned long long)(info->total_bytes - info->bytes_used - | 3337 | (unsigned long long)(info->total_bytes - info->bytes_used - |
| 3092 | info->bytes_pinned - info->bytes_reserved), | 3338 | info->bytes_pinned - info->bytes_reserved), |
| 3093 | (info->full) ? "" : "not "); | 3339 | (info->full) ? "" : "not "); |
| 3340 | printk(KERN_INFO "space_info total=%llu, pinned=%llu, delalloc=%llu," | ||
| 3341 | " may_use=%llu, used=%llu\n", info->total_bytes, | ||
| 3342 | info->bytes_pinned, info->bytes_delalloc, info->bytes_may_use, | ||
| 3343 | info->bytes_used); | ||
| 3094 | 3344 | ||
| 3095 | down_read(&info->groups_sem); | 3345 | down_read(&info->groups_sem); |
| 3096 | list_for_each_entry(cache, &info->block_groups, list) { | 3346 | list_for_each_entry(cache, &info->block_groups, list) { |
| @@ -3117,24 +3367,10 @@ static int __btrfs_reserve_extent(struct btrfs_trans_handle *trans, | |||
| 3117 | { | 3367 | { |
| 3118 | int ret; | 3368 | int ret; |
| 3119 | u64 search_start = 0; | 3369 | u64 search_start = 0; |
| 3120 | u64 alloc_profile; | ||
| 3121 | struct btrfs_fs_info *info = root->fs_info; | 3370 | struct btrfs_fs_info *info = root->fs_info; |
| 3122 | 3371 | ||
| 3123 | if (data) { | 3372 | data = btrfs_get_alloc_profile(root, data); |
| 3124 | alloc_profile = info->avail_data_alloc_bits & | ||
| 3125 | info->data_alloc_profile; | ||
| 3126 | data = BTRFS_BLOCK_GROUP_DATA | alloc_profile; | ||
| 3127 | } else if (root == root->fs_info->chunk_root) { | ||
| 3128 | alloc_profile = info->avail_system_alloc_bits & | ||
| 3129 | info->system_alloc_profile; | ||
| 3130 | data = BTRFS_BLOCK_GROUP_SYSTEM | alloc_profile; | ||
| 3131 | } else { | ||
| 3132 | alloc_profile = info->avail_metadata_alloc_bits & | ||
| 3133 | info->metadata_alloc_profile; | ||
| 3134 | data = BTRFS_BLOCK_GROUP_METADATA | alloc_profile; | ||
| 3135 | } | ||
| 3136 | again: | 3373 | again: |
| 3137 | data = btrfs_reduce_alloc_profile(root, data); | ||
| 3138 | /* | 3374 | /* |
| 3139 | * the only place that sets empty_size is btrfs_realloc_node, which | 3375 | * the only place that sets empty_size is btrfs_realloc_node, which |
| 3140 | * is not called recursively on allocations | 3376 | * is not called recursively on allocations |
| @@ -3402,7 +3638,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, | |||
| 3402 | 3638 | ||
| 3403 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | 3639 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, |
| 3404 | struct btrfs_root *root, | 3640 | struct btrfs_root *root, |
| 3405 | u64 bytenr, u32 blocksize) | 3641 | u64 bytenr, u32 blocksize, |
| 3642 | int level) | ||
| 3406 | { | 3643 | { |
| 3407 | struct extent_buffer *buf; | 3644 | struct extent_buffer *buf; |
| 3408 | 3645 | ||
| @@ -3410,6 +3647,7 @@ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | |||
| 3410 | if (!buf) | 3647 | if (!buf) |
| 3411 | return ERR_PTR(-ENOMEM); | 3648 | return ERR_PTR(-ENOMEM); |
| 3412 | btrfs_set_header_generation(buf, trans->transid); | 3649 | btrfs_set_header_generation(buf, trans->transid); |
| 3650 | btrfs_set_buffer_lockdep_class(buf, level); | ||
| 3413 | btrfs_tree_lock(buf); | 3651 | btrfs_tree_lock(buf); |
| 3414 | clean_tree_block(trans, root, buf); | 3652 | clean_tree_block(trans, root, buf); |
| 3415 | 3653 | ||
| @@ -3453,7 +3691,8 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
| 3453 | return ERR_PTR(ret); | 3691 | return ERR_PTR(ret); |
| 3454 | } | 3692 | } |
| 3455 | 3693 | ||
| 3456 | buf = btrfs_init_new_buffer(trans, root, ins.objectid, blocksize); | 3694 | buf = btrfs_init_new_buffer(trans, root, ins.objectid, |
| 3695 | blocksize, level); | ||
| 3457 | return buf; | 3696 | return buf; |
| 3458 | } | 3697 | } |
| 3459 | 3698 | ||
| @@ -4179,13 +4418,13 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans, | |||
| 4179 | path = btrfs_alloc_path(); | 4418 | path = btrfs_alloc_path(); |
| 4180 | BUG_ON(!path); | 4419 | BUG_ON(!path); |
| 4181 | 4420 | ||
| 4182 | BUG_ON(!btrfs_tree_locked(parent)); | 4421 | btrfs_assert_tree_locked(parent); |
| 4183 | parent_level = btrfs_header_level(parent); | 4422 | parent_level = btrfs_header_level(parent); |
| 4184 | extent_buffer_get(parent); | 4423 | extent_buffer_get(parent); |
| 4185 | path->nodes[parent_level] = parent; | 4424 | path->nodes[parent_level] = parent; |
| 4186 | path->slots[parent_level] = btrfs_header_nritems(parent); | 4425 | path->slots[parent_level] = btrfs_header_nritems(parent); |
| 4187 | 4426 | ||
| 4188 | BUG_ON(!btrfs_tree_locked(node)); | 4427 | btrfs_assert_tree_locked(node); |
| 4189 | level = btrfs_header_level(node); | 4428 | level = btrfs_header_level(node); |
| 4190 | extent_buffer_get(node); | 4429 | extent_buffer_get(node); |
| 4191 | path->nodes[level] = node; | 4430 | path->nodes[level] = node; |
| @@ -5641,7 +5880,9 @@ static noinline int relocate_one_extent(struct btrfs_root *extent_root, | |||
| 5641 | prev_block = block_start; | 5880 | prev_block = block_start; |
| 5642 | } | 5881 | } |
| 5643 | 5882 | ||
| 5883 | mutex_lock(&extent_root->fs_info->trans_mutex); | ||
| 5644 | btrfs_record_root_in_trans(found_root); | 5884 | btrfs_record_root_in_trans(found_root); |
| 5885 | mutex_unlock(&extent_root->fs_info->trans_mutex); | ||
| 5645 | if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { | 5886 | if (ref_path->owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { |
| 5646 | /* | 5887 | /* |
| 5647 | * try to update data extent references while | 5888 | * try to update data extent references while |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 37d43b516b79..ebe6b29e6069 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
| @@ -415,8 +415,6 @@ static int split_state(struct extent_io_tree *tree, struct extent_state *orig, | |||
| 415 | 415 | ||
| 416 | node = tree_insert(&tree->state, prealloc->end, &prealloc->rb_node); | 416 | node = tree_insert(&tree->state, prealloc->end, &prealloc->rb_node); |
| 417 | if (node) { | 417 | if (node) { |
| 418 | struct extent_state *found; | ||
| 419 | found = rb_entry(node, struct extent_state, rb_node); | ||
| 420 | free_extent_state(prealloc); | 418 | free_extent_state(prealloc); |
| 421 | return -EEXIST; | 419 | return -EEXIST; |
| 422 | } | 420 | } |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 3e8023efaff7..dc78954861b3 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -1091,19 +1091,24 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
| 1091 | WARN_ON(num_pages > nrptrs); | 1091 | WARN_ON(num_pages > nrptrs); |
| 1092 | memset(pages, 0, sizeof(struct page *) * nrptrs); | 1092 | memset(pages, 0, sizeof(struct page *) * nrptrs); |
| 1093 | 1093 | ||
| 1094 | ret = btrfs_check_free_space(root, write_bytes, 0); | 1094 | ret = btrfs_check_data_free_space(root, inode, write_bytes); |
| 1095 | if (ret) | 1095 | if (ret) |
| 1096 | goto out; | 1096 | goto out; |
| 1097 | 1097 | ||
| 1098 | ret = prepare_pages(root, file, pages, num_pages, | 1098 | ret = prepare_pages(root, file, pages, num_pages, |
| 1099 | pos, first_index, last_index, | 1099 | pos, first_index, last_index, |
| 1100 | write_bytes); | 1100 | write_bytes); |
| 1101 | if (ret) | 1101 | if (ret) { |
| 1102 | btrfs_free_reserved_data_space(root, inode, | ||
| 1103 | write_bytes); | ||
| 1102 | goto out; | 1104 | goto out; |
| 1105 | } | ||
| 1103 | 1106 | ||
| 1104 | ret = btrfs_copy_from_user(pos, num_pages, | 1107 | ret = btrfs_copy_from_user(pos, num_pages, |
| 1105 | write_bytes, pages, buf); | 1108 | write_bytes, pages, buf); |
| 1106 | if (ret) { | 1109 | if (ret) { |
| 1110 | btrfs_free_reserved_data_space(root, inode, | ||
| 1111 | write_bytes); | ||
| 1107 | btrfs_drop_pages(pages, num_pages); | 1112 | btrfs_drop_pages(pages, num_pages); |
| 1108 | goto out; | 1113 | goto out; |
| 1109 | } | 1114 | } |
| @@ -1111,8 +1116,11 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
| 1111 | ret = dirty_and_release_pages(NULL, root, file, pages, | 1116 | ret = dirty_and_release_pages(NULL, root, file, pages, |
| 1112 | num_pages, pos, write_bytes); | 1117 | num_pages, pos, write_bytes); |
| 1113 | btrfs_drop_pages(pages, num_pages); | 1118 | btrfs_drop_pages(pages, num_pages); |
| 1114 | if (ret) | 1119 | if (ret) { |
| 1120 | btrfs_free_reserved_data_space(root, inode, | ||
| 1121 | write_bytes); | ||
| 1115 | goto out; | 1122 | goto out; |
| 1123 | } | ||
| 1116 | 1124 | ||
| 1117 | if (will_write) { | 1125 | if (will_write) { |
| 1118 | btrfs_fdatawrite_range(inode->i_mapping, pos, | 1126 | btrfs_fdatawrite_range(inode->i_mapping, pos, |
| @@ -1136,6 +1144,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf, | |||
| 1136 | } | 1144 | } |
| 1137 | out: | 1145 | out: |
| 1138 | mutex_unlock(&inode->i_mutex); | 1146 | mutex_unlock(&inode->i_mutex); |
| 1147 | if (ret) | ||
| 1148 | err = ret; | ||
| 1139 | 1149 | ||
| 1140 | out_nolock: | 1150 | out_nolock: |
| 1141 | kfree(pages); | 1151 | kfree(pages); |
| @@ -1222,7 +1232,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1222 | /* | 1232 | /* |
| 1223 | * ok we haven't committed the transaction yet, lets do a commit | 1233 | * ok we haven't committed the transaction yet, lets do a commit |
| 1224 | */ | 1234 | */ |
| 1225 | if (file->private_data) | 1235 | if (file && file->private_data) |
| 1226 | btrfs_ioctl_trans_end(file); | 1236 | btrfs_ioctl_trans_end(file); |
| 1227 | 1237 | ||
| 1228 | trans = btrfs_start_transaction(root, 1); | 1238 | trans = btrfs_start_transaction(root, 1); |
| @@ -1231,7 +1241,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1231 | goto out; | 1241 | goto out; |
| 1232 | } | 1242 | } |
| 1233 | 1243 | ||
| 1234 | ret = btrfs_log_dentry_safe(trans, root, file->f_dentry); | 1244 | ret = btrfs_log_dentry_safe(trans, root, dentry); |
| 1235 | if (ret < 0) | 1245 | if (ret < 0) |
| 1236 | goto out; | 1246 | goto out; |
| 1237 | 1247 | ||
| @@ -1245,7 +1255,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1245 | * file again, but that will end up using the synchronization | 1255 | * file again, but that will end up using the synchronization |
| 1246 | * inside btrfs_sync_log to keep things safe. | 1256 | * inside btrfs_sync_log to keep things safe. |
| 1247 | */ | 1257 | */ |
| 1248 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); | 1258 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 1249 | 1259 | ||
| 1250 | if (ret > 0) { | 1260 | if (ret > 0) { |
| 1251 | ret = btrfs_commit_transaction(trans, root); | 1261 | ret = btrfs_commit_transaction(trans, root); |
| @@ -1253,7 +1263,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1253 | btrfs_sync_log(trans, root); | 1263 | btrfs_sync_log(trans, root); |
| 1254 | ret = btrfs_end_transaction(trans, root); | 1264 | ret = btrfs_end_transaction(trans, root); |
| 1255 | } | 1265 | } |
| 1256 | mutex_lock(&file->f_dentry->d_inode->i_mutex); | 1266 | mutex_lock(&dentry->d_inode->i_mutex); |
| 1257 | out: | 1267 | out: |
| 1258 | return ret > 0 ? EIO : ret; | 1268 | return ret > 0 ? EIO : ret; |
| 1259 | } | 1269 | } |
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index 2aa79873eb46..cc7334d833c9 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c | |||
| @@ -84,7 +84,6 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans, | |||
| 84 | search_key.type = 0; | 84 | search_key.type = 0; |
| 85 | search_key.offset = 0; | 85 | search_key.offset = 0; |
| 86 | 86 | ||
| 87 | btrfs_init_path(path); | ||
| 88 | start_found = 0; | 87 | start_found = 0; |
| 89 | ret = btrfs_search_slot(trans, root, &search_key, path, 0, 0); | 88 | ret = btrfs_search_slot(trans, root, &search_key, path, 0, 0); |
| 90 | if (ret < 0) | 89 | if (ret < 0) |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8f0706210a47..7d4f948bc22a 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -102,34 +102,6 @@ static int btrfs_init_inode_security(struct inode *inode, struct inode *dir) | |||
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | /* | 104 | /* |
| 105 | * a very lame attempt at stopping writes when the FS is 85% full. There | ||
| 106 | * are countless ways this is incorrect, but it is better than nothing. | ||
| 107 | */ | ||
| 108 | int btrfs_check_free_space(struct btrfs_root *root, u64 num_required, | ||
| 109 | int for_del) | ||
| 110 | { | ||
| 111 | u64 total; | ||
| 112 | u64 used; | ||
| 113 | u64 thresh; | ||
| 114 | int ret = 0; | ||
| 115 | |||
| 116 | spin_lock(&root->fs_info->delalloc_lock); | ||
| 117 | total = btrfs_super_total_bytes(&root->fs_info->super_copy); | ||
| 118 | used = btrfs_super_bytes_used(&root->fs_info->super_copy); | ||
| 119 | if (for_del) | ||
| 120 | thresh = total * 90; | ||
| 121 | else | ||
| 122 | thresh = total * 85; | ||
| 123 | |||
| 124 | do_div(thresh, 100); | ||
| 125 | |||
| 126 | if (used + root->fs_info->delalloc_bytes + num_required > thresh) | ||
| 127 | ret = -ENOSPC; | ||
| 128 | spin_unlock(&root->fs_info->delalloc_lock); | ||
| 129 | return ret; | ||
| 130 | } | ||
| 131 | |||
| 132 | /* | ||
| 133 | * this does all the hard work for inserting an inline extent into | 105 | * this does all the hard work for inserting an inline extent into |
| 134 | * the btree. The caller should have done a btrfs_drop_extents so that | 106 | * the btree. The caller should have done a btrfs_drop_extents so that |
| 135 | * no overlapping inline items exist in the btree | 107 | * no overlapping inline items exist in the btree |
| @@ -1190,6 +1162,7 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end, | |||
| 1190 | */ | 1162 | */ |
| 1191 | if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { | 1163 | if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { |
| 1192 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1164 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 1165 | btrfs_delalloc_reserve_space(root, inode, end - start + 1); | ||
| 1193 | spin_lock(&root->fs_info->delalloc_lock); | 1166 | spin_lock(&root->fs_info->delalloc_lock); |
| 1194 | BTRFS_I(inode)->delalloc_bytes += end - start + 1; | 1167 | BTRFS_I(inode)->delalloc_bytes += end - start + 1; |
| 1195 | root->fs_info->delalloc_bytes += end - start + 1; | 1168 | root->fs_info->delalloc_bytes += end - start + 1; |
| @@ -1223,9 +1196,12 @@ static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end, | |||
| 1223 | (unsigned long long)end - start + 1, | 1196 | (unsigned long long)end - start + 1, |
| 1224 | (unsigned long long) | 1197 | (unsigned long long) |
| 1225 | root->fs_info->delalloc_bytes); | 1198 | root->fs_info->delalloc_bytes); |
| 1199 | btrfs_delalloc_free_space(root, inode, (u64)-1); | ||
| 1226 | root->fs_info->delalloc_bytes = 0; | 1200 | root->fs_info->delalloc_bytes = 0; |
| 1227 | BTRFS_I(inode)->delalloc_bytes = 0; | 1201 | BTRFS_I(inode)->delalloc_bytes = 0; |
| 1228 | } else { | 1202 | } else { |
| 1203 | btrfs_delalloc_free_space(root, inode, | ||
| 1204 | end - start + 1); | ||
| 1229 | root->fs_info->delalloc_bytes -= end - start + 1; | 1205 | root->fs_info->delalloc_bytes -= end - start + 1; |
| 1230 | BTRFS_I(inode)->delalloc_bytes -= end - start + 1; | 1206 | BTRFS_I(inode)->delalloc_bytes -= end - start + 1; |
| 1231 | } | 1207 | } |
| @@ -2245,10 +2221,6 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 2245 | 2221 | ||
| 2246 | root = BTRFS_I(dir)->root; | 2222 | root = BTRFS_I(dir)->root; |
| 2247 | 2223 | ||
| 2248 | ret = btrfs_check_free_space(root, 1, 1); | ||
| 2249 | if (ret) | ||
| 2250 | goto fail; | ||
| 2251 | |||
| 2252 | trans = btrfs_start_transaction(root, 1); | 2224 | trans = btrfs_start_transaction(root, 1); |
| 2253 | 2225 | ||
| 2254 | btrfs_set_trans_block_group(trans, dir); | 2226 | btrfs_set_trans_block_group(trans, dir); |
| @@ -2261,7 +2233,6 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 2261 | nr = trans->blocks_used; | 2233 | nr = trans->blocks_used; |
| 2262 | 2234 | ||
| 2263 | btrfs_end_transaction_throttle(trans, root); | 2235 | btrfs_end_transaction_throttle(trans, root); |
| 2264 | fail: | ||
| 2265 | btrfs_btree_balance_dirty(root, nr); | 2236 | btrfs_btree_balance_dirty(root, nr); |
| 2266 | return ret; | 2237 | return ret; |
| 2267 | } | 2238 | } |
| @@ -2284,10 +2255,6 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 2284 | return -ENOTEMPTY; | 2255 | return -ENOTEMPTY; |
| 2285 | } | 2256 | } |
| 2286 | 2257 | ||
| 2287 | ret = btrfs_check_free_space(root, 1, 1); | ||
| 2288 | if (ret) | ||
| 2289 | goto fail; | ||
| 2290 | |||
| 2291 | trans = btrfs_start_transaction(root, 1); | 2258 | trans = btrfs_start_transaction(root, 1); |
| 2292 | btrfs_set_trans_block_group(trans, dir); | 2259 | btrfs_set_trans_block_group(trans, dir); |
| 2293 | 2260 | ||
| @@ -2304,7 +2271,6 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 2304 | fail_trans: | 2271 | fail_trans: |
| 2305 | nr = trans->blocks_used; | 2272 | nr = trans->blocks_used; |
| 2306 | ret = btrfs_end_transaction_throttle(trans, root); | 2273 | ret = btrfs_end_transaction_throttle(trans, root); |
| 2307 | fail: | ||
| 2308 | btrfs_btree_balance_dirty(root, nr); | 2274 | btrfs_btree_balance_dirty(root, nr); |
| 2309 | 2275 | ||
| 2310 | if (ret && !err) | 2276 | if (ret && !err) |
| @@ -2531,8 +2497,6 @@ noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, | |||
| 2531 | key.offset = (u64)-1; | 2497 | key.offset = (u64)-1; |
| 2532 | key.type = (u8)-1; | 2498 | key.type = (u8)-1; |
| 2533 | 2499 | ||
| 2534 | btrfs_init_path(path); | ||
| 2535 | |||
| 2536 | search_again: | 2500 | search_again: |
| 2537 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); | 2501 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
| 2538 | if (ret < 0) | 2502 | if (ret < 0) |
| @@ -2820,7 +2784,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) | |||
| 2820 | if (size <= hole_start) | 2784 | if (size <= hole_start) |
| 2821 | return 0; | 2785 | return 0; |
| 2822 | 2786 | ||
| 2823 | err = btrfs_check_free_space(root, 1, 0); | 2787 | err = btrfs_check_metadata_free_space(root); |
| 2824 | if (err) | 2788 | if (err) |
| 2825 | return err; | 2789 | return err; |
| 2826 | 2790 | ||
| @@ -3016,6 +2980,7 @@ static noinline void init_btrfs_i(struct inode *inode) | |||
| 3016 | bi->last_trans = 0; | 2980 | bi->last_trans = 0; |
| 3017 | bi->logged_trans = 0; | 2981 | bi->logged_trans = 0; |
| 3018 | bi->delalloc_bytes = 0; | 2982 | bi->delalloc_bytes = 0; |
| 2983 | bi->reserved_bytes = 0; | ||
| 3019 | bi->disk_i_size = 0; | 2984 | bi->disk_i_size = 0; |
| 3020 | bi->flags = 0; | 2985 | bi->flags = 0; |
| 3021 | bi->index_cnt = (u64)-1; | 2986 | bi->index_cnt = (u64)-1; |
| @@ -3037,6 +3002,7 @@ static int btrfs_init_locked_inode(struct inode *inode, void *p) | |||
| 3037 | inode->i_ino = args->ino; | 3002 | inode->i_ino = args->ino; |
| 3038 | init_btrfs_i(inode); | 3003 | init_btrfs_i(inode); |
| 3039 | BTRFS_I(inode)->root = args->root; | 3004 | BTRFS_I(inode)->root = args->root; |
| 3005 | btrfs_set_inode_space_info(args->root, inode); | ||
| 3040 | return 0; | 3006 | return 0; |
| 3041 | } | 3007 | } |
| 3042 | 3008 | ||
| @@ -3457,6 +3423,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
| 3457 | BTRFS_I(inode)->index_cnt = 2; | 3423 | BTRFS_I(inode)->index_cnt = 2; |
| 3458 | BTRFS_I(inode)->root = root; | 3424 | BTRFS_I(inode)->root = root; |
| 3459 | BTRFS_I(inode)->generation = trans->transid; | 3425 | BTRFS_I(inode)->generation = trans->transid; |
| 3426 | btrfs_set_inode_space_info(root, inode); | ||
| 3460 | 3427 | ||
| 3461 | if (mode & S_IFDIR) | 3428 | if (mode & S_IFDIR) |
| 3462 | owner = 0; | 3429 | owner = 0; |
| @@ -3604,7 +3571,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
| 3604 | if (!new_valid_dev(rdev)) | 3571 | if (!new_valid_dev(rdev)) |
| 3605 | return -EINVAL; | 3572 | return -EINVAL; |
| 3606 | 3573 | ||
| 3607 | err = btrfs_check_free_space(root, 1, 0); | 3574 | err = btrfs_check_metadata_free_space(root); |
| 3608 | if (err) | 3575 | if (err) |
| 3609 | goto fail; | 3576 | goto fail; |
| 3610 | 3577 | ||
| @@ -3667,7 +3634,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
| 3667 | u64 objectid; | 3634 | u64 objectid; |
| 3668 | u64 index = 0; | 3635 | u64 index = 0; |
| 3669 | 3636 | ||
| 3670 | err = btrfs_check_free_space(root, 1, 0); | 3637 | err = btrfs_check_metadata_free_space(root); |
| 3671 | if (err) | 3638 | if (err) |
| 3672 | goto fail; | 3639 | goto fail; |
| 3673 | trans = btrfs_start_transaction(root, 1); | 3640 | trans = btrfs_start_transaction(root, 1); |
| @@ -3735,7 +3702,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 3735 | return -ENOENT; | 3702 | return -ENOENT; |
| 3736 | 3703 | ||
| 3737 | btrfs_inc_nlink(inode); | 3704 | btrfs_inc_nlink(inode); |
| 3738 | err = btrfs_check_free_space(root, 1, 0); | 3705 | err = btrfs_check_metadata_free_space(root); |
| 3739 | if (err) | 3706 | if (err) |
| 3740 | goto fail; | 3707 | goto fail; |
| 3741 | err = btrfs_set_inode_index(dir, &index); | 3708 | err = btrfs_set_inode_index(dir, &index); |
| @@ -3781,7 +3748,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 3781 | u64 index = 0; | 3748 | u64 index = 0; |
| 3782 | unsigned long nr = 1; | 3749 | unsigned long nr = 1; |
| 3783 | 3750 | ||
| 3784 | err = btrfs_check_free_space(root, 1, 0); | 3751 | err = btrfs_check_metadata_free_space(root); |
| 3785 | if (err) | 3752 | if (err) |
| 3786 | goto out_unlock; | 3753 | goto out_unlock; |
| 3787 | 3754 | ||
| @@ -4263,7 +4230,7 @@ static int btrfs_releasepage(struct page *page, gfp_t gfp_flags) | |||
| 4263 | { | 4230 | { |
| 4264 | if (PageWriteback(page) || PageDirty(page)) | 4231 | if (PageWriteback(page) || PageDirty(page)) |
| 4265 | return 0; | 4232 | return 0; |
| 4266 | return __btrfs_releasepage(page, gfp_flags); | 4233 | return __btrfs_releasepage(page, gfp_flags & GFP_NOFS); |
| 4267 | } | 4234 | } |
| 4268 | 4235 | ||
| 4269 | static void btrfs_invalidatepage(struct page *page, unsigned long offset) | 4236 | static void btrfs_invalidatepage(struct page *page, unsigned long offset) |
| @@ -4338,7 +4305,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page) | |||
| 4338 | u64 page_start; | 4305 | u64 page_start; |
| 4339 | u64 page_end; | 4306 | u64 page_end; |
| 4340 | 4307 | ||
| 4341 | ret = btrfs_check_free_space(root, PAGE_CACHE_SIZE, 0); | 4308 | ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE); |
| 4342 | if (ret) | 4309 | if (ret) |
| 4343 | goto out; | 4310 | goto out; |
| 4344 | 4311 | ||
| @@ -4351,6 +4318,7 @@ again: | |||
| 4351 | 4318 | ||
| 4352 | if ((page->mapping != inode->i_mapping) || | 4319 | if ((page->mapping != inode->i_mapping) || |
| 4353 | (page_start >= size)) { | 4320 | (page_start >= size)) { |
| 4321 | btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE); | ||
| 4354 | /* page got truncated out from underneath us */ | 4322 | /* page got truncated out from underneath us */ |
| 4355 | goto out_unlock; | 4323 | goto out_unlock; |
| 4356 | } | 4324 | } |
| @@ -4633,7 +4601,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 4633 | if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) | 4601 | if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) |
| 4634 | return -EXDEV; | 4602 | return -EXDEV; |
| 4635 | 4603 | ||
| 4636 | ret = btrfs_check_free_space(root, 1, 0); | 4604 | ret = btrfs_check_metadata_free_space(root); |
| 4637 | if (ret) | 4605 | if (ret) |
| 4638 | goto out_unlock; | 4606 | goto out_unlock; |
| 4639 | 4607 | ||
| @@ -4751,7 +4719,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 4751 | if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root)) | 4719 | if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root)) |
| 4752 | return -ENAMETOOLONG; | 4720 | return -ENAMETOOLONG; |
| 4753 | 4721 | ||
| 4754 | err = btrfs_check_free_space(root, 1, 0); | 4722 | err = btrfs_check_metadata_free_space(root); |
| 4755 | if (err) | 4723 | if (err) |
| 4756 | goto out_fail; | 4724 | goto out_fail; |
| 4757 | 4725 | ||
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 988fdc8b49eb..bca729fc80c8 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -70,7 +70,7 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 70 | u64 index = 0; | 70 | u64 index = 0; |
| 71 | unsigned long nr = 1; | 71 | unsigned long nr = 1; |
| 72 | 72 | ||
| 73 | ret = btrfs_check_free_space(root, 1, 0); | 73 | ret = btrfs_check_metadata_free_space(root); |
| 74 | if (ret) | 74 | if (ret) |
| 75 | goto fail_commit; | 75 | goto fail_commit; |
| 76 | 76 | ||
| @@ -203,7 +203,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, | |||
| 203 | if (!root->ref_cows) | 203 | if (!root->ref_cows) |
| 204 | return -EINVAL; | 204 | return -EINVAL; |
| 205 | 205 | ||
| 206 | ret = btrfs_check_free_space(root, 1, 0); | 206 | ret = btrfs_check_metadata_free_space(root); |
| 207 | if (ret) | 207 | if (ret) |
| 208 | goto fail_unlock; | 208 | goto fail_unlock; |
| 209 | 209 | ||
| @@ -374,7 +374,7 @@ static int btrfs_defrag_file(struct file *file) | |||
| 374 | unsigned long i; | 374 | unsigned long i; |
| 375 | int ret; | 375 | int ret; |
| 376 | 376 | ||
| 377 | ret = btrfs_check_free_space(root, inode->i_size, 0); | 377 | ret = btrfs_check_data_free_space(root, inode, inode->i_size); |
| 378 | if (ret) | 378 | if (ret) |
| 379 | return -ENOSPC; | 379 | return -ENOSPC; |
| 380 | 380 | ||
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index 9ebe9385129b..47b0a88c12a2 100644 --- a/fs/btrfs/locking.c +++ b/fs/btrfs/locking.c | |||
| @@ -25,21 +25,10 @@ | |||
| 25 | #include "extent_io.h" | 25 | #include "extent_io.h" |
| 26 | #include "locking.h" | 26 | #include "locking.h" |
| 27 | 27 | ||
| 28 | /* | ||
| 29 | * btrfs_header_level() isn't free, so don't call it when lockdep isn't | ||
| 30 | * on | ||
| 31 | */ | ||
| 32 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 33 | static inline void spin_nested(struct extent_buffer *eb) | ||
| 34 | { | ||
| 35 | spin_lock_nested(&eb->lock, BTRFS_MAX_LEVEL - btrfs_header_level(eb)); | ||
| 36 | } | ||
| 37 | #else | ||
| 38 | static inline void spin_nested(struct extent_buffer *eb) | 28 | static inline void spin_nested(struct extent_buffer *eb) |
| 39 | { | 29 | { |
| 40 | spin_lock(&eb->lock); | 30 | spin_lock(&eb->lock); |
| 41 | } | 31 | } |
| 42 | #endif | ||
| 43 | 32 | ||
| 44 | /* | 33 | /* |
| 45 | * Setting a lock to blocking will drop the spinlock and set the | 34 | * Setting a lock to blocking will drop the spinlock and set the |
| @@ -231,8 +220,8 @@ int btrfs_tree_unlock(struct extent_buffer *eb) | |||
| 231 | return 0; | 220 | return 0; |
| 232 | } | 221 | } |
| 233 | 222 | ||
| 234 | int btrfs_tree_locked(struct extent_buffer *eb) | 223 | void btrfs_assert_tree_locked(struct extent_buffer *eb) |
| 235 | { | 224 | { |
| 236 | return test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags) || | 225 | if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags)) |
| 237 | spin_is_locked(&eb->lock); | 226 | assert_spin_locked(&eb->lock); |
| 238 | } | 227 | } |
diff --git a/fs/btrfs/locking.h b/fs/btrfs/locking.h index 6bb0afbff928..6c4ce457168c 100644 --- a/fs/btrfs/locking.h +++ b/fs/btrfs/locking.h | |||
| @@ -21,11 +21,11 @@ | |||
| 21 | 21 | ||
| 22 | int btrfs_tree_lock(struct extent_buffer *eb); | 22 | int btrfs_tree_lock(struct extent_buffer *eb); |
| 23 | int btrfs_tree_unlock(struct extent_buffer *eb); | 23 | int btrfs_tree_unlock(struct extent_buffer *eb); |
| 24 | int btrfs_tree_locked(struct extent_buffer *eb); | ||
| 25 | 24 | ||
| 26 | int btrfs_try_tree_lock(struct extent_buffer *eb); | 25 | int btrfs_try_tree_lock(struct extent_buffer *eb); |
| 27 | int btrfs_try_spin_lock(struct extent_buffer *eb); | 26 | int btrfs_try_spin_lock(struct extent_buffer *eb); |
| 28 | 27 | ||
| 29 | void btrfs_set_lock_blocking(struct extent_buffer *eb); | 28 | void btrfs_set_lock_blocking(struct extent_buffer *eb); |
| 30 | void btrfs_clear_lock_blocking(struct extent_buffer *eb); | 29 | void btrfs_clear_lock_blocking(struct extent_buffer *eb); |
| 30 | void btrfs_assert_tree_locked(struct extent_buffer *eb); | ||
| 31 | #endif | 31 | #endif |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index f3fd7e2cbc38..19a4daf03ccb 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -379,7 +379,6 @@ int btrfs_sync_fs(struct super_block *sb, int wait) | |||
| 379 | btrfs_start_delalloc_inodes(root); | 379 | btrfs_start_delalloc_inodes(root); |
| 380 | btrfs_wait_ordered_extents(root, 0); | 380 | btrfs_wait_ordered_extents(root, 0); |
| 381 | 381 | ||
| 382 | btrfs_clean_old_snapshots(root); | ||
| 383 | trans = btrfs_start_transaction(root, 1); | 382 | trans = btrfs_start_transaction(root, 1); |
| 384 | ret = btrfs_commit_transaction(trans, root); | 383 | ret = btrfs_commit_transaction(trans, root); |
| 385 | sb->s_dirt = 0; | 384 | sb->s_dirt = 0; |
| @@ -511,6 +510,10 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) | |||
| 511 | struct btrfs_root *root = btrfs_sb(sb); | 510 | struct btrfs_root *root = btrfs_sb(sb); |
| 512 | int ret; | 511 | int ret; |
| 513 | 512 | ||
| 513 | ret = btrfs_parse_options(root, data); | ||
| 514 | if (ret) | ||
| 515 | return -EINVAL; | ||
| 516 | |||
| 514 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) | 517 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) |
| 515 | return 0; | 518 | return 0; |
| 516 | 519 | ||
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 919172de5c9a..4112d53d4f4d 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -688,7 +688,9 @@ static noinline int drop_dirty_roots(struct btrfs_root *tree_root, | |||
| 688 | num_bytes -= btrfs_root_used(&dirty->root->root_item); | 688 | num_bytes -= btrfs_root_used(&dirty->root->root_item); |
| 689 | bytes_used = btrfs_root_used(&root->root_item); | 689 | bytes_used = btrfs_root_used(&root->root_item); |
| 690 | if (num_bytes) { | 690 | if (num_bytes) { |
| 691 | mutex_lock(&root->fs_info->trans_mutex); | ||
| 691 | btrfs_record_root_in_trans(root); | 692 | btrfs_record_root_in_trans(root); |
| 693 | mutex_unlock(&root->fs_info->trans_mutex); | ||
| 692 | btrfs_set_root_used(&root->root_item, | 694 | btrfs_set_root_used(&root->root_item, |
| 693 | bytes_used - num_bytes); | 695 | bytes_used - num_bytes); |
| 694 | } | 696 | } |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 20794290256b..9c462fbd60fa 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
| @@ -2832,7 +2832,9 @@ again: | |||
| 2832 | BUG_ON(!wc.replay_dest); | 2832 | BUG_ON(!wc.replay_dest); |
| 2833 | 2833 | ||
| 2834 | wc.replay_dest->log_root = log; | 2834 | wc.replay_dest->log_root = log; |
| 2835 | mutex_lock(&fs_info->trans_mutex); | ||
| 2835 | btrfs_record_root_in_trans(wc.replay_dest); | 2836 | btrfs_record_root_in_trans(wc.replay_dest); |
| 2837 | mutex_unlock(&fs_info->trans_mutex); | ||
| 2836 | ret = walk_log_tree(trans, log, &wc); | 2838 | ret = walk_log_tree(trans, log, &wc); |
| 2837 | BUG_ON(ret); | 2839 | BUG_ON(ret); |
| 2838 | 2840 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index bcd14ebccae1..1316139bf9e8 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -2894,10 +2894,6 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, | |||
| 2894 | free_extent_map(em); | 2894 | free_extent_map(em); |
| 2895 | } | 2895 | } |
| 2896 | 2896 | ||
| 2897 | map = kzalloc(sizeof(*map), GFP_NOFS); | ||
| 2898 | if (!map) | ||
| 2899 | return -ENOMEM; | ||
| 2900 | |||
| 2901 | em = alloc_extent_map(GFP_NOFS); | 2897 | em = alloc_extent_map(GFP_NOFS); |
| 2902 | if (!em) | 2898 | if (!em) |
| 2903 | return -ENOMEM; | 2899 | return -ENOMEM; |
| @@ -3106,6 +3102,8 @@ int btrfs_read_sys_array(struct btrfs_root *root) | |||
| 3106 | if (!sb) | 3102 | if (!sb) |
| 3107 | return -ENOMEM; | 3103 | return -ENOMEM; |
| 3108 | btrfs_set_buffer_uptodate(sb); | 3104 | btrfs_set_buffer_uptodate(sb); |
| 3105 | btrfs_set_buffer_lockdep_class(sb, 0); | ||
| 3106 | |||
| 3109 | write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE); | 3107 | write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE); |
| 3110 | array_size = btrfs_super_sys_array_size(super_copy); | 3108 | array_size = btrfs_super_sys_array_size(super_copy); |
| 3111 | 3109 | ||
diff --git a/fs/buffer.c b/fs/buffer.c index 665d446b25bc..9f697419ed8e 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
| @@ -777,6 +777,7 @@ static int __set_page_dirty(struct page *page, | |||
| 777 | __inc_zone_page_state(page, NR_FILE_DIRTY); | 777 | __inc_zone_page_state(page, NR_FILE_DIRTY); |
| 778 | __inc_bdi_stat(mapping->backing_dev_info, | 778 | __inc_bdi_stat(mapping->backing_dev_info, |
| 779 | BDI_RECLAIMABLE); | 779 | BDI_RECLAIMABLE); |
| 780 | task_dirty_inc(current); | ||
| 780 | task_io_account_write(PAGE_CACHE_SIZE); | 781 | task_io_account_write(PAGE_CACHE_SIZE); |
| 781 | } | 782 | } |
| 782 | radix_tree_tag_set(&mapping->page_tree, | 783 | radix_tree_tag_set(&mapping->page_tree, |
| @@ -3108,7 +3109,7 @@ int sync_dirty_buffer(struct buffer_head *bh) | |||
| 3108 | if (test_clear_buffer_dirty(bh)) { | 3109 | if (test_clear_buffer_dirty(bh)) { |
| 3109 | get_bh(bh); | 3110 | get_bh(bh); |
| 3110 | bh->b_end_io = end_buffer_write_sync; | 3111 | bh->b_end_io = end_buffer_write_sync; |
| 3111 | ret = submit_bh(WRITE_SYNC, bh); | 3112 | ret = submit_bh(WRITE, bh); |
| 3112 | wait_on_buffer(bh); | 3113 | wait_on_buffer(bh); |
| 3113 | if (buffer_eopnotsupp(bh)) { | 3114 | if (buffer_eopnotsupp(bh)) { |
| 3114 | clear_buffer_eopnotsupp(bh); | 3115 | clear_buffer_eopnotsupp(bh); |
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 73ac7ebd1dfc..851388fafc73 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | Version 1.57 | ||
| 2 | ------------ | ||
| 3 | Improve support for multiple security contexts to the same server. We | ||
| 4 | used to use the same "vcnumber" for all connections which could cause | ||
| 5 | the server to treat subsequent connections, especially those that | ||
| 6 | are authenticated as guest, as reconnections, invalidating the earlier | ||
| 7 | user's smb session. This fix allows cifs to mount multiple times to the | ||
| 8 | same server with different userids without risking invalidating earlier | ||
| 9 | established security contexts. | ||
| 10 | |||
| 1 | Version 1.56 | 11 | Version 1.56 |
| 2 | ------------ | 12 | ------------ |
| 3 | Add "forcemandatorylock" mount option to allow user to use mandatory | 13 | Add "forcemandatorylock" mount option to allow user to use mandatory |
| @@ -7,7 +17,10 @@ specified and user does not have access to query information about the | |||
| 7 | top of the share. Fix problem in 2.6.28 resolving DFS paths to | 17 | top of the share. Fix problem in 2.6.28 resolving DFS paths to |
| 8 | Samba servers (worked to Windows). Fix rmdir so that pending search | 18 | Samba servers (worked to Windows). Fix rmdir so that pending search |
| 9 | (readdir) requests do not get invalid results which include the now | 19 | (readdir) requests do not get invalid results which include the now |
| 10 | removed directory. | 20 | removed directory. Fix oops in cifs_dfs_ref.c when prefixpath is not reachable |
| 21 | when using DFS. Add better file create support to servers which support | ||
| 22 | the CIFS POSIX protocol extensions (this adds support for new flags | ||
| 23 | on create, and improves semantics for write of locked ranges). | ||
| 11 | 24 | ||
| 12 | Version 1.55 | 25 | Version 1.55 |
| 13 | ------------ | 26 | ------------ |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 7ac481841f87..2b1d28a9ee28 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
| @@ -100,5 +100,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); | |||
| 100 | extern const struct export_operations cifs_export_ops; | 100 | extern const struct export_operations cifs_export_ops; |
| 101 | #endif /* EXPERIMENTAL */ | 101 | #endif /* EXPERIMENTAL */ |
| 102 | 102 | ||
| 103 | #define CIFS_VERSION "1.56" | 103 | #define CIFS_VERSION "1.57" |
| 104 | #endif /* _CIFSFS_H */ | 104 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 94c1ca0ec953..e004f6db5fc8 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -164,9 +164,12 @@ struct TCP_Server_Info { | |||
| 164 | /* multiplexed reads or writes */ | 164 | /* multiplexed reads or writes */ |
| 165 | unsigned int maxBuf; /* maxBuf specifies the maximum */ | 165 | unsigned int maxBuf; /* maxBuf specifies the maximum */ |
| 166 | /* message size the server can send or receive for non-raw SMBs */ | 166 | /* message size the server can send or receive for non-raw SMBs */ |
| 167 | unsigned int maxRw; /* maxRw specifies the maximum */ | 167 | unsigned int max_rw; /* maxRw specifies the maximum */ |
| 168 | /* message size the server can send or receive for */ | 168 | /* message size the server can send or receive for */ |
| 169 | /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */ | 169 | /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */ |
| 170 | unsigned int max_vcs; /* maximum number of smb sessions, at least | ||
| 171 | those that can be specified uniquely with | ||
| 172 | vcnumbers */ | ||
| 170 | char sessid[4]; /* unique token id for this session */ | 173 | char sessid[4]; /* unique token id for this session */ |
| 171 | /* (returned on Negotiate */ | 174 | /* (returned on Negotiate */ |
| 172 | int capabilities; /* allow selective disabling of caps by smb sess */ | 175 | int capabilities; /* allow selective disabling of caps by smb sess */ |
| @@ -210,6 +213,7 @@ struct cifsSesInfo { | |||
| 210 | unsigned overrideSecFlg; /* if non-zero override global sec flags */ | 213 | unsigned overrideSecFlg; /* if non-zero override global sec flags */ |
| 211 | __u16 ipc_tid; /* special tid for connection to IPC share */ | 214 | __u16 ipc_tid; /* special tid for connection to IPC share */ |
| 212 | __u16 flags; | 215 | __u16 flags; |
| 216 | __u16 vcnum; | ||
| 213 | char *serverOS; /* name of operating system underlying server */ | 217 | char *serverOS; /* name of operating system underlying server */ |
| 214 | char *serverNOS; /* name of network operating system of server */ | 218 | char *serverNOS; /* name of network operating system of server */ |
| 215 | char *serverDomain; /* security realm of server */ | 219 | char *serverDomain; /* security realm of server */ |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 382ba6298809..083dfc57c7a3 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -42,6 +42,7 @@ extern void _FreeXid(unsigned int); | |||
| 42 | #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current_fsuid())); | 42 | #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current_fsuid())); |
| 43 | #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__func__,curr_xid,(int)rc));} | 43 | #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__func__,curr_xid,(int)rc));} |
| 44 | extern char *build_path_from_dentry(struct dentry *); | 44 | extern char *build_path_from_dentry(struct dentry *); |
| 45 | extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb); | ||
| 45 | extern char *build_wildcard_path_from_dentry(struct dentry *direntry); | 46 | extern char *build_wildcard_path_from_dentry(struct dentry *direntry); |
| 46 | /* extern void renew_parental_timestamps(struct dentry *direntry);*/ | 47 | /* extern void renew_parental_timestamps(struct dentry *direntry);*/ |
| 47 | extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, | 48 | extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, |
| @@ -91,6 +92,9 @@ extern u64 cifs_UnixTimeToNT(struct timespec); | |||
| 91 | extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); | 92 | extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); |
| 92 | extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); | 93 | extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); |
| 93 | 94 | ||
| 95 | extern void posix_fill_in_inode(struct inode *tmp_inode, | ||
| 96 | FILE_UNIX_BASIC_INFO *pData, int isNewInode); | ||
| 97 | extern struct inode *cifs_new_inode(struct super_block *sb, __u64 *inum); | ||
| 94 | extern int cifs_get_inode_info(struct inode **pinode, | 98 | extern int cifs_get_inode_info(struct inode **pinode, |
| 95 | const unsigned char *search_path, | 99 | const unsigned char *search_path, |
| 96 | FILE_ALL_INFO *pfile_info, | 100 | FILE_ALL_INFO *pfile_info, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 552642a507c4..939e2f76b959 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -528,14 +528,15 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
| 528 | server->maxReq = le16_to_cpu(rsp->MaxMpxCount); | 528 | server->maxReq = le16_to_cpu(rsp->MaxMpxCount); |
| 529 | server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize), | 529 | server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize), |
| 530 | (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); | 530 | (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); |
| 531 | server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs); | ||
| 531 | GETU32(server->sessid) = le32_to_cpu(rsp->SessionKey); | 532 | GETU32(server->sessid) = le32_to_cpu(rsp->SessionKey); |
| 532 | /* even though we do not use raw we might as well set this | 533 | /* even though we do not use raw we might as well set this |
| 533 | accurately, in case we ever find a need for it */ | 534 | accurately, in case we ever find a need for it */ |
| 534 | if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { | 535 | if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) { |
| 535 | server->maxRw = 0xFF00; | 536 | server->max_rw = 0xFF00; |
| 536 | server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE; | 537 | server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE; |
| 537 | } else { | 538 | } else { |
| 538 | server->maxRw = 0;/* we do not need to use raw anyway */ | 539 | server->max_rw = 0;/* do not need to use raw anyway */ |
| 539 | server->capabilities = CAP_MPX_MODE; | 540 | server->capabilities = CAP_MPX_MODE; |
| 540 | } | 541 | } |
| 541 | tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone); | 542 | tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone); |
| @@ -638,7 +639,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
| 638 | /* probably no need to store and check maxvcs */ | 639 | /* probably no need to store and check maxvcs */ |
| 639 | server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize), | 640 | server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize), |
| 640 | (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); | 641 | (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); |
| 641 | server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); | 642 | server->max_rw = le32_to_cpu(pSMBr->MaxRawSize); |
| 642 | cFYI(DBG2, ("Max buf = %d", ses->server->maxBuf)); | 643 | cFYI(DBG2, ("Max buf = %d", ses->server->maxBuf)); |
| 643 | GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); | 644 | GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); |
| 644 | server->capabilities = le32_to_cpu(pSMBr->Capabilities); | 645 | server->capabilities = le32_to_cpu(pSMBr->Capabilities); |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 2209be943051..da0f4ffa0613 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include <linux/string.h> | 23 | #include <linux/string.h> |
| 24 | #include <linux/list.h> | 24 | #include <linux/list.h> |
| 25 | #include <linux/wait.h> | 25 | #include <linux/wait.h> |
| 26 | #include <linux/ipv6.h> | ||
| 27 | #include <linux/pagemap.h> | 26 | #include <linux/pagemap.h> |
| 28 | #include <linux/ctype.h> | 27 | #include <linux/ctype.h> |
| 29 | #include <linux/utsname.h> | 28 | #include <linux/utsname.h> |
| @@ -35,6 +34,7 @@ | |||
| 35 | #include <linux/freezer.h> | 34 | #include <linux/freezer.h> |
| 36 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
| 37 | #include <asm/processor.h> | 36 | #include <asm/processor.h> |
| 37 | #include <net/ipv6.h> | ||
| 38 | #include "cifspdu.h" | 38 | #include "cifspdu.h" |
| 39 | #include "cifsglob.h" | 39 | #include "cifsglob.h" |
| 40 | #include "cifsproto.h" | 40 | #include "cifsproto.h" |
| @@ -1379,8 +1379,8 @@ cifs_find_tcp_session(struct sockaddr_storage *addr) | |||
| 1379 | server->addr.sockAddr.sin_addr.s_addr)) | 1379 | server->addr.sockAddr.sin_addr.s_addr)) |
| 1380 | continue; | 1380 | continue; |
| 1381 | else if (addr->ss_family == AF_INET6 && | 1381 | else if (addr->ss_family == AF_INET6 && |
| 1382 | memcmp(&server->addr.sockAddr6.sin6_addr, | 1382 | !ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr, |
| 1383 | &addr6->sin6_addr, sizeof(addr6->sin6_addr))) | 1383 | &addr6->sin6_addr)) |
| 1384 | continue; | 1384 | continue; |
| 1385 | 1385 | ||
| 1386 | ++server->srv_count; | 1386 | ++server->srv_count; |
| @@ -2180,6 +2180,33 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, | |||
| 2180 | "mount option supported")); | 2180 | "mount option supported")); |
| 2181 | } | 2181 | } |
| 2182 | 2182 | ||
| 2183 | static int | ||
| 2184 | is_path_accessible(int xid, struct cifsTconInfo *tcon, | ||
| 2185 | struct cifs_sb_info *cifs_sb, const char *full_path) | ||
| 2186 | { | ||
| 2187 | int rc; | ||
| 2188 | __u64 inode_num; | ||
| 2189 | FILE_ALL_INFO *pfile_info; | ||
| 2190 | |||
| 2191 | rc = CIFSGetSrvInodeNumber(xid, tcon, full_path, &inode_num, | ||
| 2192 | cifs_sb->local_nls, | ||
| 2193 | cifs_sb->mnt_cifs_flags & | ||
| 2194 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 2195 | if (rc != -EOPNOTSUPP) | ||
| 2196 | return rc; | ||
| 2197 | |||
| 2198 | pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | ||
| 2199 | if (pfile_info == NULL) | ||
| 2200 | return -ENOMEM; | ||
| 2201 | |||
| 2202 | rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info, | ||
| 2203 | 0 /* not legacy */, cifs_sb->local_nls, | ||
| 2204 | cifs_sb->mnt_cifs_flags & | ||
| 2205 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 2206 | kfree(pfile_info); | ||
| 2207 | return rc; | ||
| 2208 | } | ||
| 2209 | |||
| 2183 | int | 2210 | int |
| 2184 | cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | 2211 | cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, |
| 2185 | char *mount_data, const char *devname) | 2212 | char *mount_data, const char *devname) |
| @@ -2190,6 +2217,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
| 2190 | struct cifsSesInfo *pSesInfo = NULL; | 2217 | struct cifsSesInfo *pSesInfo = NULL; |
| 2191 | struct cifsTconInfo *tcon = NULL; | 2218 | struct cifsTconInfo *tcon = NULL; |
| 2192 | struct TCP_Server_Info *srvTcp = NULL; | 2219 | struct TCP_Server_Info *srvTcp = NULL; |
| 2220 | char *full_path; | ||
| 2193 | 2221 | ||
| 2194 | xid = GetXid(); | 2222 | xid = GetXid(); |
| 2195 | 2223 | ||
| @@ -2426,6 +2454,23 @@ mount_fail_check: | |||
| 2426 | cifs_sb->rsize = min(cifs_sb->rsize, | 2454 | cifs_sb->rsize = min(cifs_sb->rsize, |
| 2427 | (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); | 2455 | (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); |
| 2428 | 2456 | ||
| 2457 | if (!rc && cifs_sb->prepathlen) { | ||
| 2458 | /* build_path_to_root works only when we have a valid tcon */ | ||
| 2459 | full_path = cifs_build_path_to_root(cifs_sb); | ||
| 2460 | if (full_path == NULL) { | ||
| 2461 | rc = -ENOMEM; | ||
| 2462 | goto mount_fail_check; | ||
| 2463 | } | ||
| 2464 | rc = is_path_accessible(xid, tcon, cifs_sb, full_path); | ||
| 2465 | if (rc) { | ||
| 2466 | cERROR(1, ("Path %s in not accessible: %d", | ||
| 2467 | full_path, rc)); | ||
| 2468 | kfree(full_path); | ||
| 2469 | goto mount_fail_check; | ||
| 2470 | } | ||
| 2471 | kfree(full_path); | ||
| 2472 | } | ||
| 2473 | |||
| 2429 | /* volume_info->password is freed above when existing session found | 2474 | /* volume_info->password is freed above when existing session found |
| 2430 | (in which case it is not needed anymore) but when new sesion is created | 2475 | (in which case it is not needed anymore) but when new sesion is created |
| 2431 | the password ptr is put in the new session structure (in which case the | 2476 | the password ptr is put in the new session structure (in which case the |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 964aad03c5ad..89fb72832652 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * vfs operations that deal with dentries | 4 | * vfs operations that deal with dentries |
| 5 | * | 5 | * |
| 6 | * Copyright (C) International Business Machines Corp., 2002,2008 | 6 | * Copyright (C) International Business Machines Corp., 2002,2009 |
| 7 | * Author(s): Steve French (sfrench@us.ibm.com) | 7 | * Author(s): Steve French (sfrench@us.ibm.com) |
| 8 | * | 8 | * |
| 9 | * This library is free software; you can redistribute it and/or modify | 9 | * This library is free software; you can redistribute it and/or modify |
| @@ -129,6 +129,78 @@ cifs_bp_rename_retry: | |||
| 129 | return full_path; | 129 | return full_path; |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | static int cifs_posix_open(char *full_path, struct inode **pinode, | ||
| 133 | struct super_block *sb, int mode, int oflags, | ||
| 134 | int *poplock, __u16 *pnetfid, int xid) | ||
| 135 | { | ||
| 136 | int rc; | ||
| 137 | __u32 oplock; | ||
| 138 | FILE_UNIX_BASIC_INFO *presp_data; | ||
| 139 | __u32 posix_flags = 0; | ||
| 140 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | ||
| 141 | |||
| 142 | cFYI(1, ("posix open %s", full_path)); | ||
| 143 | |||
| 144 | presp_data = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); | ||
| 145 | if (presp_data == NULL) | ||
| 146 | return -ENOMEM; | ||
| 147 | |||
| 148 | /* So far cifs posix extensions can only map the following flags. | ||
| 149 | There are other valid fmode oflags such as FMODE_LSEEK, FMODE_PREAD, but | ||
| 150 | so far we do not seem to need them, and we can treat them as local only */ | ||
| 151 | if ((oflags & (FMODE_READ | FMODE_WRITE)) == | ||
| 152 | (FMODE_READ | FMODE_WRITE)) | ||
| 153 | posix_flags = SMB_O_RDWR; | ||
| 154 | else if (oflags & FMODE_READ) | ||
| 155 | posix_flags = SMB_O_RDONLY; | ||
| 156 | else if (oflags & FMODE_WRITE) | ||
| 157 | posix_flags = SMB_O_WRONLY; | ||
| 158 | if (oflags & O_CREAT) | ||
| 159 | posix_flags |= SMB_O_CREAT; | ||
| 160 | if (oflags & O_EXCL) | ||
| 161 | posix_flags |= SMB_O_EXCL; | ||
| 162 | if (oflags & O_TRUNC) | ||
| 163 | posix_flags |= SMB_O_TRUNC; | ||
| 164 | if (oflags & O_APPEND) | ||
| 165 | posix_flags |= SMB_O_APPEND; | ||
| 166 | if (oflags & O_SYNC) | ||
| 167 | posix_flags |= SMB_O_SYNC; | ||
| 168 | if (oflags & O_DIRECTORY) | ||
| 169 | posix_flags |= SMB_O_DIRECTORY; | ||
| 170 | if (oflags & O_NOFOLLOW) | ||
| 171 | posix_flags |= SMB_O_NOFOLLOW; | ||
| 172 | if (oflags & O_DIRECT) | ||
| 173 | posix_flags |= SMB_O_DIRECT; | ||
| 174 | |||
| 175 | |||
| 176 | rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, | ||
| 177 | pnetfid, presp_data, &oplock, full_path, | ||
| 178 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | ||
| 179 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 180 | if (rc) | ||
| 181 | goto posix_open_ret; | ||
| 182 | |||
| 183 | if (presp_data->Type == cpu_to_le32(-1)) | ||
| 184 | goto posix_open_ret; /* open ok, caller does qpathinfo */ | ||
| 185 | |||
| 186 | /* get new inode and set it up */ | ||
| 187 | if (!pinode) | ||
| 188 | goto posix_open_ret; /* caller does not need info */ | ||
| 189 | |||
| 190 | *pinode = cifs_new_inode(sb, &presp_data->UniqueId); | ||
| 191 | |||
| 192 | /* We do not need to close the file if new_inode fails since | ||
| 193 | the caller will retry qpathinfo as long as inode is null */ | ||
| 194 | if (*pinode == NULL) | ||
| 195 | goto posix_open_ret; | ||
| 196 | |||
| 197 | posix_fill_in_inode(*pinode, presp_data, 1); | ||
| 198 | |||
| 199 | posix_open_ret: | ||
| 200 | kfree(presp_data); | ||
| 201 | return rc; | ||
| 202 | } | ||
| 203 | |||
| 132 | static void setup_cifs_dentry(struct cifsTconInfo *tcon, | 204 | static void setup_cifs_dentry(struct cifsTconInfo *tcon, |
| 133 | struct dentry *direntry, | 205 | struct dentry *direntry, |
| 134 | struct inode *newinode) | 206 | struct inode *newinode) |
| @@ -150,7 +222,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
| 150 | int xid; | 222 | int xid; |
| 151 | int create_options = CREATE_NOT_DIR; | 223 | int create_options = CREATE_NOT_DIR; |
| 152 | int oplock = 0; | 224 | int oplock = 0; |
| 153 | /* BB below access is too much for the mknod to request */ | 225 | int oflags; |
| 226 | /* | ||
| 227 | * BB below access is probably too much for mknod to request | ||
| 228 | * but we have to do query and setpathinfo so requesting | ||
| 229 | * less could fail (unless we want to request getatr and setatr | ||
| 230 | * permissions (only). At least for POSIX we do not have to | ||
| 231 | * request so much. | ||
| 232 | */ | ||
| 154 | int desiredAccess = GENERIC_READ | GENERIC_WRITE; | 233 | int desiredAccess = GENERIC_READ | GENERIC_WRITE; |
| 155 | __u16 fileHandle; | 234 | __u16 fileHandle; |
| 156 | struct cifs_sb_info *cifs_sb; | 235 | struct cifs_sb_info *cifs_sb; |
| @@ -174,13 +253,43 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
| 174 | } | 253 | } |
| 175 | 254 | ||
| 176 | mode &= ~current->fs->umask; | 255 | mode &= ~current->fs->umask; |
| 256 | if (oplockEnabled) | ||
| 257 | oplock = REQ_OPLOCK; | ||
| 177 | 258 | ||
| 178 | if (nd && (nd->flags & LOOKUP_OPEN)) { | 259 | if (nd && (nd->flags & LOOKUP_OPEN)) |
| 179 | int oflags = nd->intent.open.flags; | 260 | oflags = nd->intent.open.flags; |
| 261 | else | ||
| 262 | oflags = FMODE_READ; | ||
| 263 | |||
| 264 | if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && | ||
| 265 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & | ||
| 266 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { | ||
| 267 | rc = cifs_posix_open(full_path, &newinode, inode->i_sb, | ||
| 268 | mode, oflags, &oplock, &fileHandle, xid); | ||
| 269 | /* EIO could indicate that (posix open) operation is not | ||
| 270 | supported, despite what server claimed in capability | ||
| 271 | negotation. EREMOTE indicates DFS junction, which is not | ||
| 272 | handled in posix open */ | ||
| 273 | |||
| 274 | if ((rc == 0) && (newinode == NULL)) | ||
| 275 | goto cifs_create_get_file_info; /* query inode info */ | ||
| 276 | else if (rc == 0) /* success, no need to query */ | ||
| 277 | goto cifs_create_set_dentry; | ||
| 278 | else if ((rc != -EIO) && (rc != -EREMOTE) && | ||
| 279 | (rc != -EOPNOTSUPP)) /* path not found or net err */ | ||
| 280 | goto cifs_create_out; | ||
| 281 | /* else fallthrough to retry, using older open call, this is | ||
| 282 | case where server does not support this SMB level, and | ||
| 283 | falsely claims capability (also get here for DFS case | ||
| 284 | which should be rare for path not covered on files) */ | ||
| 285 | } | ||
| 180 | 286 | ||
| 287 | if (nd && (nd->flags & LOOKUP_OPEN)) { | ||
| 288 | /* if the file is going to stay open, then we | ||
| 289 | need to set the desired access properly */ | ||
| 181 | desiredAccess = 0; | 290 | desiredAccess = 0; |
| 182 | if (oflags & FMODE_READ) | 291 | if (oflags & FMODE_READ) |
| 183 | desiredAccess |= GENERIC_READ; | 292 | desiredAccess |= GENERIC_READ; /* is this too little? */ |
| 184 | if (oflags & FMODE_WRITE) { | 293 | if (oflags & FMODE_WRITE) { |
| 185 | desiredAccess |= GENERIC_WRITE; | 294 | desiredAccess |= GENERIC_WRITE; |
| 186 | if (!(oflags & FMODE_READ)) | 295 | if (!(oflags & FMODE_READ)) |
| @@ -199,8 +308,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
| 199 | 308 | ||
| 200 | /* BB add processing to set equivalent of mode - e.g. via CreateX with | 309 | /* BB add processing to set equivalent of mode - e.g. via CreateX with |
| 201 | ACLs */ | 310 | ACLs */ |
| 202 | if (oplockEnabled) | ||
| 203 | oplock = REQ_OPLOCK; | ||
| 204 | 311 | ||
| 205 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | 312 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
| 206 | if (buf == NULL) { | 313 | if (buf == NULL) { |
| @@ -233,116 +340,112 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
| 233 | } | 340 | } |
| 234 | if (rc) { | 341 | if (rc) { |
| 235 | cFYI(1, ("cifs_create returned 0x%x", rc)); | 342 | cFYI(1, ("cifs_create returned 0x%x", rc)); |
| 236 | } else { | 343 | goto cifs_create_out; |
| 237 | /* If Open reported that we actually created a file | 344 | } |
| 238 | then we now have to set the mode if possible */ | 345 | |
| 239 | if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { | 346 | /* If Open reported that we actually created a file |
| 240 | struct cifs_unix_set_info_args args = { | 347 | then we now have to set the mode if possible */ |
| 348 | if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { | ||
| 349 | struct cifs_unix_set_info_args args = { | ||
| 241 | .mode = mode, | 350 | .mode = mode, |
| 242 | .ctime = NO_CHANGE_64, | 351 | .ctime = NO_CHANGE_64, |
| 243 | .atime = NO_CHANGE_64, | 352 | .atime = NO_CHANGE_64, |
| 244 | .mtime = NO_CHANGE_64, | 353 | .mtime = NO_CHANGE_64, |
| 245 | .device = 0, | 354 | .device = 0, |
| 246 | }; | 355 | }; |
| 247 | 356 | ||
| 248 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 357 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
| 249 | args.uid = (__u64) current_fsuid(); | 358 | args.uid = (__u64) current_fsuid(); |
| 250 | if (inode->i_mode & S_ISGID) | 359 | if (inode->i_mode & S_ISGID) |
| 251 | args.gid = (__u64) inode->i_gid; | 360 | args.gid = (__u64) inode->i_gid; |
| 252 | else | 361 | else |
| 253 | args.gid = (__u64) current_fsgid(); | 362 | args.gid = (__u64) current_fsgid(); |
| 254 | } else { | ||
| 255 | args.uid = NO_CHANGE_64; | ||
| 256 | args.gid = NO_CHANGE_64; | ||
| 257 | } | ||
| 258 | CIFSSMBUnixSetInfo(xid, tcon, full_path, &args, | ||
| 259 | cifs_sb->local_nls, | ||
| 260 | cifs_sb->mnt_cifs_flags & | ||
| 261 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 262 | } else { | 363 | } else { |
| 263 | /* BB implement mode setting via Windows security | 364 | args.uid = NO_CHANGE_64; |
| 264 | descriptors e.g. */ | 365 | args.gid = NO_CHANGE_64; |
| 265 | /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/ | ||
| 266 | |||
| 267 | /* Could set r/o dos attribute if mode & 0222 == 0 */ | ||
| 268 | } | 366 | } |
| 367 | CIFSSMBUnixSetInfo(xid, tcon, full_path, &args, | ||
| 368 | cifs_sb->local_nls, | ||
| 369 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 370 | } else { | ||
| 371 | /* BB implement mode setting via Windows security | ||
| 372 | descriptors e.g. */ | ||
| 373 | /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/ | ||
| 269 | 374 | ||
| 270 | /* server might mask mode so we have to query for it */ | 375 | /* Could set r/o dos attribute if mode & 0222 == 0 */ |
| 271 | if (tcon->unix_ext) | 376 | } |
| 272 | rc = cifs_get_inode_info_unix(&newinode, full_path, | 377 | |
| 273 | inode->i_sb, xid); | 378 | cifs_create_get_file_info: |
| 274 | else { | 379 | /* server might mask mode so we have to query for it */ |
| 275 | rc = cifs_get_inode_info(&newinode, full_path, | 380 | if (tcon->unix_ext) |
| 276 | buf, inode->i_sb, xid, | 381 | rc = cifs_get_inode_info_unix(&newinode, full_path, |
| 277 | &fileHandle); | 382 | inode->i_sb, xid); |
| 278 | if (newinode) { | 383 | else { |
| 279 | if (cifs_sb->mnt_cifs_flags & | 384 | rc = cifs_get_inode_info(&newinode, full_path, buf, |
| 280 | CIFS_MOUNT_DYNPERM) | 385 | inode->i_sb, xid, &fileHandle); |
| 281 | newinode->i_mode = mode; | 386 | if (newinode) { |
| 282 | if ((oplock & CIFS_CREATE_ACTION) && | 387 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) |
| 283 | (cifs_sb->mnt_cifs_flags & | 388 | newinode->i_mode = mode; |
| 284 | CIFS_MOUNT_SET_UID)) { | 389 | if ((oplock & CIFS_CREATE_ACTION) && |
| 285 | newinode->i_uid = current_fsuid(); | 390 | (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) { |
| 286 | if (inode->i_mode & S_ISGID) | 391 | newinode->i_uid = current_fsuid(); |
| 287 | newinode->i_gid = | 392 | if (inode->i_mode & S_ISGID) |
| 288 | inode->i_gid; | 393 | newinode->i_gid = inode->i_gid; |
| 289 | else | 394 | else |
| 290 | newinode->i_gid = | 395 | newinode->i_gid = current_fsgid(); |
| 291 | current_fsgid(); | ||
| 292 | } | ||
| 293 | } | 396 | } |
| 294 | } | 397 | } |
| 398 | } | ||
| 295 | 399 | ||
| 296 | if (rc != 0) { | 400 | cifs_create_set_dentry: |
| 297 | cFYI(1, ("Create worked, get_inode_info failed rc = %d", | 401 | if (rc == 0) |
| 298 | rc)); | 402 | setup_cifs_dentry(tcon, direntry, newinode); |
| 299 | } else | 403 | else |
| 300 | setup_cifs_dentry(tcon, direntry, newinode); | 404 | cFYI(1, ("Create worked, get_inode_info failed rc = %d", rc)); |
| 301 | 405 | ||
| 302 | if ((nd == NULL /* nfsd case - nfs srv does not set nd */) || | 406 | /* nfsd case - nfs srv does not set nd */ |
| 303 | (!(nd->flags & LOOKUP_OPEN))) { | 407 | if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) { |
| 304 | /* mknod case - do not leave file open */ | 408 | /* mknod case - do not leave file open */ |
| 305 | CIFSSMBClose(xid, tcon, fileHandle); | 409 | CIFSSMBClose(xid, tcon, fileHandle); |
| 306 | } else if (newinode) { | 410 | } else if (newinode) { |
| 307 | struct cifsFileInfo *pCifsFile = | 411 | struct cifsFileInfo *pCifsFile = |
| 308 | kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); | 412 | kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); |
| 309 | 413 | ||
| 310 | if (pCifsFile == NULL) | 414 | if (pCifsFile == NULL) |
| 311 | goto cifs_create_out; | 415 | goto cifs_create_out; |
| 312 | pCifsFile->netfid = fileHandle; | 416 | pCifsFile->netfid = fileHandle; |
| 313 | pCifsFile->pid = current->tgid; | 417 | pCifsFile->pid = current->tgid; |
| 314 | pCifsFile->pInode = newinode; | 418 | pCifsFile->pInode = newinode; |
| 315 | pCifsFile->invalidHandle = false; | 419 | pCifsFile->invalidHandle = false; |
| 316 | pCifsFile->closePend = false; | 420 | pCifsFile->closePend = false; |
| 317 | init_MUTEX(&pCifsFile->fh_sem); | 421 | init_MUTEX(&pCifsFile->fh_sem); |
| 318 | mutex_init(&pCifsFile->lock_mutex); | 422 | mutex_init(&pCifsFile->lock_mutex); |
| 319 | INIT_LIST_HEAD(&pCifsFile->llist); | 423 | INIT_LIST_HEAD(&pCifsFile->llist); |
| 320 | atomic_set(&pCifsFile->wrtPending, 0); | 424 | atomic_set(&pCifsFile->wrtPending, 0); |
| 321 | 425 | ||
| 322 | /* set the following in open now | 426 | /* set the following in open now |
| 323 | pCifsFile->pfile = file; */ | 427 | pCifsFile->pfile = file; */ |
| 324 | write_lock(&GlobalSMBSeslock); | 428 | write_lock(&GlobalSMBSeslock); |
| 325 | list_add(&pCifsFile->tlist, &tcon->openFileList); | 429 | list_add(&pCifsFile->tlist, &tcon->openFileList); |
| 326 | pCifsInode = CIFS_I(newinode); | 430 | pCifsInode = CIFS_I(newinode); |
| 327 | if (pCifsInode) { | 431 | if (pCifsInode) { |
| 328 | /* if readable file instance put first in list*/ | 432 | /* if readable file instance put first in list*/ |
| 329 | if (write_only) { | 433 | if (write_only) { |
| 330 | list_add_tail(&pCifsFile->flist, | 434 | list_add_tail(&pCifsFile->flist, |
| 331 | &pCifsInode->openFileList); | 435 | &pCifsInode->openFileList); |
| 332 | } else { | 436 | } else { |
| 333 | list_add(&pCifsFile->flist, | 437 | list_add(&pCifsFile->flist, |
| 334 | &pCifsInode->openFileList); | 438 | &pCifsInode->openFileList); |
| 335 | } | ||
| 336 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { | ||
| 337 | pCifsInode->clientCanCacheAll = true; | ||
| 338 | pCifsInode->clientCanCacheRead = true; | ||
| 339 | cFYI(1, ("Exclusive Oplock inode %p", | ||
| 340 | newinode)); | ||
| 341 | } else if ((oplock & 0xF) == OPLOCK_READ) | ||
| 342 | pCifsInode->clientCanCacheRead = true; | ||
| 343 | } | 439 | } |
| 344 | write_unlock(&GlobalSMBSeslock); | 440 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { |
| 441 | pCifsInode->clientCanCacheAll = true; | ||
| 442 | pCifsInode->clientCanCacheRead = true; | ||
| 443 | cFYI(1, ("Exclusive Oplock inode %p", | ||
| 444 | newinode)); | ||
| 445 | } else if ((oplock & 0xF) == OPLOCK_READ) | ||
| 446 | pCifsInode->clientCanCacheRead = true; | ||
| 345 | } | 447 | } |
| 448 | write_unlock(&GlobalSMBSeslock); | ||
| 346 | } | 449 | } |
| 347 | cifs_create_out: | 450 | cifs_create_out: |
| 348 | kfree(buf); | 451 | kfree(buf); |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index bcf7b5184664..4690a360c855 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -199,6 +199,49 @@ static void fill_fake_finddataunix(FILE_UNIX_BASIC_INFO *pfnd_dat, | |||
| 199 | pfnd_dat->Gid = cpu_to_le64(pinode->i_gid); | 199 | pfnd_dat->Gid = cpu_to_le64(pinode->i_gid); |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | /** | ||
| 203 | * cifs_new inode - create new inode, initialize, and hash it | ||
| 204 | * @sb - pointer to superblock | ||
| 205 | * @inum - if valid pointer and serverino is enabled, replace i_ino with val | ||
| 206 | * | ||
| 207 | * Create a new inode, initialize it for CIFS and hash it. Returns the new | ||
| 208 | * inode or NULL if one couldn't be allocated. | ||
| 209 | * | ||
| 210 | * If the share isn't mounted with "serverino" or inum is a NULL pointer then | ||
| 211 | * we'll just use the inode number assigned by new_inode(). Note that this can | ||
| 212 | * mean i_ino collisions since the i_ino assigned by new_inode is not | ||
| 213 | * guaranteed to be unique. | ||
| 214 | */ | ||
| 215 | struct inode * | ||
| 216 | cifs_new_inode(struct super_block *sb, __u64 *inum) | ||
| 217 | { | ||
| 218 | struct inode *inode; | ||
| 219 | |||
| 220 | inode = new_inode(sb); | ||
| 221 | if (inode == NULL) | ||
| 222 | return NULL; | ||
| 223 | |||
| 224 | /* | ||
| 225 | * BB: Is i_ino == 0 legal? Here, we assume that it is. If it isn't we | ||
| 226 | * stop passing inum as ptr. Are there sanity checks we can use to | ||
| 227 | * ensure that the server is really filling in that field? Also, | ||
| 228 | * if serverino is disabled, perhaps we should be using iunique()? | ||
| 229 | */ | ||
| 230 | if (inum && (CIFS_SB(sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) | ||
| 231 | inode->i_ino = (unsigned long) *inum; | ||
| 232 | |||
| 233 | /* | ||
| 234 | * must set this here instead of cifs_alloc_inode since VFS will | ||
| 235 | * clobber i_flags | ||
| 236 | */ | ||
| 237 | if (sb->s_flags & MS_NOATIME) | ||
| 238 | inode->i_flags |= S_NOATIME | S_NOCMTIME; | ||
| 239 | |||
| 240 | insert_inode_hash(inode); | ||
| 241 | |||
| 242 | return inode; | ||
| 243 | } | ||
| 244 | |||
| 202 | int cifs_get_inode_info_unix(struct inode **pinode, | 245 | int cifs_get_inode_info_unix(struct inode **pinode, |
| 203 | const unsigned char *full_path, struct super_block *sb, int xid) | 246 | const unsigned char *full_path, struct super_block *sb, int xid) |
| 204 | { | 247 | { |
| @@ -233,22 +276,11 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
| 233 | 276 | ||
| 234 | /* get new inode */ | 277 | /* get new inode */ |
| 235 | if (*pinode == NULL) { | 278 | if (*pinode == NULL) { |
| 236 | *pinode = new_inode(sb); | 279 | *pinode = cifs_new_inode(sb, &find_data.UniqueId); |
| 237 | if (*pinode == NULL) { | 280 | if (*pinode == NULL) { |
| 238 | rc = -ENOMEM; | 281 | rc = -ENOMEM; |
| 239 | goto cgiiu_exit; | 282 | goto cgiiu_exit; |
| 240 | } | 283 | } |
| 241 | /* Is an i_ino of zero legal? */ | ||
| 242 | /* note ino incremented to unique num in new_inode */ | ||
| 243 | /* Are there sanity checks we can use to ensure that | ||
| 244 | the server is really filling in that field? */ | ||
| 245 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) | ||
| 246 | (*pinode)->i_ino = (unsigned long)find_data.UniqueId; | ||
| 247 | |||
| 248 | if (sb->s_flags & MS_NOATIME) | ||
| 249 | (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; | ||
| 250 | |||
| 251 | insert_inode_hash(*pinode); | ||
| 252 | } | 284 | } |
| 253 | 285 | ||
| 254 | inode = *pinode; | 286 | inode = *pinode; |
| @@ -465,11 +497,9 @@ int cifs_get_inode_info(struct inode **pinode, | |||
| 465 | 497 | ||
| 466 | /* get new inode */ | 498 | /* get new inode */ |
| 467 | if (*pinode == NULL) { | 499 | if (*pinode == NULL) { |
| 468 | *pinode = new_inode(sb); | 500 | __u64 inode_num; |
| 469 | if (*pinode == NULL) { | 501 | __u64 *pinum = &inode_num; |
| 470 | rc = -ENOMEM; | 502 | |
| 471 | goto cgii_exit; | ||
| 472 | } | ||
| 473 | /* Is an i_ino of zero legal? Can we use that to check | 503 | /* Is an i_ino of zero legal? Can we use that to check |
| 474 | if the server supports returning inode numbers? Are | 504 | if the server supports returning inode numbers? Are |
| 475 | there other sanity checks we can use to ensure that | 505 | there other sanity checks we can use to ensure that |
| @@ -486,22 +516,26 @@ int cifs_get_inode_info(struct inode **pinode, | |||
| 486 | 516 | ||
| 487 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { | 517 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { |
| 488 | int rc1 = 0; | 518 | int rc1 = 0; |
| 489 | __u64 inode_num; | ||
| 490 | 519 | ||
| 491 | rc1 = CIFSGetSrvInodeNumber(xid, pTcon, | 520 | rc1 = CIFSGetSrvInodeNumber(xid, pTcon, |
| 492 | full_path, &inode_num, | 521 | full_path, pinum, |
| 493 | cifs_sb->local_nls, | 522 | cifs_sb->local_nls, |
| 494 | cifs_sb->mnt_cifs_flags & | 523 | cifs_sb->mnt_cifs_flags & |
| 495 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 524 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
| 496 | if (rc1) { | 525 | if (rc1) { |
| 497 | cFYI(1, ("GetSrvInodeNum rc %d", rc1)); | 526 | cFYI(1, ("GetSrvInodeNum rc %d", rc1)); |
| 527 | pinum = NULL; | ||
| 498 | /* BB EOPNOSUPP disable SERVER_INUM? */ | 528 | /* BB EOPNOSUPP disable SERVER_INUM? */ |
| 499 | } else /* do we need cast or hash to ino? */ | 529 | } |
| 500 | (*pinode)->i_ino = inode_num; | 530 | } else { |
| 501 | } /* else ino incremented to unique num in new_inode*/ | 531 | pinum = NULL; |
| 502 | if (sb->s_flags & MS_NOATIME) | 532 | } |
| 503 | (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; | 533 | |
| 504 | insert_inode_hash(*pinode); | 534 | *pinode = cifs_new_inode(sb, pinum); |
| 535 | if (*pinode == NULL) { | ||
| 536 | rc = -ENOMEM; | ||
| 537 | goto cgii_exit; | ||
| 538 | } | ||
| 505 | } | 539 | } |
| 506 | inode = *pinode; | 540 | inode = *pinode; |
| 507 | cifsInfo = CIFS_I(inode); | 541 | cifsInfo = CIFS_I(inode); |
| @@ -621,7 +655,7 @@ static const struct inode_operations cifs_ipc_inode_ops = { | |||
| 621 | .lookup = cifs_lookup, | 655 | .lookup = cifs_lookup, |
| 622 | }; | 656 | }; |
| 623 | 657 | ||
| 624 | static char *build_path_to_root(struct cifs_sb_info *cifs_sb) | 658 | char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) |
| 625 | { | 659 | { |
| 626 | int pplen = cifs_sb->prepathlen; | 660 | int pplen = cifs_sb->prepathlen; |
| 627 | int dfsplen; | 661 | int dfsplen; |
| @@ -678,7 +712,7 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | |||
| 678 | return inode; | 712 | return inode; |
| 679 | 713 | ||
| 680 | cifs_sb = CIFS_SB(inode->i_sb); | 714 | cifs_sb = CIFS_SB(inode->i_sb); |
| 681 | full_path = build_path_to_root(cifs_sb); | 715 | full_path = cifs_build_path_to_root(cifs_sb); |
| 682 | if (full_path == NULL) | 716 | if (full_path == NULL) |
| 683 | return ERR_PTR(-ENOMEM); | 717 | return ERR_PTR(-ENOMEM); |
| 684 | 718 | ||
| @@ -1017,7 +1051,7 @@ out_reval: | |||
| 1017 | return rc; | 1051 | return rc; |
| 1018 | } | 1052 | } |
| 1019 | 1053 | ||
| 1020 | static void posix_fill_in_inode(struct inode *tmp_inode, | 1054 | void posix_fill_in_inode(struct inode *tmp_inode, |
| 1021 | FILE_UNIX_BASIC_INFO *pData, int isNewInode) | 1055 | FILE_UNIX_BASIC_INFO *pData, int isNewInode) |
| 1022 | { | 1056 | { |
| 1023 | struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); | 1057 | struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); |
| @@ -1114,24 +1148,14 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
| 1114 | else | 1148 | else |
| 1115 | direntry->d_op = &cifs_dentry_ops; | 1149 | direntry->d_op = &cifs_dentry_ops; |
| 1116 | 1150 | ||
| 1117 | newinode = new_inode(inode->i_sb); | 1151 | newinode = cifs_new_inode(inode->i_sb, |
| 1152 | &pInfo->UniqueId); | ||
| 1118 | if (newinode == NULL) { | 1153 | if (newinode == NULL) { |
| 1119 | kfree(pInfo); | 1154 | kfree(pInfo); |
| 1120 | goto mkdir_get_info; | 1155 | goto mkdir_get_info; |
| 1121 | } | 1156 | } |
| 1122 | 1157 | ||
| 1123 | /* Is an i_ino of zero legal? */ | ||
| 1124 | /* Are there sanity checks we can use to ensure that | ||
| 1125 | the server is really filling in that field? */ | ||
| 1126 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { | ||
| 1127 | newinode->i_ino = | ||
| 1128 | (unsigned long)pInfo->UniqueId; | ||
| 1129 | } /* note ino incremented to unique num in new_inode */ | ||
| 1130 | if (inode->i_sb->s_flags & MS_NOATIME) | ||
| 1131 | newinode->i_flags |= S_NOATIME | S_NOCMTIME; | ||
| 1132 | newinode->i_nlink = 2; | 1158 | newinode->i_nlink = 2; |
| 1133 | |||
| 1134 | insert_inode_hash(newinode); | ||
| 1135 | d_instantiate(direntry, newinode); | 1159 | d_instantiate(direntry, newinode); |
| 1136 | 1160 | ||
| 1137 | /* we already checked in POSIXCreate whether | 1161 | /* we already checked in POSIXCreate whether |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 9f51f9bf0292..c2c01ff4c32c 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
| @@ -56,35 +56,34 @@ static inline void dump_cifs_file_struct(struct file *file, char *label) | |||
| 56 | } | 56 | } |
| 57 | #endif /* DEBUG2 */ | 57 | #endif /* DEBUG2 */ |
| 58 | 58 | ||
| 59 | /* Returns one if new inode created (which therefore needs to be hashed) */ | 59 | /* Returns 1 if new inode created, 2 if both dentry and inode were */ |
| 60 | /* Might check in the future if inode number changed so we can rehash inode */ | 60 | /* Might check in the future if inode number changed so we can rehash inode */ |
| 61 | static int construct_dentry(struct qstr *qstring, struct file *file, | 61 | static int |
| 62 | struct inode **ptmp_inode, struct dentry **pnew_dentry) | 62 | construct_dentry(struct qstr *qstring, struct file *file, |
| 63 | struct inode **ptmp_inode, struct dentry **pnew_dentry, | ||
| 64 | __u64 *inum) | ||
| 63 | { | 65 | { |
| 64 | struct dentry *tmp_dentry; | 66 | struct dentry *tmp_dentry = NULL; |
| 65 | struct cifs_sb_info *cifs_sb; | 67 | struct super_block *sb = file->f_path.dentry->d_sb; |
| 66 | struct cifsTconInfo *pTcon; | ||
| 67 | int rc = 0; | 68 | int rc = 0; |
| 68 | 69 | ||
| 69 | cFYI(1, ("For %s", qstring->name)); | 70 | cFYI(1, ("For %s", qstring->name)); |
| 70 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | ||
| 71 | pTcon = cifs_sb->tcon; | ||
| 72 | 71 | ||
| 73 | qstring->hash = full_name_hash(qstring->name, qstring->len); | 72 | qstring->hash = full_name_hash(qstring->name, qstring->len); |
| 74 | tmp_dentry = d_lookup(file->f_path.dentry, qstring); | 73 | tmp_dentry = d_lookup(file->f_path.dentry, qstring); |
| 75 | if (tmp_dentry) { | 74 | if (tmp_dentry) { |
| 75 | /* BB: overwrite old name? i.e. tmp_dentry->d_name and | ||
| 76 | * tmp_dentry->d_name.len?? | ||
| 77 | */ | ||
| 76 | cFYI(0, ("existing dentry with inode 0x%p", | 78 | cFYI(0, ("existing dentry with inode 0x%p", |
| 77 | tmp_dentry->d_inode)); | 79 | tmp_dentry->d_inode)); |
| 78 | *ptmp_inode = tmp_dentry->d_inode; | 80 | *ptmp_inode = tmp_dentry->d_inode; |
| 79 | /* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ | ||
| 80 | if (*ptmp_inode == NULL) { | 81 | if (*ptmp_inode == NULL) { |
| 81 | *ptmp_inode = new_inode(file->f_path.dentry->d_sb); | 82 | *ptmp_inode = cifs_new_inode(sb, inum); |
| 82 | if (*ptmp_inode == NULL) | 83 | if (*ptmp_inode == NULL) |
| 83 | return rc; | 84 | return rc; |
| 84 | rc = 1; | 85 | rc = 1; |
| 85 | } | 86 | } |
| 86 | if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) | ||
| 87 | (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; | ||
| 88 | } else { | 87 | } else { |
| 89 | tmp_dentry = d_alloc(file->f_path.dentry, qstring); | 88 | tmp_dentry = d_alloc(file->f_path.dentry, qstring); |
| 90 | if (tmp_dentry == NULL) { | 89 | if (tmp_dentry == NULL) { |
| @@ -93,15 +92,14 @@ static int construct_dentry(struct qstr *qstring, struct file *file, | |||
| 93 | return rc; | 92 | return rc; |
| 94 | } | 93 | } |
| 95 | 94 | ||
| 96 | *ptmp_inode = new_inode(file->f_path.dentry->d_sb); | 95 | if (CIFS_SB(sb)->tcon->nocase) |
| 97 | if (pTcon->nocase) | ||
| 98 | tmp_dentry->d_op = &cifs_ci_dentry_ops; | 96 | tmp_dentry->d_op = &cifs_ci_dentry_ops; |
| 99 | else | 97 | else |
| 100 | tmp_dentry->d_op = &cifs_dentry_ops; | 98 | tmp_dentry->d_op = &cifs_dentry_ops; |
| 99 | |||
| 100 | *ptmp_inode = cifs_new_inode(sb, inum); | ||
| 101 | if (*ptmp_inode == NULL) | 101 | if (*ptmp_inode == NULL) |
| 102 | return rc; | 102 | return rc; |
| 103 | if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) | ||
| 104 | (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; | ||
| 105 | rc = 2; | 103 | rc = 2; |
| 106 | } | 104 | } |
| 107 | 105 | ||
| @@ -822,7 +820,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, | |||
| 822 | /* inode num, inode type and filename returned */ | 820 | /* inode num, inode type and filename returned */ |
| 823 | static int cifs_get_name_from_search_buf(struct qstr *pqst, | 821 | static int cifs_get_name_from_search_buf(struct qstr *pqst, |
| 824 | char *current_entry, __u16 level, unsigned int unicode, | 822 | char *current_entry, __u16 level, unsigned int unicode, |
| 825 | struct cifs_sb_info *cifs_sb, int max_len, ino_t *pinum) | 823 | struct cifs_sb_info *cifs_sb, int max_len, __u64 *pinum) |
| 826 | { | 824 | { |
| 827 | int rc = 0; | 825 | int rc = 0; |
| 828 | unsigned int len = 0; | 826 | unsigned int len = 0; |
| @@ -842,9 +840,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst, | |||
| 842 | len = strnlen(filename, PATH_MAX); | 840 | len = strnlen(filename, PATH_MAX); |
| 843 | } | 841 | } |
| 844 | 842 | ||
| 845 | /* BB fixme - hash low and high 32 bits if not 64 bit arch BB */ | 843 | *pinum = pFindData->UniqueId; |
| 846 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) | ||
| 847 | *pinum = pFindData->UniqueId; | ||
| 848 | } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) { | 844 | } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) { |
| 849 | FILE_DIRECTORY_INFO *pFindData = | 845 | FILE_DIRECTORY_INFO *pFindData = |
| 850 | (FILE_DIRECTORY_INFO *)current_entry; | 846 | (FILE_DIRECTORY_INFO *)current_entry; |
| @@ -907,7 +903,7 @@ static int cifs_filldir(char *pfindEntry, struct file *file, | |||
| 907 | struct qstr qstring; | 903 | struct qstr qstring; |
| 908 | struct cifsFileInfo *pCifsF; | 904 | struct cifsFileInfo *pCifsF; |
| 909 | unsigned int obj_type; | 905 | unsigned int obj_type; |
| 910 | ino_t inum; | 906 | __u64 inum; |
| 911 | struct cifs_sb_info *cifs_sb; | 907 | struct cifs_sb_info *cifs_sb; |
| 912 | struct inode *tmp_inode; | 908 | struct inode *tmp_inode; |
| 913 | struct dentry *tmp_dentry; | 909 | struct dentry *tmp_dentry; |
| @@ -940,20 +936,18 @@ static int cifs_filldir(char *pfindEntry, struct file *file, | |||
| 940 | if (rc) | 936 | if (rc) |
| 941 | return rc; | 937 | return rc; |
| 942 | 938 | ||
| 943 | rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry); | 939 | /* only these two infolevels return valid inode numbers */ |
| 940 | if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX || | ||
| 941 | pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO) | ||
| 942 | rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, | ||
| 943 | &inum); | ||
| 944 | else | ||
| 945 | rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, | ||
| 946 | NULL); | ||
| 947 | |||
| 944 | if ((tmp_inode == NULL) || (tmp_dentry == NULL)) | 948 | if ((tmp_inode == NULL) || (tmp_dentry == NULL)) |
| 945 | return -ENOMEM; | 949 | return -ENOMEM; |
| 946 | 950 | ||
| 947 | if (rc) { | ||
| 948 | /* inode created, we need to hash it with right inode number */ | ||
| 949 | if (inum != 0) { | ||
| 950 | /* BB fixme - hash the 2 32 quantities bits together if | ||
| 951 | * necessary BB */ | ||
| 952 | tmp_inode->i_ino = inum; | ||
| 953 | } | ||
| 954 | insert_inode_hash(tmp_inode); | ||
| 955 | } | ||
| 956 | |||
| 957 | /* we pass in rc below, indicating whether it is a new inode, | 951 | /* we pass in rc below, indicating whether it is a new inode, |
| 958 | so we can figure out whether to invalidate the inode cached | 952 | so we can figure out whether to invalidate the inode cached |
| 959 | data if the file has changed */ | 953 | data if the file has changed */ |
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 5f22de7b79a9..5c68b4282be9 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
| @@ -34,15 +34,99 @@ | |||
| 34 | extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, | 34 | extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, |
| 35 | unsigned char *p24); | 35 | unsigned char *p24); |
| 36 | 36 | ||
| 37 | /* Checks if this is the first smb session to be reconnected after | ||
| 38 | the socket has been reestablished (so we know whether to use vc 0). | ||
| 39 | Called while holding the cifs_tcp_ses_lock, so do not block */ | ||
| 40 | static bool is_first_ses_reconnect(struct cifsSesInfo *ses) | ||
| 41 | { | ||
| 42 | struct list_head *tmp; | ||
| 43 | struct cifsSesInfo *tmp_ses; | ||
| 44 | |||
| 45 | list_for_each(tmp, &ses->server->smb_ses_list) { | ||
| 46 | tmp_ses = list_entry(tmp, struct cifsSesInfo, | ||
| 47 | smb_ses_list); | ||
| 48 | if (tmp_ses->need_reconnect == false) | ||
| 49 | return false; | ||
| 50 | } | ||
| 51 | /* could not find a session that was already connected, | ||
| 52 | this must be the first one we are reconnecting */ | ||
| 53 | return true; | ||
| 54 | } | ||
| 55 | |||
| 56 | /* | ||
| 57 | * vc number 0 is treated specially by some servers, and should be the | ||
| 58 | * first one we request. After that we can use vcnumbers up to maxvcs, | ||
| 59 | * one for each smb session (some Windows versions set maxvcs incorrectly | ||
| 60 | * so maxvc=1 can be ignored). If we have too many vcs, we can reuse | ||
| 61 | * any vc but zero (some servers reset the connection on vcnum zero) | ||
| 62 | * | ||
| 63 | */ | ||
| 64 | static __le16 get_next_vcnum(struct cifsSesInfo *ses) | ||
| 65 | { | ||
| 66 | __u16 vcnum = 0; | ||
| 67 | struct list_head *tmp; | ||
| 68 | struct cifsSesInfo *tmp_ses; | ||
| 69 | __u16 max_vcs = ses->server->max_vcs; | ||
| 70 | __u16 i; | ||
| 71 | int free_vc_found = 0; | ||
| 72 | |||
| 73 | /* Quoting the MS-SMB specification: "Windows-based SMB servers set this | ||
| 74 | field to one but do not enforce this limit, which allows an SMB client | ||
| 75 | to establish more virtual circuits than allowed by this value ... but | ||
| 76 | other server implementations can enforce this limit." */ | ||
| 77 | if (max_vcs < 2) | ||
| 78 | max_vcs = 0xFFFF; | ||
| 79 | |||
| 80 | write_lock(&cifs_tcp_ses_lock); | ||
| 81 | if ((ses->need_reconnect) && is_first_ses_reconnect(ses)) | ||
| 82 | goto get_vc_num_exit; /* vcnum will be zero */ | ||
| 83 | for (i = ses->server->srv_count - 1; i < max_vcs; i++) { | ||
| 84 | if (i == 0) /* this is the only connection, use vc 0 */ | ||
| 85 | break; | ||
| 86 | |||
| 87 | free_vc_found = 1; | ||
| 88 | |||
| 89 | list_for_each(tmp, &ses->server->smb_ses_list) { | ||
| 90 | tmp_ses = list_entry(tmp, struct cifsSesInfo, | ||
| 91 | smb_ses_list); | ||
| 92 | if (tmp_ses->vcnum == i) { | ||
| 93 | free_vc_found = 0; | ||
| 94 | break; /* found duplicate, try next vcnum */ | ||
| 95 | } | ||
| 96 | } | ||
| 97 | if (free_vc_found) | ||
| 98 | break; /* we found a vcnumber that will work - use it */ | ||
| 99 | } | ||
| 100 | |||
| 101 | if (i == 0) | ||
| 102 | vcnum = 0; /* for most common case, ie if one smb session, use | ||
| 103 | vc zero. Also for case when no free vcnum, zero | ||
| 104 | is safest to send (some clients only send zero) */ | ||
| 105 | else if (free_vc_found == 0) | ||
| 106 | vcnum = 1; /* we can not reuse vc=0 safely, since some servers | ||
| 107 | reset all uids on that, but 1 is ok. */ | ||
| 108 | else | ||
| 109 | vcnum = i; | ||
| 110 | ses->vcnum = vcnum; | ||
| 111 | get_vc_num_exit: | ||
| 112 | write_unlock(&cifs_tcp_ses_lock); | ||
| 113 | |||
| 114 | return le16_to_cpu(vcnum); | ||
| 115 | } | ||
| 116 | |||
| 37 | static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) | 117 | static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) |
| 38 | { | 118 | { |
| 39 | __u32 capabilities = 0; | 119 | __u32 capabilities = 0; |
| 40 | 120 | ||
| 41 | /* init fields common to all four types of SessSetup */ | 121 | /* init fields common to all four types of SessSetup */ |
| 42 | /* note that header is initialized to zero in header_assemble */ | 122 | /* Note that offsets for first seven fields in req struct are same */ |
| 123 | /* in CIFS Specs so does not matter which of 3 forms of struct */ | ||
| 124 | /* that we use in next few lines */ | ||
| 125 | /* Note that header is initialized to zero in header_assemble */ | ||
| 43 | pSMB->req.AndXCommand = 0xFF; | 126 | pSMB->req.AndXCommand = 0xFF; |
| 44 | pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); | 127 | pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); |
| 45 | pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); | 128 | pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); |
| 129 | pSMB->req.VcNumber = get_next_vcnum(ses); | ||
| 46 | 130 | ||
| 47 | /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */ | 131 | /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */ |
| 48 | 132 | ||
| @@ -71,7 +155,6 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) | |||
| 71 | if (ses->capabilities & CAP_UNIX) | 155 | if (ses->capabilities & CAP_UNIX) |
| 72 | capabilities |= CAP_UNIX; | 156 | capabilities |= CAP_UNIX; |
| 73 | 157 | ||
| 74 | /* BB check whether to init vcnum BB */ | ||
| 75 | return capabilities; | 158 | return capabilities; |
| 76 | } | 159 | } |
| 77 | 160 | ||
| @@ -228,7 +311,7 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, | |||
| 228 | 311 | ||
| 229 | kfree(ses->serverOS); | 312 | kfree(ses->serverOS); |
| 230 | /* UTF-8 string will not grow more than four times as big as UCS-16 */ | 313 | /* UTF-8 string will not grow more than four times as big as UCS-16 */ |
| 231 | ses->serverOS = kzalloc(4 * len, GFP_KERNEL); | 314 | ses->serverOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL); |
| 232 | if (ses->serverOS != NULL) | 315 | if (ses->serverOS != NULL) |
| 233 | cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp); | 316 | cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp); |
| 234 | data += 2 * (len + 1); | 317 | data += 2 * (len + 1); |
| @@ -241,7 +324,7 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, | |||
| 241 | return rc; | 324 | return rc; |
| 242 | 325 | ||
| 243 | kfree(ses->serverNOS); | 326 | kfree(ses->serverNOS); |
| 244 | ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */ | 327 | ses->serverNOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL); |
| 245 | if (ses->serverNOS != NULL) { | 328 | if (ses->serverNOS != NULL) { |
| 246 | cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, | 329 | cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, |
| 247 | nls_cp); | 330 | nls_cp); |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 9c6d815dd191..45e59d3c7f1f 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
| @@ -1913,6 +1913,9 @@ COMPATIBLE_IOCTL(FIONREAD) /* This is also TIOCINQ */ | |||
| 1913 | /* 0x00 */ | 1913 | /* 0x00 */ |
| 1914 | COMPATIBLE_IOCTL(FIBMAP) | 1914 | COMPATIBLE_IOCTL(FIBMAP) |
| 1915 | COMPATIBLE_IOCTL(FIGETBSZ) | 1915 | COMPATIBLE_IOCTL(FIGETBSZ) |
| 1916 | /* 'X' - originally XFS but some now in the VFS */ | ||
| 1917 | COMPATIBLE_IOCTL(FIFREEZE) | ||
| 1918 | COMPATIBLE_IOCTL(FITHAW) | ||
| 1916 | /* RAID */ | 1919 | /* RAID */ |
| 1917 | COMPATIBLE_IOCTL(RAID_VERSION) | 1920 | COMPATIBLE_IOCTL(RAID_VERSION) |
| 1918 | COMPATIBLE_IOCTL(GET_ARRAY_INFO) | 1921 | COMPATIBLE_IOCTL(GET_ARRAY_INFO) |
| @@ -1938,6 +1941,8 @@ ULONG_IOCTL(SET_BITMAP_FILE) | |||
| 1938 | /* Big K */ | 1941 | /* Big K */ |
| 1939 | COMPATIBLE_IOCTL(PIO_FONT) | 1942 | COMPATIBLE_IOCTL(PIO_FONT) |
| 1940 | COMPATIBLE_IOCTL(GIO_FONT) | 1943 | COMPATIBLE_IOCTL(GIO_FONT) |
| 1944 | COMPATIBLE_IOCTL(PIO_CMAP) | ||
| 1945 | COMPATIBLE_IOCTL(GIO_CMAP) | ||
| 1941 | ULONG_IOCTL(KDSIGACCEPT) | 1946 | ULONG_IOCTL(KDSIGACCEPT) |
| 1942 | COMPATIBLE_IOCTL(KDGETKEYCODE) | 1947 | COMPATIBLE_IOCTL(KDGETKEYCODE) |
| 1943 | COMPATIBLE_IOCTL(KDSETKEYCODE) | 1948 | COMPATIBLE_IOCTL(KDSETKEYCODE) |
diff --git a/fs/dcache.c b/fs/dcache.c index 937df0fb0da5..07e2d4a44bda 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
| @@ -1180,7 +1180,7 @@ struct dentry *d_obtain_alias(struct inode *inode) | |||
| 1180 | iput(inode); | 1180 | iput(inode); |
| 1181 | return res; | 1181 | return res; |
| 1182 | } | 1182 | } |
| 1183 | EXPORT_SYMBOL_GPL(d_obtain_alias); | 1183 | EXPORT_SYMBOL(d_obtain_alias); |
| 1184 | 1184 | ||
| 1185 | /** | 1185 | /** |
| 1186 | * d_splice_alias - splice a disconnected dentry into the tree if one exists | 1186 | * d_splice_alias - splice a disconnected dentry into the tree if one exists |
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 5f3231b9633f..bff4052b05e7 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
| @@ -198,9 +198,6 @@ static int mknod_ptmx(struct super_block *sb) | |||
| 198 | 198 | ||
| 199 | fsi->ptmx_dentry = dentry; | 199 | fsi->ptmx_dentry = dentry; |
| 200 | rc = 0; | 200 | rc = 0; |
| 201 | |||
| 202 | printk(KERN_DEBUG "Created ptmx node in devpts ino %lu\n", | ||
| 203 | inode->i_ino); | ||
| 204 | out: | 201 | out: |
| 205 | mutex_unlock(&root->d_inode->i_mutex); | 202 | mutex_unlock(&root->d_inode->i_mutex); |
| 206 | return rc; | 203 | return rc; |
| @@ -369,8 +366,6 @@ static int new_pts_mount(struct file_system_type *fs_type, int flags, | |||
| 369 | struct pts_fs_info *fsi; | 366 | struct pts_fs_info *fsi; |
| 370 | struct pts_mount_opts *opts; | 367 | struct pts_mount_opts *opts; |
| 371 | 368 | ||
| 372 | printk(KERN_NOTICE "devpts: newinstance mount\n"); | ||
| 373 | |||
| 374 | err = get_sb_nodev(fs_type, flags, data, devpts_fill_super, mnt); | 369 | err = get_sb_nodev(fs_type, flags, data, devpts_fill_super, mnt); |
| 375 | if (err) | 370 | if (err) |
| 376 | return err; | 371 | return err; |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index f6caeb1d1106..bdca1f4b3a3e 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); |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index c11fc95714ab..eb2267eca1fe 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; |
| @@ -696,7 +697,7 @@ ecryptfs_write_header_metadata(char *virt, | |||
| 696 | int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig); | 697 | int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig); |
| 697 | int | 698 | int |
| 698 | ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | 699 | ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, |
| 699 | char *sig); | 700 | char *sig, u32 global_auth_tok_flags); |
| 700 | int ecryptfs_get_global_auth_tok_for_sig( | 701 | int ecryptfs_get_global_auth_tok_for_sig( |
| 701 | struct ecryptfs_global_auth_tok **global_auth_tok, | 702 | struct ecryptfs_global_auth_tok **global_auth_tok, |
| 702 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig); | 703 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig); |
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/balloc.c b/fs/ext4/balloc.c index 9a50b8052dcf..de9459b4cb94 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
| @@ -609,7 +609,9 @@ int ext4_claim_free_blocks(struct ext4_sb_info *sbi, | |||
| 609 | */ | 609 | */ |
| 610 | int ext4_should_retry_alloc(struct super_block *sb, int *retries) | 610 | int ext4_should_retry_alloc(struct super_block *sb, int *retries) |
| 611 | { | 611 | { |
| 612 | if (!ext4_has_free_blocks(EXT4_SB(sb), 1) || (*retries)++ > 3) | 612 | if (!ext4_has_free_blocks(EXT4_SB(sb), 1) || |
| 613 | (*retries)++ > 3 || | ||
| 614 | !EXT4_SB(sb)->s_journal) | ||
| 613 | return 0; | 615 | return 0; |
| 614 | 616 | ||
| 615 | jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id); | 617 | jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id); |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index aafc9eba1c25..b0c87dce66a3 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
| @@ -868,7 +868,7 @@ static inline unsigned ext4_rec_len_from_disk(__le16 dlen) | |||
| 868 | { | 868 | { |
| 869 | unsigned len = le16_to_cpu(dlen); | 869 | unsigned len = le16_to_cpu(dlen); |
| 870 | 870 | ||
| 871 | if (len == EXT4_MAX_REC_LEN) | 871 | if (len == EXT4_MAX_REC_LEN || len == 0) |
| 872 | return 1 << 16; | 872 | return 1 << 16; |
| 873 | return len; | 873 | return len; |
| 874 | } | 874 | } |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 4fb86a0061d0..627f8c3337a3 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
| @@ -188,7 +188,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) | |||
| 188 | struct ext4_group_desc *gdp; | 188 | struct ext4_group_desc *gdp; |
| 189 | struct ext4_super_block *es; | 189 | struct ext4_super_block *es; |
| 190 | struct ext4_sb_info *sbi; | 190 | struct ext4_sb_info *sbi; |
| 191 | int fatal = 0, err, count; | 191 | int fatal = 0, err, count, cleared; |
| 192 | ext4_group_t flex_group; | 192 | ext4_group_t flex_group; |
| 193 | 193 | ||
| 194 | if (atomic_read(&inode->i_count) > 1) { | 194 | if (atomic_read(&inode->i_count) > 1) { |
| @@ -248,8 +248,10 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) | |||
| 248 | goto error_return; | 248 | goto error_return; |
| 249 | 249 | ||
| 250 | /* Ok, now we can actually update the inode bitmaps.. */ | 250 | /* Ok, now we can actually update the inode bitmaps.. */ |
| 251 | if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group), | 251 | spin_lock(sb_bgl_lock(sbi, block_group)); |
| 252 | bit, bitmap_bh->b_data)) | 252 | cleared = ext4_clear_bit(bit, bitmap_bh->b_data); |
| 253 | spin_unlock(sb_bgl_lock(sbi, block_group)); | ||
| 254 | if (!cleared) | ||
| 253 | ext4_error(sb, "ext4_free_inode", | 255 | ext4_error(sb, "ext4_free_inode", |
| 254 | "bit already cleared for inode %lu", ino); | 256 | "bit already cleared for inode %lu", ino); |
| 255 | else { | 257 | else { |
| @@ -715,6 +717,13 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) | |||
| 715 | 717 | ||
| 716 | if (sbi->s_log_groups_per_flex) { | 718 | if (sbi->s_log_groups_per_flex) { |
| 717 | ret2 = find_group_flex(sb, dir, &group); | 719 | ret2 = find_group_flex(sb, dir, &group); |
| 720 | if (ret2 == -1) { | ||
| 721 | ret2 = find_group_other(sb, dir, &group); | ||
| 722 | if (ret2 == 0 && printk_ratelimit()) | ||
| 723 | printk(KERN_NOTICE "ext4: find_group_flex " | ||
| 724 | "failed, fallback succeeded dir %lu\n", | ||
| 725 | dir->i_ino); | ||
| 726 | } | ||
| 718 | goto got_group; | 727 | goto got_group; |
| 719 | } | 728 | } |
| 720 | 729 | ||
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 03ba20be1329..c7fed5b18745 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -47,8 +47,10 @@ | |||
| 47 | static inline int ext4_begin_ordered_truncate(struct inode *inode, | 47 | static inline int ext4_begin_ordered_truncate(struct inode *inode, |
| 48 | loff_t new_size) | 48 | loff_t new_size) |
| 49 | { | 49 | { |
| 50 | return jbd2_journal_begin_ordered_truncate(&EXT4_I(inode)->jinode, | 50 | return jbd2_journal_begin_ordered_truncate( |
| 51 | new_size); | 51 | EXT4_SB(inode->i_sb)->s_journal, |
| 52 | &EXT4_I(inode)->jinode, | ||
| 53 | new_size); | ||
| 52 | } | 54 | } |
| 53 | 55 | ||
| 54 | static void ext4_invalidatepage(struct page *page, unsigned long offset); | 56 | static void ext4_invalidatepage(struct page *page, unsigned long offset); |
| @@ -1366,6 +1368,10 @@ retry: | |||
| 1366 | goto out; | 1368 | goto out; |
| 1367 | } | 1369 | } |
| 1368 | 1370 | ||
| 1371 | /* We cannot recurse into the filesystem as the transaction is already | ||
| 1372 | * started */ | ||
| 1373 | flags |= AOP_FLAG_NOFS; | ||
| 1374 | |||
| 1369 | page = grab_cache_page_write_begin(mapping, index, flags); | 1375 | page = grab_cache_page_write_begin(mapping, index, flags); |
| 1370 | if (!page) { | 1376 | if (!page) { |
| 1371 | ext4_journal_stop(handle); | 1377 | ext4_journal_stop(handle); |
| @@ -1375,7 +1381,7 @@ retry: | |||
| 1375 | *pagep = page; | 1381 | *pagep = page; |
| 1376 | 1382 | ||
| 1377 | ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 1383 | ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, |
| 1378 | ext4_get_block); | 1384 | ext4_get_block); |
| 1379 | 1385 | ||
| 1380 | if (!ret && ext4_should_journal_data(inode)) { | 1386 | if (!ret && ext4_should_journal_data(inode)) { |
| 1381 | ret = walk_page_buffers(handle, page_buffers(page), | 1387 | ret = walk_page_buffers(handle, page_buffers(page), |
| @@ -2437,6 +2443,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
| 2437 | int no_nrwrite_index_update; | 2443 | int no_nrwrite_index_update; |
| 2438 | int pages_written = 0; | 2444 | int pages_written = 0; |
| 2439 | long pages_skipped; | 2445 | long pages_skipped; |
| 2446 | int range_cyclic, cycled = 1, io_done = 0; | ||
| 2440 | int needed_blocks, ret = 0, nr_to_writebump = 0; | 2447 | int needed_blocks, ret = 0, nr_to_writebump = 0; |
| 2441 | struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); | 2448 | struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); |
| 2442 | 2449 | ||
| @@ -2488,9 +2495,15 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
| 2488 | if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) | 2495 | if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) |
| 2489 | range_whole = 1; | 2496 | range_whole = 1; |
| 2490 | 2497 | ||
| 2491 | if (wbc->range_cyclic) | 2498 | range_cyclic = wbc->range_cyclic; |
| 2499 | if (wbc->range_cyclic) { | ||
| 2492 | index = mapping->writeback_index; | 2500 | index = mapping->writeback_index; |
| 2493 | else | 2501 | if (index) |
| 2502 | cycled = 0; | ||
| 2503 | wbc->range_start = index << PAGE_CACHE_SHIFT; | ||
| 2504 | wbc->range_end = LLONG_MAX; | ||
| 2505 | wbc->range_cyclic = 0; | ||
| 2506 | } else | ||
| 2494 | index = wbc->range_start >> PAGE_CACHE_SHIFT; | 2507 | index = wbc->range_start >> PAGE_CACHE_SHIFT; |
| 2495 | 2508 | ||
| 2496 | mpd.wbc = wbc; | 2509 | mpd.wbc = wbc; |
| @@ -2504,6 +2517,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
| 2504 | wbc->no_nrwrite_index_update = 1; | 2517 | wbc->no_nrwrite_index_update = 1; |
| 2505 | pages_skipped = wbc->pages_skipped; | 2518 | pages_skipped = wbc->pages_skipped; |
| 2506 | 2519 | ||
| 2520 | retry: | ||
| 2507 | while (!ret && wbc->nr_to_write > 0) { | 2521 | while (!ret && wbc->nr_to_write > 0) { |
| 2508 | 2522 | ||
| 2509 | /* | 2523 | /* |
| @@ -2530,7 +2544,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
| 2530 | 2544 | ||
| 2531 | ext4_journal_stop(handle); | 2545 | ext4_journal_stop(handle); |
| 2532 | 2546 | ||
| 2533 | if (mpd.retval == -ENOSPC) { | 2547 | if ((mpd.retval == -ENOSPC) && sbi->s_journal) { |
| 2534 | /* commit the transaction which would | 2548 | /* commit the transaction which would |
| 2535 | * free blocks released in the transaction | 2549 | * free blocks released in the transaction |
| 2536 | * and try again | 2550 | * and try again |
| @@ -2546,6 +2560,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
| 2546 | pages_written += mpd.pages_written; | 2560 | pages_written += mpd.pages_written; |
| 2547 | wbc->pages_skipped = pages_skipped; | 2561 | wbc->pages_skipped = pages_skipped; |
| 2548 | ret = 0; | 2562 | ret = 0; |
| 2563 | io_done = 1; | ||
| 2549 | } else if (wbc->nr_to_write) | 2564 | } else if (wbc->nr_to_write) |
| 2550 | /* | 2565 | /* |
| 2551 | * There is no more writeout needed | 2566 | * There is no more writeout needed |
| @@ -2554,6 +2569,13 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
| 2554 | */ | 2569 | */ |
| 2555 | break; | 2570 | break; |
| 2556 | } | 2571 | } |
| 2572 | if (!io_done && !cycled) { | ||
| 2573 | cycled = 1; | ||
| 2574 | index = 0; | ||
| 2575 | wbc->range_start = index << PAGE_CACHE_SHIFT; | ||
| 2576 | wbc->range_end = mapping->writeback_index - 1; | ||
| 2577 | goto retry; | ||
| 2578 | } | ||
| 2557 | if (pages_skipped != wbc->pages_skipped) | 2579 | if (pages_skipped != wbc->pages_skipped) |
| 2558 | printk(KERN_EMERG "This should not happen leaving %s " | 2580 | printk(KERN_EMERG "This should not happen leaving %s " |
| 2559 | "with nr_to_write = %ld ret = %d\n", | 2581 | "with nr_to_write = %ld ret = %d\n", |
| @@ -2561,6 +2583,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
| 2561 | 2583 | ||
| 2562 | /* Update index */ | 2584 | /* Update index */ |
| 2563 | index += pages_written; | 2585 | index += pages_written; |
| 2586 | wbc->range_cyclic = range_cyclic; | ||
| 2564 | if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) | 2587 | if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) |
| 2565 | /* | 2588 | /* |
| 2566 | * set the writeback_index so that range_cyclic | 2589 | * set the writeback_index so that range_cyclic |
| @@ -2648,6 +2671,9 @@ retry: | |||
| 2648 | ret = PTR_ERR(handle); | 2671 | ret = PTR_ERR(handle); |
| 2649 | goto out; | 2672 | goto out; |
| 2650 | } | 2673 | } |
| 2674 | /* We cannot recurse into the filesystem as the transaction is already | ||
| 2675 | * started */ | ||
| 2676 | flags |= AOP_FLAG_NOFS; | ||
| 2651 | 2677 | ||
| 2652 | page = grab_cache_page_write_begin(mapping, index, flags); | 2678 | page = grab_cache_page_write_begin(mapping, index, flags); |
| 2653 | if (!page) { | 2679 | if (!page) { |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index deba54f6cbed..4415beeb0b62 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
| @@ -3693,6 +3693,8 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac) | |||
| 3693 | pa->pa_free = pa->pa_len; | 3693 | pa->pa_free = pa->pa_len; |
| 3694 | atomic_set(&pa->pa_count, 1); | 3694 | atomic_set(&pa->pa_count, 1); |
| 3695 | spin_lock_init(&pa->pa_lock); | 3695 | spin_lock_init(&pa->pa_lock); |
| 3696 | INIT_LIST_HEAD(&pa->pa_inode_list); | ||
| 3697 | INIT_LIST_HEAD(&pa->pa_group_list); | ||
| 3696 | pa->pa_deleted = 0; | 3698 | pa->pa_deleted = 0; |
| 3697 | pa->pa_linear = 0; | 3699 | pa->pa_linear = 0; |
| 3698 | 3700 | ||
| @@ -3755,6 +3757,7 @@ ext4_mb_new_group_pa(struct ext4_allocation_context *ac) | |||
| 3755 | atomic_set(&pa->pa_count, 1); | 3757 | atomic_set(&pa->pa_count, 1); |
| 3756 | spin_lock_init(&pa->pa_lock); | 3758 | spin_lock_init(&pa->pa_lock); |
| 3757 | INIT_LIST_HEAD(&pa->pa_inode_list); | 3759 | INIT_LIST_HEAD(&pa->pa_inode_list); |
| 3760 | INIT_LIST_HEAD(&pa->pa_group_list); | ||
| 3758 | pa->pa_deleted = 0; | 3761 | pa->pa_deleted = 0; |
| 3759 | pa->pa_linear = 1; | 3762 | pa->pa_linear = 1; |
| 3760 | 3763 | ||
| @@ -4476,23 +4479,26 @@ static int ext4_mb_release_context(struct ext4_allocation_context *ac) | |||
| 4476 | pa->pa_free -= ac->ac_b_ex.fe_len; | 4479 | pa->pa_free -= ac->ac_b_ex.fe_len; |
| 4477 | pa->pa_len -= ac->ac_b_ex.fe_len; | 4480 | pa->pa_len -= ac->ac_b_ex.fe_len; |
| 4478 | spin_unlock(&pa->pa_lock); | 4481 | spin_unlock(&pa->pa_lock); |
| 4479 | /* | ||
| 4480 | * We want to add the pa to the right bucket. | ||
| 4481 | * Remove it from the list and while adding | ||
| 4482 | * make sure the list to which we are adding | ||
| 4483 | * doesn't grow big. | ||
| 4484 | */ | ||
| 4485 | if (likely(pa->pa_free)) { | ||
| 4486 | spin_lock(pa->pa_obj_lock); | ||
| 4487 | list_del_rcu(&pa->pa_inode_list); | ||
| 4488 | spin_unlock(pa->pa_obj_lock); | ||
| 4489 | ext4_mb_add_n_trim(ac); | ||
| 4490 | } | ||
| 4491 | } | 4482 | } |
| 4492 | ext4_mb_put_pa(ac, ac->ac_sb, pa); | ||
| 4493 | } | 4483 | } |
| 4494 | if (ac->alloc_semp) | 4484 | if (ac->alloc_semp) |
| 4495 | up_read(ac->alloc_semp); | 4485 | up_read(ac->alloc_semp); |
| 4486 | if (pa) { | ||
| 4487 | /* | ||
| 4488 | * We want to add the pa to the right bucket. | ||
| 4489 | * Remove it from the list and while adding | ||
| 4490 | * make sure the list to which we are adding | ||
| 4491 | * doesn't grow big. We need to release | ||
| 4492 | * alloc_semp before calling ext4_mb_add_n_trim() | ||
| 4493 | */ | ||
| 4494 | if (pa->pa_linear && likely(pa->pa_free)) { | ||
| 4495 | spin_lock(pa->pa_obj_lock); | ||
| 4496 | list_del_rcu(&pa->pa_inode_list); | ||
| 4497 | spin_unlock(pa->pa_obj_lock); | ||
| 4498 | ext4_mb_add_n_trim(ac); | ||
| 4499 | } | ||
| 4500 | ext4_mb_put_pa(ac, ac->ac_sb, pa); | ||
| 4501 | } | ||
| 4496 | if (ac->ac_bitmap_page) | 4502 | if (ac->ac_bitmap_page) |
| 4497 | page_cache_release(ac->ac_bitmap_page); | 4503 | page_cache_release(ac->ac_bitmap_page); |
| 4498 | if (ac->ac_buddy_page) | 4504 | if (ac->ac_buddy_page) |
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index 734abca25e35..fe64d9f79852 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c | |||
| @@ -481,7 +481,7 @@ int ext4_ext_migrate(struct inode *inode) | |||
| 481 | + 1); | 481 | + 1); |
| 482 | if (IS_ERR(handle)) { | 482 | if (IS_ERR(handle)) { |
| 483 | retval = PTR_ERR(handle); | 483 | retval = PTR_ERR(handle); |
| 484 | goto err_out; | 484 | return retval; |
| 485 | } | 485 | } |
| 486 | tmp_inode = ext4_new_inode(handle, | 486 | tmp_inode = ext4_new_inode(handle, |
| 487 | inode->i_sb->s_root->d_inode, | 487 | inode->i_sb->s_root->d_inode, |
| @@ -489,8 +489,7 @@ int ext4_ext_migrate(struct inode *inode) | |||
| 489 | if (IS_ERR(tmp_inode)) { | 489 | if (IS_ERR(tmp_inode)) { |
| 490 | retval = -ENOMEM; | 490 | retval = -ENOMEM; |
| 491 | ext4_journal_stop(handle); | 491 | ext4_journal_stop(handle); |
| 492 | tmp_inode = NULL; | 492 | return retval; |
| 493 | goto err_out; | ||
| 494 | } | 493 | } |
| 495 | i_size_write(tmp_inode, i_size_read(inode)); | 494 | i_size_write(tmp_inode, i_size_read(inode)); |
| 496 | /* | 495 | /* |
| @@ -618,8 +617,7 @@ err_out: | |||
| 618 | 617 | ||
| 619 | ext4_journal_stop(handle); | 618 | ext4_journal_stop(handle); |
| 620 | 619 | ||
| 621 | if (tmp_inode) | 620 | iput(tmp_inode); |
| 622 | iput(tmp_inode); | ||
| 623 | 621 | ||
| 624 | return retval; | 622 | return retval; |
| 625 | } | 623 | } |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index e5f06a5f045e..39d1993cfa13 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -3046,14 +3046,17 @@ static void ext4_write_super(struct super_block *sb) | |||
| 3046 | static int ext4_sync_fs(struct super_block *sb, int wait) | 3046 | static int ext4_sync_fs(struct super_block *sb, int wait) |
| 3047 | { | 3047 | { |
| 3048 | int ret = 0; | 3048 | int ret = 0; |
| 3049 | tid_t target; | ||
| 3049 | 3050 | ||
| 3050 | trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); | 3051 | trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); |
| 3051 | sb->s_dirt = 0; | 3052 | sb->s_dirt = 0; |
| 3052 | if (EXT4_SB(sb)->s_journal) { | 3053 | if (EXT4_SB(sb)->s_journal) { |
| 3053 | if (wait) | 3054 | if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, |
| 3054 | ret = ext4_force_commit(sb); | 3055 | &target)) { |
| 3055 | else | 3056 | if (wait) |
| 3056 | jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, NULL); | 3057 | jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, |
| 3058 | target); | ||
| 3059 | } | ||
| 3057 | } else { | 3060 | } else { |
| 3058 | ext4_commit_super(sb, EXT4_SB(sb)->s_es, wait); | 3061 | ext4_commit_super(sb, EXT4_SB(sb)->s_es, wait); |
| 3059 | } | 3062 | } |
| @@ -3088,7 +3091,6 @@ static int ext4_freeze(struct super_block *sb) | |||
| 3088 | 3091 | ||
| 3089 | /* Journal blocked and flushed, clear needs_recovery flag. */ | 3092 | /* Journal blocked and flushed, clear needs_recovery flag. */ |
| 3090 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 3093 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
| 3091 | ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); | ||
| 3092 | error = ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); | 3094 | error = ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); |
| 3093 | if (error) | 3095 | if (error) |
| 3094 | goto out; | 3096 | goto out; |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 6b74d09adbe5..de0004fe6e00 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
| @@ -202,9 +202,9 @@ static sector_t _fat_bmap(struct address_space *mapping, sector_t block) | |||
| 202 | sector_t blocknr; | 202 | sector_t blocknr; |
| 203 | 203 | ||
| 204 | /* fat_get_cluster() assumes the requested blocknr isn't truncated. */ | 204 | /* fat_get_cluster() assumes the requested blocknr isn't truncated. */ |
| 205 | mutex_lock(&mapping->host->i_mutex); | 205 | down_read(&mapping->host->i_alloc_sem); |
| 206 | blocknr = generic_block_bmap(mapping, block, fat_get_block); | 206 | blocknr = generic_block_bmap(mapping, block, fat_get_block); |
| 207 | mutex_unlock(&mapping->host->i_mutex); | 207 | up_read(&mapping->host->i_alloc_sem); |
| 208 | 208 | ||
| 209 | return blocknr; | 209 | return blocknr; |
| 210 | } | 210 | } |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index e5eaa62fd17f..e3fe9918faaf 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
| @@ -274,6 +274,7 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc) | |||
| 274 | int ret; | 274 | int ret; |
| 275 | 275 | ||
| 276 | BUG_ON(inode->i_state & I_SYNC); | 276 | BUG_ON(inode->i_state & I_SYNC); |
| 277 | WARN_ON(inode->i_state & I_NEW); | ||
| 277 | 278 | ||
| 278 | /* Set I_SYNC, reset I_DIRTY */ | 279 | /* Set I_SYNC, reset I_DIRTY */ |
| 279 | dirty = inode->i_state & I_DIRTY; | 280 | dirty = inode->i_state & I_DIRTY; |
| @@ -298,6 +299,7 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc) | |||
| 298 | } | 299 | } |
| 299 | 300 | ||
| 300 | spin_lock(&inode_lock); | 301 | spin_lock(&inode_lock); |
| 302 | WARN_ON(inode->i_state & I_NEW); | ||
| 301 | inode->i_state &= ~I_SYNC; | 303 | inode->i_state &= ~I_SYNC; |
| 302 | if (!(inode->i_state & I_FREEING)) { | 304 | if (!(inode->i_state & I_FREEING)) { |
| 303 | if (!(inode->i_state & I_DIRTY) && | 305 | if (!(inode->i_state & I_DIRTY) && |
| @@ -470,6 +472,11 @@ void generic_sync_sb_inodes(struct super_block *sb, | |||
| 470 | break; | 472 | break; |
| 471 | } | 473 | } |
| 472 | 474 | ||
| 475 | if (inode->i_state & I_NEW) { | ||
| 476 | requeue_io(inode); | ||
| 477 | continue; | ||
| 478 | } | ||
| 479 | |||
| 473 | if (wbc->nonblocking && bdi_write_congested(bdi)) { | 480 | if (wbc->nonblocking && bdi_write_congested(bdi)) { |
| 474 | wbc->encountered_congestion = 1; | 481 | wbc->encountered_congestion = 1; |
| 475 | if (!sb_is_blkdev_sb(sb)) | 482 | if (!sb_is_blkdev_sb(sb)) |
| @@ -531,7 +538,7 @@ void generic_sync_sb_inodes(struct super_block *sb, | |||
| 531 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { | 538 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { |
| 532 | struct address_space *mapping; | 539 | struct address_space *mapping; |
| 533 | 540 | ||
| 534 | if (inode->i_state & (I_FREEING|I_WILL_FREE)) | 541 | if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) |
| 535 | continue; | 542 | continue; |
| 536 | mapping = inode->i_mapping; | 543 | mapping = inode->i_mapping; |
| 537 | if (mapping->nrpages == 0) | 544 | if (mapping->nrpages == 0) |
diff --git a/fs/inode.c b/fs/inode.c index 913ab2d9a5d1..826fb0b9d1c3 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
| @@ -359,6 +359,7 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose) | |||
| 359 | invalidate_inode_buffers(inode); | 359 | invalidate_inode_buffers(inode); |
| 360 | if (!atomic_read(&inode->i_count)) { | 360 | if (!atomic_read(&inode->i_count)) { |
| 361 | list_move(&inode->i_list, dispose); | 361 | list_move(&inode->i_list, dispose); |
| 362 | WARN_ON(inode->i_state & I_NEW); | ||
| 362 | inode->i_state |= I_FREEING; | 363 | inode->i_state |= I_FREEING; |
| 363 | count++; | 364 | count++; |
| 364 | continue; | 365 | continue; |
| @@ -460,6 +461,7 @@ static void prune_icache(int nr_to_scan) | |||
| 460 | continue; | 461 | continue; |
| 461 | } | 462 | } |
| 462 | list_move(&inode->i_list, &freeable); | 463 | list_move(&inode->i_list, &freeable); |
| 464 | WARN_ON(inode->i_state & I_NEW); | ||
| 463 | inode->i_state |= I_FREEING; | 465 | inode->i_state |= I_FREEING; |
| 464 | nr_pruned++; | 466 | nr_pruned++; |
| 465 | } | 467 | } |
| @@ -656,6 +658,7 @@ void unlock_new_inode(struct inode *inode) | |||
| 656 | * just created it (so there can be no old holders | 658 | * just created it (so there can be no old holders |
| 657 | * that haven't tested I_LOCK). | 659 | * that haven't tested I_LOCK). |
| 658 | */ | 660 | */ |
| 661 | WARN_ON((inode->i_state & (I_LOCK|I_NEW)) != (I_LOCK|I_NEW)); | ||
| 659 | inode->i_state &= ~(I_LOCK|I_NEW); | 662 | inode->i_state &= ~(I_LOCK|I_NEW); |
| 660 | wake_up_inode(inode); | 663 | wake_up_inode(inode); |
| 661 | } | 664 | } |
| @@ -1145,6 +1148,7 @@ void generic_delete_inode(struct inode *inode) | |||
| 1145 | 1148 | ||
| 1146 | list_del_init(&inode->i_list); | 1149 | list_del_init(&inode->i_list); |
| 1147 | list_del_init(&inode->i_sb_list); | 1150 | list_del_init(&inode->i_sb_list); |
| 1151 | WARN_ON(inode->i_state & I_NEW); | ||
| 1148 | inode->i_state |= I_FREEING; | 1152 | inode->i_state |= I_FREEING; |
| 1149 | inodes_stat.nr_inodes--; | 1153 | inodes_stat.nr_inodes--; |
| 1150 | spin_unlock(&inode_lock); | 1154 | spin_unlock(&inode_lock); |
| @@ -1186,16 +1190,19 @@ static void generic_forget_inode(struct inode *inode) | |||
| 1186 | spin_unlock(&inode_lock); | 1190 | spin_unlock(&inode_lock); |
| 1187 | return; | 1191 | return; |
| 1188 | } | 1192 | } |
| 1193 | WARN_ON(inode->i_state & I_NEW); | ||
| 1189 | inode->i_state |= I_WILL_FREE; | 1194 | inode->i_state |= I_WILL_FREE; |
| 1190 | spin_unlock(&inode_lock); | 1195 | spin_unlock(&inode_lock); |
| 1191 | write_inode_now(inode, 1); | 1196 | write_inode_now(inode, 1); |
| 1192 | spin_lock(&inode_lock); | 1197 | spin_lock(&inode_lock); |
| 1198 | WARN_ON(inode->i_state & I_NEW); | ||
| 1193 | inode->i_state &= ~I_WILL_FREE; | 1199 | inode->i_state &= ~I_WILL_FREE; |
| 1194 | inodes_stat.nr_unused--; | 1200 | inodes_stat.nr_unused--; |
| 1195 | hlist_del_init(&inode->i_hash); | 1201 | hlist_del_init(&inode->i_hash); |
| 1196 | } | 1202 | } |
| 1197 | list_del_init(&inode->i_list); | 1203 | list_del_init(&inode->i_list); |
| 1198 | list_del_init(&inode->i_sb_list); | 1204 | list_del_init(&inode->i_sb_list); |
| 1205 | WARN_ON(inode->i_state & I_NEW); | ||
| 1199 | inode->i_state |= I_FREEING; | 1206 | inode->i_state |= I_FREEING; |
| 1200 | inodes_stat.nr_inodes--; | 1207 | inodes_stat.nr_inodes--; |
| 1201 | spin_unlock(&inode_lock); | 1208 | spin_unlock(&inode_lock); |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index eb343008eded..58144102bf25 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
| @@ -450,7 +450,7 @@ int __jbd2_log_space_left(journal_t *journal) | |||
| 450 | } | 450 | } |
| 451 | 451 | ||
| 452 | /* | 452 | /* |
| 453 | * Called under j_state_lock. Returns true if a transaction was started. | 453 | * Called under j_state_lock. Returns true if a transaction commit was started. |
| 454 | */ | 454 | */ |
| 455 | int __jbd2_log_start_commit(journal_t *journal, tid_t target) | 455 | int __jbd2_log_start_commit(journal_t *journal, tid_t target) |
| 456 | { | 456 | { |
| @@ -518,7 +518,8 @@ int jbd2_journal_force_commit_nested(journal_t *journal) | |||
| 518 | 518 | ||
| 519 | /* | 519 | /* |
| 520 | * Start a commit of the current running transaction (if any). Returns true | 520 | * Start a commit of the current running transaction (if any). Returns true |
| 521 | * if a transaction was started, and fills its tid in at *ptid | 521 | * if a transaction is going to be committed (or is currently already |
| 522 | * committing), and fills its tid in at *ptid | ||
| 522 | */ | 523 | */ |
| 523 | int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid) | 524 | int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid) |
| 524 | { | 525 | { |
| @@ -528,15 +529,19 @@ int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid) | |||
| 528 | if (journal->j_running_transaction) { | 529 | if (journal->j_running_transaction) { |
| 529 | tid_t tid = journal->j_running_transaction->t_tid; | 530 | tid_t tid = journal->j_running_transaction->t_tid; |
| 530 | 531 | ||
| 531 | ret = __jbd2_log_start_commit(journal, tid); | 532 | __jbd2_log_start_commit(journal, tid); |
| 532 | if (ret && ptid) | 533 | /* There's a running transaction and we've just made sure |
| 534 | * it's commit has been scheduled. */ | ||
| 535 | if (ptid) | ||
| 533 | *ptid = tid; | 536 | *ptid = tid; |
| 534 | } else if (journal->j_committing_transaction && ptid) { | 537 | ret = 1; |
| 538 | } else if (journal->j_committing_transaction) { | ||
| 535 | /* | 539 | /* |
| 536 | * If ext3_write_super() recently started a commit, then we | 540 | * If ext3_write_super() recently started a commit, then we |
| 537 | * have to wait for completion of that transaction | 541 | * have to wait for completion of that transaction |
| 538 | */ | 542 | */ |
| 539 | *ptid = journal->j_committing_transaction->t_tid; | 543 | if (ptid) |
| 544 | *ptid = journal->j_committing_transaction->t_tid; | ||
| 540 | ret = 1; | 545 | ret = 1; |
| 541 | } | 546 | } |
| 542 | spin_unlock(&journal->j_state_lock); | 547 | spin_unlock(&journal->j_state_lock); |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 46b4e347ed7d..28ce21d8598e 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
| @@ -2129,26 +2129,46 @@ done: | |||
| 2129 | } | 2129 | } |
| 2130 | 2130 | ||
| 2131 | /* | 2131 | /* |
| 2132 | * This function must be called when inode is journaled in ordered mode | 2132 | * File truncate and transaction commit interact with each other in a |
| 2133 | * before truncation happens. It starts writeout of truncated part in | 2133 | * non-trivial way. If a transaction writing data block A is |
| 2134 | * case it is in the committing transaction so that we stand to ordered | 2134 | * committing, we cannot discard the data by truncate until we have |
| 2135 | * mode consistency guarantees. | 2135 | * written them. Otherwise if we crashed after the transaction with |
| 2136 | * write has committed but before the transaction with truncate has | ||
| 2137 | * committed, we could see stale data in block A. This function is a | ||
| 2138 | * helper to solve this problem. It starts writeout of the truncated | ||
| 2139 | * part in case it is in the committing transaction. | ||
| 2140 | * | ||
| 2141 | * Filesystem code must call this function when inode is journaled in | ||
| 2142 | * ordered mode before truncation happens and after the inode has been | ||
| 2143 | * placed on orphan list with the new inode size. The second condition | ||
| 2144 | * avoids the race that someone writes new data and we start | ||
| 2145 | * committing the transaction after this function has been called but | ||
| 2146 | * before a transaction for truncate is started (and furthermore it | ||
| 2147 | * allows us to optimize the case where the addition to orphan list | ||
| 2148 | * happens in the same transaction as write --- we don't have to write | ||
| 2149 | * any data in such case). | ||
| 2136 | */ | 2150 | */ |
| 2137 | int jbd2_journal_begin_ordered_truncate(struct jbd2_inode *inode, | 2151 | int jbd2_journal_begin_ordered_truncate(journal_t *journal, |
| 2152 | struct jbd2_inode *jinode, | ||
| 2138 | loff_t new_size) | 2153 | loff_t new_size) |
| 2139 | { | 2154 | { |
| 2140 | journal_t *journal; | 2155 | transaction_t *inode_trans, *commit_trans; |
| 2141 | transaction_t *commit_trans; | ||
| 2142 | int ret = 0; | 2156 | int ret = 0; |
| 2143 | 2157 | ||
| 2144 | if (!inode->i_transaction && !inode->i_next_transaction) | 2158 | /* This is a quick check to avoid locking if not necessary */ |
| 2159 | if (!jinode->i_transaction) | ||
| 2145 | goto out; | 2160 | goto out; |
| 2146 | journal = inode->i_transaction->t_journal; | 2161 | /* Locks are here just to force reading of recent values, it is |
| 2162 | * enough that the transaction was not committing before we started | ||
| 2163 | * a transaction adding the inode to orphan list */ | ||
| 2147 | spin_lock(&journal->j_state_lock); | 2164 | spin_lock(&journal->j_state_lock); |
| 2148 | commit_trans = journal->j_committing_transaction; | 2165 | commit_trans = journal->j_committing_transaction; |
| 2149 | spin_unlock(&journal->j_state_lock); | 2166 | spin_unlock(&journal->j_state_lock); |
| 2150 | if (inode->i_transaction == commit_trans) { | 2167 | spin_lock(&journal->j_list_lock); |
| 2151 | ret = filemap_fdatawrite_range(inode->i_vfs_inode->i_mapping, | 2168 | inode_trans = jinode->i_transaction; |
| 2169 | spin_unlock(&journal->j_list_lock); | ||
| 2170 | if (inode_trans == commit_trans) { | ||
| 2171 | ret = filemap_fdatawrite_range(jinode->i_vfs_inode->i_mapping, | ||
| 2152 | new_size, LLONG_MAX); | 2172 | new_size, LLONG_MAX); |
| 2153 | if (ret) | 2173 | if (ret) |
| 2154 | jbd2_journal_abort(journal, ret); | 2174 | jbd2_journal_abort(journal, ret); |
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c index 3cceef4ad2b7..e9580104b6ba 100644 --- a/fs/jffs2/background.c +++ b/fs/jffs2/background.c | |||
| @@ -95,13 +95,17 @@ static int jffs2_garbage_collect_thread(void *_c) | |||
| 95 | spin_unlock(&c->erase_completion_lock); | 95 | spin_unlock(&c->erase_completion_lock); |
| 96 | 96 | ||
| 97 | 97 | ||
| 98 | /* This thread is purely an optimisation. But if it runs when | 98 | /* Problem - immediately after bootup, the GCD spends a lot |
| 99 | other things could be running, it actually makes things a | 99 | * of time in places like jffs2_kill_fragtree(); so much so |
| 100 | lot worse. Use yield() and put it at the back of the runqueue | 100 | * that userspace processes (like gdm and X) are starved |
| 101 | every time. Especially during boot, pulling an inode in | 101 | * despite plenty of cond_resched()s and renicing. Yield() |
| 102 | with read_inode() is much preferable to having the GC thread | 102 | * doesn't help, either (presumably because userspace and GCD |
| 103 | get there first. */ | 103 | * are generally competing for a higher latency resource - |
| 104 | yield(); | 104 | * disk). |
| 105 | * This forces the GCD to slow the hell down. Pulling an | ||
| 106 | * inode in with read_inode() is much preferable to having | ||
| 107 | * the GC thread get there first. */ | ||
| 108 | schedule_timeout_interruptible(msecs_to_jiffies(50)); | ||
| 105 | 109 | ||
| 106 | /* Put_super will send a SIGKILL and then wait on the sem. | 110 | /* Put_super will send a SIGKILL and then wait on the sem. |
| 107 | */ | 111 | */ |
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 6ca08ad887c0..1fc1e92356ee 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c | |||
| @@ -220,7 +220,7 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, | |||
| 220 | struct jffs2_tmp_dnode_info *tn) | 220 | struct jffs2_tmp_dnode_info *tn) |
| 221 | { | 221 | { |
| 222 | uint32_t fn_end = tn->fn->ofs + tn->fn->size; | 222 | uint32_t fn_end = tn->fn->ofs + tn->fn->size; |
| 223 | struct jffs2_tmp_dnode_info *this; | 223 | struct jffs2_tmp_dnode_info *this, *ptn; |
| 224 | 224 | ||
| 225 | dbg_readinode("insert fragment %#04x-%#04x, ver %u at %08x\n", tn->fn->ofs, fn_end, tn->version, ref_offset(tn->fn->raw)); | 225 | dbg_readinode("insert fragment %#04x-%#04x, ver %u at %08x\n", tn->fn->ofs, fn_end, tn->version, ref_offset(tn->fn->raw)); |
| 226 | 226 | ||
| @@ -251,11 +251,18 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, | |||
| 251 | if (this) { | 251 | if (this) { |
| 252 | /* If the node is coincident with another at a lower address, | 252 | /* If the node is coincident with another at a lower address, |
| 253 | back up until the other node is found. It may be relevant */ | 253 | back up until the other node is found. It may be relevant */ |
| 254 | while (this->overlapped) | 254 | while (this->overlapped) { |
| 255 | this = tn_prev(this); | 255 | ptn = tn_prev(this); |
| 256 | 256 | if (!ptn) { | |
| 257 | /* First node should never be marked overlapped */ | 257 | /* |
| 258 | BUG_ON(!this); | 258 | * We killed a node which set the overlapped |
| 259 | * flags during the scan. Fix it up. | ||
| 260 | */ | ||
| 261 | this->overlapped = 0; | ||
| 262 | break; | ||
| 263 | } | ||
| 264 | this = ptn; | ||
| 265 | } | ||
| 259 | dbg_readinode("'this' found %#04x-%#04x (%s)\n", this->fn->ofs, this->fn->ofs + this->fn->size, this->fn ? "data" : "hole"); | 266 | dbg_readinode("'this' found %#04x-%#04x (%s)\n", this->fn->ofs, this->fn->ofs + this->fn->size, this->fn ? "data" : "hole"); |
| 260 | } | 267 | } |
| 261 | 268 | ||
| @@ -360,7 +367,17 @@ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, | |||
| 360 | } | 367 | } |
| 361 | if (!this->overlapped) | 368 | if (!this->overlapped) |
| 362 | break; | 369 | break; |
| 363 | this = tn_prev(this); | 370 | |
| 371 | ptn = tn_prev(this); | ||
| 372 | if (!ptn) { | ||
| 373 | /* | ||
| 374 | * We killed a node which set the overlapped | ||
| 375 | * flags during the scan. Fix it up. | ||
| 376 | */ | ||
| 377 | this->overlapped = 0; | ||
| 378 | break; | ||
| 379 | } | ||
| 380 | this = ptn; | ||
| 364 | } | 381 | } |
| 365 | } | 382 | } |
| 366 | 383 | ||
| @@ -456,8 +473,15 @@ static int jffs2_build_inode_fragtree(struct jffs2_sb_info *c, | |||
| 456 | eat_last(&rii->tn_root, &last->rb); | 473 | eat_last(&rii->tn_root, &last->rb); |
| 457 | ver_insert(&ver_root, last); | 474 | ver_insert(&ver_root, last); |
| 458 | 475 | ||
| 459 | if (unlikely(last->overlapped)) | 476 | if (unlikely(last->overlapped)) { |
| 460 | continue; | 477 | if (pen) |
| 478 | continue; | ||
| 479 | /* | ||
| 480 | * We killed a node which set the overlapped | ||
| 481 | * flags during the scan. Fix it up. | ||
| 482 | */ | ||
| 483 | last->overlapped = 0; | ||
| 484 | } | ||
| 461 | 485 | ||
| 462 | /* Now we have a bunch of nodes in reverse version | 486 | /* Now we have a bunch of nodes in reverse version |
| 463 | order, in the tree at ver_root. Most of the time, | 487 | order, in the tree at ver_root. Most of the time, |
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/namespace.c b/fs/namespace.c index 228d8c4bfd18..06f8e63f6cb1 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
| @@ -614,9 +614,11 @@ static inline void __mntput(struct vfsmount *mnt) | |||
| 614 | */ | 614 | */ |
| 615 | for_each_possible_cpu(cpu) { | 615 | for_each_possible_cpu(cpu) { |
| 616 | struct mnt_writer *cpu_writer = &per_cpu(mnt_writers, cpu); | 616 | struct mnt_writer *cpu_writer = &per_cpu(mnt_writers, cpu); |
| 617 | if (cpu_writer->mnt != mnt) | ||
| 618 | continue; | ||
| 619 | spin_lock(&cpu_writer->lock); | 617 | spin_lock(&cpu_writer->lock); |
| 618 | if (cpu_writer->mnt != mnt) { | ||
| 619 | spin_unlock(&cpu_writer->lock); | ||
| 620 | continue; | ||
| 621 | } | ||
| 620 | atomic_add(cpu_writer->count, &mnt->__mnt_writers); | 622 | atomic_add(cpu_writer->count, &mnt->__mnt_writers); |
| 621 | cpu_writer->count = 0; | 623 | cpu_writer->count = 0; |
| 622 | /* | 624 | /* |
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/notify/inotify/inotify.c b/fs/notify/inotify/inotify.c index dae3f28f30d4..331f2e88e284 100644 --- a/fs/notify/inotify/inotify.c +++ b/fs/notify/inotify/inotify.c | |||
| @@ -156,7 +156,7 @@ static int inotify_handle_get_wd(struct inotify_handle *ih, | |||
| 156 | int ret; | 156 | int ret; |
| 157 | 157 | ||
| 158 | do { | 158 | do { |
| 159 | if (unlikely(!idr_pre_get(&ih->idr, GFP_KERNEL))) | 159 | if (unlikely(!idr_pre_get(&ih->idr, GFP_NOFS))) |
| 160 | return -ENOSPC; | 160 | return -ENOSPC; |
| 161 | ret = idr_get_new_above(&ih->idr, watch, ih->last_wd+1, &watch->wd); | 161 | ret = idr_get_new_above(&ih->idr, watch, ih->last_wd+1, &watch->wd); |
| 162 | } while (ret == -EAGAIN); | 162 | } while (ret == -EAGAIN); |
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 60fe74035db5..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, |
| @@ -4796,6 +4797,29 @@ out: | |||
| 4796 | return ret; | 4797 | return ret; |
| 4797 | } | 4798 | } |
| 4798 | 4799 | ||
| 4800 | static int ocfs2_replace_extent_rec(struct inode *inode, | ||
| 4801 | handle_t *handle, | ||
| 4802 | struct ocfs2_path *path, | ||
| 4803 | struct ocfs2_extent_list *el, | ||
| 4804 | int split_index, | ||
| 4805 | struct ocfs2_extent_rec *split_rec) | ||
| 4806 | { | ||
| 4807 | int ret; | ||
| 4808 | |||
| 4809 | ret = ocfs2_path_bh_journal_access(handle, inode, path, | ||
| 4810 | path_num_items(path) - 1); | ||
| 4811 | if (ret) { | ||
| 4812 | mlog_errno(ret); | ||
| 4813 | goto out; | ||
| 4814 | } | ||
| 4815 | |||
| 4816 | el->l_recs[split_index] = *split_rec; | ||
| 4817 | |||
| 4818 | ocfs2_journal_dirty(handle, path_leaf_bh(path)); | ||
| 4819 | out: | ||
| 4820 | return ret; | ||
| 4821 | } | ||
| 4822 | |||
| 4799 | /* | 4823 | /* |
| 4800 | * Mark part or all of the extent record at split_index in the leaf | 4824 | * Mark part or all of the extent record at split_index in the leaf |
| 4801 | * pointed to by path as written. This removes the unwritten | 4825 | * pointed to by path as written. This removes the unwritten |
| @@ -4885,7 +4909,9 @@ static int __ocfs2_mark_extent_written(struct inode *inode, | |||
| 4885 | 4909 | ||
| 4886 | if (ctxt.c_contig_type == CONTIG_NONE) { | 4910 | if (ctxt.c_contig_type == CONTIG_NONE) { |
| 4887 | if (ctxt.c_split_covers_rec) | 4911 | if (ctxt.c_split_covers_rec) |
| 4888 | el->l_recs[split_index] = *split_rec; | 4912 | ret = ocfs2_replace_extent_rec(inode, handle, |
| 4913 | path, el, | ||
| 4914 | split_index, split_rec); | ||
| 4889 | else | 4915 | else |
| 4890 | ret = ocfs2_split_and_insert(inode, handle, path, et, | 4916 | ret = ocfs2_split_and_insert(inode, handle, path, et, |
| 4891 | &last_eb_bh, split_index, | 4917 | &last_eb_bh, split_index, |
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/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 54e182a27caf..0a2813947853 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
| @@ -1849,12 +1849,12 @@ int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 1849 | if (!mle) { | 1849 | if (!mle) { |
| 1850 | if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN && | 1850 | if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN && |
| 1851 | res->owner != assert->node_idx) { | 1851 | res->owner != assert->node_idx) { |
| 1852 | mlog(ML_ERROR, "assert_master from " | 1852 | mlog(ML_ERROR, "DIE! Mastery assert from %u, " |
| 1853 | "%u, but current owner is " | 1853 | "but current owner is %u! (%.*s)\n", |
| 1854 | "%u! (%.*s)\n", | 1854 | assert->node_idx, res->owner, namelen, |
| 1855 | assert->node_idx, res->owner, | 1855 | name); |
| 1856 | namelen, name); | 1856 | __dlm_print_one_lock_resource(res); |
| 1857 | goto kill; | 1857 | BUG(); |
| 1858 | } | 1858 | } |
| 1859 | } else if (mle->type != DLM_MLE_MIGRATION) { | 1859 | } else if (mle->type != DLM_MLE_MIGRATION) { |
| 1860 | if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN) { | 1860 | if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN) { |
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index d1295203029f..4060bb328bc8 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c | |||
| @@ -181,8 +181,7 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm, | |||
| 181 | 181 | ||
| 182 | spin_lock(&res->spinlock); | 182 | spin_lock(&res->spinlock); |
| 183 | /* This ensures that clear refmap is sent after the set */ | 183 | /* This ensures that clear refmap is sent after the set */ |
| 184 | __dlm_wait_on_lockres_flags(res, (DLM_LOCK_RES_SETREF_INPROG | | 184 | __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG); |
| 185 | DLM_LOCK_RES_MIGRATING)); | ||
| 186 | spin_unlock(&res->spinlock); | 185 | spin_unlock(&res->spinlock); |
| 187 | 186 | ||
| 188 | /* clear our bit from the master's refmap, ignore errors */ | 187 | /* clear our bit from the master's refmap, ignore errors */ |
diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c index 86ca085ef324..fcf879ed6930 100644 --- a/fs/ocfs2/dlm/dlmunlock.c +++ b/fs/ocfs2/dlm/dlmunlock.c | |||
| @@ -117,11 +117,11 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, | |||
| 117 | else | 117 | else |
| 118 | BUG_ON(res->owner == dlm->node_num); | 118 | BUG_ON(res->owner == dlm->node_num); |
| 119 | 119 | ||
| 120 | spin_lock(&dlm->spinlock); | 120 | spin_lock(&dlm->ast_lock); |
| 121 | /* We want to be sure that we're not freeing a lock | 121 | /* We want to be sure that we're not freeing a lock |
| 122 | * that still has AST's pending... */ | 122 | * that still has AST's pending... */ |
| 123 | in_use = !list_empty(&lock->ast_list); | 123 | in_use = !list_empty(&lock->ast_list); |
| 124 | spin_unlock(&dlm->spinlock); | 124 | spin_unlock(&dlm->ast_lock); |
| 125 | if (in_use) { | 125 | if (in_use) { |
| 126 | mlog(ML_ERROR, "lockres %.*s: Someone is calling dlmunlock " | 126 | mlog(ML_ERROR, "lockres %.*s: Someone is calling dlmunlock " |
| 127 | "while waiting for an ast!", res->lockname.len, | 127 | "while waiting for an ast!", res->lockname.len, |
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 206a2370876a..7219a86d34cc 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
| @@ -320,9 +320,14 @@ static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb, | |||
| 320 | struct ocfs2_lock_res *lockres); | 320 | struct ocfs2_lock_res *lockres); |
| 321 | static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres, | 321 | static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres, |
| 322 | int convert); | 322 | int convert); |
| 323 | #define ocfs2_log_dlm_error(_func, _err, _lockres) do { \ | 323 | #define ocfs2_log_dlm_error(_func, _err, _lockres) do { \ |
| 324 | mlog(ML_ERROR, "DLM error %d while calling %s on resource %s\n", \ | 324 | if ((_lockres)->l_type != OCFS2_LOCK_TYPE_DENTRY) \ |
| 325 | _err, _func, _lockres->l_name); \ | 325 | mlog(ML_ERROR, "DLM error %d while calling %s on resource %s\n", \ |
| 326 | _err, _func, _lockres->l_name); \ | ||
| 327 | else \ | ||
| 328 | mlog(ML_ERROR, "DLM error %d while calling %s on resource %.*s%08x\n", \ | ||
| 329 | _err, _func, OCFS2_DENTRY_LOCK_INO_START - 1, (_lockres)->l_name, \ | ||
| 330 | (unsigned int)ocfs2_get_dentry_lock_ino(_lockres)); \ | ||
| 326 | } while (0) | 331 | } while (0) |
| 327 | static int ocfs2_downconvert_thread(void *arg); | 332 | static int ocfs2_downconvert_thread(void *arg); |
| 328 | static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb, | 333 | static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb, |
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h index 3c3532e1307c..172850a9a12a 100644 --- a/fs/ocfs2/journal.h +++ b/fs/ocfs2/journal.h | |||
| @@ -513,8 +513,10 @@ static inline int ocfs2_jbd2_file_inode(handle_t *handle, struct inode *inode) | |||
| 513 | static inline int ocfs2_begin_ordered_truncate(struct inode *inode, | 513 | static inline int ocfs2_begin_ordered_truncate(struct inode *inode, |
| 514 | loff_t new_size) | 514 | loff_t new_size) |
| 515 | { | 515 | { |
| 516 | return jbd2_journal_begin_ordered_truncate(&OCFS2_I(inode)->ip_jinode, | 516 | return jbd2_journal_begin_ordered_truncate( |
| 517 | new_size); | 517 | OCFS2_SB(inode->i_sb)->journal->j_journal, |
| 518 | &OCFS2_I(inode)->ip_jinode, | ||
| 519 | new_size); | ||
| 518 | } | 520 | } |
| 519 | 521 | ||
| 520 | #endif /* OCFS2_JOURNAL_H */ | 522 | #endif /* OCFS2_JOURNAL_H */ |
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.h b/fs/ocfs2/ocfs2.h index 077384135f4e..946d3c34b90b 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
| @@ -341,6 +341,9 @@ struct ocfs2_super | |||
| 341 | struct ocfs2_node_map osb_recovering_orphan_dirs; | 341 | struct ocfs2_node_map osb_recovering_orphan_dirs; |
| 342 | unsigned int *osb_orphan_wipes; | 342 | unsigned int *osb_orphan_wipes; |
| 343 | wait_queue_head_t osb_wipe_event; | 343 | wait_queue_head_t osb_wipe_event; |
| 344 | |||
| 345 | /* used to protect metaecc calculation check of xattr. */ | ||
| 346 | spinlock_t osb_xattr_lock; | ||
| 344 | }; | 347 | }; |
| 345 | 348 | ||
| 346 | #define OCFS2_SB(sb) ((struct ocfs2_super *)(sb)->s_fs_info) | 349 | #define OCFS2_SB(sb) ((struct ocfs2_super *)(sb)->s_fs_info) |
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/super.c b/fs/ocfs2/super.c index b1cb38fbe807..7ac83a81ee55 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
| @@ -1537,6 +1537,13 @@ static int ocfs2_get_sector(struct super_block *sb, | |||
| 1537 | unlock_buffer(*bh); | 1537 | unlock_buffer(*bh); |
| 1538 | ll_rw_block(READ, 1, bh); | 1538 | ll_rw_block(READ, 1, bh); |
| 1539 | wait_on_buffer(*bh); | 1539 | wait_on_buffer(*bh); |
| 1540 | if (!buffer_uptodate(*bh)) { | ||
| 1541 | mlog_errno(-EIO); | ||
| 1542 | brelse(*bh); | ||
| 1543 | *bh = NULL; | ||
| 1544 | return -EIO; | ||
| 1545 | } | ||
| 1546 | |||
| 1540 | return 0; | 1547 | return 0; |
| 1541 | } | 1548 | } |
| 1542 | 1549 | ||
| @@ -1747,6 +1754,7 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
| 1747 | INIT_LIST_HEAD(&osb->blocked_lock_list); | 1754 | INIT_LIST_HEAD(&osb->blocked_lock_list); |
| 1748 | osb->blocked_lock_count = 0; | 1755 | osb->blocked_lock_count = 0; |
| 1749 | spin_lock_init(&osb->osb_lock); | 1756 | spin_lock_init(&osb->osb_lock); |
| 1757 | spin_lock_init(&osb->osb_xattr_lock); | ||
| 1750 | ocfs2_init_inode_steal_slot(osb); | 1758 | ocfs2_init_inode_steal_slot(osb); |
| 1751 | 1759 | ||
| 1752 | atomic_set(&osb->alloc_stats.moves, 0); | 1760 | atomic_set(&osb->alloc_stats.moves, 0); |
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 915039fffe6e..2563df89fc2a 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
| @@ -82,13 +82,14 @@ struct ocfs2_xattr_set_ctxt { | |||
| 82 | 82 | ||
| 83 | #define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root)) | 83 | #define OCFS2_XATTR_ROOT_SIZE (sizeof(struct ocfs2_xattr_def_value_root)) |
| 84 | #define OCFS2_XATTR_INLINE_SIZE 80 | 84 | #define OCFS2_XATTR_INLINE_SIZE 80 |
| 85 | #define OCFS2_XATTR_HEADER_GAP 4 | ||
| 85 | #define OCFS2_XATTR_FREE_IN_IBODY (OCFS2_MIN_XATTR_INLINE_SIZE \ | 86 | #define OCFS2_XATTR_FREE_IN_IBODY (OCFS2_MIN_XATTR_INLINE_SIZE \ |
| 86 | - sizeof(struct ocfs2_xattr_header) \ | 87 | - sizeof(struct ocfs2_xattr_header) \ |
| 87 | - sizeof(__u32)) | 88 | - OCFS2_XATTR_HEADER_GAP) |
| 88 | #define OCFS2_XATTR_FREE_IN_BLOCK(ptr) ((ptr)->i_sb->s_blocksize \ | 89 | #define OCFS2_XATTR_FREE_IN_BLOCK(ptr) ((ptr)->i_sb->s_blocksize \ |
| 89 | - sizeof(struct ocfs2_xattr_block) \ | 90 | - sizeof(struct ocfs2_xattr_block) \ |
| 90 | - sizeof(struct ocfs2_xattr_header) \ | 91 | - sizeof(struct ocfs2_xattr_header) \ |
| 91 | - sizeof(__u32)) | 92 | - OCFS2_XATTR_HEADER_GAP) |
| 92 | 93 | ||
| 93 | static struct ocfs2_xattr_def_value_root def_xv = { | 94 | static struct ocfs2_xattr_def_value_root def_xv = { |
| 94 | .xv.xr_list.l_count = cpu_to_le16(1), | 95 | .xv.xr_list.l_count = cpu_to_le16(1), |
| @@ -274,10 +275,12 @@ static int ocfs2_read_xattr_bucket(struct ocfs2_xattr_bucket *bucket, | |||
| 274 | bucket->bu_blocks, bucket->bu_bhs, 0, | 275 | bucket->bu_blocks, bucket->bu_bhs, 0, |
| 275 | NULL); | 276 | NULL); |
| 276 | if (!rc) { | 277 | if (!rc) { |
| 278 | spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); | ||
| 277 | rc = ocfs2_validate_meta_ecc_bhs(bucket->bu_inode->i_sb, | 279 | rc = ocfs2_validate_meta_ecc_bhs(bucket->bu_inode->i_sb, |
| 278 | bucket->bu_bhs, | 280 | bucket->bu_bhs, |
| 279 | bucket->bu_blocks, | 281 | bucket->bu_blocks, |
| 280 | &bucket_xh(bucket)->xh_check); | 282 | &bucket_xh(bucket)->xh_check); |
| 283 | spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); | ||
| 281 | if (rc) | 284 | if (rc) |
| 282 | mlog_errno(rc); | 285 | mlog_errno(rc); |
| 283 | } | 286 | } |
| @@ -310,9 +313,11 @@ static void ocfs2_xattr_bucket_journal_dirty(handle_t *handle, | |||
| 310 | { | 313 | { |
| 311 | int i; | 314 | int i; |
| 312 | 315 | ||
| 316 | spin_lock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); | ||
| 313 | ocfs2_compute_meta_ecc_bhs(bucket->bu_inode->i_sb, | 317 | ocfs2_compute_meta_ecc_bhs(bucket->bu_inode->i_sb, |
| 314 | bucket->bu_bhs, bucket->bu_blocks, | 318 | bucket->bu_bhs, bucket->bu_blocks, |
| 315 | &bucket_xh(bucket)->xh_check); | 319 | &bucket_xh(bucket)->xh_check); |
| 320 | spin_unlock(&OCFS2_SB(bucket->bu_inode->i_sb)->osb_xattr_lock); | ||
| 316 | 321 | ||
| 317 | for (i = 0; i < bucket->bu_blocks; i++) | 322 | for (i = 0; i < bucket->bu_blocks; i++) |
| 318 | ocfs2_journal_dirty(handle, bucket->bu_bhs[i]); | 323 | ocfs2_journal_dirty(handle, bucket->bu_bhs[i]); |
| @@ -542,8 +547,12 @@ int ocfs2_calc_xattr_init(struct inode *dir, | |||
| 542 | * when blocksize = 512, may reserve one more cluser for | 547 | * when blocksize = 512, may reserve one more cluser for |
| 543 | * xattr bucket, otherwise reserve one metadata block | 548 | * xattr bucket, otherwise reserve one metadata block |
| 544 | * 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. | ||
| 545 | */ | 553 | */ |
| 546 | 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)) || | ||
| 547 | (s_size + a_size) > OCFS2_XATTR_FREE_IN_IBODY) { | 556 | (s_size + a_size) > OCFS2_XATTR_FREE_IN_IBODY) { |
| 548 | ret = ocfs2_reserve_new_metadata_blocks(osb, 1, xattr_ac); | 557 | ret = ocfs2_reserve_new_metadata_blocks(osb, 1, xattr_ac); |
| 549 | if (ret) { | 558 | if (ret) { |
| @@ -1507,7 +1516,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode, | |||
| 1507 | last += 1; | 1516 | last += 1; |
| 1508 | } | 1517 | } |
| 1509 | 1518 | ||
| 1510 | free = min_offs - ((void *)last - xs->base) - sizeof(__u32); | 1519 | free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP; |
| 1511 | if (free < 0) | 1520 | if (free < 0) |
| 1512 | return -EIO; | 1521 | return -EIO; |
| 1513 | 1522 | ||
| @@ -2190,7 +2199,7 @@ static int ocfs2_xattr_can_be_in_inode(struct inode *inode, | |||
| 2190 | last += 1; | 2199 | last += 1; |
| 2191 | } | 2200 | } |
| 2192 | 2201 | ||
| 2193 | free = min_offs - ((void *)last - xs->base) - sizeof(__u32); | 2202 | free = min_offs - ((void *)last - xs->base) - OCFS2_XATTR_HEADER_GAP; |
| 2194 | if (free < 0) | 2203 | if (free < 0) |
| 2195 | return 0; | 2204 | return 0; |
| 2196 | 2205 | ||
| @@ -2592,8 +2601,9 @@ static int __ocfs2_xattr_set_handle(struct inode *inode, | |||
| 2592 | 2601 | ||
| 2593 | if (!ret) { | 2602 | if (!ret) { |
| 2594 | /* Update inode ctime. */ | 2603 | /* Update inode ctime. */ |
| 2595 | ret = ocfs2_journal_access(ctxt->handle, inode, xis->inode_bh, | 2604 | ret = ocfs2_journal_access_di(ctxt->handle, inode, |
| 2596 | OCFS2_JOURNAL_ACCESS_WRITE); | 2605 | xis->inode_bh, |
| 2606 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
| 2597 | if (ret) { | 2607 | if (ret) { |
| 2598 | mlog_errno(ret); | 2608 | mlog_errno(ret); |
| 2599 | goto out; | 2609 | goto out; |
| @@ -4785,19 +4795,33 @@ static int ocfs2_xattr_bucket_set_value_outside(struct inode *inode, | |||
| 4785 | char *val, | 4795 | char *val, |
| 4786 | int value_len) | 4796 | int value_len) |
| 4787 | { | 4797 | { |
| 4788 | int offset; | 4798 | int ret, offset, block_off; |
| 4789 | struct ocfs2_xattr_value_root *xv; | 4799 | struct ocfs2_xattr_value_root *xv; |
| 4790 | 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; | ||
| 4791 | 4803 | ||
| 4792 | BUG_ON(!xs->base || !xe || ocfs2_xattr_is_local(xe)); | 4804 | BUG_ON(!xs->base || !xe || ocfs2_xattr_is_local(xe)); |
| 4793 | 4805 | ||
| 4794 | offset = le16_to_cpu(xe->xe_name_offset) + | 4806 | ret = ocfs2_xattr_bucket_get_name_value(inode, xh, |
| 4795 | 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 | } | ||
| 4796 | 4814 | ||
| 4797 | 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)); | ||
| 4798 | 4818 | ||
| 4799 | return __ocfs2_xattr_set_value_outside(inode, handle, | 4819 | ret = __ocfs2_xattr_set_value_outside(inode, handle, |
| 4800 | xv, val, value_len); | 4820 | xv, val, value_len); |
| 4821 | if (ret) | ||
| 4822 | mlog_errno(ret); | ||
| 4823 | out: | ||
| 4824 | return ret; | ||
| 4801 | } | 4825 | } |
| 4802 | 4826 | ||
| 4803 | static int ocfs2_rm_xattr_cluster(struct inode *inode, | 4827 | static int ocfs2_rm_xattr_cluster(struct inode *inode, |
| @@ -5060,8 +5084,8 @@ try_again: | |||
| 5060 | xh_free_start = le16_to_cpu(xh->xh_free_start); | 5084 | xh_free_start = le16_to_cpu(xh->xh_free_start); |
| 5061 | header_size = sizeof(struct ocfs2_xattr_header) + | 5085 | header_size = sizeof(struct ocfs2_xattr_header) + |
| 5062 | count * sizeof(struct ocfs2_xattr_entry); | 5086 | count * sizeof(struct ocfs2_xattr_entry); |
| 5063 | max_free = OCFS2_XATTR_BUCKET_SIZE - | 5087 | max_free = OCFS2_XATTR_BUCKET_SIZE - header_size - |
| 5064 | le16_to_cpu(xh->xh_name_value_len) - header_size; | 5088 | le16_to_cpu(xh->xh_name_value_len) - OCFS2_XATTR_HEADER_GAP; |
| 5065 | 5089 | ||
| 5066 | mlog_bug_on_msg(header_size > blocksize, "bucket %llu has header size " | 5090 | mlog_bug_on_msg(header_size > blocksize, "bucket %llu has header size " |
| 5067 | "of %u which exceed block size\n", | 5091 | "of %u which exceed block size\n", |
| @@ -5094,7 +5118,7 @@ try_again: | |||
| 5094 | need = 0; | 5118 | need = 0; |
| 5095 | } | 5119 | } |
| 5096 | 5120 | ||
| 5097 | free = xh_free_start - header_size; | 5121 | free = xh_free_start - header_size - OCFS2_XATTR_HEADER_GAP; |
| 5098 | /* | 5122 | /* |
| 5099 | * We need to make sure the new name/value pair | 5123 | * We need to make sure the new name/value pair |
| 5100 | * can exist in the same block. | 5124 | * can exist in the same block. |
| @@ -5127,7 +5151,8 @@ try_again: | |||
| 5127 | } | 5151 | } |
| 5128 | 5152 | ||
| 5129 | xh_free_start = le16_to_cpu(xh->xh_free_start); | 5153 | xh_free_start = le16_to_cpu(xh->xh_free_start); |
| 5130 | free = xh_free_start - header_size; | 5154 | free = xh_free_start - header_size |
| 5155 | - OCFS2_XATTR_HEADER_GAP; | ||
| 5131 | if (xh_free_start % blocksize < need) | 5156 | if (xh_free_start % blocksize < need) |
| 5132 | free -= xh_free_start % blocksize; | 5157 | free -= xh_free_start % blocksize; |
| 5133 | 5158 | ||
| @@ -699,12 +699,12 @@ pipe_rdwr_fasync(int fd, struct file *filp, int on) | |||
| 699 | int retval; | 699 | int retval; |
| 700 | 700 | ||
| 701 | mutex_lock(&inode->i_mutex); | 701 | mutex_lock(&inode->i_mutex); |
| 702 | |||
| 703 | retval = fasync_helper(fd, filp, on, &pipe->fasync_readers); | 702 | retval = fasync_helper(fd, filp, on, &pipe->fasync_readers); |
| 704 | 703 | if (retval >= 0) { | |
| 705 | if (retval >= 0) | ||
| 706 | retval = fasync_helper(fd, filp, on, &pipe->fasync_writers); | 704 | retval = fasync_helper(fd, filp, on, &pipe->fasync_writers); |
| 707 | 705 | if (retval < 0) /* this can happen only if on == T */ | |
| 706 | fasync_helper(-1, filp, 0, &pipe->fasync_readers); | ||
| 707 | } | ||
| 708 | mutex_unlock(&inode->i_mutex); | 708 | mutex_unlock(&inode->i_mutex); |
| 709 | 709 | ||
| 710 | if (retval < 0) | 710 | if (retval < 0) |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 3e76bb9b3ad6..d8bb5c671f42 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
| @@ -485,8 +485,10 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, | |||
| 485 | } | 485 | } |
| 486 | } | 486 | } |
| 487 | unlock_new_inode(inode); | 487 | unlock_new_inode(inode); |
| 488 | } else | 488 | } else { |
| 489 | module_put(de->owner); | 489 | module_put(de->owner); |
| 490 | de_put(de); | ||
| 491 | } | ||
| 490 | return inode; | 492 | return inode; |
| 491 | 493 | ||
| 492 | out_ino: | 494 | out_ino: |
diff --git a/fs/proc/page.c b/fs/proc/page.c index 767d95a6d1b1..e9983837d08d 100644 --- a/fs/proc/page.c +++ b/fs/proc/page.c | |||
| @@ -80,7 +80,7 @@ static const struct file_operations proc_kpagecount_operations = { | |||
| 80 | #define KPF_RECLAIM 9 | 80 | #define KPF_RECLAIM 9 |
| 81 | #define KPF_BUDDY 10 | 81 | #define KPF_BUDDY 10 |
| 82 | 82 | ||
| 83 | #define kpf_copy_bit(flags, srcpos, dstpos) (((flags >> srcpos) & 1) << dstpos) | 83 | #define kpf_copy_bit(flags, dstpos, srcpos) (((flags >> srcpos) & 1) << dstpos) |
| 84 | 84 | ||
| 85 | static ssize_t kpageflags_read(struct file *file, char __user *buf, | 85 | static ssize_t kpageflags_read(struct file *file, char __user *buf, |
| 86 | size_t count, loff_t *ppos) | 86 | size_t count, loff_t *ppos) |
| @@ -107,7 +107,7 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf, | |||
| 107 | else | 107 | else |
| 108 | kflags = ppage->flags; | 108 | kflags = ppage->flags; |
| 109 | 109 | ||
| 110 | uflags = kpf_copy_bit(KPF_LOCKED, PG_locked, kflags) | | 110 | uflags = kpf_copy_bit(kflags, KPF_LOCKED, PG_locked) | |
| 111 | kpf_copy_bit(kflags, KPF_ERROR, PG_error) | | 111 | kpf_copy_bit(kflags, KPF_ERROR, PG_error) | |
| 112 | kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) | | 112 | kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) | |
| 113 | kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) | | 113 | kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) | |
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/seq_file.c b/fs/seq_file.c index 5267098532bf..a1a4cfe19210 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
| @@ -48,8 +48,16 @@ int seq_open(struct file *file, const struct seq_operations *op) | |||
| 48 | */ | 48 | */ |
| 49 | file->f_version = 0; | 49 | file->f_version = 0; |
| 50 | 50 | ||
| 51 | /* SEQ files support lseek, but not pread/pwrite */ | 51 | /* |
| 52 | file->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); | 52 | * seq_files support lseek() and pread(). They do not implement |
| 53 | * write() at all, but we clear FMODE_PWRITE here for historical | ||
| 54 | * reasons. | ||
| 55 | * | ||
| 56 | * If a client of seq_files a) implements file.write() and b) wishes to | ||
| 57 | * support pwrite() then that client will need to implement its own | ||
| 58 | * file.open() which calls seq_open() and then sets FMODE_PWRITE. | ||
| 59 | */ | ||
| 60 | file->f_mode &= ~FMODE_PWRITE; | ||
| 53 | return 0; | 61 | return 0; |
| 54 | } | 62 | } |
| 55 | EXPORT_SYMBOL(seq_open); | 63 | EXPORT_SYMBOL(seq_open); |
| @@ -131,6 +139,22 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) | |||
| 131 | int err = 0; | 139 | int err = 0; |
| 132 | 140 | ||
| 133 | mutex_lock(&m->lock); | 141 | mutex_lock(&m->lock); |
| 142 | |||
| 143 | /* Don't assume *ppos is where we left it */ | ||
| 144 | if (unlikely(*ppos != m->read_pos)) { | ||
| 145 | m->read_pos = *ppos; | ||
| 146 | while ((err = traverse(m, *ppos)) == -EAGAIN) | ||
| 147 | ; | ||
| 148 | if (err) { | ||
| 149 | /* With prejudice... */ | ||
| 150 | m->read_pos = 0; | ||
| 151 | m->version = 0; | ||
| 152 | m->index = 0; | ||
| 153 | m->count = 0; | ||
| 154 | goto Done; | ||
| 155 | } | ||
| 156 | } | ||
| 157 | |||
| 134 | /* | 158 | /* |
| 135 | * seq_file->op->..m_start/m_stop/m_next may do special actions | 159 | * seq_file->op->..m_start/m_stop/m_next may do special actions |
| 136 | * or optimisations based on the file->f_version, so we want to | 160 | * or optimisations based on the file->f_version, so we want to |
| @@ -230,8 +254,10 @@ Fill: | |||
| 230 | Done: | 254 | Done: |
| 231 | if (!copied) | 255 | if (!copied) |
| 232 | copied = err; | 256 | copied = err; |
| 233 | else | 257 | else { |
| 234 | *ppos += copied; | 258 | *ppos += copied; |
| 259 | m->read_pos += copied; | ||
| 260 | } | ||
| 235 | file->f_version = m->version; | 261 | file->f_version = m->version; |
| 236 | mutex_unlock(&m->lock); | 262 | mutex_unlock(&m->lock); |
| 237 | return copied; | 263 | return copied; |
| @@ -266,16 +292,18 @@ loff_t seq_lseek(struct file *file, loff_t offset, int origin) | |||
| 266 | if (offset < 0) | 292 | if (offset < 0) |
| 267 | break; | 293 | break; |
| 268 | retval = offset; | 294 | retval = offset; |
| 269 | if (offset != file->f_pos) { | 295 | if (offset != m->read_pos) { |
| 270 | while ((retval=traverse(m, offset)) == -EAGAIN) | 296 | while ((retval=traverse(m, offset)) == -EAGAIN) |
| 271 | ; | 297 | ; |
| 272 | if (retval) { | 298 | if (retval) { |
| 273 | /* with extreme prejudice... */ | 299 | /* with extreme prejudice... */ |
| 274 | file->f_pos = 0; | 300 | file->f_pos = 0; |
| 301 | m->read_pos = 0; | ||
| 275 | m->version = 0; | 302 | m->version = 0; |
| 276 | m->index = 0; | 303 | m->index = 0; |
| 277 | m->count = 0; | 304 | m->count = 0; |
| 278 | } else { | 305 | } else { |
| 306 | m->read_pos = offset; | ||
| 279 | retval = file->f_pos = offset; | 307 | retval = file->f_pos = offset; |
| 280 | } | 308 | } |
| 281 | } | 309 | } |
diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c index c837dfc2b3c6..2a7960310349 100644 --- a/fs/squashfs/block.c +++ b/fs/squashfs/block.c | |||
| @@ -80,7 +80,7 @@ static struct buffer_head *get_block_length(struct super_block *sb, | |||
| 80 | * generated a larger block - this does occasionally happen with zlib). | 80 | * generated a larger block - this does occasionally happen with zlib). |
| 81 | */ | 81 | */ |
| 82 | int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, | 82 | int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, |
| 83 | int length, u64 *next_index, int srclength) | 83 | int length, u64 *next_index, int srclength, int pages) |
| 84 | { | 84 | { |
| 85 | struct squashfs_sb_info *msblk = sb->s_fs_info; | 85 | struct squashfs_sb_info *msblk = sb->s_fs_info; |
| 86 | struct buffer_head **bh; | 86 | struct buffer_head **bh; |
| @@ -184,7 +184,7 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, | |||
| 184 | offset = 0; | 184 | offset = 0; |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | if (msblk->stream.avail_out == 0) { | 187 | if (msblk->stream.avail_out == 0 && page < pages) { |
| 188 | msblk->stream.next_out = buffer[page++]; | 188 | msblk->stream.next_out = buffer[page++]; |
| 189 | msblk->stream.avail_out = PAGE_CACHE_SIZE; | 189 | msblk->stream.avail_out = PAGE_CACHE_SIZE; |
| 190 | } | 190 | } |
| @@ -201,25 +201,20 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, | |||
| 201 | zlib_init = 1; | 201 | zlib_init = 1; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH); | 204 | zlib_err = zlib_inflate(&msblk->stream, Z_SYNC_FLUSH); |
| 205 | 205 | ||
| 206 | if (msblk->stream.avail_in == 0 && k < b) | 206 | if (msblk->stream.avail_in == 0 && k < b) |
| 207 | put_bh(bh[k++]); | 207 | put_bh(bh[k++]); |
| 208 | } while (zlib_err == Z_OK); | 208 | } while (zlib_err == Z_OK); |
| 209 | 209 | ||
| 210 | if (zlib_err != Z_STREAM_END) { | 210 | if (zlib_err != Z_STREAM_END) { |
| 211 | ERROR("zlib_inflate returned unexpected result" | 211 | ERROR("zlib_inflate error, data probably corrupt\n"); |
| 212 | " 0x%x, srclength %d, avail_in %d," | ||
| 213 | " avail_out %d\n", zlib_err, srclength, | ||
| 214 | msblk->stream.avail_in, | ||
| 215 | msblk->stream.avail_out); | ||
| 216 | goto release_mutex; | 212 | goto release_mutex; |
| 217 | } | 213 | } |
| 218 | 214 | ||
| 219 | zlib_err = zlib_inflateEnd(&msblk->stream); | 215 | zlib_err = zlib_inflateEnd(&msblk->stream); |
| 220 | if (zlib_err != Z_OK) { | 216 | if (zlib_err != Z_OK) { |
| 221 | ERROR("zlib_inflateEnd returned unexpected result 0x%x," | 217 | ERROR("zlib_inflate error, data probably corrupt\n"); |
| 222 | " srclength %d\n", zlib_err, srclength); | ||
| 223 | goto release_mutex; | 218 | goto release_mutex; |
| 224 | } | 219 | } |
| 225 | length = msblk->stream.total_out; | 220 | length = msblk->stream.total_out; |
| @@ -268,7 +263,8 @@ block_release: | |||
| 268 | put_bh(bh[k]); | 263 | put_bh(bh[k]); |
| 269 | 264 | ||
| 270 | read_failure: | 265 | read_failure: |
| 271 | ERROR("sb_bread failed reading block 0x%llx\n", cur_index); | 266 | ERROR("squashfs_read_data failed to read block 0x%llx\n", |
| 267 | (unsigned long long) index); | ||
| 272 | kfree(bh); | 268 | kfree(bh); |
| 273 | return -EIO; | 269 | return -EIO; |
| 274 | } | 270 | } |
diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c index f29eda16d25e..1c4739e33af6 100644 --- a/fs/squashfs/cache.c +++ b/fs/squashfs/cache.c | |||
| @@ -119,7 +119,7 @@ struct squashfs_cache_entry *squashfs_cache_get(struct super_block *sb, | |||
| 119 | 119 | ||
| 120 | entry->length = squashfs_read_data(sb, entry->data, | 120 | entry->length = squashfs_read_data(sb, entry->data, |
| 121 | block, length, &entry->next_index, | 121 | block, length, &entry->next_index, |
| 122 | cache->block_size); | 122 | cache->block_size, cache->pages); |
| 123 | 123 | ||
| 124 | spin_lock(&cache->lock); | 124 | spin_lock(&cache->lock); |
| 125 | 125 | ||
| @@ -406,7 +406,7 @@ int squashfs_read_table(struct super_block *sb, void *buffer, u64 block, | |||
| 406 | for (i = 0; i < pages; i++, buffer += PAGE_CACHE_SIZE) | 406 | for (i = 0; i < pages; i++, buffer += PAGE_CACHE_SIZE) |
| 407 | data[i] = buffer; | 407 | data[i] = buffer; |
| 408 | res = squashfs_read_data(sb, data, block, length | | 408 | res = squashfs_read_data(sb, data, block, length | |
| 409 | SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length); | 409 | SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length, pages); |
| 410 | kfree(data); | 410 | kfree(data); |
| 411 | return res; | 411 | return res; |
| 412 | } | 412 | } |
diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c index 7a63398bb855..9101dbde39ec 100644 --- a/fs/squashfs/inode.c +++ b/fs/squashfs/inode.c | |||
| @@ -133,7 +133,8 @@ int squashfs_read_inode(struct inode *inode, long long ino) | |||
| 133 | type = le16_to_cpu(sqshb_ino->inode_type); | 133 | type = le16_to_cpu(sqshb_ino->inode_type); |
| 134 | switch (type) { | 134 | switch (type) { |
| 135 | case SQUASHFS_REG_TYPE: { | 135 | case SQUASHFS_REG_TYPE: { |
| 136 | unsigned int frag_offset, frag_size, frag; | 136 | unsigned int frag_offset, frag; |
| 137 | int frag_size; | ||
| 137 | u64 frag_blk; | 138 | u64 frag_blk; |
| 138 | struct squashfs_reg_inode *sqsh_ino = &squashfs_ino.reg; | 139 | struct squashfs_reg_inode *sqsh_ino = &squashfs_ino.reg; |
| 139 | 140 | ||
| @@ -175,7 +176,8 @@ int squashfs_read_inode(struct inode *inode, long long ino) | |||
| 175 | break; | 176 | break; |
| 176 | } | 177 | } |
| 177 | case SQUASHFS_LREG_TYPE: { | 178 | case SQUASHFS_LREG_TYPE: { |
| 178 | unsigned int frag_offset, frag_size, frag; | 179 | unsigned int frag_offset, frag; |
| 180 | int frag_size; | ||
| 179 | u64 frag_blk; | 181 | u64 frag_blk; |
| 180 | struct squashfs_lreg_inode *sqsh_ino = &squashfs_ino.lreg; | 182 | struct squashfs_lreg_inode *sqsh_ino = &squashfs_ino.lreg; |
| 181 | 183 | ||
diff --git a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h index 6b2515d027d5..0e9feb6adf7e 100644 --- a/fs/squashfs/squashfs.h +++ b/fs/squashfs/squashfs.h | |||
| @@ -34,7 +34,7 @@ static inline struct squashfs_inode_info *squashfs_i(struct inode *inode) | |||
| 34 | 34 | ||
| 35 | /* block.c */ | 35 | /* block.c */ |
| 36 | extern int squashfs_read_data(struct super_block *, void **, u64, int, u64 *, | 36 | extern int squashfs_read_data(struct super_block *, void **, u64, int, u64 *, |
| 37 | int); | 37 | int, int); |
| 38 | 38 | ||
| 39 | /* cache.c */ | 39 | /* cache.c */ |
| 40 | extern struct squashfs_cache *squashfs_cache_init(char *, int, int); | 40 | extern struct squashfs_cache *squashfs_cache_init(char *, int, int); |
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index 071df5b5b491..681ec0d83799 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c | |||
| @@ -389,7 +389,7 @@ static int __init init_squashfs_fs(void) | |||
| 389 | return err; | 389 | return err; |
| 390 | } | 390 | } |
| 391 | 391 | ||
| 392 | printk(KERN_INFO "squashfs: version 4.0 (2009/01/03) " | 392 | printk(KERN_INFO "squashfs: version 4.0 (2009/01/31) " |
| 393 | "Phillip Lougher\n"); | 393 | "Phillip Lougher\n"); |
| 394 | 394 | ||
| 395 | return 0; | 395 | return 0; |
diff --git a/fs/super.c b/fs/super.c index 61dce001dd57..6ce501447ada 100644 --- a/fs/super.c +++ b/fs/super.c | |||
| @@ -82,7 +82,22 @@ static struct super_block *alloc_super(struct file_system_type *type) | |||
| 82 | * lock ordering than usbfs: | 82 | * lock ordering than usbfs: |
| 83 | */ | 83 | */ |
| 84 | lockdep_set_class(&s->s_lock, &type->s_lock_key); | 84 | lockdep_set_class(&s->s_lock, &type->s_lock_key); |
| 85 | down_write(&s->s_umount); | 85 | /* |
| 86 | * sget() can have s_umount recursion. | ||
| 87 | * | ||
| 88 | * When it cannot find a suitable sb, it allocates a new | ||
| 89 | * one (this one), and tries again to find a suitable old | ||
| 90 | * one. | ||
| 91 | * | ||
| 92 | * In case that succeeds, it will acquire the s_umount | ||
| 93 | * lock of the old one. Since these are clearly distrinct | ||
| 94 | * locks, and this object isn't exposed yet, there's no | ||
| 95 | * risk of deadlocks. | ||
| 96 | * | ||
| 97 | * Annotate this by putting this lock in a different | ||
| 98 | * subclass. | ||
| 99 | */ | ||
| 100 | down_write_nested(&s->s_umount, SINGLE_DEPTH_NESTING); | ||
| 86 | s->s_count = S_BIAS; | 101 | s->s_count = S_BIAS; |
| 87 | atomic_set(&s->s_active, 1); | 102 | atomic_set(&s->s_active, 1); |
| 88 | mutex_init(&s->s_vfs_rename_mutex); | 103 | mutex_init(&s->s_vfs_rename_mutex); |
| @@ -356,8 +371,10 @@ retry: | |||
| 356 | continue; | 371 | continue; |
| 357 | if (!grab_super(old)) | 372 | if (!grab_super(old)) |
| 358 | goto retry; | 373 | goto retry; |
| 359 | if (s) | 374 | if (s) { |
| 375 | up_write(&s->s_umount); | ||
| 360 | destroy_super(s); | 376 | destroy_super(s); |
| 377 | } | ||
| 361 | return old; | 378 | return old; |
| 362 | } | 379 | } |
| 363 | } | 380 | } |
| @@ -372,6 +389,7 @@ retry: | |||
| 372 | err = set(s, data); | 389 | err = set(s, data); |
| 373 | if (err) { | 390 | if (err) { |
| 374 | spin_unlock(&sb_lock); | 391 | spin_unlock(&sb_lock); |
| 392 | up_write(&s->s_umount); | ||
| 375 | destroy_super(s); | 393 | destroy_super(s); |
| 376 | return ERR_PTR(err); | 394 | return ERR_PTR(err); |
| 377 | } | 395 | } |
diff --git a/fs/timerfd.c b/fs/timerfd.c index 6a123b8ff3f5..b042bd7034b1 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c | |||
| @@ -186,10 +186,9 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) | |||
| 186 | BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC); | 186 | BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC); |
| 187 | BUILD_BUG_ON(TFD_NONBLOCK != O_NONBLOCK); | 187 | BUILD_BUG_ON(TFD_NONBLOCK != O_NONBLOCK); |
| 188 | 188 | ||
| 189 | if (flags & ~(TFD_CLOEXEC | TFD_NONBLOCK)) | 189 | if ((flags & ~TFD_CREATE_FLAGS) || |
| 190 | return -EINVAL; | 190 | (clockid != CLOCK_MONOTONIC && |
| 191 | if (clockid != CLOCK_MONOTONIC && | 191 | clockid != CLOCK_REALTIME)) |
| 192 | clockid != CLOCK_REALTIME) | ||
| 193 | return -EINVAL; | 192 | return -EINVAL; |
| 194 | 193 | ||
| 195 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | 194 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); |
| @@ -201,7 +200,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) | |||
| 201 | hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS); | 200 | hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS); |
| 202 | 201 | ||
| 203 | ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx, | 202 | ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx, |
| 204 | flags & (O_CLOEXEC | O_NONBLOCK)); | 203 | flags & TFD_SHARED_FCNTL_FLAGS); |
| 205 | if (ufd < 0) | 204 | if (ufd < 0) |
| 206 | kfree(ctx); | 205 | kfree(ctx); |
| 207 | 206 | ||
| @@ -219,7 +218,8 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
| 219 | if (copy_from_user(&ktmr, utmr, sizeof(ktmr))) | 218 | if (copy_from_user(&ktmr, utmr, sizeof(ktmr))) |
| 220 | return -EFAULT; | 219 | return -EFAULT; |
| 221 | 220 | ||
| 222 | if (!timespec_valid(&ktmr.it_value) || | 221 | if ((flags & ~TFD_SETTIME_FLAGS) || |
| 222 | !timespec_valid(&ktmr.it_value) || | ||
| 223 | !timespec_valid(&ktmr.it_interval)) | 223 | !timespec_valid(&ktmr.it_interval)) |
| 224 | return -EINVAL; | 224 | return -EINVAL; |
| 225 | 225 | ||
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index d71dc44e21ed..aa1016bb9134 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
| @@ -34,6 +34,12 @@ | |||
| 34 | #include <linux/backing-dev.h> | 34 | #include <linux/backing-dev.h> |
| 35 | #include <linux/freezer.h> | 35 | #include <linux/freezer.h> |
| 36 | 36 | ||
| 37 | #include "xfs_sb.h" | ||
| 38 | #include "xfs_inum.h" | ||
| 39 | #include "xfs_ag.h" | ||
| 40 | #include "xfs_dmapi.h" | ||
| 41 | #include "xfs_mount.h" | ||
| 42 | |||
| 37 | static kmem_zone_t *xfs_buf_zone; | 43 | static kmem_zone_t *xfs_buf_zone; |
| 38 | STATIC int xfsbufd(void *); | 44 | STATIC int xfsbufd(void *); |
| 39 | STATIC int xfsbufd_wakeup(int, gfp_t); | 45 | STATIC int xfsbufd_wakeup(int, gfp_t); |
| @@ -166,6 +172,75 @@ test_page_region( | |||
| 166 | } | 172 | } |
| 167 | 173 | ||
| 168 | /* | 174 | /* |
| 175 | * Mapping of multi-page buffers into contiguous virtual space | ||
| 176 | */ | ||
| 177 | |||
| 178 | typedef struct a_list { | ||
| 179 | void *vm_addr; | ||
| 180 | struct a_list *next; | ||
| 181 | } a_list_t; | ||
| 182 | |||
| 183 | static a_list_t *as_free_head; | ||
| 184 | static int as_list_len; | ||
| 185 | static DEFINE_SPINLOCK(as_lock); | ||
| 186 | |||
| 187 | /* | ||
| 188 | * Try to batch vunmaps because they are costly. | ||
| 189 | */ | ||
| 190 | STATIC void | ||
| 191 | free_address( | ||
| 192 | void *addr) | ||
| 193 | { | ||
| 194 | a_list_t *aentry; | ||
| 195 | |||
| 196 | #ifdef CONFIG_XEN | ||
| 197 | /* | ||
| 198 | * Xen needs to be able to make sure it can get an exclusive | ||
| 199 | * RO mapping of pages it wants to turn into a pagetable. If | ||
| 200 | * a newly allocated page is also still being vmap()ed by xfs, | ||
| 201 | * it will cause pagetable construction to fail. This is a | ||
| 202 | * quick workaround to always eagerly unmap pages so that Xen | ||
| 203 | * is happy. | ||
| 204 | */ | ||
| 205 | vunmap(addr); | ||
| 206 | return; | ||
| 207 | #endif | ||
| 208 | |||
| 209 | aentry = kmalloc(sizeof(a_list_t), GFP_NOWAIT); | ||
| 210 | if (likely(aentry)) { | ||
| 211 | spin_lock(&as_lock); | ||
| 212 | aentry->next = as_free_head; | ||
| 213 | aentry->vm_addr = addr; | ||
| 214 | as_free_head = aentry; | ||
| 215 | as_list_len++; | ||
| 216 | spin_unlock(&as_lock); | ||
| 217 | } else { | ||
| 218 | vunmap(addr); | ||
| 219 | } | ||
| 220 | } | ||
| 221 | |||
| 222 | STATIC void | ||
| 223 | purge_addresses(void) | ||
| 224 | { | ||
| 225 | a_list_t *aentry, *old; | ||
| 226 | |||
| 227 | if (as_free_head == NULL) | ||
| 228 | return; | ||
| 229 | |||
| 230 | spin_lock(&as_lock); | ||
| 231 | aentry = as_free_head; | ||
| 232 | as_free_head = NULL; | ||
| 233 | as_list_len = 0; | ||
| 234 | spin_unlock(&as_lock); | ||
| 235 | |||
| 236 | while ((old = aentry) != NULL) { | ||
| 237 | vunmap(aentry->vm_addr); | ||
| 238 | aentry = aentry->next; | ||
| 239 | kfree(old); | ||
| 240 | } | ||
| 241 | } | ||
| 242 | |||
| 243 | /* | ||
| 169 | * Internal xfs_buf_t object manipulation | 244 | * Internal xfs_buf_t object manipulation |
| 170 | */ | 245 | */ |
| 171 | 246 | ||
| @@ -264,7 +339,7 @@ xfs_buf_free( | |||
| 264 | uint i; | 339 | uint i; |
| 265 | 340 | ||
| 266 | if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1)) | 341 | if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1)) |
| 267 | vm_unmap_ram(bp->b_addr - bp->b_offset, bp->b_page_count); | 342 | free_address(bp->b_addr - bp->b_offset); |
| 268 | 343 | ||
| 269 | for (i = 0; i < bp->b_page_count; i++) { | 344 | for (i = 0; i < bp->b_page_count; i++) { |
| 270 | struct page *page = bp->b_pages[i]; | 345 | struct page *page = bp->b_pages[i]; |
| @@ -386,8 +461,10 @@ _xfs_buf_map_pages( | |||
| 386 | bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset; | 461 | bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset; |
| 387 | bp->b_flags |= XBF_MAPPED; | 462 | bp->b_flags |= XBF_MAPPED; |
| 388 | } else if (flags & XBF_MAPPED) { | 463 | } else if (flags & XBF_MAPPED) { |
| 389 | bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count, | 464 | if (as_list_len > 64) |
| 390 | -1, PAGE_KERNEL); | 465 | purge_addresses(); |
| 466 | bp->b_addr = vmap(bp->b_pages, bp->b_page_count, | ||
| 467 | VM_MAP, PAGE_KERNEL); | ||
| 391 | if (unlikely(bp->b_addr == NULL)) | 468 | if (unlikely(bp->b_addr == NULL)) |
| 392 | return -ENOMEM; | 469 | return -ENOMEM; |
| 393 | bp->b_addr += bp->b_offset; | 470 | bp->b_addr += bp->b_offset; |
| @@ -1364,10 +1441,12 @@ xfs_unregister_buftarg( | |||
| 1364 | 1441 | ||
| 1365 | void | 1442 | void |
| 1366 | xfs_free_buftarg( | 1443 | xfs_free_buftarg( |
| 1367 | xfs_buftarg_t *btp) | 1444 | struct xfs_mount *mp, |
| 1445 | struct xfs_buftarg *btp) | ||
| 1368 | { | 1446 | { |
| 1369 | xfs_flush_buftarg(btp, 1); | 1447 | xfs_flush_buftarg(btp, 1); |
| 1370 | xfs_blkdev_issue_flush(btp); | 1448 | if (mp->m_flags & XFS_MOUNT_BARRIER) |
| 1449 | xfs_blkdev_issue_flush(btp); | ||
| 1371 | xfs_free_bufhash(btp); | 1450 | xfs_free_bufhash(btp); |
| 1372 | iput(btp->bt_mapping->host); | 1451 | iput(btp->bt_mapping->host); |
| 1373 | 1452 | ||
| @@ -1672,6 +1751,8 @@ xfsbufd( | |||
| 1672 | count++; | 1751 | count++; |
| 1673 | } | 1752 | } |
| 1674 | 1753 | ||
| 1754 | if (as_list_len > 0) | ||
| 1755 | purge_addresses(); | ||
| 1675 | if (count) | 1756 | if (count) |
| 1676 | blk_run_address_space(target->bt_mapping); | 1757 | blk_run_address_space(target->bt_mapping); |
| 1677 | 1758 | ||
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 288ae7c4c800..9b4d666ad31f 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
| @@ -413,7 +413,7 @@ static inline int XFS_bwrite(xfs_buf_t *bp) | |||
| 413 | * Handling of buftargs. | 413 | * Handling of buftargs. |
| 414 | */ | 414 | */ |
| 415 | extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int); | 415 | extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *, int); |
| 416 | extern void xfs_free_buftarg(xfs_buftarg_t *); | 416 | extern void xfs_free_buftarg(struct xfs_mount *, struct xfs_buftarg *); |
| 417 | extern void xfs_wait_buftarg(xfs_buftarg_t *); | 417 | extern void xfs_wait_buftarg(xfs_buftarg_t *); |
| 418 | extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); | 418 | extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); |
| 419 | extern int xfs_flush_buftarg(xfs_buftarg_t *, int); | 419 | extern int xfs_flush_buftarg(xfs_buftarg_t *, int); |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index c71e226da7f5..32ae5028e96b 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
| @@ -734,15 +734,15 @@ xfs_close_devices( | |||
| 734 | { | 734 | { |
| 735 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { | 735 | if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) { |
| 736 | struct block_device *logdev = mp->m_logdev_targp->bt_bdev; | 736 | struct block_device *logdev = mp->m_logdev_targp->bt_bdev; |
| 737 | xfs_free_buftarg(mp->m_logdev_targp); | 737 | xfs_free_buftarg(mp, mp->m_logdev_targp); |
| 738 | xfs_blkdev_put(logdev); | 738 | xfs_blkdev_put(logdev); |
| 739 | } | 739 | } |
| 740 | if (mp->m_rtdev_targp) { | 740 | if (mp->m_rtdev_targp) { |
| 741 | struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev; | 741 | struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev; |
| 742 | xfs_free_buftarg(mp->m_rtdev_targp); | 742 | xfs_free_buftarg(mp, mp->m_rtdev_targp); |
| 743 | xfs_blkdev_put(rtdev); | 743 | xfs_blkdev_put(rtdev); |
| 744 | } | 744 | } |
| 745 | xfs_free_buftarg(mp->m_ddev_targp); | 745 | xfs_free_buftarg(mp, mp->m_ddev_targp); |
| 746 | } | 746 | } |
| 747 | 747 | ||
| 748 | /* | 748 | /* |
| @@ -811,9 +811,9 @@ xfs_open_devices( | |||
| 811 | 811 | ||
| 812 | out_free_rtdev_targ: | 812 | out_free_rtdev_targ: |
| 813 | if (mp->m_rtdev_targp) | 813 | if (mp->m_rtdev_targp) |
| 814 | xfs_free_buftarg(mp->m_rtdev_targp); | 814 | xfs_free_buftarg(mp, mp->m_rtdev_targp); |
| 815 | out_free_ddev_targ: | 815 | out_free_ddev_targ: |
| 816 | xfs_free_buftarg(mp->m_ddev_targp); | 816 | xfs_free_buftarg(mp, mp->m_ddev_targp); |
| 817 | out_close_rtdev: | 817 | out_close_rtdev: |
| 818 | if (rtdev) | 818 | if (rtdev) |
| 819 | xfs_blkdev_put(rtdev); | 819 | xfs_blkdev_put(rtdev); |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index e2fb6210d4c5..478e587087fe 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
| @@ -246,9 +246,6 @@ xfs_iget_cache_miss( | |||
| 246 | goto out_destroy; | 246 | goto out_destroy; |
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | if (lock_flags) | ||
| 250 | xfs_ilock(ip, lock_flags); | ||
| 251 | |||
| 252 | /* | 249 | /* |
| 253 | * Preload the radix tree so we can insert safely under the | 250 | * Preload the radix tree so we can insert safely under the |
| 254 | * write spinlock. Note that we cannot sleep inside the preload | 251 | * write spinlock. Note that we cannot sleep inside the preload |
| @@ -256,7 +253,16 @@ xfs_iget_cache_miss( | |||
| 256 | */ | 253 | */ |
| 257 | if (radix_tree_preload(GFP_KERNEL)) { | 254 | if (radix_tree_preload(GFP_KERNEL)) { |
| 258 | error = EAGAIN; | 255 | error = EAGAIN; |
| 259 | goto out_unlock; | 256 | goto out_destroy; |
| 257 | } | ||
| 258 | |||
| 259 | /* | ||
| 260 | * Because the inode hasn't been added to the radix-tree yet it can't | ||
| 261 | * be found by another thread, so we can do the non-sleeping lock here. | ||
| 262 | */ | ||
| 263 | if (lock_flags) { | ||
| 264 | if (!xfs_ilock_nowait(ip, lock_flags)) | ||
| 265 | BUG(); | ||
| 260 | } | 266 | } |
| 261 | 267 | ||
| 262 | mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); | 268 | mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); |
| @@ -284,7 +290,6 @@ xfs_iget_cache_miss( | |||
| 284 | out_preload_end: | 290 | out_preload_end: |
| 285 | write_unlock(&pag->pag_ici_lock); | 291 | write_unlock(&pag->pag_ici_lock); |
| 286 | radix_tree_preload_end(); | 292 | radix_tree_preload_end(); |
| 287 | out_unlock: | ||
| 288 | if (lock_flags) | 293 | if (lock_flags) |
| 289 | xfs_iunlock(ip, lock_flags); | 294 | xfs_iunlock(ip, lock_flags); |
| 290 | out_destroy: | 295 | out_destroy: |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index b1047de2fffd..61af610d79b3 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
| @@ -1455,10 +1455,19 @@ xlog_recover_add_to_trans( | |||
| 1455 | item = item->ri_prev; | 1455 | item = item->ri_prev; |
| 1456 | 1456 | ||
| 1457 | if (item->ri_total == 0) { /* first region to be added */ | 1457 | if (item->ri_total == 0) { /* first region to be added */ |
| 1458 | item->ri_total = in_f->ilf_size; | 1458 | if (in_f->ilf_size == 0 || |
| 1459 | ASSERT(item->ri_total <= XLOG_MAX_REGIONS_IN_ITEM); | 1459 | in_f->ilf_size > XLOG_MAX_REGIONS_IN_ITEM) { |
| 1460 | item->ri_buf = kmem_zalloc((item->ri_total * | 1460 | xlog_warn( |
| 1461 | sizeof(xfs_log_iovec_t)), KM_SLEEP); | 1461 | "XFS: bad number of regions (%d) in inode log format", |
| 1462 | in_f->ilf_size); | ||
| 1463 | ASSERT(0); | ||
| 1464 | return XFS_ERROR(EIO); | ||
| 1465 | } | ||
| 1466 | |||
| 1467 | item->ri_total = in_f->ilf_size; | ||
| 1468 | item->ri_buf = | ||
| 1469 | kmem_zalloc(item->ri_total * sizeof(xfs_log_iovec_t), | ||
| 1470 | KM_SLEEP); | ||
| 1462 | } | 1471 | } |
| 1463 | ASSERT(item->ri_total > item->ri_cnt); | 1472 | ASSERT(item->ri_total > item->ri_cnt); |
| 1464 | /* Description region is ri_buf[0] */ | 1473 | /* Description region is ri_buf[0] */ |
