diff options
Diffstat (limited to 'fs')
44 files changed, 652 insertions, 211 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 3e074dab2d57..9ac2eca681eb 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -1467,8 +1467,11 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, | |||
| 1467 | if (ret && !insert) { | 1467 | if (ret && !insert) { |
| 1468 | err = -ENOENT; | 1468 | err = -ENOENT; |
| 1469 | goto out; | 1469 | goto out; |
| 1470 | } else if (ret) { | ||
| 1471 | err = -EIO; | ||
| 1472 | WARN_ON(1); | ||
| 1473 | goto out; | ||
| 1470 | } | 1474 | } |
| 1471 | BUG_ON(ret); /* Corruption */ | ||
| 1472 | 1475 | ||
| 1473 | leaf = path->nodes[0]; | 1476 | leaf = path->nodes[0]; |
| 1474 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); | 1477 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index af1d0605a5c1..5b4ea5f55b8f 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -591,6 +591,7 @@ void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | |||
| 591 | } | 591 | } |
| 592 | compressed = test_bit(EXTENT_FLAG_COMPRESSED, &em->flags); | 592 | compressed = test_bit(EXTENT_FLAG_COMPRESSED, &em->flags); |
| 593 | clear_bit(EXTENT_FLAG_PINNED, &em->flags); | 593 | clear_bit(EXTENT_FLAG_PINNED, &em->flags); |
| 594 | clear_bit(EXTENT_FLAG_LOGGING, &flags); | ||
| 594 | remove_extent_mapping(em_tree, em); | 595 | remove_extent_mapping(em_tree, em); |
| 595 | if (no_splits) | 596 | if (no_splits) |
| 596 | goto next; | 597 | goto next; |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d1470adca8f8..ca1b767d51f7 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -2312,6 +2312,7 @@ again: | |||
| 2312 | key.type = BTRFS_EXTENT_DATA_KEY; | 2312 | key.type = BTRFS_EXTENT_DATA_KEY; |
| 2313 | key.offset = start; | 2313 | key.offset = start; |
| 2314 | 2314 | ||
| 2315 | path->leave_spinning = 1; | ||
| 2315 | if (merge) { | 2316 | if (merge) { |
| 2316 | struct btrfs_file_extent_item *fi; | 2317 | struct btrfs_file_extent_item *fi; |
| 2317 | u64 extent_len; | 2318 | u64 extent_len; |
| @@ -2368,6 +2369,7 @@ again: | |||
| 2368 | 2369 | ||
| 2369 | btrfs_mark_buffer_dirty(leaf); | 2370 | btrfs_mark_buffer_dirty(leaf); |
| 2370 | inode_add_bytes(inode, len); | 2371 | inode_add_bytes(inode, len); |
| 2372 | btrfs_release_path(path); | ||
| 2371 | 2373 | ||
| 2372 | ret = btrfs_inc_extent_ref(trans, root, new->bytenr, | 2374 | ret = btrfs_inc_extent_ref(trans, root, new->bytenr, |
| 2373 | new->disk_len, 0, | 2375 | new->disk_len, 0, |
| @@ -2381,6 +2383,7 @@ again: | |||
| 2381 | ret = 1; | 2383 | ret = 1; |
| 2382 | out_free_path: | 2384 | out_free_path: |
| 2383 | btrfs_release_path(path); | 2385 | btrfs_release_path(path); |
| 2386 | path->leave_spinning = 0; | ||
| 2384 | btrfs_end_transaction(trans, root); | 2387 | btrfs_end_transaction(trans, root); |
| 2385 | out_unlock: | 2388 | out_unlock: |
| 2386 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, lock_start, lock_end, | 2389 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, lock_start, lock_end, |
diff --git a/fs/btrfs/locking.h b/fs/btrfs/locking.h index ca52681e5f40..b81e0e9a4894 100644 --- a/fs/btrfs/locking.h +++ b/fs/btrfs/locking.h | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | 26 | ||
| 27 | void btrfs_tree_lock(struct extent_buffer *eb); | 27 | void btrfs_tree_lock(struct extent_buffer *eb); |
| 28 | void btrfs_tree_unlock(struct extent_buffer *eb); | 28 | void btrfs_tree_unlock(struct extent_buffer *eb); |
| 29 | int btrfs_try_spin_lock(struct extent_buffer *eb); | ||
| 30 | 29 | ||
| 31 | void btrfs_tree_read_lock(struct extent_buffer *eb); | 30 | void btrfs_tree_read_lock(struct extent_buffer *eb); |
| 32 | void btrfs_tree_read_unlock(struct extent_buffer *eb); | 31 | void btrfs_tree_read_unlock(struct extent_buffer *eb); |
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index aee4b1cc3d98..5471e47d6559 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c | |||
| @@ -1525,21 +1525,23 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes) | |||
| 1525 | 1525 | ||
| 1526 | if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) && | 1526 | if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) && |
| 1527 | qg->reserved + qg->rfer + num_bytes > | 1527 | qg->reserved + qg->rfer + num_bytes > |
| 1528 | qg->max_rfer) | 1528 | qg->max_rfer) { |
| 1529 | ret = -EDQUOT; | 1529 | ret = -EDQUOT; |
| 1530 | goto out; | ||
| 1531 | } | ||
| 1530 | 1532 | ||
| 1531 | if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) && | 1533 | if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) && |
| 1532 | qg->reserved + qg->excl + num_bytes > | 1534 | qg->reserved + qg->excl + num_bytes > |
| 1533 | qg->max_excl) | 1535 | qg->max_excl) { |
| 1534 | ret = -EDQUOT; | 1536 | ret = -EDQUOT; |
| 1537 | goto out; | ||
| 1538 | } | ||
| 1535 | 1539 | ||
| 1536 | list_for_each_entry(glist, &qg->groups, next_group) { | 1540 | list_for_each_entry(glist, &qg->groups, next_group) { |
| 1537 | ulist_add(ulist, glist->group->qgroupid, | 1541 | ulist_add(ulist, glist->group->qgroupid, |
| 1538 | (uintptr_t)glist->group, GFP_ATOMIC); | 1542 | (uintptr_t)glist->group, GFP_ATOMIC); |
| 1539 | } | 1543 | } |
| 1540 | } | 1544 | } |
| 1541 | if (ret) | ||
| 1542 | goto out; | ||
| 1543 | 1545 | ||
| 1544 | /* | 1546 | /* |
| 1545 | * no limits exceeded, now record the reservation into all qgroups | 1547 | * no limits exceeded, now record the reservation into all qgroups |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 9250b9c4f01e..50767bbaad6c 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -625,14 +625,13 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
| 625 | 625 | ||
| 626 | btrfs_trans_release_metadata(trans, root); | 626 | btrfs_trans_release_metadata(trans, root); |
| 627 | trans->block_rsv = NULL; | 627 | trans->block_rsv = NULL; |
| 628 | /* | ||
| 629 | * the same root has to be passed to start_transaction and | ||
| 630 | * end_transaction. Subvolume quota depends on this. | ||
| 631 | */ | ||
| 632 | WARN_ON(trans->root != root); | ||
| 633 | 628 | ||
| 634 | if (trans->qgroup_reserved) { | 629 | if (trans->qgroup_reserved) { |
| 635 | btrfs_qgroup_free(root, trans->qgroup_reserved); | 630 | /* |
| 631 | * the same root has to be passed here between start_transaction | ||
| 632 | * and end_transaction. Subvolume quota depends on this. | ||
| 633 | */ | ||
| 634 | btrfs_qgroup_free(trans->root, trans->qgroup_reserved); | ||
| 636 | trans->qgroup_reserved = 0; | 635 | trans->qgroup_reserved = 0; |
| 637 | } | 636 | } |
| 638 | 637 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 6b9cff42265d..5989a92236f7 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -684,6 +684,12 @@ int btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | |||
| 684 | __btrfs_close_devices(fs_devices); | 684 | __btrfs_close_devices(fs_devices); |
| 685 | free_fs_devices(fs_devices); | 685 | free_fs_devices(fs_devices); |
| 686 | } | 686 | } |
| 687 | /* | ||
| 688 | * Wait for rcu kworkers under __btrfs_close_devices | ||
| 689 | * to finish all blkdev_puts so device is really | ||
| 690 | * free when umount is done. | ||
| 691 | */ | ||
| 692 | rcu_barrier(); | ||
| 687 | return ret; | 693 | return ret; |
| 688 | } | 694 | } |
| 689 | 695 | ||
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index cfd1ce34e0bc..1d36db114772 100644 --- a/fs/cifs/asn1.c +++ b/fs/cifs/asn1.c | |||
| @@ -614,53 +614,10 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
| 614 | } | 614 | } |
| 615 | } | 615 | } |
| 616 | 616 | ||
| 617 | /* mechlistMIC */ | 617 | /* |
| 618 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 618 | * We currently ignore anything at the end of the SPNEGO blob after |
| 619 | /* Check if we have reached the end of the blob, but with | 619 | * the mechTypes have been parsed, since none of that info is |
| 620 | no mechListMic (e.g. NTLMSSP instead of KRB5) */ | 620 | * used at the moment. |
| 621 | if (ctx.error == ASN1_ERR_DEC_EMPTY) | 621 | */ |
| 622 | goto decode_negtoken_exit; | ||
| 623 | cFYI(1, "Error decoding last part negTokenInit exit3"); | ||
| 624 | return 0; | ||
| 625 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { | ||
| 626 | /* tag = 3 indicating mechListMIC */ | ||
| 627 | cFYI(1, "Exit 4 cls = %d con = %d tag = %d end = %p (%d)", | ||
| 628 | cls, con, tag, end, *end); | ||
| 629 | return 0; | ||
| 630 | } | ||
| 631 | |||
| 632 | /* sequence */ | ||
| 633 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | ||
| 634 | cFYI(1, "Error decoding last part negTokenInit exit5"); | ||
| 635 | return 0; | ||
| 636 | } else if ((cls != ASN1_UNI) || (con != ASN1_CON) | ||
| 637 | || (tag != ASN1_SEQ)) { | ||
| 638 | cFYI(1, "cls = %d con = %d tag = %d end = %p (%d)", | ||
| 639 | cls, con, tag, end, *end); | ||
| 640 | } | ||
| 641 | |||
| 642 | /* sequence of */ | ||
| 643 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | ||
| 644 | cFYI(1, "Error decoding last part negTokenInit exit 7"); | ||
| 645 | return 0; | ||
| 646 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { | ||
| 647 | cFYI(1, "Exit 8 cls = %d con = %d tag = %d end = %p (%d)", | ||
| 648 | cls, con, tag, end, *end); | ||
| 649 | return 0; | ||
| 650 | } | ||
| 651 | |||
| 652 | /* general string */ | ||
| 653 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | ||
| 654 | cFYI(1, "Error decoding last part negTokenInit exit9"); | ||
| 655 | return 0; | ||
| 656 | } else if ((cls != ASN1_UNI) || (con != ASN1_PRI) | ||
| 657 | || (tag != ASN1_GENSTR)) { | ||
| 658 | cFYI(1, "Exit10 cls = %d con = %d tag = %d end = %p (%d)", | ||
| 659 | cls, con, tag, end, *end); | ||
| 660 | return 0; | ||
| 661 | } | ||
| 662 | cFYI(1, "Need to call asn1_octets_decode() function for %s", | ||
| 663 | ctx.pointer); /* is this UTF-8 or ASCII? */ | ||
| 664 | decode_negtoken_exit: | ||
| 665 | return 1; | 622 | return 1; |
| 666 | } | 623 | } |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 1a052c0eee8e..345fc89c4286 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -91,6 +91,30 @@ struct workqueue_struct *cifsiod_wq; | |||
| 91 | __u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE]; | 91 | __u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE]; |
| 92 | #endif | 92 | #endif |
| 93 | 93 | ||
| 94 | /* | ||
| 95 | * Bumps refcount for cifs super block. | ||
| 96 | * Note that it should be only called if a referece to VFS super block is | ||
| 97 | * already held, e.g. in open-type syscalls context. Otherwise it can race with | ||
| 98 | * atomic_dec_and_test in deactivate_locked_super. | ||
| 99 | */ | ||
| 100 | void | ||
| 101 | cifs_sb_active(struct super_block *sb) | ||
| 102 | { | ||
| 103 | struct cifs_sb_info *server = CIFS_SB(sb); | ||
| 104 | |||
| 105 | if (atomic_inc_return(&server->active) == 1) | ||
| 106 | atomic_inc(&sb->s_active); | ||
| 107 | } | ||
| 108 | |||
| 109 | void | ||
| 110 | cifs_sb_deactive(struct super_block *sb) | ||
| 111 | { | ||
| 112 | struct cifs_sb_info *server = CIFS_SB(sb); | ||
| 113 | |||
| 114 | if (atomic_dec_and_test(&server->active)) | ||
| 115 | deactivate_super(sb); | ||
| 116 | } | ||
| 117 | |||
| 94 | static int | 118 | static int |
| 95 | cifs_read_super(struct super_block *sb) | 119 | cifs_read_super(struct super_block *sb) |
| 96 | { | 120 | { |
| @@ -777,6 +801,7 @@ struct file_system_type cifs_fs_type = { | |||
| 777 | .kill_sb = cifs_kill_sb, | 801 | .kill_sb = cifs_kill_sb, |
| 778 | /* .fs_flags */ | 802 | /* .fs_flags */ |
| 779 | }; | 803 | }; |
| 804 | MODULE_ALIAS_FS("cifs"); | ||
| 780 | const struct inode_operations cifs_dir_inode_ops = { | 805 | const struct inode_operations cifs_dir_inode_ops = { |
| 781 | .create = cifs_create, | 806 | .create = cifs_create, |
| 782 | .atomic_open = cifs_atomic_open, | 807 | .atomic_open = cifs_atomic_open, |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 7163419cecd9..0e32c3446ce9 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
| @@ -41,6 +41,10 @@ extern struct file_system_type cifs_fs_type; | |||
| 41 | extern const struct address_space_operations cifs_addr_ops; | 41 | extern const struct address_space_operations cifs_addr_ops; |
| 42 | extern const struct address_space_operations cifs_addr_ops_smallbuf; | 42 | extern const struct address_space_operations cifs_addr_ops_smallbuf; |
| 43 | 43 | ||
| 44 | /* Functions related to super block operations */ | ||
| 45 | extern void cifs_sb_active(struct super_block *sb); | ||
| 46 | extern void cifs_sb_deactive(struct super_block *sb); | ||
| 47 | |||
| 44 | /* Functions related to inodes */ | 48 | /* Functions related to inodes */ |
| 45 | extern const struct inode_operations cifs_dir_inode_ops; | 49 | extern const struct inode_operations cifs_dir_inode_ops; |
| 46 | extern struct inode *cifs_root_iget(struct super_block *); | 50 | extern struct inode *cifs_root_iget(struct super_block *); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 8c0d85577314..7a0dd99e4507 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -300,6 +300,8 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, | |||
| 300 | INIT_WORK(&cfile->oplock_break, cifs_oplock_break); | 300 | INIT_WORK(&cfile->oplock_break, cifs_oplock_break); |
| 301 | mutex_init(&cfile->fh_mutex); | 301 | mutex_init(&cfile->fh_mutex); |
| 302 | 302 | ||
| 303 | cifs_sb_active(inode->i_sb); | ||
| 304 | |||
| 303 | /* | 305 | /* |
| 304 | * If the server returned a read oplock and we have mandatory brlocks, | 306 | * If the server returned a read oplock and we have mandatory brlocks, |
| 305 | * set oplock level to None. | 307 | * set oplock level to None. |
| @@ -349,7 +351,8 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) | |||
| 349 | struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink); | 351 | struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink); |
| 350 | struct TCP_Server_Info *server = tcon->ses->server; | 352 | struct TCP_Server_Info *server = tcon->ses->server; |
| 351 | struct cifsInodeInfo *cifsi = CIFS_I(inode); | 353 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
| 352 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 354 | struct super_block *sb = inode->i_sb; |
| 355 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | ||
| 353 | struct cifsLockInfo *li, *tmp; | 356 | struct cifsLockInfo *li, *tmp; |
| 354 | struct cifs_fid fid; | 357 | struct cifs_fid fid; |
| 355 | struct cifs_pending_open open; | 358 | struct cifs_pending_open open; |
| @@ -414,6 +417,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) | |||
| 414 | 417 | ||
| 415 | cifs_put_tlink(cifs_file->tlink); | 418 | cifs_put_tlink(cifs_file->tlink); |
| 416 | dput(cifs_file->dentry); | 419 | dput(cifs_file->dentry); |
| 420 | cifs_sb_deactive(sb); | ||
| 417 | kfree(cifs_file); | 421 | kfree(cifs_file); |
| 418 | } | 422 | } |
| 419 | 423 | ||
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 0079696305c9..20887bf63121 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -1043,7 +1043,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry, | |||
| 1043 | cifs_sb->mnt_cifs_flags & | 1043 | cifs_sb->mnt_cifs_flags & |
| 1044 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1044 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
| 1045 | if (rc != 0) { | 1045 | if (rc != 0) { |
| 1046 | rc = -ETXTBSY; | 1046 | rc = -EBUSY; |
| 1047 | goto undo_setattr; | 1047 | goto undo_setattr; |
| 1048 | } | 1048 | } |
| 1049 | 1049 | ||
| @@ -1062,7 +1062,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry, | |||
| 1062 | if (rc == -ENOENT) | 1062 | if (rc == -ENOENT) |
| 1063 | rc = 0; | 1063 | rc = 0; |
| 1064 | else if (rc != 0) { | 1064 | else if (rc != 0) { |
| 1065 | rc = -ETXTBSY; | 1065 | rc = -EBUSY; |
| 1066 | goto undo_rename; | 1066 | goto undo_rename; |
| 1067 | } | 1067 | } |
| 1068 | cifsInode->delete_pending = true; | 1068 | cifsInode->delete_pending = true; |
| @@ -1169,15 +1169,13 @@ psx_del_no_retry: | |||
| 1169 | cifs_drop_nlink(inode); | 1169 | cifs_drop_nlink(inode); |
| 1170 | } else if (rc == -ENOENT) { | 1170 | } else if (rc == -ENOENT) { |
| 1171 | d_drop(dentry); | 1171 | d_drop(dentry); |
| 1172 | } else if (rc == -ETXTBSY) { | 1172 | } else if (rc == -EBUSY) { |
| 1173 | if (server->ops->rename_pending_delete) { | 1173 | if (server->ops->rename_pending_delete) { |
| 1174 | rc = server->ops->rename_pending_delete(full_path, | 1174 | rc = server->ops->rename_pending_delete(full_path, |
| 1175 | dentry, xid); | 1175 | dentry, xid); |
| 1176 | if (rc == 0) | 1176 | if (rc == 0) |
| 1177 | cifs_drop_nlink(inode); | 1177 | cifs_drop_nlink(inode); |
| 1178 | } | 1178 | } |
| 1179 | if (rc == -ETXTBSY) | ||
| 1180 | rc = -EBUSY; | ||
| 1181 | } else if ((rc == -EACCES) && (dosattr == 0) && inode) { | 1179 | } else if ((rc == -EACCES) && (dosattr == 0) && inode) { |
| 1182 | attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); | 1180 | attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); |
| 1183 | if (attrs == NULL) { | 1181 | if (attrs == NULL) { |
| @@ -1518,7 +1516,7 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry, | |||
| 1518 | * source. Note that cross directory moves do not work with | 1516 | * source. Note that cross directory moves do not work with |
| 1519 | * rename by filehandle to various Windows servers. | 1517 | * rename by filehandle to various Windows servers. |
| 1520 | */ | 1518 | */ |
| 1521 | if (rc == 0 || rc != -ETXTBSY) | 1519 | if (rc == 0 || rc != -EBUSY) |
| 1522 | goto do_rename_exit; | 1520 | goto do_rename_exit; |
| 1523 | 1521 | ||
| 1524 | /* open-file renames don't work across directories */ | 1522 | /* open-file renames don't work across directories */ |
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index a82bc51fdc82..c0b25b28be6c 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
| @@ -62,7 +62,7 @@ static const struct smb_to_posix_error mapping_table_ERRDOS[] = { | |||
| 62 | {ERRdiffdevice, -EXDEV}, | 62 | {ERRdiffdevice, -EXDEV}, |
| 63 | {ERRnofiles, -ENOENT}, | 63 | {ERRnofiles, -ENOENT}, |
| 64 | {ERRwriteprot, -EROFS}, | 64 | {ERRwriteprot, -EROFS}, |
| 65 | {ERRbadshare, -ETXTBSY}, | 65 | {ERRbadshare, -EBUSY}, |
| 66 | {ERRlock, -EACCES}, | 66 | {ERRlock, -EACCES}, |
| 67 | {ERRunsup, -EINVAL}, | 67 | {ERRunsup, -EINVAL}, |
| 68 | {ERRnosuchshare, -ENXIO}, | 68 | {ERRnosuchshare, -ENXIO}, |
diff --git a/fs/compat.c b/fs/compat.c index fe40fde29111..d487985dd0ea 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
| @@ -558,6 +558,10 @@ ssize_t compat_rw_copy_check_uvector(int type, | |||
| 558 | } | 558 | } |
| 559 | *ret_pointer = iov; | 559 | *ret_pointer = iov; |
| 560 | 560 | ||
| 561 | ret = -EFAULT; | ||
| 562 | if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector))) | ||
| 563 | goto out; | ||
| 564 | |||
| 561 | /* | 565 | /* |
| 562 | * Single unix specification: | 566 | * Single unix specification: |
| 563 | * We should -EINVAL if an element length is not >= 0 and fitting an | 567 | * We should -EINVAL if an element length is not >= 0 and fitting an |
| @@ -1080,17 +1084,12 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, | |||
| 1080 | if (!file->f_op) | 1084 | if (!file->f_op) |
| 1081 | goto out; | 1085 | goto out; |
| 1082 | 1086 | ||
| 1083 | ret = -EFAULT; | 1087 | ret = compat_rw_copy_check_uvector(type, uvector, nr_segs, |
| 1084 | if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector))) | ||
| 1085 | goto out; | ||
| 1086 | |||
| 1087 | tot_len = compat_rw_copy_check_uvector(type, uvector, nr_segs, | ||
| 1088 | UIO_FASTIOV, iovstack, &iov); | 1088 | UIO_FASTIOV, iovstack, &iov); |
| 1089 | if (tot_len == 0) { | 1089 | if (ret <= 0) |
| 1090 | ret = 0; | ||
| 1091 | goto out; | 1090 | goto out; |
| 1092 | } | ||
| 1093 | 1091 | ||
| 1092 | tot_len = ret; | ||
| 1094 | ret = rw_verify_area(type, file, pos, tot_len); | 1093 | ret = rw_verify_area(type, file, pos, tot_len); |
| 1095 | if (ret < 0) | 1094 | if (ret < 0) |
| 1096 | goto out; | 1095 | goto out; |
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 8f370e012e61..7cadd823bb31 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c | |||
| @@ -118,7 +118,6 @@ void ext2_free_inode (struct inode * inode) | |||
| 118 | * as writing the quota to disk may need the lock as well. | 118 | * as writing the quota to disk may need the lock as well. |
| 119 | */ | 119 | */ |
| 120 | /* Quota is already initialized in iput() */ | 120 | /* Quota is already initialized in iput() */ |
| 121 | ext2_xattr_delete_inode(inode); | ||
| 122 | dquot_free_inode(inode); | 121 | dquot_free_inode(inode); |
| 123 | dquot_drop(inode); | 122 | dquot_drop(inode); |
| 124 | 123 | ||
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index c3881e56662e..fe60cc1117d8 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include "ext2.h" | 34 | #include "ext2.h" |
| 35 | #include "acl.h" | 35 | #include "acl.h" |
| 36 | #include "xip.h" | 36 | #include "xip.h" |
| 37 | #include "xattr.h" | ||
| 37 | 38 | ||
| 38 | static int __ext2_write_inode(struct inode *inode, int do_sync); | 39 | static int __ext2_write_inode(struct inode *inode, int do_sync); |
| 39 | 40 | ||
| @@ -88,6 +89,7 @@ void ext2_evict_inode(struct inode * inode) | |||
| 88 | inode->i_size = 0; | 89 | inode->i_size = 0; |
| 89 | if (inode->i_blocks) | 90 | if (inode->i_blocks) |
| 90 | ext2_truncate_blocks(inode, 0); | 91 | ext2_truncate_blocks(inode, 0); |
| 92 | ext2_xattr_delete_inode(inode); | ||
| 91 | } | 93 | } |
| 92 | 94 | ||
| 93 | invalidate_inode_buffers(inode); | 95 | invalidate_inode_buffers(inode); |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 1d6e2ed85322..fb5120a5505c 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
| @@ -353,7 +353,7 @@ static struct block_device *ext3_blkdev_get(dev_t dev, struct super_block *sb) | |||
| 353 | return bdev; | 353 | return bdev; |
| 354 | 354 | ||
| 355 | fail: | 355 | fail: |
| 356 | ext3_msg(sb, "error: failed to open journal device %s: %ld", | 356 | ext3_msg(sb, KERN_ERR, "error: failed to open journal device %s: %ld", |
| 357 | __bdevname(dev, b), PTR_ERR(bdev)); | 357 | __bdevname(dev, b), PTR_ERR(bdev)); |
| 358 | 358 | ||
| 359 | return NULL; | 359 | return NULL; |
| @@ -887,7 +887,7 @@ static ext3_fsblk_t get_sb_block(void **data, struct super_block *sb) | |||
| 887 | /*todo: use simple_strtoll with >32bit ext3 */ | 887 | /*todo: use simple_strtoll with >32bit ext3 */ |
| 888 | sb_block = simple_strtoul(options, &options, 0); | 888 | sb_block = simple_strtoul(options, &options, 0); |
| 889 | if (*options && *options != ',') { | 889 | if (*options && *options != ',') { |
| 890 | ext3_msg(sb, "error: invalid sb specification: %s", | 890 | ext3_msg(sb, KERN_ERR, "error: invalid sb specification: %s", |
| 891 | (char *) *data); | 891 | (char *) *data); |
| 892 | return 1; | 892 | return 1; |
| 893 | } | 893 | } |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 4a01ba315262..3b83cd604796 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
| @@ -335,9 +335,9 @@ struct ext4_group_desc | |||
| 335 | */ | 335 | */ |
| 336 | 336 | ||
| 337 | struct flex_groups { | 337 | struct flex_groups { |
| 338 | atomic_t free_inodes; | 338 | atomic64_t free_clusters; |
| 339 | atomic_t free_clusters; | 339 | atomic_t free_inodes; |
| 340 | atomic_t used_dirs; | 340 | atomic_t used_dirs; |
| 341 | }; | 341 | }; |
| 342 | 342 | ||
| 343 | #define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */ | 343 | #define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */ |
| @@ -2617,7 +2617,7 @@ extern int ext4_move_extents(struct file *o_filp, struct file *d_filp, | |||
| 2617 | extern int __init ext4_init_pageio(void); | 2617 | extern int __init ext4_init_pageio(void); |
| 2618 | extern void ext4_add_complete_io(ext4_io_end_t *io_end); | 2618 | extern void ext4_add_complete_io(ext4_io_end_t *io_end); |
| 2619 | extern void ext4_exit_pageio(void); | 2619 | extern void ext4_exit_pageio(void); |
| 2620 | extern void ext4_ioend_wait(struct inode *); | 2620 | extern void ext4_ioend_shutdown(struct inode *); |
| 2621 | extern void ext4_free_io_end(ext4_io_end_t *io); | 2621 | extern void ext4_free_io_end(ext4_io_end_t *io); |
| 2622 | extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags); | 2622 | extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags); |
| 2623 | extern void ext4_end_io_work(struct work_struct *work); | 2623 | extern void ext4_end_io_work(struct work_struct *work); |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 28dd8eeea6a9..56efcaadf848 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
| @@ -1584,10 +1584,12 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, | |||
| 1584 | unsigned short ext1_ee_len, ext2_ee_len, max_len; | 1584 | unsigned short ext1_ee_len, ext2_ee_len, max_len; |
| 1585 | 1585 | ||
| 1586 | /* | 1586 | /* |
| 1587 | * Make sure that either both extents are uninitialized, or | 1587 | * Make sure that both extents are initialized. We don't merge |
| 1588 | * both are _not_. | 1588 | * uninitialized extents so that we can be sure that end_io code has |
| 1589 | * the extent that was written properly split out and conversion to | ||
| 1590 | * initialized is trivial. | ||
| 1589 | */ | 1591 | */ |
| 1590 | if (ext4_ext_is_uninitialized(ex1) ^ ext4_ext_is_uninitialized(ex2)) | 1592 | if (ext4_ext_is_uninitialized(ex1) || ext4_ext_is_uninitialized(ex2)) |
| 1591 | return 0; | 1593 | return 0; |
| 1592 | 1594 | ||
| 1593 | if (ext4_ext_is_uninitialized(ex1)) | 1595 | if (ext4_ext_is_uninitialized(ex1)) |
| @@ -2923,7 +2925,7 @@ static int ext4_split_extent_at(handle_t *handle, | |||
| 2923 | { | 2925 | { |
| 2924 | ext4_fsblk_t newblock; | 2926 | ext4_fsblk_t newblock; |
| 2925 | ext4_lblk_t ee_block; | 2927 | ext4_lblk_t ee_block; |
| 2926 | struct ext4_extent *ex, newex, orig_ex; | 2928 | struct ext4_extent *ex, newex, orig_ex, zero_ex; |
| 2927 | struct ext4_extent *ex2 = NULL; | 2929 | struct ext4_extent *ex2 = NULL; |
| 2928 | unsigned int ee_len, depth; | 2930 | unsigned int ee_len, depth; |
| 2929 | int err = 0; | 2931 | int err = 0; |
| @@ -2943,6 +2945,10 @@ static int ext4_split_extent_at(handle_t *handle, | |||
| 2943 | newblock = split - ee_block + ext4_ext_pblock(ex); | 2945 | newblock = split - ee_block + ext4_ext_pblock(ex); |
| 2944 | 2946 | ||
| 2945 | BUG_ON(split < ee_block || split >= (ee_block + ee_len)); | 2947 | BUG_ON(split < ee_block || split >= (ee_block + ee_len)); |
| 2948 | BUG_ON(!ext4_ext_is_uninitialized(ex) && | ||
| 2949 | split_flag & (EXT4_EXT_MAY_ZEROOUT | | ||
| 2950 | EXT4_EXT_MARK_UNINIT1 | | ||
| 2951 | EXT4_EXT_MARK_UNINIT2)); | ||
| 2946 | 2952 | ||
| 2947 | err = ext4_ext_get_access(handle, inode, path + depth); | 2953 | err = ext4_ext_get_access(handle, inode, path + depth); |
| 2948 | if (err) | 2954 | if (err) |
| @@ -2990,12 +2996,26 @@ static int ext4_split_extent_at(handle_t *handle, | |||
| 2990 | err = ext4_ext_insert_extent(handle, inode, path, &newex, flags); | 2996 | err = ext4_ext_insert_extent(handle, inode, path, &newex, flags); |
| 2991 | if (err == -ENOSPC && (EXT4_EXT_MAY_ZEROOUT & split_flag)) { | 2997 | if (err == -ENOSPC && (EXT4_EXT_MAY_ZEROOUT & split_flag)) { |
| 2992 | if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) { | 2998 | if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) { |
| 2993 | if (split_flag & EXT4_EXT_DATA_VALID1) | 2999 | if (split_flag & EXT4_EXT_DATA_VALID1) { |
| 2994 | err = ext4_ext_zeroout(inode, ex2); | 3000 | err = ext4_ext_zeroout(inode, ex2); |
| 2995 | else | 3001 | zero_ex.ee_block = ex2->ee_block; |
| 3002 | zero_ex.ee_len = ext4_ext_get_actual_len(ex2); | ||
| 3003 | ext4_ext_store_pblock(&zero_ex, | ||
| 3004 | ext4_ext_pblock(ex2)); | ||
| 3005 | } else { | ||
| 2996 | err = ext4_ext_zeroout(inode, ex); | 3006 | err = ext4_ext_zeroout(inode, ex); |
| 2997 | } else | 3007 | zero_ex.ee_block = ex->ee_block; |
| 3008 | zero_ex.ee_len = ext4_ext_get_actual_len(ex); | ||
| 3009 | ext4_ext_store_pblock(&zero_ex, | ||
| 3010 | ext4_ext_pblock(ex)); | ||
| 3011 | } | ||
| 3012 | } else { | ||
| 2998 | err = ext4_ext_zeroout(inode, &orig_ex); | 3013 | err = ext4_ext_zeroout(inode, &orig_ex); |
| 3014 | zero_ex.ee_block = orig_ex.ee_block; | ||
| 3015 | zero_ex.ee_len = ext4_ext_get_actual_len(&orig_ex); | ||
| 3016 | ext4_ext_store_pblock(&zero_ex, | ||
| 3017 | ext4_ext_pblock(&orig_ex)); | ||
| 3018 | } | ||
| 2999 | 3019 | ||
| 3000 | if (err) | 3020 | if (err) |
| 3001 | goto fix_extent_len; | 3021 | goto fix_extent_len; |
| @@ -3003,6 +3023,12 @@ static int ext4_split_extent_at(handle_t *handle, | |||
| 3003 | ex->ee_len = cpu_to_le16(ee_len); | 3023 | ex->ee_len = cpu_to_le16(ee_len); |
| 3004 | ext4_ext_try_to_merge(handle, inode, path, ex); | 3024 | ext4_ext_try_to_merge(handle, inode, path, ex); |
| 3005 | err = ext4_ext_dirty(handle, inode, path + path->p_depth); | 3025 | err = ext4_ext_dirty(handle, inode, path + path->p_depth); |
| 3026 | if (err) | ||
| 3027 | goto fix_extent_len; | ||
| 3028 | |||
| 3029 | /* update extent status tree */ | ||
| 3030 | err = ext4_es_zeroout(inode, &zero_ex); | ||
| 3031 | |||
| 3006 | goto out; | 3032 | goto out; |
| 3007 | } else if (err) | 3033 | } else if (err) |
| 3008 | goto fix_extent_len; | 3034 | goto fix_extent_len; |
| @@ -3041,6 +3067,7 @@ static int ext4_split_extent(handle_t *handle, | |||
| 3041 | int err = 0; | 3067 | int err = 0; |
| 3042 | int uninitialized; | 3068 | int uninitialized; |
| 3043 | int split_flag1, flags1; | 3069 | int split_flag1, flags1; |
| 3070 | int allocated = map->m_len; | ||
| 3044 | 3071 | ||
| 3045 | depth = ext_depth(inode); | 3072 | depth = ext_depth(inode); |
| 3046 | ex = path[depth].p_ext; | 3073 | ex = path[depth].p_ext; |
| @@ -3060,20 +3087,29 @@ static int ext4_split_extent(handle_t *handle, | |||
| 3060 | map->m_lblk + map->m_len, split_flag1, flags1); | 3087 | map->m_lblk + map->m_len, split_flag1, flags1); |
| 3061 | if (err) | 3088 | if (err) |
| 3062 | goto out; | 3089 | goto out; |
| 3090 | } else { | ||
| 3091 | allocated = ee_len - (map->m_lblk - ee_block); | ||
| 3063 | } | 3092 | } |
| 3064 | 3093 | /* | |
| 3094 | * Update path is required because previous ext4_split_extent_at() may | ||
| 3095 | * result in split of original leaf or extent zeroout. | ||
| 3096 | */ | ||
| 3065 | ext4_ext_drop_refs(path); | 3097 | ext4_ext_drop_refs(path); |
| 3066 | path = ext4_ext_find_extent(inode, map->m_lblk, path); | 3098 | path = ext4_ext_find_extent(inode, map->m_lblk, path); |
| 3067 | if (IS_ERR(path)) | 3099 | if (IS_ERR(path)) |
| 3068 | return PTR_ERR(path); | 3100 | return PTR_ERR(path); |
| 3101 | depth = ext_depth(inode); | ||
| 3102 | ex = path[depth].p_ext; | ||
| 3103 | uninitialized = ext4_ext_is_uninitialized(ex); | ||
| 3104 | split_flag1 = 0; | ||
| 3069 | 3105 | ||
| 3070 | if (map->m_lblk >= ee_block) { | 3106 | if (map->m_lblk >= ee_block) { |
| 3071 | split_flag1 = split_flag & (EXT4_EXT_MAY_ZEROOUT | | 3107 | split_flag1 = split_flag & EXT4_EXT_DATA_VALID2; |
| 3072 | EXT4_EXT_DATA_VALID2); | 3108 | if (uninitialized) { |
| 3073 | if (uninitialized) | ||
| 3074 | split_flag1 |= EXT4_EXT_MARK_UNINIT1; | 3109 | split_flag1 |= EXT4_EXT_MARK_UNINIT1; |
| 3075 | if (split_flag & EXT4_EXT_MARK_UNINIT2) | 3110 | split_flag1 |= split_flag & (EXT4_EXT_MAY_ZEROOUT | |
| 3076 | split_flag1 |= EXT4_EXT_MARK_UNINIT2; | 3111 | EXT4_EXT_MARK_UNINIT2); |
| 3112 | } | ||
| 3077 | err = ext4_split_extent_at(handle, inode, path, | 3113 | err = ext4_split_extent_at(handle, inode, path, |
| 3078 | map->m_lblk, split_flag1, flags); | 3114 | map->m_lblk, split_flag1, flags); |
| 3079 | if (err) | 3115 | if (err) |
| @@ -3082,7 +3118,7 @@ static int ext4_split_extent(handle_t *handle, | |||
| 3082 | 3118 | ||
| 3083 | ext4_ext_show_leaf(inode, path); | 3119 | ext4_ext_show_leaf(inode, path); |
| 3084 | out: | 3120 | out: |
| 3085 | return err ? err : map->m_len; | 3121 | return err ? err : allocated; |
| 3086 | } | 3122 | } |
| 3087 | 3123 | ||
| 3088 | /* | 3124 | /* |
| @@ -3137,6 +3173,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
| 3137 | ee_block = le32_to_cpu(ex->ee_block); | 3173 | ee_block = le32_to_cpu(ex->ee_block); |
| 3138 | ee_len = ext4_ext_get_actual_len(ex); | 3174 | ee_len = ext4_ext_get_actual_len(ex); |
| 3139 | allocated = ee_len - (map->m_lblk - ee_block); | 3175 | allocated = ee_len - (map->m_lblk - ee_block); |
| 3176 | zero_ex.ee_len = 0; | ||
| 3140 | 3177 | ||
| 3141 | trace_ext4_ext_convert_to_initialized_enter(inode, map, ex); | 3178 | trace_ext4_ext_convert_to_initialized_enter(inode, map, ex); |
| 3142 | 3179 | ||
| @@ -3227,13 +3264,16 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
| 3227 | 3264 | ||
| 3228 | if (EXT4_EXT_MAY_ZEROOUT & split_flag) | 3265 | if (EXT4_EXT_MAY_ZEROOUT & split_flag) |
| 3229 | max_zeroout = sbi->s_extent_max_zeroout_kb >> | 3266 | max_zeroout = sbi->s_extent_max_zeroout_kb >> |
| 3230 | inode->i_sb->s_blocksize_bits; | 3267 | (inode->i_sb->s_blocksize_bits - 10); |
| 3231 | 3268 | ||
| 3232 | /* If extent is less than s_max_zeroout_kb, zeroout directly */ | 3269 | /* If extent is less than s_max_zeroout_kb, zeroout directly */ |
| 3233 | if (max_zeroout && (ee_len <= max_zeroout)) { | 3270 | if (max_zeroout && (ee_len <= max_zeroout)) { |
| 3234 | err = ext4_ext_zeroout(inode, ex); | 3271 | err = ext4_ext_zeroout(inode, ex); |
| 3235 | if (err) | 3272 | if (err) |
| 3236 | goto out; | 3273 | goto out; |
| 3274 | zero_ex.ee_block = ex->ee_block; | ||
| 3275 | zero_ex.ee_len = ext4_ext_get_actual_len(ex); | ||
| 3276 | ext4_ext_store_pblock(&zero_ex, ext4_ext_pblock(ex)); | ||
| 3237 | 3277 | ||
| 3238 | err = ext4_ext_get_access(handle, inode, path + depth); | 3278 | err = ext4_ext_get_access(handle, inode, path + depth); |
| 3239 | if (err) | 3279 | if (err) |
| @@ -3292,6 +3332,9 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, | |||
| 3292 | err = allocated; | 3332 | err = allocated; |
| 3293 | 3333 | ||
| 3294 | out: | 3334 | out: |
| 3335 | /* If we have gotten a failure, don't zero out status tree */ | ||
| 3336 | if (!err) | ||
| 3337 | err = ext4_es_zeroout(inode, &zero_ex); | ||
| 3295 | return err ? err : allocated; | 3338 | return err ? err : allocated; |
| 3296 | } | 3339 | } |
| 3297 | 3340 | ||
| @@ -3374,8 +3417,19 @@ static int ext4_convert_unwritten_extents_endio(handle_t *handle, | |||
| 3374 | "block %llu, max_blocks %u\n", inode->i_ino, | 3417 | "block %llu, max_blocks %u\n", inode->i_ino, |
| 3375 | (unsigned long long)ee_block, ee_len); | 3418 | (unsigned long long)ee_block, ee_len); |
| 3376 | 3419 | ||
| 3377 | /* If extent is larger than requested then split is required */ | 3420 | /* If extent is larger than requested it is a clear sign that we still |
| 3421 | * have some extent state machine issues left. So extent_split is still | ||
| 3422 | * required. | ||
| 3423 | * TODO: Once all related issues will be fixed this situation should be | ||
| 3424 | * illegal. | ||
| 3425 | */ | ||
| 3378 | if (ee_block != map->m_lblk || ee_len > map->m_len) { | 3426 | if (ee_block != map->m_lblk || ee_len > map->m_len) { |
| 3427 | #ifdef EXT4_DEBUG | ||
| 3428 | ext4_warning("Inode (%ld) finished: extent logical block %llu," | ||
| 3429 | " len %u; IO logical block %llu, len %u\n", | ||
| 3430 | inode->i_ino, (unsigned long long)ee_block, ee_len, | ||
| 3431 | (unsigned long long)map->m_lblk, map->m_len); | ||
| 3432 | #endif | ||
| 3379 | err = ext4_split_unwritten_extents(handle, inode, map, path, | 3433 | err = ext4_split_unwritten_extents(handle, inode, map, path, |
| 3380 | EXT4_GET_BLOCKS_CONVERT); | 3434 | EXT4_GET_BLOCKS_CONVERT); |
| 3381 | if (err < 0) | 3435 | if (err < 0) |
| @@ -3626,6 +3680,10 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, | |||
| 3626 | path, map->m_len); | 3680 | path, map->m_len); |
| 3627 | } else | 3681 | } else |
| 3628 | err = ret; | 3682 | err = ret; |
| 3683 | map->m_flags |= EXT4_MAP_MAPPED; | ||
| 3684 | if (allocated > map->m_len) | ||
| 3685 | allocated = map->m_len; | ||
| 3686 | map->m_len = allocated; | ||
| 3629 | goto out2; | 3687 | goto out2; |
| 3630 | } | 3688 | } |
| 3631 | /* buffered IO case */ | 3689 | /* buffered IO case */ |
| @@ -3675,6 +3733,7 @@ out: | |||
| 3675 | allocated - map->m_len); | 3733 | allocated - map->m_len); |
| 3676 | allocated = map->m_len; | 3734 | allocated = map->m_len; |
| 3677 | } | 3735 | } |
| 3736 | map->m_len = allocated; | ||
| 3678 | 3737 | ||
| 3679 | /* | 3738 | /* |
| 3680 | * If we have done fallocate with the offset that is already | 3739 | * If we have done fallocate with the offset that is already |
| @@ -4106,9 +4165,6 @@ got_allocated_blocks: | |||
| 4106 | } | 4165 | } |
| 4107 | } else { | 4166 | } else { |
| 4108 | BUG_ON(allocated_clusters < reserved_clusters); | 4167 | BUG_ON(allocated_clusters < reserved_clusters); |
| 4109 | /* We will claim quota for all newly allocated blocks.*/ | ||
| 4110 | ext4_da_update_reserve_space(inode, allocated_clusters, | ||
| 4111 | 1); | ||
| 4112 | if (reserved_clusters < allocated_clusters) { | 4168 | if (reserved_clusters < allocated_clusters) { |
| 4113 | struct ext4_inode_info *ei = EXT4_I(inode); | 4169 | struct ext4_inode_info *ei = EXT4_I(inode); |
| 4114 | int reservation = allocated_clusters - | 4170 | int reservation = allocated_clusters - |
| @@ -4159,6 +4215,15 @@ got_allocated_blocks: | |||
| 4159 | ei->i_reserved_data_blocks += reservation; | 4215 | ei->i_reserved_data_blocks += reservation; |
| 4160 | spin_unlock(&ei->i_block_reservation_lock); | 4216 | spin_unlock(&ei->i_block_reservation_lock); |
| 4161 | } | 4217 | } |
| 4218 | /* | ||
| 4219 | * We will claim quota for all newly allocated blocks. | ||
| 4220 | * We're updating the reserved space *after* the | ||
| 4221 | * correction above so we do not accidentally free | ||
| 4222 | * all the metadata reservation because we might | ||
| 4223 | * actually need it later on. | ||
| 4224 | */ | ||
| 4225 | ext4_da_update_reserve_space(inode, allocated_clusters, | ||
| 4226 | 1); | ||
| 4162 | } | 4227 | } |
| 4163 | } | 4228 | } |
| 4164 | 4229 | ||
| @@ -4368,8 +4433,6 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) | |||
| 4368 | if (len <= EXT_UNINIT_MAX_LEN << blkbits) | 4433 | if (len <= EXT_UNINIT_MAX_LEN << blkbits) |
| 4369 | flags |= EXT4_GET_BLOCKS_NO_NORMALIZE; | 4434 | flags |= EXT4_GET_BLOCKS_NO_NORMALIZE; |
| 4370 | 4435 | ||
| 4371 | /* Prevent race condition between unwritten */ | ||
| 4372 | ext4_flush_unwritten_io(inode); | ||
| 4373 | retry: | 4436 | retry: |
| 4374 | while (ret >= 0 && ret < max_blocks) { | 4437 | while (ret >= 0 && ret < max_blocks) { |
| 4375 | map.m_lblk = map.m_lblk + ret; | 4438 | map.m_lblk = map.m_lblk + ret; |
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index 95796a1b7522..fe3337a85ede 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c | |||
| @@ -333,17 +333,27 @@ static void ext4_es_free_extent(struct inode *inode, struct extent_status *es) | |||
| 333 | static int ext4_es_can_be_merged(struct extent_status *es1, | 333 | static int ext4_es_can_be_merged(struct extent_status *es1, |
| 334 | struct extent_status *es2) | 334 | struct extent_status *es2) |
| 335 | { | 335 | { |
| 336 | if (es1->es_lblk + es1->es_len != es2->es_lblk) | 336 | if (ext4_es_status(es1) != ext4_es_status(es2)) |
| 337 | return 0; | 337 | return 0; |
| 338 | 338 | ||
| 339 | if (ext4_es_status(es1) != ext4_es_status(es2)) | 339 | if (((__u64) es1->es_len) + es2->es_len > 0xFFFFFFFFULL) |
| 340 | return 0; | 340 | return 0; |
| 341 | 341 | ||
| 342 | if ((ext4_es_is_written(es1) || ext4_es_is_unwritten(es1)) && | 342 | if (((__u64) es1->es_lblk) + es1->es_len != es2->es_lblk) |
| 343 | (ext4_es_pblock(es1) + es1->es_len != ext4_es_pblock(es2))) | ||
| 344 | return 0; | 343 | return 0; |
| 345 | 344 | ||
| 346 | return 1; | 345 | if ((ext4_es_is_written(es1) || ext4_es_is_unwritten(es1)) && |
| 346 | (ext4_es_pblock(es1) + es1->es_len == ext4_es_pblock(es2))) | ||
| 347 | return 1; | ||
| 348 | |||
| 349 | if (ext4_es_is_hole(es1)) | ||
| 350 | return 1; | ||
| 351 | |||
| 352 | /* we need to check delayed extent is without unwritten status */ | ||
| 353 | if (ext4_es_is_delayed(es1) && !ext4_es_is_unwritten(es1)) | ||
| 354 | return 1; | ||
| 355 | |||
| 356 | return 0; | ||
| 347 | } | 357 | } |
| 348 | 358 | ||
| 349 | static struct extent_status * | 359 | static struct extent_status * |
| @@ -389,6 +399,179 @@ ext4_es_try_to_merge_right(struct inode *inode, struct extent_status *es) | |||
| 389 | return es; | 399 | return es; |
| 390 | } | 400 | } |
| 391 | 401 | ||
| 402 | #ifdef ES_AGGRESSIVE_TEST | ||
| 403 | static void ext4_es_insert_extent_ext_check(struct inode *inode, | ||
| 404 | struct extent_status *es) | ||
| 405 | { | ||
| 406 | struct ext4_ext_path *path = NULL; | ||
| 407 | struct ext4_extent *ex; | ||
| 408 | ext4_lblk_t ee_block; | ||
| 409 | ext4_fsblk_t ee_start; | ||
| 410 | unsigned short ee_len; | ||
| 411 | int depth, ee_status, es_status; | ||
| 412 | |||
| 413 | path = ext4_ext_find_extent(inode, es->es_lblk, NULL); | ||
| 414 | if (IS_ERR(path)) | ||
| 415 | return; | ||
| 416 | |||
| 417 | depth = ext_depth(inode); | ||
| 418 | ex = path[depth].p_ext; | ||
| 419 | |||
| 420 | if (ex) { | ||
| 421 | |||
| 422 | ee_block = le32_to_cpu(ex->ee_block); | ||
| 423 | ee_start = ext4_ext_pblock(ex); | ||
| 424 | ee_len = ext4_ext_get_actual_len(ex); | ||
| 425 | |||
| 426 | ee_status = ext4_ext_is_uninitialized(ex) ? 1 : 0; | ||
| 427 | es_status = ext4_es_is_unwritten(es) ? 1 : 0; | ||
| 428 | |||
| 429 | /* | ||
| 430 | * Make sure ex and es are not overlap when we try to insert | ||
| 431 | * a delayed/hole extent. | ||
| 432 | */ | ||
| 433 | if (!ext4_es_is_written(es) && !ext4_es_is_unwritten(es)) { | ||
| 434 | if (in_range(es->es_lblk, ee_block, ee_len)) { | ||
| 435 | pr_warn("ES insert assertation failed for " | ||
| 436 | "inode: %lu we can find an extent " | ||
| 437 | "at block [%d/%d/%llu/%c], but we " | ||
| 438 | "want to add an delayed/hole extent " | ||
| 439 | "[%d/%d/%llu/%llx]\n", | ||
| 440 | inode->i_ino, ee_block, ee_len, | ||
| 441 | ee_start, ee_status ? 'u' : 'w', | ||
| 442 | es->es_lblk, es->es_len, | ||
| 443 | ext4_es_pblock(es), ext4_es_status(es)); | ||
| 444 | } | ||
| 445 | goto out; | ||
| 446 | } | ||
| 447 | |||
| 448 | /* | ||
| 449 | * We don't check ee_block == es->es_lblk, etc. because es | ||
| 450 | * might be a part of whole extent, vice versa. | ||
| 451 | */ | ||
| 452 | if (es->es_lblk < ee_block || | ||
| 453 | ext4_es_pblock(es) != ee_start + es->es_lblk - ee_block) { | ||
| 454 | pr_warn("ES insert assertation failed for inode: %lu " | ||
| 455 | "ex_status [%d/%d/%llu/%c] != " | ||
| 456 | "es_status [%d/%d/%llu/%c]\n", inode->i_ino, | ||
| 457 | ee_block, ee_len, ee_start, | ||
| 458 | ee_status ? 'u' : 'w', es->es_lblk, es->es_len, | ||
| 459 | ext4_es_pblock(es), es_status ? 'u' : 'w'); | ||
| 460 | goto out; | ||
| 461 | } | ||
| 462 | |||
| 463 | if (ee_status ^ es_status) { | ||
| 464 | pr_warn("ES insert assertation failed for inode: %lu " | ||
| 465 | "ex_status [%d/%d/%llu/%c] != " | ||
| 466 | "es_status [%d/%d/%llu/%c]\n", inode->i_ino, | ||
| 467 | ee_block, ee_len, ee_start, | ||
| 468 | ee_status ? 'u' : 'w', es->es_lblk, es->es_len, | ||
| 469 | ext4_es_pblock(es), es_status ? 'u' : 'w'); | ||
| 470 | } | ||
| 471 | } else { | ||
| 472 | /* | ||
| 473 | * We can't find an extent on disk. So we need to make sure | ||
| 474 | * that we don't want to add an written/unwritten extent. | ||
| 475 | */ | ||
| 476 | if (!ext4_es_is_delayed(es) && !ext4_es_is_hole(es)) { | ||
| 477 | pr_warn("ES insert assertation failed for inode: %lu " | ||
| 478 | "can't find an extent at block %d but we want " | ||
| 479 | "to add an written/unwritten extent " | ||
| 480 | "[%d/%d/%llu/%llx]\n", inode->i_ino, | ||
| 481 | es->es_lblk, es->es_lblk, es->es_len, | ||
| 482 | ext4_es_pblock(es), ext4_es_status(es)); | ||
| 483 | } | ||
| 484 | } | ||
| 485 | out: | ||
| 486 | if (path) { | ||
| 487 | ext4_ext_drop_refs(path); | ||
| 488 | kfree(path); | ||
| 489 | } | ||
| 490 | } | ||
| 491 | |||
| 492 | static void ext4_es_insert_extent_ind_check(struct inode *inode, | ||
| 493 | struct extent_status *es) | ||
| 494 | { | ||
| 495 | struct ext4_map_blocks map; | ||
| 496 | int retval; | ||
| 497 | |||
| 498 | /* | ||
| 499 | * Here we call ext4_ind_map_blocks to lookup a block mapping because | ||
| 500 | * 'Indirect' structure is defined in indirect.c. So we couldn't | ||
| 501 | * access direct/indirect tree from outside. It is too dirty to define | ||
| 502 | * this function in indirect.c file. | ||
| 503 | */ | ||
| 504 | |||
| 505 | map.m_lblk = es->es_lblk; | ||
| 506 | map.m_len = es->es_len; | ||
| 507 | |||
| 508 | retval = ext4_ind_map_blocks(NULL, inode, &map, 0); | ||
| 509 | if (retval > 0) { | ||
| 510 | if (ext4_es_is_delayed(es) || ext4_es_is_hole(es)) { | ||
| 511 | /* | ||
| 512 | * We want to add a delayed/hole extent but this | ||
| 513 | * block has been allocated. | ||
| 514 | */ | ||
| 515 | pr_warn("ES insert assertation failed for inode: %lu " | ||
| 516 | "We can find blocks but we want to add a " | ||
| 517 | "delayed/hole extent [%d/%d/%llu/%llx]\n", | ||
| 518 | inode->i_ino, es->es_lblk, es->es_len, | ||
| 519 | ext4_es_pblock(es), ext4_es_status(es)); | ||
| 520 | return; | ||
| 521 | } else if (ext4_es_is_written(es)) { | ||
| 522 | if (retval != es->es_len) { | ||
| 523 | pr_warn("ES insert assertation failed for " | ||
| 524 | "inode: %lu retval %d != es_len %d\n", | ||
| 525 | inode->i_ino, retval, es->es_len); | ||
| 526 | return; | ||
| 527 | } | ||
| 528 | if (map.m_pblk != ext4_es_pblock(es)) { | ||
| 529 | pr_warn("ES insert assertation failed for " | ||
| 530 | "inode: %lu m_pblk %llu != " | ||
| 531 | "es_pblk %llu\n", | ||
| 532 | inode->i_ino, map.m_pblk, | ||
| 533 | ext4_es_pblock(es)); | ||
| 534 | return; | ||
| 535 | } | ||
| 536 | } else { | ||
| 537 | /* | ||
| 538 | * We don't need to check unwritten extent because | ||
| 539 | * indirect-based file doesn't have it. | ||
| 540 | */ | ||
| 541 | BUG_ON(1); | ||
| 542 | } | ||
| 543 | } else if (retval == 0) { | ||
| 544 | if (ext4_es_is_written(es)) { | ||
| 545 | pr_warn("ES insert assertation failed for inode: %lu " | ||
| 546 | "We can't find the block but we want to add " | ||
| 547 | "an written extent [%d/%d/%llu/%llx]\n", | ||
| 548 | inode->i_ino, es->es_lblk, es->es_len, | ||
| 549 | ext4_es_pblock(es), ext4_es_status(es)); | ||
| 550 | return; | ||
| 551 | } | ||
| 552 | } | ||
| 553 | } | ||
| 554 | |||
| 555 | static inline void ext4_es_insert_extent_check(struct inode *inode, | ||
| 556 | struct extent_status *es) | ||
| 557 | { | ||
| 558 | /* | ||
| 559 | * We don't need to worry about the race condition because | ||
| 560 | * caller takes i_data_sem locking. | ||
| 561 | */ | ||
| 562 | BUG_ON(!rwsem_is_locked(&EXT4_I(inode)->i_data_sem)); | ||
| 563 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) | ||
| 564 | ext4_es_insert_extent_ext_check(inode, es); | ||
| 565 | else | ||
| 566 | ext4_es_insert_extent_ind_check(inode, es); | ||
| 567 | } | ||
| 568 | #else | ||
| 569 | static inline void ext4_es_insert_extent_check(struct inode *inode, | ||
| 570 | struct extent_status *es) | ||
| 571 | { | ||
| 572 | } | ||
| 573 | #endif | ||
| 574 | |||
| 392 | static int __es_insert_extent(struct inode *inode, struct extent_status *newes) | 575 | static int __es_insert_extent(struct inode *inode, struct extent_status *newes) |
| 393 | { | 576 | { |
| 394 | struct ext4_es_tree *tree = &EXT4_I(inode)->i_es_tree; | 577 | struct ext4_es_tree *tree = &EXT4_I(inode)->i_es_tree; |
| @@ -471,6 +654,8 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk, | |||
| 471 | ext4_es_store_status(&newes, status); | 654 | ext4_es_store_status(&newes, status); |
| 472 | trace_ext4_es_insert_extent(inode, &newes); | 655 | trace_ext4_es_insert_extent(inode, &newes); |
| 473 | 656 | ||
| 657 | ext4_es_insert_extent_check(inode, &newes); | ||
| 658 | |||
| 474 | write_lock(&EXT4_I(inode)->i_es_lock); | 659 | write_lock(&EXT4_I(inode)->i_es_lock); |
| 475 | err = __es_remove_extent(inode, lblk, end); | 660 | err = __es_remove_extent(inode, lblk, end); |
| 476 | if (err != 0) | 661 | if (err != 0) |
| @@ -669,6 +854,23 @@ int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, | |||
| 669 | return err; | 854 | return err; |
| 670 | } | 855 | } |
| 671 | 856 | ||
| 857 | int ext4_es_zeroout(struct inode *inode, struct ext4_extent *ex) | ||
| 858 | { | ||
| 859 | ext4_lblk_t ee_block; | ||
| 860 | ext4_fsblk_t ee_pblock; | ||
| 861 | unsigned int ee_len; | ||
| 862 | |||
| 863 | ee_block = le32_to_cpu(ex->ee_block); | ||
| 864 | ee_len = ext4_ext_get_actual_len(ex); | ||
| 865 | ee_pblock = ext4_ext_pblock(ex); | ||
| 866 | |||
| 867 | if (ee_len == 0) | ||
| 868 | return 0; | ||
| 869 | |||
| 870 | return ext4_es_insert_extent(inode, ee_block, ee_len, ee_pblock, | ||
| 871 | EXTENT_STATUS_WRITTEN); | ||
| 872 | } | ||
| 873 | |||
| 672 | static int ext4_es_shrink(struct shrinker *shrink, struct shrink_control *sc) | 874 | static int ext4_es_shrink(struct shrinker *shrink, struct shrink_control *sc) |
| 673 | { | 875 | { |
| 674 | struct ext4_sb_info *sbi = container_of(shrink, | 876 | struct ext4_sb_info *sbi = container_of(shrink, |
diff --git a/fs/ext4/extents_status.h b/fs/ext4/extents_status.h index f190dfe969da..d8e2d4dc311e 100644 --- a/fs/ext4/extents_status.h +++ b/fs/ext4/extents_status.h | |||
| @@ -21,6 +21,12 @@ | |||
| 21 | #endif | 21 | #endif |
| 22 | 22 | ||
| 23 | /* | 23 | /* |
| 24 | * With ES_AGGRESSIVE_TEST defined, the result of es caching will be | ||
| 25 | * checked with old map_block's result. | ||
| 26 | */ | ||
| 27 | #define ES_AGGRESSIVE_TEST__ | ||
| 28 | |||
| 29 | /* | ||
| 24 | * These flags live in the high bits of extent_status.es_pblk | 30 | * These flags live in the high bits of extent_status.es_pblk |
| 25 | */ | 31 | */ |
| 26 | #define EXTENT_STATUS_WRITTEN (1ULL << 63) | 32 | #define EXTENT_STATUS_WRITTEN (1ULL << 63) |
| @@ -33,6 +39,8 @@ | |||
| 33 | EXTENT_STATUS_DELAYED | \ | 39 | EXTENT_STATUS_DELAYED | \ |
| 34 | EXTENT_STATUS_HOLE) | 40 | EXTENT_STATUS_HOLE) |
| 35 | 41 | ||
| 42 | struct ext4_extent; | ||
| 43 | |||
| 36 | struct extent_status { | 44 | struct extent_status { |
| 37 | struct rb_node rb_node; | 45 | struct rb_node rb_node; |
| 38 | ext4_lblk_t es_lblk; /* first logical block extent covers */ | 46 | ext4_lblk_t es_lblk; /* first logical block extent covers */ |
| @@ -58,6 +66,7 @@ extern void ext4_es_find_delayed_extent(struct inode *inode, ext4_lblk_t lblk, | |||
| 58 | struct extent_status *es); | 66 | struct extent_status *es); |
| 59 | extern int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk, | 67 | extern int ext4_es_lookup_extent(struct inode *inode, ext4_lblk_t lblk, |
| 60 | struct extent_status *es); | 68 | struct extent_status *es); |
| 69 | extern int ext4_es_zeroout(struct inode *inode, struct ext4_extent *ex); | ||
| 61 | 70 | ||
| 62 | static inline int ext4_es_is_written(struct extent_status *es) | 71 | static inline int ext4_es_is_written(struct extent_status *es) |
| 63 | { | 72 | { |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 32fd2b9075dd..6c5bb8d993fe 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
| @@ -324,8 +324,8 @@ error_return: | |||
| 324 | } | 324 | } |
| 325 | 325 | ||
| 326 | struct orlov_stats { | 326 | struct orlov_stats { |
| 327 | __u64 free_clusters; | ||
| 327 | __u32 free_inodes; | 328 | __u32 free_inodes; |
| 328 | __u32 free_clusters; | ||
| 329 | __u32 used_dirs; | 329 | __u32 used_dirs; |
| 330 | }; | 330 | }; |
| 331 | 331 | ||
| @@ -342,7 +342,7 @@ static void get_orlov_stats(struct super_block *sb, ext4_group_t g, | |||
| 342 | 342 | ||
| 343 | if (flex_size > 1) { | 343 | if (flex_size > 1) { |
| 344 | stats->free_inodes = atomic_read(&flex_group[g].free_inodes); | 344 | stats->free_inodes = atomic_read(&flex_group[g].free_inodes); |
| 345 | stats->free_clusters = atomic_read(&flex_group[g].free_clusters); | 345 | stats->free_clusters = atomic64_read(&flex_group[g].free_clusters); |
| 346 | stats->used_dirs = atomic_read(&flex_group[g].used_dirs); | 346 | stats->used_dirs = atomic_read(&flex_group[g].used_dirs); |
| 347 | return; | 347 | return; |
| 348 | } | 348 | } |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 9ea0cde3fa9e..b3a5213bc73e 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -185,8 +185,6 @@ void ext4_evict_inode(struct inode *inode) | |||
| 185 | 185 | ||
| 186 | trace_ext4_evict_inode(inode); | 186 | trace_ext4_evict_inode(inode); |
| 187 | 187 | ||
| 188 | ext4_ioend_wait(inode); | ||
| 189 | |||
| 190 | if (inode->i_nlink) { | 188 | if (inode->i_nlink) { |
| 191 | /* | 189 | /* |
| 192 | * When journalling data dirty buffers are tracked only in the | 190 | * When journalling data dirty buffers are tracked only in the |
| @@ -207,7 +205,8 @@ void ext4_evict_inode(struct inode *inode) | |||
| 207 | * don't use page cache. | 205 | * don't use page cache. |
| 208 | */ | 206 | */ |
| 209 | if (ext4_should_journal_data(inode) && | 207 | if (ext4_should_journal_data(inode) && |
| 210 | (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode))) { | 208 | (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode)) && |
| 209 | inode->i_ino != EXT4_JOURNAL_INO) { | ||
| 211 | journal_t *journal = EXT4_SB(inode->i_sb)->s_journal; | 210 | journal_t *journal = EXT4_SB(inode->i_sb)->s_journal; |
| 212 | tid_t commit_tid = EXT4_I(inode)->i_datasync_tid; | 211 | tid_t commit_tid = EXT4_I(inode)->i_datasync_tid; |
| 213 | 212 | ||
| @@ -216,6 +215,7 @@ void ext4_evict_inode(struct inode *inode) | |||
| 216 | filemap_write_and_wait(&inode->i_data); | 215 | filemap_write_and_wait(&inode->i_data); |
| 217 | } | 216 | } |
| 218 | truncate_inode_pages(&inode->i_data, 0); | 217 | truncate_inode_pages(&inode->i_data, 0); |
| 218 | ext4_ioend_shutdown(inode); | ||
| 219 | goto no_delete; | 219 | goto no_delete; |
| 220 | } | 220 | } |
| 221 | 221 | ||
| @@ -225,6 +225,7 @@ void ext4_evict_inode(struct inode *inode) | |||
| 225 | if (ext4_should_order_data(inode)) | 225 | if (ext4_should_order_data(inode)) |
| 226 | ext4_begin_ordered_truncate(inode, 0); | 226 | ext4_begin_ordered_truncate(inode, 0); |
| 227 | truncate_inode_pages(&inode->i_data, 0); | 227 | truncate_inode_pages(&inode->i_data, 0); |
| 228 | ext4_ioend_shutdown(inode); | ||
| 228 | 229 | ||
| 229 | if (is_bad_inode(inode)) | 230 | if (is_bad_inode(inode)) |
| 230 | goto no_delete; | 231 | goto no_delete; |
| @@ -482,6 +483,58 @@ static pgoff_t ext4_num_dirty_pages(struct inode *inode, pgoff_t idx, | |||
| 482 | return num; | 483 | return num; |
| 483 | } | 484 | } |
| 484 | 485 | ||
| 486 | #ifdef ES_AGGRESSIVE_TEST | ||
| 487 | static void ext4_map_blocks_es_recheck(handle_t *handle, | ||
| 488 | struct inode *inode, | ||
| 489 | struct ext4_map_blocks *es_map, | ||
| 490 | struct ext4_map_blocks *map, | ||
| 491 | int flags) | ||
| 492 | { | ||
| 493 | int retval; | ||
| 494 | |||
| 495 | map->m_flags = 0; | ||
| 496 | /* | ||
| 497 | * There is a race window that the result is not the same. | ||
| 498 | * e.g. xfstests #223 when dioread_nolock enables. The reason | ||
| 499 | * is that we lookup a block mapping in extent status tree with | ||
| 500 | * out taking i_data_sem. So at the time the unwritten extent | ||
| 501 | * could be converted. | ||
| 502 | */ | ||
| 503 | if (!(flags & EXT4_GET_BLOCKS_NO_LOCK)) | ||
| 504 | down_read((&EXT4_I(inode)->i_data_sem)); | ||
| 505 | if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { | ||
| 506 | retval = ext4_ext_map_blocks(handle, inode, map, flags & | ||
| 507 | EXT4_GET_BLOCKS_KEEP_SIZE); | ||
| 508 | } else { | ||
| 509 | retval = ext4_ind_map_blocks(handle, inode, map, flags & | ||
| 510 | EXT4_GET_BLOCKS_KEEP_SIZE); | ||
| 511 | } | ||
| 512 | if (!(flags & EXT4_GET_BLOCKS_NO_LOCK)) | ||
| 513 | up_read((&EXT4_I(inode)->i_data_sem)); | ||
| 514 | /* | ||
| 515 | * Clear EXT4_MAP_FROM_CLUSTER and EXT4_MAP_BOUNDARY flag | ||
| 516 | * because it shouldn't be marked in es_map->m_flags. | ||
| 517 | */ | ||
| 518 | map->m_flags &= ~(EXT4_MAP_FROM_CLUSTER | EXT4_MAP_BOUNDARY); | ||
| 519 | |||
| 520 | /* | ||
| 521 | * We don't check m_len because extent will be collpased in status | ||
| 522 | * tree. So the m_len might not equal. | ||
| 523 | */ | ||
| 524 | if (es_map->m_lblk != map->m_lblk || | ||
| 525 | es_map->m_flags != map->m_flags || | ||
| 526 | es_map->m_pblk != map->m_pblk) { | ||
| 527 | printk("ES cache assertation failed for inode: %lu " | ||
| 528 | "es_cached ex [%d/%d/%llu/%x] != " | ||
| 529 | "found ex [%d/%d/%llu/%x] retval %d flags %x\n", | ||
| 530 | inode->i_ino, es_map->m_lblk, es_map->m_len, | ||
| 531 | es_map->m_pblk, es_map->m_flags, map->m_lblk, | ||
| 532 | map->m_len, map->m_pblk, map->m_flags, | ||
| 533 | retval, flags); | ||
| 534 | } | ||
| 535 | } | ||
| 536 | #endif /* ES_AGGRESSIVE_TEST */ | ||
| 537 | |||
| 485 | /* | 538 | /* |
| 486 | * The ext4_map_blocks() function tries to look up the requested blocks, | 539 | * The ext4_map_blocks() function tries to look up the requested blocks, |
| 487 | * and returns if the blocks are already mapped. | 540 | * and returns if the blocks are already mapped. |
| @@ -509,6 +562,11 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, | |||
| 509 | { | 562 | { |
| 510 | struct extent_status es; | 563 | struct extent_status es; |
| 511 | int retval; | 564 | int retval; |
| 565 | #ifdef ES_AGGRESSIVE_TEST | ||
| 566 | struct ext4_map_blocks orig_map; | ||
| 567 | |||
| 568 | memcpy(&orig_map, map, sizeof(*map)); | ||
| 569 | #endif | ||
| 512 | 570 | ||
| 513 | map->m_flags = 0; | 571 | map->m_flags = 0; |
| 514 | ext_debug("ext4_map_blocks(): inode %lu, flag %d, max_blocks %u," | 572 | ext_debug("ext4_map_blocks(): inode %lu, flag %d, max_blocks %u," |
| @@ -531,6 +589,10 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, | |||
| 531 | } else { | 589 | } else { |
| 532 | BUG_ON(1); | 590 | BUG_ON(1); |
| 533 | } | 591 | } |
| 592 | #ifdef ES_AGGRESSIVE_TEST | ||
| 593 | ext4_map_blocks_es_recheck(handle, inode, map, | ||
| 594 | &orig_map, flags); | ||
| 595 | #endif | ||
| 534 | goto found; | 596 | goto found; |
| 535 | } | 597 | } |
| 536 | 598 | ||
| @@ -551,6 +613,15 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, | |||
| 551 | int ret; | 613 | int ret; |
| 552 | unsigned long long status; | 614 | unsigned long long status; |
| 553 | 615 | ||
| 616 | #ifdef ES_AGGRESSIVE_TEST | ||
| 617 | if (retval != map->m_len) { | ||
| 618 | printk("ES len assertation failed for inode: %lu " | ||
| 619 | "retval %d != map->m_len %d " | ||
| 620 | "in %s (lookup)\n", inode->i_ino, retval, | ||
| 621 | map->m_len, __func__); | ||
| 622 | } | ||
| 623 | #endif | ||
| 624 | |||
| 554 | status = map->m_flags & EXT4_MAP_UNWRITTEN ? | 625 | status = map->m_flags & EXT4_MAP_UNWRITTEN ? |
| 555 | EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; | 626 | EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; |
| 556 | if (!(flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) && | 627 | if (!(flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) && |
| @@ -643,6 +714,24 @@ found: | |||
| 643 | int ret; | 714 | int ret; |
| 644 | unsigned long long status; | 715 | unsigned long long status; |
| 645 | 716 | ||
| 717 | #ifdef ES_AGGRESSIVE_TEST | ||
| 718 | if (retval != map->m_len) { | ||
| 719 | printk("ES len assertation failed for inode: %lu " | ||
| 720 | "retval %d != map->m_len %d " | ||
| 721 | "in %s (allocation)\n", inode->i_ino, retval, | ||
| 722 | map->m_len, __func__); | ||
| 723 | } | ||
| 724 | #endif | ||
| 725 | |||
| 726 | /* | ||
| 727 | * If the extent has been zeroed out, we don't need to update | ||
| 728 | * extent status tree. | ||
| 729 | */ | ||
| 730 | if ((flags & EXT4_GET_BLOCKS_PRE_IO) && | ||
| 731 | ext4_es_lookup_extent(inode, map->m_lblk, &es)) { | ||
| 732 | if (ext4_es_is_written(&es)) | ||
| 733 | goto has_zeroout; | ||
| 734 | } | ||
| 646 | status = map->m_flags & EXT4_MAP_UNWRITTEN ? | 735 | status = map->m_flags & EXT4_MAP_UNWRITTEN ? |
| 647 | EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; | 736 | EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; |
| 648 | if (!(flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) && | 737 | if (!(flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) && |
| @@ -655,6 +744,7 @@ found: | |||
| 655 | retval = ret; | 744 | retval = ret; |
| 656 | } | 745 | } |
| 657 | 746 | ||
| 747 | has_zeroout: | ||
| 658 | up_write((&EXT4_I(inode)->i_data_sem)); | 748 | up_write((&EXT4_I(inode)->i_data_sem)); |
| 659 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { | 749 | if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) { |
| 660 | int ret = check_block_validity(inode, map); | 750 | int ret = check_block_validity(inode, map); |
| @@ -1216,6 +1306,55 @@ static int ext4_journalled_write_end(struct file *file, | |||
| 1216 | } | 1306 | } |
| 1217 | 1307 | ||
| 1218 | /* | 1308 | /* |
| 1309 | * Reserve a metadata for a single block located at lblock | ||
| 1310 | */ | ||
| 1311 | static int ext4_da_reserve_metadata(struct inode *inode, ext4_lblk_t lblock) | ||
| 1312 | { | ||
| 1313 | int retries = 0; | ||
| 1314 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | ||
| 1315 | struct ext4_inode_info *ei = EXT4_I(inode); | ||
| 1316 | unsigned int md_needed; | ||
| 1317 | ext4_lblk_t save_last_lblock; | ||
| 1318 | int save_len; | ||
| 1319 | |||
| 1320 | /* | ||
| 1321 | * recalculate the amount of metadata blocks to reserve | ||
| 1322 | * in order to allocate nrblocks | ||
| 1323 | * worse case is one extent per block | ||
| 1324 | */ | ||
| 1325 | repeat: | ||
| 1326 | spin_lock(&ei->i_block_reservation_lock); | ||
| 1327 | /* | ||
| 1328 | * ext4_calc_metadata_amount() has side effects, which we have | ||
| 1329 | * to be prepared undo if we fail to claim space. | ||
| 1330 | */ | ||
| 1331 | save_len = ei->i_da_metadata_calc_len; | ||
| 1332 | save_last_lblock = ei->i_da_metadata_calc_last_lblock; | ||
| 1333 | md_needed = EXT4_NUM_B2C(sbi, | ||
| 1334 | ext4_calc_metadata_amount(inode, lblock)); | ||
| 1335 | trace_ext4_da_reserve_space(inode, md_needed); | ||
| 1336 | |||
| 1337 | /* | ||
| 1338 | * We do still charge estimated metadata to the sb though; | ||
| 1339 | * we cannot afford to run out of free blocks. | ||
| 1340 | */ | ||
| 1341 | if (ext4_claim_free_clusters(sbi, md_needed, 0)) { | ||
| 1342 | ei->i_da_metadata_calc_len = save_len; | ||
| 1343 | ei->i_da_metadata_calc_last_lblock = save_last_lblock; | ||
| 1344 | spin_unlock(&ei->i_block_reservation_lock); | ||
| 1345 | if (ext4_should_retry_alloc(inode->i_sb, &retries)) { | ||
| 1346 | cond_resched(); | ||
| 1347 | goto repeat; | ||
| 1348 | } | ||
| 1349 | return -ENOSPC; | ||
| 1350 | } | ||
| 1351 | ei->i_reserved_meta_blocks += md_needed; | ||
| 1352 | spin_unlock(&ei->i_block_reservation_lock); | ||
| 1353 | |||
| 1354 | return 0; /* success */ | ||
| 1355 | } | ||
| 1356 | |||
| 1357 | /* | ||
| 1219 | * Reserve a single cluster located at lblock | 1358 | * Reserve a single cluster located at lblock |
| 1220 | */ | 1359 | */ |
| 1221 | static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock) | 1360 | static int ext4_da_reserve_space(struct inode *inode, ext4_lblk_t lblock) |
| @@ -1263,7 +1402,7 @@ repeat: | |||
| 1263 | ei->i_da_metadata_calc_last_lblock = save_last_lblock; | 1402 | ei->i_da_metadata_calc_last_lblock = save_last_lblock; |
| 1264 | spin_unlock(&ei->i_block_reservation_lock); | 1403 | spin_unlock(&ei->i_block_reservation_lock); |
| 1265 | if (ext4_should_retry_alloc(inode->i_sb, &retries)) { | 1404 | if (ext4_should_retry_alloc(inode->i_sb, &retries)) { |
| 1266 | yield(); | 1405 | cond_resched(); |
| 1267 | goto repeat; | 1406 | goto repeat; |
| 1268 | } | 1407 | } |
| 1269 | dquot_release_reservation_block(inode, EXT4_C2B(sbi, 1)); | 1408 | dquot_release_reservation_block(inode, EXT4_C2B(sbi, 1)); |
| @@ -1768,6 +1907,11 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock, | |||
| 1768 | struct extent_status es; | 1907 | struct extent_status es; |
| 1769 | int retval; | 1908 | int retval; |
| 1770 | sector_t invalid_block = ~((sector_t) 0xffff); | 1909 | sector_t invalid_block = ~((sector_t) 0xffff); |
| 1910 | #ifdef ES_AGGRESSIVE_TEST | ||
| 1911 | struct ext4_map_blocks orig_map; | ||
| 1912 | |||
| 1913 | memcpy(&orig_map, map, sizeof(*map)); | ||
| 1914 | #endif | ||
| 1771 | 1915 | ||
| 1772 | if (invalid_block < ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es)) | 1916 | if (invalid_block < ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es)) |
| 1773 | invalid_block = ~0; | 1917 | invalid_block = ~0; |
| @@ -1809,6 +1953,9 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock, | |||
| 1809 | else | 1953 | else |
| 1810 | BUG_ON(1); | 1954 | BUG_ON(1); |
| 1811 | 1955 | ||
| 1956 | #ifdef ES_AGGRESSIVE_TEST | ||
| 1957 | ext4_map_blocks_es_recheck(NULL, inode, map, &orig_map, 0); | ||
| 1958 | #endif | ||
| 1812 | return retval; | 1959 | return retval; |
| 1813 | } | 1960 | } |
| 1814 | 1961 | ||
| @@ -1843,8 +1990,11 @@ add_delayed: | |||
| 1843 | * XXX: __block_prepare_write() unmaps passed block, | 1990 | * XXX: __block_prepare_write() unmaps passed block, |
| 1844 | * is it OK? | 1991 | * is it OK? |
| 1845 | */ | 1992 | */ |
| 1846 | /* If the block was allocated from previously allocated cluster, | 1993 | /* |
| 1847 | * then we dont need to reserve it again. */ | 1994 | * If the block was allocated from previously allocated cluster, |
| 1995 | * then we don't need to reserve it again. However we still need | ||
| 1996 | * to reserve metadata for every block we're going to write. | ||
| 1997 | */ | ||
| 1848 | if (!(map->m_flags & EXT4_MAP_FROM_CLUSTER)) { | 1998 | if (!(map->m_flags & EXT4_MAP_FROM_CLUSTER)) { |
| 1849 | ret = ext4_da_reserve_space(inode, iblock); | 1999 | ret = ext4_da_reserve_space(inode, iblock); |
| 1850 | if (ret) { | 2000 | if (ret) { |
| @@ -1852,6 +2002,13 @@ add_delayed: | |||
| 1852 | retval = ret; | 2002 | retval = ret; |
| 1853 | goto out_unlock; | 2003 | goto out_unlock; |
| 1854 | } | 2004 | } |
| 2005 | } else { | ||
| 2006 | ret = ext4_da_reserve_metadata(inode, iblock); | ||
| 2007 | if (ret) { | ||
| 2008 | /* not enough space to reserve */ | ||
| 2009 | retval = ret; | ||
| 2010 | goto out_unlock; | ||
| 2011 | } | ||
| 1855 | } | 2012 | } |
| 1856 | 2013 | ||
| 1857 | ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len, | 2014 | ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len, |
| @@ -1873,6 +2030,15 @@ add_delayed: | |||
| 1873 | int ret; | 2030 | int ret; |
| 1874 | unsigned long long status; | 2031 | unsigned long long status; |
| 1875 | 2032 | ||
| 2033 | #ifdef ES_AGGRESSIVE_TEST | ||
| 2034 | if (retval != map->m_len) { | ||
| 2035 | printk("ES len assertation failed for inode: %lu " | ||
| 2036 | "retval %d != map->m_len %d " | ||
| 2037 | "in %s (lookup)\n", inode->i_ino, retval, | ||
| 2038 | map->m_len, __func__); | ||
| 2039 | } | ||
| 2040 | #endif | ||
| 2041 | |||
| 1876 | status = map->m_flags & EXT4_MAP_UNWRITTEN ? | 2042 | status = map->m_flags & EXT4_MAP_UNWRITTEN ? |
| 1877 | EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; | 2043 | EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; |
| 1878 | ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len, | 2044 | ret = ext4_es_insert_extent(inode, map->m_lblk, map->m_len, |
| @@ -2908,8 +3074,8 @@ static int ext4_releasepage(struct page *page, gfp_t wait) | |||
| 2908 | 3074 | ||
| 2909 | trace_ext4_releasepage(page); | 3075 | trace_ext4_releasepage(page); |
| 2910 | 3076 | ||
| 2911 | WARN_ON(PageChecked(page)); | 3077 | /* Page has dirty journalled data -> cannot release */ |
| 2912 | if (!page_has_buffers(page)) | 3078 | if (PageChecked(page)) |
| 2913 | return 0; | 3079 | return 0; |
| 2914 | if (journal) | 3080 | if (journal) |
| 2915 | return jbd2_journal_try_to_free_buffers(journal, page, wait); | 3081 | return jbd2_journal_try_to_free_buffers(journal, page, wait); |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 7bb713a46fe4..ee6614bdb639 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
| @@ -2804,8 +2804,8 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, | |||
| 2804 | if (sbi->s_log_groups_per_flex) { | 2804 | if (sbi->s_log_groups_per_flex) { |
| 2805 | ext4_group_t flex_group = ext4_flex_group(sbi, | 2805 | ext4_group_t flex_group = ext4_flex_group(sbi, |
| 2806 | ac->ac_b_ex.fe_group); | 2806 | ac->ac_b_ex.fe_group); |
| 2807 | atomic_sub(ac->ac_b_ex.fe_len, | 2807 | atomic64_sub(ac->ac_b_ex.fe_len, |
| 2808 | &sbi->s_flex_groups[flex_group].free_clusters); | 2808 | &sbi->s_flex_groups[flex_group].free_clusters); |
| 2809 | } | 2809 | } |
| 2810 | 2810 | ||
| 2811 | err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); | 2811 | err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); |
| @@ -3692,11 +3692,7 @@ repeat: | |||
| 3692 | if (free < needed && busy) { | 3692 | if (free < needed && busy) { |
| 3693 | busy = 0; | 3693 | busy = 0; |
| 3694 | ext4_unlock_group(sb, group); | 3694 | ext4_unlock_group(sb, group); |
| 3695 | /* | 3695 | cond_resched(); |
| 3696 | * Yield the CPU here so that we don't get soft lockup | ||
| 3697 | * in non preempt case. | ||
| 3698 | */ | ||
| 3699 | yield(); | ||
| 3700 | goto repeat; | 3696 | goto repeat; |
| 3701 | } | 3697 | } |
| 3702 | 3698 | ||
| @@ -4246,7 +4242,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, | |||
| 4246 | ext4_claim_free_clusters(sbi, ar->len, ar->flags)) { | 4242 | ext4_claim_free_clusters(sbi, ar->len, ar->flags)) { |
| 4247 | 4243 | ||
| 4248 | /* let others to free the space */ | 4244 | /* let others to free the space */ |
| 4249 | yield(); | 4245 | cond_resched(); |
| 4250 | ar->len = ar->len >> 1; | 4246 | ar->len = ar->len >> 1; |
| 4251 | } | 4247 | } |
| 4252 | if (!ar->len) { | 4248 | if (!ar->len) { |
| @@ -4464,7 +4460,6 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, | |||
| 4464 | struct buffer_head *bitmap_bh = NULL; | 4460 | struct buffer_head *bitmap_bh = NULL; |
| 4465 | struct super_block *sb = inode->i_sb; | 4461 | struct super_block *sb = inode->i_sb; |
| 4466 | struct ext4_group_desc *gdp; | 4462 | struct ext4_group_desc *gdp; |
| 4467 | unsigned long freed = 0; | ||
| 4468 | unsigned int overflow; | 4463 | unsigned int overflow; |
| 4469 | ext4_grpblk_t bit; | 4464 | ext4_grpblk_t bit; |
| 4470 | struct buffer_head *gd_bh; | 4465 | struct buffer_head *gd_bh; |
| @@ -4666,14 +4661,12 @@ do_more: | |||
| 4666 | 4661 | ||
| 4667 | if (sbi->s_log_groups_per_flex) { | 4662 | if (sbi->s_log_groups_per_flex) { |
| 4668 | ext4_group_t flex_group = ext4_flex_group(sbi, block_group); | 4663 | ext4_group_t flex_group = ext4_flex_group(sbi, block_group); |
| 4669 | atomic_add(count_clusters, | 4664 | atomic64_add(count_clusters, |
| 4670 | &sbi->s_flex_groups[flex_group].free_clusters); | 4665 | &sbi->s_flex_groups[flex_group].free_clusters); |
| 4671 | } | 4666 | } |
| 4672 | 4667 | ||
| 4673 | ext4_mb_unload_buddy(&e4b); | 4668 | ext4_mb_unload_buddy(&e4b); |
| 4674 | 4669 | ||
| 4675 | freed += count; | ||
| 4676 | |||
| 4677 | if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE)) | 4670 | if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE)) |
| 4678 | dquot_free_block(inode, EXT4_C2B(sbi, count_clusters)); | 4671 | dquot_free_block(inode, EXT4_C2B(sbi, count_clusters)); |
| 4679 | 4672 | ||
| @@ -4811,8 +4804,8 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb, | |||
| 4811 | 4804 | ||
| 4812 | if (sbi->s_log_groups_per_flex) { | 4805 | if (sbi->s_log_groups_per_flex) { |
| 4813 | ext4_group_t flex_group = ext4_flex_group(sbi, block_group); | 4806 | ext4_group_t flex_group = ext4_flex_group(sbi, block_group); |
| 4814 | atomic_add(EXT4_NUM_B2C(sbi, blocks_freed), | 4807 | atomic64_add(EXT4_NUM_B2C(sbi, blocks_freed), |
| 4815 | &sbi->s_flex_groups[flex_group].free_clusters); | 4808 | &sbi->s_flex_groups[flex_group].free_clusters); |
| 4816 | } | 4809 | } |
| 4817 | 4810 | ||
| 4818 | ext4_mb_unload_buddy(&e4b); | 4811 | ext4_mb_unload_buddy(&e4b); |
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c index 4e81d47aa8cb..33e1c086858b 100644 --- a/fs/ext4/move_extent.c +++ b/fs/ext4/move_extent.c | |||
| @@ -32,16 +32,18 @@ | |||
| 32 | */ | 32 | */ |
| 33 | static inline int | 33 | static inline int |
| 34 | get_ext_path(struct inode *inode, ext4_lblk_t lblock, | 34 | get_ext_path(struct inode *inode, ext4_lblk_t lblock, |
| 35 | struct ext4_ext_path **path) | 35 | struct ext4_ext_path **orig_path) |
| 36 | { | 36 | { |
| 37 | int ret = 0; | 37 | int ret = 0; |
| 38 | struct ext4_ext_path *path; | ||
| 38 | 39 | ||
| 39 | *path = ext4_ext_find_extent(inode, lblock, *path); | 40 | path = ext4_ext_find_extent(inode, lblock, *orig_path); |
| 40 | if (IS_ERR(*path)) { | 41 | if (IS_ERR(path)) |
| 41 | ret = PTR_ERR(*path); | 42 | ret = PTR_ERR(path); |
| 42 | *path = NULL; | 43 | else if (path[ext_depth(inode)].p_ext == NULL) |
| 43 | } else if ((*path)[ext_depth(inode)].p_ext == NULL) | ||
| 44 | ret = -ENODATA; | 44 | ret = -ENODATA; |
| 45 | else | ||
| 46 | *orig_path = path; | ||
| 45 | 47 | ||
| 46 | return ret; | 48 | return ret; |
| 47 | } | 49 | } |
| @@ -611,24 +613,25 @@ mext_check_coverage(struct inode *inode, ext4_lblk_t from, ext4_lblk_t count, | |||
| 611 | { | 613 | { |
| 612 | struct ext4_ext_path *path = NULL; | 614 | struct ext4_ext_path *path = NULL; |
| 613 | struct ext4_extent *ext; | 615 | struct ext4_extent *ext; |
| 616 | int ret = 0; | ||
| 614 | ext4_lblk_t last = from + count; | 617 | ext4_lblk_t last = from + count; |
| 615 | while (from < last) { | 618 | while (from < last) { |
| 616 | *err = get_ext_path(inode, from, &path); | 619 | *err = get_ext_path(inode, from, &path); |
| 617 | if (*err) | 620 | if (*err) |
| 618 | return 0; | 621 | goto out; |
| 619 | ext = path[ext_depth(inode)].p_ext; | 622 | ext = path[ext_depth(inode)].p_ext; |
| 620 | if (!ext) { | 623 | if (uninit != ext4_ext_is_uninitialized(ext)) |
| 621 | ext4_ext_drop_refs(path); | 624 | goto out; |
| 622 | return 0; | ||
| 623 | } | ||
| 624 | if (uninit != ext4_ext_is_uninitialized(ext)) { | ||
| 625 | ext4_ext_drop_refs(path); | ||
| 626 | return 0; | ||
| 627 | } | ||
| 628 | from += ext4_ext_get_actual_len(ext); | 625 | from += ext4_ext_get_actual_len(ext); |
| 629 | ext4_ext_drop_refs(path); | 626 | ext4_ext_drop_refs(path); |
| 630 | } | 627 | } |
| 631 | return 1; | 628 | ret = 1; |
| 629 | out: | ||
| 630 | if (path) { | ||
| 631 | ext4_ext_drop_refs(path); | ||
| 632 | kfree(path); | ||
| 633 | } | ||
| 634 | return ret; | ||
| 632 | } | 635 | } |
| 633 | 636 | ||
| 634 | /** | 637 | /** |
| @@ -666,6 +669,14 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode, | |||
| 666 | int replaced_count = 0; | 669 | int replaced_count = 0; |
| 667 | int dext_alen; | 670 | int dext_alen; |
| 668 | 671 | ||
| 672 | *err = ext4_es_remove_extent(orig_inode, from, count); | ||
| 673 | if (*err) | ||
| 674 | goto out; | ||
| 675 | |||
| 676 | *err = ext4_es_remove_extent(donor_inode, from, count); | ||
| 677 | if (*err) | ||
| 678 | goto out; | ||
| 679 | |||
| 669 | /* Get the original extent for the block "orig_off" */ | 680 | /* Get the original extent for the block "orig_off" */ |
| 670 | *err = get_ext_path(orig_inode, orig_off, &orig_path); | 681 | *err = get_ext_path(orig_inode, orig_off, &orig_path); |
| 671 | if (*err) | 682 | if (*err) |
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 809b31003ecc..047a6de04a0a 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c | |||
| @@ -50,11 +50,21 @@ void ext4_exit_pageio(void) | |||
| 50 | kmem_cache_destroy(io_page_cachep); | 50 | kmem_cache_destroy(io_page_cachep); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | void ext4_ioend_wait(struct inode *inode) | 53 | /* |
| 54 | * This function is called by ext4_evict_inode() to make sure there is | ||
| 55 | * no more pending I/O completion work left to do. | ||
| 56 | */ | ||
| 57 | void ext4_ioend_shutdown(struct inode *inode) | ||
| 54 | { | 58 | { |
| 55 | wait_queue_head_t *wq = ext4_ioend_wq(inode); | 59 | wait_queue_head_t *wq = ext4_ioend_wq(inode); |
| 56 | 60 | ||
| 57 | wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_ioend_count) == 0)); | 61 | wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_ioend_count) == 0)); |
| 62 | /* | ||
| 63 | * We need to make sure the work structure is finished being | ||
| 64 | * used before we let the inode get destroyed. | ||
| 65 | */ | ||
| 66 | if (work_pending(&EXT4_I(inode)->i_unwritten_work)) | ||
| 67 | cancel_work_sync(&EXT4_I(inode)->i_unwritten_work); | ||
| 58 | } | 68 | } |
| 59 | 69 | ||
| 60 | static void put_io_page(struct ext4_io_page *io_page) | 70 | static void put_io_page(struct ext4_io_page *io_page) |
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index b2c8ee56eb98..c169477a62c9 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
| @@ -1360,8 +1360,8 @@ static void ext4_update_super(struct super_block *sb, | |||
| 1360 | sbi->s_log_groups_per_flex) { | 1360 | sbi->s_log_groups_per_flex) { |
| 1361 | ext4_group_t flex_group; | 1361 | ext4_group_t flex_group; |
| 1362 | flex_group = ext4_flex_group(sbi, group_data[0].group); | 1362 | flex_group = ext4_flex_group(sbi, group_data[0].group); |
| 1363 | atomic_add(EXT4_NUM_B2C(sbi, free_blocks), | 1363 | atomic64_add(EXT4_NUM_B2C(sbi, free_blocks), |
| 1364 | &sbi->s_flex_groups[flex_group].free_clusters); | 1364 | &sbi->s_flex_groups[flex_group].free_clusters); |
| 1365 | atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count, | 1365 | atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count, |
| 1366 | &sbi->s_flex_groups[flex_group].free_inodes); | 1366 | &sbi->s_flex_groups[flex_group].free_inodes); |
| 1367 | } | 1367 | } |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 34e855219231..5d6d53578124 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -91,6 +91,7 @@ static struct file_system_type ext2_fs_type = { | |||
| 91 | .fs_flags = FS_REQUIRES_DEV, | 91 | .fs_flags = FS_REQUIRES_DEV, |
| 92 | }; | 92 | }; |
| 93 | MODULE_ALIAS_FS("ext2"); | 93 | MODULE_ALIAS_FS("ext2"); |
| 94 | MODULE_ALIAS("ext2"); | ||
| 94 | #define IS_EXT2_SB(sb) ((sb)->s_bdev->bd_holder == &ext2_fs_type) | 95 | #define IS_EXT2_SB(sb) ((sb)->s_bdev->bd_holder == &ext2_fs_type) |
| 95 | #else | 96 | #else |
| 96 | #define IS_EXT2_SB(sb) (0) | 97 | #define IS_EXT2_SB(sb) (0) |
| @@ -106,6 +107,7 @@ static struct file_system_type ext3_fs_type = { | |||
| 106 | .fs_flags = FS_REQUIRES_DEV, | 107 | .fs_flags = FS_REQUIRES_DEV, |
| 107 | }; | 108 | }; |
| 108 | MODULE_ALIAS_FS("ext3"); | 109 | MODULE_ALIAS_FS("ext3"); |
| 110 | MODULE_ALIAS("ext3"); | ||
| 109 | #define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type) | 111 | #define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type) |
| 110 | #else | 112 | #else |
| 111 | #define IS_EXT3_SB(sb) (0) | 113 | #define IS_EXT3_SB(sb) (0) |
| @@ -1925,8 +1927,8 @@ static int ext4_fill_flex_info(struct super_block *sb) | |||
| 1925 | flex_group = ext4_flex_group(sbi, i); | 1927 | flex_group = ext4_flex_group(sbi, i); |
| 1926 | atomic_add(ext4_free_inodes_count(sb, gdp), | 1928 | atomic_add(ext4_free_inodes_count(sb, gdp), |
| 1927 | &sbi->s_flex_groups[flex_group].free_inodes); | 1929 | &sbi->s_flex_groups[flex_group].free_inodes); |
| 1928 | atomic_add(ext4_free_group_clusters(sb, gdp), | 1930 | atomic64_add(ext4_free_group_clusters(sb, gdp), |
| 1929 | &sbi->s_flex_groups[flex_group].free_clusters); | 1931 | &sbi->s_flex_groups[flex_group].free_clusters); |
| 1930 | atomic_add(ext4_used_dirs_count(sb, gdp), | 1932 | atomic_add(ext4_used_dirs_count(sb, gdp), |
| 1931 | &sbi->s_flex_groups[flex_group].used_dirs); | 1933 | &sbi->s_flex_groups[flex_group].used_dirs); |
| 1932 | } | 1934 | } |
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c index 455074308069..e37eb274e492 100644 --- a/fs/freevxfs/vxfs_super.c +++ b/fs/freevxfs/vxfs_super.c | |||
| @@ -258,6 +258,7 @@ static struct file_system_type vxfs_fs_type = { | |||
| 258 | .fs_flags = FS_REQUIRES_DEV, | 258 | .fs_flags = FS_REQUIRES_DEV, |
| 259 | }; | 259 | }; |
| 260 | MODULE_ALIAS_FS("vxfs"); /* makes mount -t vxfs autoload the module */ | 260 | MODULE_ALIAS_FS("vxfs"); /* makes mount -t vxfs autoload the module */ |
| 261 | MODULE_ALIAS("vxfs"); | ||
| 261 | 262 | ||
| 262 | static int __init | 263 | static int __init |
| 263 | vxfs_init(void) | 264 | vxfs_init(void) |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index fbabb906066f..0f6e52d22b84 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
| @@ -845,15 +845,8 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 845 | return err; | 845 | return err; |
| 846 | 846 | ||
| 847 | if ((attr->ia_valid & ATTR_SIZE) && | 847 | if ((attr->ia_valid & ATTR_SIZE) && |
| 848 | attr->ia_size != i_size_read(inode)) { | 848 | attr->ia_size != i_size_read(inode)) |
| 849 | int error; | ||
| 850 | |||
| 851 | error = inode_newsize_ok(inode, attr->ia_size); | ||
| 852 | if (error) | ||
| 853 | return error; | ||
| 854 | |||
| 855 | truncate_setsize(inode, attr->ia_size); | 849 | truncate_setsize(inode, attr->ia_size); |
| 856 | } | ||
| 857 | 850 | ||
| 858 | setattr_copy(inode, attr); | 851 | setattr_copy(inode, attr); |
| 859 | mark_inode_dirty(inode); | 852 | mark_inode_dirty(inode); |
| @@ -993,6 +986,7 @@ static struct file_system_type hostfs_type = { | |||
| 993 | .kill_sb = hostfs_kill_sb, | 986 | .kill_sb = hostfs_kill_sb, |
| 994 | .fs_flags = 0, | 987 | .fs_flags = 0, |
| 995 | }; | 988 | }; |
| 989 | MODULE_ALIAS_FS("hostfs"); | ||
| 996 | 990 | ||
| 997 | static int __init init_hostfs(void) | 991 | static int __init init_hostfs(void) |
| 998 | { | 992 | { |
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index a3076228523d..a0617e706957 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c | |||
| @@ -688,6 +688,7 @@ static struct file_system_type hpfs_fs_type = { | |||
| 688 | .kill_sb = kill_block_super, | 688 | .kill_sb = kill_block_super, |
| 689 | .fs_flags = FS_REQUIRES_DEV, | 689 | .fs_flags = FS_REQUIRES_DEV, |
| 690 | }; | 690 | }; |
| 691 | MODULE_ALIAS_FS("hpfs"); | ||
| 691 | 692 | ||
| 692 | static int __init init_hpfs_fs(void) | 693 | static int __init init_hpfs_fs(void) |
| 693 | { | 694 | { |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index a67f16e846a2..d9b8aebdeb22 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
| @@ -1557,6 +1557,7 @@ static struct file_system_type iso9660_fs_type = { | |||
| 1557 | .fs_flags = FS_REQUIRES_DEV, | 1557 | .fs_flags = FS_REQUIRES_DEV, |
| 1558 | }; | 1558 | }; |
| 1559 | MODULE_ALIAS_FS("iso9660"); | 1559 | MODULE_ALIAS_FS("iso9660"); |
| 1560 | MODULE_ALIAS("iso9660"); | ||
| 1560 | 1561 | ||
| 1561 | static int __init init_iso9660_fs(void) | 1562 | static int __init init_iso9660_fs(void) |
| 1562 | { | 1563 | { |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index d6ee5aed56b1..325bc019ed88 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
| @@ -1065,9 +1065,12 @@ out: | |||
| 1065 | void jbd2_journal_set_triggers(struct buffer_head *bh, | 1065 | void jbd2_journal_set_triggers(struct buffer_head *bh, |
| 1066 | struct jbd2_buffer_trigger_type *type) | 1066 | struct jbd2_buffer_trigger_type *type) |
| 1067 | { | 1067 | { |
| 1068 | struct journal_head *jh = bh2jh(bh); | 1068 | struct journal_head *jh = jbd2_journal_grab_journal_head(bh); |
| 1069 | 1069 | ||
| 1070 | if (WARN_ON(!jh)) | ||
| 1071 | return; | ||
| 1070 | jh->b_triggers = type; | 1072 | jh->b_triggers = type; |
| 1073 | jbd2_journal_put_journal_head(jh); | ||
| 1071 | } | 1074 | } |
| 1072 | 1075 | ||
| 1073 | void jbd2_buffer_frozen_trigger(struct journal_head *jh, void *mapped_data, | 1076 | void jbd2_buffer_frozen_trigger(struct journal_head *jh, void *mapped_data, |
| @@ -1119,17 +1122,18 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) | |||
| 1119 | { | 1122 | { |
| 1120 | transaction_t *transaction = handle->h_transaction; | 1123 | transaction_t *transaction = handle->h_transaction; |
| 1121 | journal_t *journal = transaction->t_journal; | 1124 | journal_t *journal = transaction->t_journal; |
| 1122 | struct journal_head *jh = bh2jh(bh); | 1125 | struct journal_head *jh; |
| 1123 | int ret = 0; | 1126 | int ret = 0; |
| 1124 | 1127 | ||
| 1125 | jbd_debug(5, "journal_head %p\n", jh); | ||
| 1126 | JBUFFER_TRACE(jh, "entry"); | ||
| 1127 | if (is_handle_aborted(handle)) | 1128 | if (is_handle_aborted(handle)) |
| 1128 | goto out; | 1129 | goto out; |
| 1129 | if (!buffer_jbd(bh)) { | 1130 | jh = jbd2_journal_grab_journal_head(bh); |
| 1131 | if (!jh) { | ||
| 1130 | ret = -EUCLEAN; | 1132 | ret = -EUCLEAN; |
| 1131 | goto out; | 1133 | goto out; |
| 1132 | } | 1134 | } |
| 1135 | jbd_debug(5, "journal_head %p\n", jh); | ||
| 1136 | JBUFFER_TRACE(jh, "entry"); | ||
| 1133 | 1137 | ||
| 1134 | jbd_lock_bh_state(bh); | 1138 | jbd_lock_bh_state(bh); |
| 1135 | 1139 | ||
| @@ -1220,6 +1224,7 @@ int jbd2_journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) | |||
| 1220 | spin_unlock(&journal->j_list_lock); | 1224 | spin_unlock(&journal->j_list_lock); |
| 1221 | out_unlock_bh: | 1225 | out_unlock_bh: |
| 1222 | jbd_unlock_bh_state(bh); | 1226 | jbd_unlock_bh_state(bh); |
| 1227 | jbd2_journal_put_journal_head(jh); | ||
| 1223 | out: | 1228 | out: |
| 1224 | JBUFFER_TRACE(jh, "exit"); | 1229 | JBUFFER_TRACE(jh, "exit"); |
| 1225 | WARN_ON(ret); /* All errors are bugs, so dump the stack */ | 1230 | WARN_ON(ret); /* All errors are bugs, so dump the stack */ |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 95cdcb208dfb..2f8a29db0f1b 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
| @@ -335,6 +335,7 @@ struct file_system_type nfs4_fs_type = { | |||
| 335 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, | 335 | .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, |
| 336 | }; | 336 | }; |
| 337 | MODULE_ALIAS_FS("nfs4"); | 337 | MODULE_ALIAS_FS("nfs4"); |
| 338 | MODULE_ALIAS("nfs4"); | ||
| 338 | EXPORT_SYMBOL_GPL(nfs4_fs_type); | 339 | EXPORT_SYMBOL_GPL(nfs4_fs_type); |
| 339 | 340 | ||
| 340 | static int __init register_nfs4_fs(void) | 341 | static int __init register_nfs4_fs(void) |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 16d39c6c4fbb..2e27430b9070 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
| @@ -230,37 +230,6 @@ static void nfs4_file_put_access(struct nfs4_file *fp, int oflag) | |||
| 230 | __nfs4_file_put_access(fp, oflag); | 230 | __nfs4_file_put_access(fp, oflag); |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | static inline int get_new_stid(struct nfs4_stid *stid) | ||
| 234 | { | ||
| 235 | static int min_stateid = 0; | ||
| 236 | struct idr *stateids = &stid->sc_client->cl_stateids; | ||
| 237 | int new_stid; | ||
| 238 | int error; | ||
| 239 | |||
| 240 | error = idr_get_new_above(stateids, stid, min_stateid, &new_stid); | ||
| 241 | /* | ||
| 242 | * Note: the necessary preallocation was done in | ||
| 243 | * nfs4_alloc_stateid(). The idr code caps the number of | ||
| 244 | * preallocations that can exist at a time, but the state lock | ||
| 245 | * prevents anyone from using ours before we get here: | ||
| 246 | */ | ||
| 247 | WARN_ON_ONCE(error); | ||
| 248 | /* | ||
| 249 | * It shouldn't be a problem to reuse an opaque stateid value. | ||
| 250 | * I don't think it is for 4.1. But with 4.0 I worry that, for | ||
| 251 | * example, a stray write retransmission could be accepted by | ||
| 252 | * the server when it should have been rejected. Therefore, | ||
| 253 | * adopt a trick from the sctp code to attempt to maximize the | ||
| 254 | * amount of time until an id is reused, by ensuring they always | ||
| 255 | * "increase" (mod INT_MAX): | ||
| 256 | */ | ||
| 257 | |||
| 258 | min_stateid = new_stid+1; | ||
| 259 | if (min_stateid == INT_MAX) | ||
| 260 | min_stateid = 0; | ||
| 261 | return new_stid; | ||
| 262 | } | ||
| 263 | |||
| 264 | static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct | 233 | static struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct |
| 265 | kmem_cache *slab) | 234 | kmem_cache *slab) |
| 266 | { | 235 | { |
| @@ -273,9 +242,8 @@ kmem_cache *slab) | |||
| 273 | if (!stid) | 242 | if (!stid) |
| 274 | return NULL; | 243 | return NULL; |
| 275 | 244 | ||
| 276 | if (!idr_pre_get(stateids, GFP_KERNEL)) | 245 | new_id = idr_alloc(stateids, stid, min_stateid, 0, GFP_KERNEL); |
| 277 | goto out_free; | 246 | if (new_id < 0) |
| 278 | if (idr_get_new_above(stateids, stid, min_stateid, &new_id)) | ||
| 279 | goto out_free; | 247 | goto out_free; |
| 280 | stid->sc_client = cl; | 248 | stid->sc_client = cl; |
| 281 | stid->sc_type = 0; | 249 | stid->sc_type = 0; |
| @@ -863,6 +863,9 @@ pipe_rdwr_open(struct inode *inode, struct file *filp) | |||
| 863 | { | 863 | { |
| 864 | int ret = -ENOENT; | 864 | int ret = -ENOENT; |
| 865 | 865 | ||
| 866 | if (!(filp->f_mode & (FMODE_READ|FMODE_WRITE))) | ||
| 867 | return -EINVAL; | ||
| 868 | |||
| 866 | mutex_lock(&inode->i_mutex); | 869 | mutex_lock(&inode->i_mutex); |
| 867 | 870 | ||
| 868 | if (inode->i_pipe) { | 871 | if (inode->i_pipe) { |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index a86aebc9ba7c..869116c2afbe 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
| @@ -446,9 +446,10 @@ static const struct file_operations proc_reg_file_ops_no_compat = { | |||
| 446 | 446 | ||
| 447 | struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) | 447 | struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) |
| 448 | { | 448 | { |
| 449 | struct inode *inode = iget_locked(sb, de->low_ino); | 449 | struct inode *inode = new_inode_pseudo(sb); |
| 450 | 450 | ||
| 451 | if (inode && (inode->i_state & I_NEW)) { | 451 | if (inode) { |
| 452 | inode->i_ino = de->low_ino; | ||
| 452 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 453 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
| 453 | PROC_I(inode)->pde = de; | 454 | PROC_I(inode)->pde = de; |
| 454 | 455 | ||
| @@ -476,7 +477,6 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de) | |||
| 476 | inode->i_fop = de->proc_fops; | 477 | inode->i_fop = de->proc_fops; |
| 477 | } | 478 | } |
| 478 | } | 479 | } |
| 479 | unlock_new_inode(inode); | ||
| 480 | } else | 480 | } else |
| 481 | pde_put(de); | 481 | pde_put(de); |
| 482 | return inode; | 482 | return inode; |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 05ae3c97f7a5..3e64169ef527 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
| @@ -1439,8 +1439,11 @@ static void __dquot_initialize(struct inode *inode, int type) | |||
| 1439 | * did a write before quota was turned on | 1439 | * did a write before quota was turned on |
| 1440 | */ | 1440 | */ |
| 1441 | rsv = inode_get_rsv_space(inode); | 1441 | rsv = inode_get_rsv_space(inode); |
| 1442 | if (unlikely(rsv)) | 1442 | if (unlikely(rsv)) { |
| 1443 | spin_lock(&dq_data_lock); | ||
| 1443 | dquot_resv_space(inode->i_dquot[cnt], rsv); | 1444 | dquot_resv_space(inode->i_dquot[cnt], rsv); |
| 1445 | spin_unlock(&dq_data_lock); | ||
| 1446 | } | ||
| 1444 | } | 1447 | } |
| 1445 | } | 1448 | } |
| 1446 | out_err: | 1449 | out_err: |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 194113b1b11b..f8a23c3078f8 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
| @@ -1147,8 +1147,7 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin | |||
| 1147 | "on filesystem root."); | 1147 | "on filesystem root."); |
| 1148 | return 0; | 1148 | return 0; |
| 1149 | } | 1149 | } |
| 1150 | qf_names[qtype] = | 1150 | qf_names[qtype] = kstrdup(arg, GFP_KERNEL); |
| 1151 | kmalloc(strlen(arg) + 1, GFP_KERNEL); | ||
| 1152 | if (!qf_names[qtype]) { | 1151 | if (!qf_names[qtype]) { |
| 1153 | reiserfs_warning(s, "reiserfs-2502", | 1152 | reiserfs_warning(s, "reiserfs-2502", |
| 1154 | "not enough memory " | 1153 | "not enough memory " |
| @@ -1156,7 +1155,6 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin | |||
| 1156 | "quotafile name."); | 1155 | "quotafile name."); |
| 1157 | return 0; | 1156 | return 0; |
| 1158 | } | 1157 | } |
| 1159 | strcpy(qf_names[qtype], arg); | ||
| 1160 | if (qtype == USRQUOTA) | 1158 | if (qtype == USRQUOTA) |
| 1161 | *mount_options |= 1 << REISERFS_USRQUOTA; | 1159 | *mount_options |= 1 << REISERFS_USRQUOTA; |
| 1162 | else | 1160 | else |
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index 260e3928d4f5..60553a9053ca 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c | |||
| @@ -489,6 +489,7 @@ static struct file_system_type squashfs_fs_type = { | |||
| 489 | .kill_sb = kill_block_super, | 489 | .kill_sb = kill_block_super, |
| 490 | .fs_flags = FS_REQUIRES_DEV | 490 | .fs_flags = FS_REQUIRES_DEV |
| 491 | }; | 491 | }; |
| 492 | MODULE_ALIAS_FS("squashfs"); | ||
| 492 | 493 | ||
| 493 | static const struct super_operations squashfs_super_ops = { | 494 | static const struct super_operations squashfs_super_ops = { |
| 494 | .alloc_inode = squashfs_alloc_inode, | 495 | .alloc_inode = squashfs_alloc_inode, |
diff --git a/fs/sysv/super.c b/fs/sysv/super.c index a39938b1feea..d0c6a007ce83 100644 --- a/fs/sysv/super.c +++ b/fs/sysv/super.c | |||
| @@ -555,6 +555,7 @@ static struct file_system_type v7_fs_type = { | |||
| 555 | .fs_flags = FS_REQUIRES_DEV, | 555 | .fs_flags = FS_REQUIRES_DEV, |
| 556 | }; | 556 | }; |
| 557 | MODULE_ALIAS_FS("v7"); | 557 | MODULE_ALIAS_FS("v7"); |
| 558 | MODULE_ALIAS("v7"); | ||
| 558 | 559 | ||
| 559 | static int __init init_sysv_fs(void) | 560 | static int __init init_sysv_fs(void) |
| 560 | { | 561 | { |
diff --git a/fs/udf/super.c b/fs/udf/super.c index bc5b30a819e8..9ac4057a86c9 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
| @@ -118,6 +118,7 @@ static struct file_system_type udf_fstype = { | |||
| 118 | .kill_sb = kill_block_super, | 118 | .kill_sb = kill_block_super, |
| 119 | .fs_flags = FS_REQUIRES_DEV, | 119 | .fs_flags = FS_REQUIRES_DEV, |
| 120 | }; | 120 | }; |
| 121 | MODULE_ALIAS_FS("udf"); | ||
| 121 | 122 | ||
| 122 | static struct kmem_cache *udf_inode_cachep; | 123 | static struct kmem_cache *udf_inode_cachep; |
| 123 | 124 | ||
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 4e8f0df82d02..8459b5d8cb71 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c | |||
| @@ -1334,6 +1334,12 @@ _xfs_buf_ioapply( | |||
| 1334 | int size; | 1334 | int size; |
| 1335 | int i; | 1335 | int i; |
| 1336 | 1336 | ||
| 1337 | /* | ||
| 1338 | * Make sure we capture only current IO errors rather than stale errors | ||
| 1339 | * left over from previous use of the buffer (e.g. failed readahead). | ||
| 1340 | */ | ||
| 1341 | bp->b_error = 0; | ||
| 1342 | |||
| 1337 | if (bp->b_flags & XBF_WRITE) { | 1343 | if (bp->b_flags & XBF_WRITE) { |
| 1338 | if (bp->b_flags & XBF_SYNCIO) | 1344 | if (bp->b_flags & XBF_SYNCIO) |
| 1339 | rw = WRITE_SYNC; | 1345 | rw = WRITE_SYNC; |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 912d83d8860a..5a30dd899d2b 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
| @@ -325,7 +325,7 @@ xfs_iomap_eof_want_preallocate( | |||
| 325 | * rather than falling short due to things like stripe unit/width alignment of | 325 | * rather than falling short due to things like stripe unit/width alignment of |
| 326 | * real extents. | 326 | * real extents. |
| 327 | */ | 327 | */ |
| 328 | STATIC int | 328 | STATIC xfs_fsblock_t |
| 329 | xfs_iomap_eof_prealloc_initial_size( | 329 | xfs_iomap_eof_prealloc_initial_size( |
| 330 | struct xfs_mount *mp, | 330 | struct xfs_mount *mp, |
| 331 | struct xfs_inode *ip, | 331 | struct xfs_inode *ip, |
| @@ -413,7 +413,7 @@ xfs_iomap_prealloc_size( | |||
| 413 | * have a large file on a small filesystem and the above | 413 | * have a large file on a small filesystem and the above |
| 414 | * lowspace thresholds are smaller than MAXEXTLEN. | 414 | * lowspace thresholds are smaller than MAXEXTLEN. |
| 415 | */ | 415 | */ |
| 416 | while (alloc_blocks >= freesp) | 416 | while (alloc_blocks && alloc_blocks >= freesp) |
| 417 | alloc_blocks >>= 4; | 417 | alloc_blocks >>= 4; |
| 418 | } | 418 | } |
| 419 | 419 | ||
