diff options
Diffstat (limited to 'fs')
36 files changed, 301 insertions, 98 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index d4bf8caad8d0..2126078a38ed 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
| @@ -135,8 +135,8 @@ config TMPFS_POSIX_ACL | |||
| 135 | 135 | ||
| 136 | config HUGETLBFS | 136 | config HUGETLBFS |
| 137 | bool "HugeTLB file system support" | 137 | bool "HugeTLB file system support" |
| 138 | depends on X86 || IA64 || PPC64 || SPARC64 || (SUPERH && MMU) || \ | 138 | depends on X86 || IA64 || PPC_BOOK3S_64 || SPARC64 || (S390 && 64BIT) || \ |
| 139 | (S390 && 64BIT) || SYS_SUPPORTS_HUGETLBFS || BROKEN | 139 | SYS_SUPPORTS_HUGETLBFS || BROKEN |
| 140 | help | 140 | help |
| 141 | hugetlbfs is a filesystem backing for HugeTLB pages, based on | 141 | hugetlbfs is a filesystem backing for HugeTLB pages, based on |
| 142 | ramfs. For architectures that support it, say Y here and read | 142 | ramfs. For architectures that support it, say Y here and read |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 9cf4b926f8e4..8bed0557d88c 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
| @@ -1248,8 +1248,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) | |||
| 1248 | bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9); | 1248 | bd_set_size(bdev, (loff_t)bdev->bd_part->nr_sects << 9); |
| 1249 | } | 1249 | } |
| 1250 | } else { | 1250 | } else { |
| 1251 | put_disk(disk); | ||
| 1252 | module_put(disk->fops->owner); | 1251 | module_put(disk->fops->owner); |
| 1252 | put_disk(disk); | ||
| 1253 | disk = NULL; | 1253 | disk = NULL; |
| 1254 | if (bdev->bd_contains == bdev) { | 1254 | if (bdev->bd_contains == bdev) { |
| 1255 | if (bdev->bd_disk->fops->open) { | 1255 | if (bdev->bd_disk->fops->open) { |
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 69b355ae7f49..361604244271 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | #include "btrfs_inode.h" | 27 | #include "btrfs_inode.h" |
| 28 | #include "xattr.h" | 28 | #include "xattr.h" |
| 29 | 29 | ||
| 30 | #ifdef CONFIG_BTRFS_POSIX_ACL | 30 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL |
| 31 | 31 | ||
| 32 | static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) | 32 | static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) |
| 33 | { | 33 | { |
| @@ -313,7 +313,7 @@ struct xattr_handler btrfs_xattr_acl_access_handler = { | |||
| 313 | .set = btrfs_xattr_acl_access_set, | 313 | .set = btrfs_xattr_acl_access_set, |
| 314 | }; | 314 | }; |
| 315 | 315 | ||
| 316 | #else /* CONFIG_BTRFS_POSIX_ACL */ | 316 | #else /* CONFIG_BTRFS_FS_POSIX_ACL */ |
| 317 | 317 | ||
| 318 | int btrfs_acl_chmod(struct inode *inode) | 318 | int btrfs_acl_chmod(struct inode *inode) |
| 319 | { | 319 | { |
| @@ -325,4 +325,4 @@ int btrfs_init_acl(struct inode *inode, struct inode *dir) | |||
| 325 | return 0; | 325 | return 0; |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | #endif /* CONFIG_BTRFS_POSIX_ACL */ | 328 | #endif /* CONFIG_BTRFS_FS_POSIX_ACL */ |
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index c71abec0ab90..f6783a42f010 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h | |||
| @@ -86,6 +86,12 @@ struct btrfs_inode { | |||
| 86 | * transid of the trans_handle that last modified this inode | 86 | * transid of the trans_handle that last modified this inode |
| 87 | */ | 87 | */ |
| 88 | u64 last_trans; | 88 | u64 last_trans; |
| 89 | |||
| 90 | /* | ||
| 91 | * log transid when this inode was last modified | ||
| 92 | */ | ||
| 93 | u64 last_sub_trans; | ||
| 94 | |||
| 89 | /* | 95 | /* |
| 90 | * transid that last logged this inode | 96 | * transid that last logged this inode |
| 91 | */ | 97 | */ |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 1bb897ecdeeb..444b3e9b92a4 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -1009,6 +1009,7 @@ struct btrfs_root { | |||
| 1009 | atomic_t log_writers; | 1009 | atomic_t log_writers; |
| 1010 | atomic_t log_commit[2]; | 1010 | atomic_t log_commit[2]; |
| 1011 | unsigned long log_transid; | 1011 | unsigned long log_transid; |
| 1012 | unsigned long last_log_commit; | ||
| 1012 | unsigned long log_batch; | 1013 | unsigned long log_batch; |
| 1013 | pid_t log_start_pid; | 1014 | pid_t log_start_pid; |
| 1014 | bool log_multiple_pids; | 1015 | bool log_multiple_pids; |
| @@ -1152,6 +1153,7 @@ struct btrfs_root { | |||
| 1152 | #define BTRFS_MOUNT_FLUSHONCOMMIT (1 << 7) | 1153 | #define BTRFS_MOUNT_FLUSHONCOMMIT (1 << 7) |
| 1153 | #define BTRFS_MOUNT_SSD_SPREAD (1 << 8) | 1154 | #define BTRFS_MOUNT_SSD_SPREAD (1 << 8) |
| 1154 | #define BTRFS_MOUNT_NOSSD (1 << 9) | 1155 | #define BTRFS_MOUNT_NOSSD (1 << 9) |
| 1156 | #define BTRFS_MOUNT_DISCARD (1 << 10) | ||
| 1155 | 1157 | ||
| 1156 | #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt) | 1158 | #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt) |
| 1157 | #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) | 1159 | #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) |
| @@ -2373,7 +2375,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options); | |||
| 2373 | int btrfs_sync_fs(struct super_block *sb, int wait); | 2375 | int btrfs_sync_fs(struct super_block *sb, int wait); |
| 2374 | 2376 | ||
| 2375 | /* acl.c */ | 2377 | /* acl.c */ |
| 2376 | #ifdef CONFIG_BTRFS_POSIX_ACL | 2378 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL |
| 2377 | int btrfs_check_acl(struct inode *inode, int mask); | 2379 | int btrfs_check_acl(struct inode *inode, int mask); |
| 2378 | #else | 2380 | #else |
| 2379 | #define btrfs_check_acl NULL | 2381 | #define btrfs_check_acl NULL |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 100551a66c46..02b6afbd7450 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -917,6 +917,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
| 917 | atomic_set(&root->log_writers, 0); | 917 | atomic_set(&root->log_writers, 0); |
| 918 | root->log_batch = 0; | 918 | root->log_batch = 0; |
| 919 | root->log_transid = 0; | 919 | root->log_transid = 0; |
| 920 | root->last_log_commit = 0; | ||
| 920 | extent_io_tree_init(&root->dirty_log_pages, | 921 | extent_io_tree_init(&root->dirty_log_pages, |
| 921 | fs_info->btree_inode->i_mapping, GFP_NOFS); | 922 | fs_info->btree_inode->i_mapping, GFP_NOFS); |
| 922 | 923 | ||
| @@ -1087,6 +1088,7 @@ int btrfs_add_log_tree(struct btrfs_trans_handle *trans, | |||
| 1087 | WARN_ON(root->log_root); | 1088 | WARN_ON(root->log_root); |
| 1088 | root->log_root = log_root; | 1089 | root->log_root = log_root; |
| 1089 | root->log_transid = 0; | 1090 | root->log_transid = 0; |
| 1091 | root->last_log_commit = 0; | ||
| 1090 | return 0; | 1092 | return 0; |
| 1091 | } | 1093 | } |
| 1092 | 1094 | ||
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index d0c4d584efad..e238a0cdac67 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -1568,23 +1568,23 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans, | |||
| 1568 | return ret; | 1568 | return ret; |
| 1569 | } | 1569 | } |
| 1570 | 1570 | ||
| 1571 | #ifdef BIO_RW_DISCARD | ||
| 1572 | static void btrfs_issue_discard(struct block_device *bdev, | 1571 | static void btrfs_issue_discard(struct block_device *bdev, |
| 1573 | u64 start, u64 len) | 1572 | u64 start, u64 len) |
| 1574 | { | 1573 | { |
| 1575 | blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL, | 1574 | blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL, |
| 1576 | DISCARD_FL_BARRIER); | 1575 | DISCARD_FL_BARRIER); |
| 1577 | } | 1576 | } |
| 1578 | #endif | ||
| 1579 | 1577 | ||
| 1580 | static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, | 1578 | static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, |
| 1581 | u64 num_bytes) | 1579 | u64 num_bytes) |
| 1582 | { | 1580 | { |
| 1583 | #ifdef BIO_RW_DISCARD | ||
| 1584 | int ret; | 1581 | int ret; |
| 1585 | u64 map_length = num_bytes; | 1582 | u64 map_length = num_bytes; |
| 1586 | struct btrfs_multi_bio *multi = NULL; | 1583 | struct btrfs_multi_bio *multi = NULL; |
| 1587 | 1584 | ||
| 1585 | if (!btrfs_test_opt(root, DISCARD)) | ||
| 1586 | return 0; | ||
| 1587 | |||
| 1588 | /* Tell the block device(s) that the sectors can be discarded */ | 1588 | /* Tell the block device(s) that the sectors can be discarded */ |
| 1589 | ret = btrfs_map_block(&root->fs_info->mapping_tree, READ, | 1589 | ret = btrfs_map_block(&root->fs_info->mapping_tree, READ, |
| 1590 | bytenr, &map_length, &multi, 0); | 1590 | bytenr, &map_length, &multi, 0); |
| @@ -1604,9 +1604,6 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, | |||
| 1604 | } | 1604 | } |
| 1605 | 1605 | ||
| 1606 | return ret; | 1606 | return ret; |
| 1607 | #else | ||
| 1608 | return 0; | ||
| 1609 | #endif | ||
| 1610 | } | 1607 | } |
| 1611 | 1608 | ||
| 1612 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 1609 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
| @@ -3690,6 +3687,14 @@ static int pin_down_bytes(struct btrfs_trans_handle *trans, | |||
| 3690 | if (is_data) | 3687 | if (is_data) |
| 3691 | goto pinit; | 3688 | goto pinit; |
| 3692 | 3689 | ||
| 3690 | /* | ||
| 3691 | * discard is sloooow, and so triggering discards on | ||
| 3692 | * individual btree blocks isn't a good plan. Just | ||
| 3693 | * pin everything in discard mode. | ||
| 3694 | */ | ||
| 3695 | if (btrfs_test_opt(root, DISCARD)) | ||
| 3696 | goto pinit; | ||
| 3697 | |||
| 3693 | buf = btrfs_find_tree_block(root, bytenr, num_bytes); | 3698 | buf = btrfs_find_tree_block(root, bytenr, num_bytes); |
| 3694 | if (!buf) | 3699 | if (!buf) |
| 3695 | goto pinit; | 3700 | goto pinit; |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 2d623aa0625f..06550affbd27 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -1086,8 +1086,10 @@ out_nolock: | |||
| 1086 | btrfs_end_transaction(trans, root); | 1086 | btrfs_end_transaction(trans, root); |
| 1087 | else | 1087 | else |
| 1088 | btrfs_commit_transaction(trans, root); | 1088 | btrfs_commit_transaction(trans, root); |
| 1089 | } else { | 1089 | } else if (ret != BTRFS_NO_LOG_SYNC) { |
| 1090 | btrfs_commit_transaction(trans, root); | 1090 | btrfs_commit_transaction(trans, root); |
| 1091 | } else { | ||
| 1092 | btrfs_end_transaction(trans, root); | ||
| 1091 | } | 1093 | } |
| 1092 | } | 1094 | } |
| 1093 | if (file->f_flags & O_DIRECT) { | 1095 | if (file->f_flags & O_DIRECT) { |
| @@ -1137,6 +1139,13 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1137 | int ret = 0; | 1139 | int ret = 0; |
| 1138 | struct btrfs_trans_handle *trans; | 1140 | struct btrfs_trans_handle *trans; |
| 1139 | 1141 | ||
| 1142 | |||
| 1143 | /* we wait first, since the writeback may change the inode */ | ||
| 1144 | root->log_batch++; | ||
| 1145 | /* the VFS called filemap_fdatawrite for us */ | ||
| 1146 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | ||
| 1147 | root->log_batch++; | ||
| 1148 | |||
| 1140 | /* | 1149 | /* |
| 1141 | * check the transaction that last modified this inode | 1150 | * check the transaction that last modified this inode |
| 1142 | * and see if its already been committed | 1151 | * and see if its already been committed |
| @@ -1144,6 +1153,11 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1144 | if (!BTRFS_I(inode)->last_trans) | 1153 | if (!BTRFS_I(inode)->last_trans) |
| 1145 | goto out; | 1154 | goto out; |
| 1146 | 1155 | ||
| 1156 | /* | ||
| 1157 | * if the last transaction that changed this file was before | ||
| 1158 | * the current transaction, we can bail out now without any | ||
| 1159 | * syncing | ||
| 1160 | */ | ||
| 1147 | mutex_lock(&root->fs_info->trans_mutex); | 1161 | mutex_lock(&root->fs_info->trans_mutex); |
| 1148 | if (BTRFS_I(inode)->last_trans <= | 1162 | if (BTRFS_I(inode)->last_trans <= |
| 1149 | root->fs_info->last_trans_committed) { | 1163 | root->fs_info->last_trans_committed) { |
| @@ -1153,13 +1167,6 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1153 | } | 1167 | } |
| 1154 | mutex_unlock(&root->fs_info->trans_mutex); | 1168 | mutex_unlock(&root->fs_info->trans_mutex); |
| 1155 | 1169 | ||
| 1156 | root->log_batch++; | ||
| 1157 | filemap_fdatawrite(inode->i_mapping); | ||
| 1158 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | ||
| 1159 | root->log_batch++; | ||
| 1160 | |||
| 1161 | if (datasync && !(inode->i_state & I_DIRTY_PAGES)) | ||
| 1162 | goto out; | ||
| 1163 | /* | 1170 | /* |
| 1164 | * ok we haven't committed the transaction yet, lets do a commit | 1171 | * ok we haven't committed the transaction yet, lets do a commit |
| 1165 | */ | 1172 | */ |
| @@ -1188,14 +1195,18 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync) | |||
| 1188 | */ | 1195 | */ |
| 1189 | mutex_unlock(&dentry->d_inode->i_mutex); | 1196 | mutex_unlock(&dentry->d_inode->i_mutex); |
| 1190 | 1197 | ||
| 1191 | if (ret > 0) { | 1198 | if (ret != BTRFS_NO_LOG_SYNC) { |
| 1192 | ret = btrfs_commit_transaction(trans, root); | 1199 | if (ret > 0) { |
| 1193 | } else { | ||
| 1194 | ret = btrfs_sync_log(trans, root); | ||
| 1195 | if (ret == 0) | ||
| 1196 | ret = btrfs_end_transaction(trans, root); | ||
| 1197 | else | ||
| 1198 | ret = btrfs_commit_transaction(trans, root); | 1200 | ret = btrfs_commit_transaction(trans, root); |
| 1201 | } else { | ||
| 1202 | ret = btrfs_sync_log(trans, root); | ||
| 1203 | if (ret == 0) | ||
| 1204 | ret = btrfs_end_transaction(trans, root); | ||
| 1205 | else | ||
| 1206 | ret = btrfs_commit_transaction(trans, root); | ||
| 1207 | } | ||
| 1208 | } else { | ||
| 1209 | ret = btrfs_end_transaction(trans, root); | ||
| 1199 | } | 1210 | } |
| 1200 | mutex_lock(&dentry->d_inode->i_mutex); | 1211 | mutex_lock(&dentry->d_inode->i_mutex); |
| 1201 | out: | 1212 | out: |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9e138b793dc7..dae12dc7e159 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -3032,12 +3032,22 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from) | |||
| 3032 | 3032 | ||
| 3033 | if ((offset & (blocksize - 1)) == 0) | 3033 | if ((offset & (blocksize - 1)) == 0) |
| 3034 | goto out; | 3034 | goto out; |
| 3035 | ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE); | ||
| 3036 | if (ret) | ||
| 3037 | goto out; | ||
| 3038 | |||
| 3039 | ret = btrfs_reserve_metadata_for_delalloc(root, inode, 1); | ||
| 3040 | if (ret) | ||
| 3041 | goto out; | ||
| 3035 | 3042 | ||
| 3036 | ret = -ENOMEM; | 3043 | ret = -ENOMEM; |
| 3037 | again: | 3044 | again: |
| 3038 | page = grab_cache_page(mapping, index); | 3045 | page = grab_cache_page(mapping, index); |
| 3039 | if (!page) | 3046 | if (!page) { |
| 3047 | btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE); | ||
| 3048 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); | ||
| 3040 | goto out; | 3049 | goto out; |
| 3050 | } | ||
| 3041 | 3051 | ||
| 3042 | page_start = page_offset(page); | 3052 | page_start = page_offset(page); |
| 3043 | page_end = page_start + PAGE_CACHE_SIZE - 1; | 3053 | page_end = page_start + PAGE_CACHE_SIZE - 1; |
| @@ -3070,6 +3080,10 @@ again: | |||
| 3070 | goto again; | 3080 | goto again; |
| 3071 | } | 3081 | } |
| 3072 | 3082 | ||
| 3083 | clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end, | ||
| 3084 | EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING, | ||
| 3085 | GFP_NOFS); | ||
| 3086 | |||
| 3073 | ret = btrfs_set_extent_delalloc(inode, page_start, page_end); | 3087 | ret = btrfs_set_extent_delalloc(inode, page_start, page_end); |
| 3074 | if (ret) { | 3088 | if (ret) { |
| 3075 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 3089 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); |
| @@ -3088,6 +3102,9 @@ again: | |||
| 3088 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 3102 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); |
| 3089 | 3103 | ||
| 3090 | out_unlock: | 3104 | out_unlock: |
| 3105 | if (ret) | ||
| 3106 | btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE); | ||
| 3107 | btrfs_unreserve_metadata_for_delalloc(root, inode, 1); | ||
| 3091 | unlock_page(page); | 3108 | unlock_page(page); |
| 3092 | page_cache_release(page); | 3109 | page_cache_release(page); |
| 3093 | out: | 3110 | out: |
| @@ -3111,7 +3128,9 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) | |||
| 3111 | if (size <= hole_start) | 3128 | if (size <= hole_start) |
| 3112 | return 0; | 3129 | return 0; |
| 3113 | 3130 | ||
| 3114 | btrfs_truncate_page(inode->i_mapping, inode->i_size); | 3131 | err = btrfs_truncate_page(inode->i_mapping, inode->i_size); |
| 3132 | if (err) | ||
| 3133 | return err; | ||
| 3115 | 3134 | ||
| 3116 | while (1) { | 3135 | while (1) { |
| 3117 | struct btrfs_ordered_extent *ordered; | 3136 | struct btrfs_ordered_extent *ordered; |
| @@ -3480,6 +3499,7 @@ static noinline void init_btrfs_i(struct inode *inode) | |||
| 3480 | bi->generation = 0; | 3499 | bi->generation = 0; |
| 3481 | bi->sequence = 0; | 3500 | bi->sequence = 0; |
| 3482 | bi->last_trans = 0; | 3501 | bi->last_trans = 0; |
| 3502 | bi->last_sub_trans = 0; | ||
| 3483 | bi->logged_trans = 0; | 3503 | bi->logged_trans = 0; |
| 3484 | bi->delalloc_bytes = 0; | 3504 | bi->delalloc_bytes = 0; |
| 3485 | bi->reserved_bytes = 0; | 3505 | bi->reserved_bytes = 0; |
| @@ -4980,7 +5000,9 @@ again: | |||
| 4980 | set_page_dirty(page); | 5000 | set_page_dirty(page); |
| 4981 | SetPageUptodate(page); | 5001 | SetPageUptodate(page); |
| 4982 | 5002 | ||
| 4983 | BTRFS_I(inode)->last_trans = root->fs_info->generation + 1; | 5003 | BTRFS_I(inode)->last_trans = root->fs_info->generation; |
| 5004 | BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid; | ||
| 5005 | |||
| 4984 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 5006 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); |
| 4985 | 5007 | ||
| 4986 | out_unlock: | 5008 | out_unlock: |
| @@ -5005,7 +5027,9 @@ static void btrfs_truncate(struct inode *inode) | |||
| 5005 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 5027 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
| 5006 | return; | 5028 | return; |
| 5007 | 5029 | ||
| 5008 | btrfs_truncate_page(inode->i_mapping, inode->i_size); | 5030 | ret = btrfs_truncate_page(inode->i_mapping, inode->i_size); |
| 5031 | if (ret) | ||
| 5032 | return; | ||
| 5009 | btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1); | 5033 | btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1); |
| 5010 | 5034 | ||
| 5011 | trans = btrfs_start_transaction(root, 1); | 5035 | trans = btrfs_start_transaction(root, 1); |
| @@ -5100,6 +5124,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) | |||
| 5100 | if (!ei) | 5124 | if (!ei) |
| 5101 | return NULL; | 5125 | return NULL; |
| 5102 | ei->last_trans = 0; | 5126 | ei->last_trans = 0; |
| 5127 | ei->last_sub_trans = 0; | ||
| 5103 | ei->logged_trans = 0; | 5128 | ei->logged_trans = 0; |
| 5104 | ei->outstanding_extents = 0; | 5129 | ei->outstanding_extents = 0; |
| 5105 | ei->reserved_extents = 0; | 5130 | ei->reserved_extents = 0; |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 9de9b2236419..752a5463bf53 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -66,7 +66,8 @@ enum { | |||
| 66 | Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow, | 66 | Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow, |
| 67 | Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, | 67 | Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, |
| 68 | Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, | 68 | Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, |
| 69 | Opt_compress, Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_err, | 69 | Opt_compress, Opt_notreelog, Opt_ratio, Opt_flushoncommit, |
| 70 | Opt_discard, Opt_err, | ||
| 70 | }; | 71 | }; |
| 71 | 72 | ||
| 72 | static match_table_t tokens = { | 73 | static match_table_t tokens = { |
| @@ -88,6 +89,7 @@ static match_table_t tokens = { | |||
| 88 | {Opt_notreelog, "notreelog"}, | 89 | {Opt_notreelog, "notreelog"}, |
| 89 | {Opt_flushoncommit, "flushoncommit"}, | 90 | {Opt_flushoncommit, "flushoncommit"}, |
| 90 | {Opt_ratio, "metadata_ratio=%d"}, | 91 | {Opt_ratio, "metadata_ratio=%d"}, |
| 92 | {Opt_discard, "discard"}, | ||
| 91 | {Opt_err, NULL}, | 93 | {Opt_err, NULL}, |
| 92 | }; | 94 | }; |
| 93 | 95 | ||
| @@ -257,6 +259,9 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
| 257 | info->metadata_ratio); | 259 | info->metadata_ratio); |
| 258 | } | 260 | } |
| 259 | break; | 261 | break; |
| 262 | case Opt_discard: | ||
| 263 | btrfs_set_opt(info->mount_opt, DISCARD); | ||
| 264 | break; | ||
| 260 | default: | 265 | default: |
| 261 | break; | 266 | break; |
| 262 | } | 267 | } |
| @@ -344,7 +349,7 @@ static int btrfs_fill_super(struct super_block *sb, | |||
| 344 | sb->s_export_op = &btrfs_export_ops; | 349 | sb->s_export_op = &btrfs_export_ops; |
| 345 | sb->s_xattr = btrfs_xattr_handlers; | 350 | sb->s_xattr = btrfs_xattr_handlers; |
| 346 | sb->s_time_gran = 1; | 351 | sb->s_time_gran = 1; |
| 347 | #ifdef CONFIG_BTRFS_POSIX_ACL | 352 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL |
| 348 | sb->s_flags |= MS_POSIXACL; | 353 | sb->s_flags |= MS_POSIXACL; |
| 349 | #endif | 354 | #endif |
| 350 | 355 | ||
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 0b8f36d4400a..bca82a4ca8e6 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -344,10 +344,10 @@ int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans, | |||
| 344 | /* | 344 | /* |
| 345 | * when btree blocks are allocated, they have some corresponding bits set for | 345 | * when btree blocks are allocated, they have some corresponding bits set for |
| 346 | * them in one of two extent_io trees. This is used to make sure all of | 346 | * them in one of two extent_io trees. This is used to make sure all of |
| 347 | * those extents are on disk for transaction or log commit | 347 | * those extents are sent to disk but does not wait on them |
| 348 | */ | 348 | */ |
| 349 | int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, | 349 | int btrfs_write_marked_extents(struct btrfs_root *root, |
| 350 | struct extent_io_tree *dirty_pages) | 350 | struct extent_io_tree *dirty_pages) |
| 351 | { | 351 | { |
| 352 | int ret; | 352 | int ret; |
| 353 | int err = 0; | 353 | int err = 0; |
| @@ -394,6 +394,29 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, | |||
| 394 | page_cache_release(page); | 394 | page_cache_release(page); |
| 395 | } | 395 | } |
| 396 | } | 396 | } |
| 397 | if (err) | ||
| 398 | werr = err; | ||
| 399 | return werr; | ||
| 400 | } | ||
| 401 | |||
| 402 | /* | ||
| 403 | * when btree blocks are allocated, they have some corresponding bits set for | ||
| 404 | * them in one of two extent_io trees. This is used to make sure all of | ||
| 405 | * those extents are on disk for transaction or log commit. We wait | ||
| 406 | * on all the pages and clear them from the dirty pages state tree | ||
| 407 | */ | ||
| 408 | int btrfs_wait_marked_extents(struct btrfs_root *root, | ||
| 409 | struct extent_io_tree *dirty_pages) | ||
| 410 | { | ||
| 411 | int ret; | ||
| 412 | int err = 0; | ||
| 413 | int werr = 0; | ||
| 414 | struct page *page; | ||
| 415 | struct inode *btree_inode = root->fs_info->btree_inode; | ||
| 416 | u64 start = 0; | ||
| 417 | u64 end; | ||
| 418 | unsigned long index; | ||
| 419 | |||
| 397 | while (1) { | 420 | while (1) { |
| 398 | ret = find_first_extent_bit(dirty_pages, 0, &start, &end, | 421 | ret = find_first_extent_bit(dirty_pages, 0, &start, &end, |
| 399 | EXTENT_DIRTY); | 422 | EXTENT_DIRTY); |
| @@ -424,6 +447,22 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, | |||
| 424 | return werr; | 447 | return werr; |
| 425 | } | 448 | } |
| 426 | 449 | ||
| 450 | /* | ||
| 451 | * when btree blocks are allocated, they have some corresponding bits set for | ||
| 452 | * them in one of two extent_io trees. This is used to make sure all of | ||
| 453 | * those extents are on disk for transaction or log commit | ||
| 454 | */ | ||
| 455 | int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, | ||
| 456 | struct extent_io_tree *dirty_pages) | ||
| 457 | { | ||
| 458 | int ret; | ||
| 459 | int ret2; | ||
| 460 | |||
| 461 | ret = btrfs_write_marked_extents(root, dirty_pages); | ||
| 462 | ret2 = btrfs_wait_marked_extents(root, dirty_pages); | ||
| 463 | return ret || ret2; | ||
| 464 | } | ||
| 465 | |||
| 427 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, | 466 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, |
| 428 | struct btrfs_root *root) | 467 | struct btrfs_root *root) |
| 429 | { | 468 | { |
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index 663c67404918..d4e3e7a6938c 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
| @@ -79,6 +79,7 @@ static inline void btrfs_set_inode_last_trans(struct btrfs_trans_handle *trans, | |||
| 79 | struct inode *inode) | 79 | struct inode *inode) |
| 80 | { | 80 | { |
| 81 | BTRFS_I(inode)->last_trans = trans->transaction->transid; | 81 | BTRFS_I(inode)->last_trans = trans->transaction->transid; |
| 82 | BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid; | ||
| 82 | } | 83 | } |
| 83 | 84 | ||
| 84 | int btrfs_end_transaction(struct btrfs_trans_handle *trans, | 85 | int btrfs_end_transaction(struct btrfs_trans_handle *trans, |
| @@ -107,5 +108,9 @@ int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans, | |||
| 107 | struct btrfs_root *root); | 108 | struct btrfs_root *root); |
| 108 | int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, | 109 | int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, |
| 109 | struct extent_io_tree *dirty_pages); | 110 | struct extent_io_tree *dirty_pages); |
| 111 | int btrfs_write_marked_extents(struct btrfs_root *root, | ||
| 112 | struct extent_io_tree *dirty_pages); | ||
| 113 | int btrfs_wait_marked_extents(struct btrfs_root *root, | ||
| 114 | struct extent_io_tree *dirty_pages); | ||
| 110 | int btrfs_transaction_in_commit(struct btrfs_fs_info *info); | 115 | int btrfs_transaction_in_commit(struct btrfs_fs_info *info); |
| 111 | #endif | 116 | #endif |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 4edfdc2acc5f..741666a7676a 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
| @@ -1980,6 +1980,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 1980 | int ret; | 1980 | int ret; |
| 1981 | struct btrfs_root *log = root->log_root; | 1981 | struct btrfs_root *log = root->log_root; |
| 1982 | struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; | 1982 | struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; |
| 1983 | u64 log_transid = 0; | ||
| 1983 | 1984 | ||
| 1984 | mutex_lock(&root->log_mutex); | 1985 | mutex_lock(&root->log_mutex); |
| 1985 | index1 = root->log_transid % 2; | 1986 | index1 = root->log_transid % 2; |
| @@ -1994,12 +1995,13 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 1994 | if (atomic_read(&root->log_commit[(index1 + 1) % 2])) | 1995 | if (atomic_read(&root->log_commit[(index1 + 1) % 2])) |
| 1995 | wait_log_commit(trans, root, root->log_transid - 1); | 1996 | wait_log_commit(trans, root, root->log_transid - 1); |
| 1996 | 1997 | ||
| 1997 | while (root->log_multiple_pids) { | 1998 | while (1) { |
| 1998 | unsigned long batch = root->log_batch; | 1999 | unsigned long batch = root->log_batch; |
| 1999 | mutex_unlock(&root->log_mutex); | 2000 | if (root->log_multiple_pids) { |
| 2000 | schedule_timeout_uninterruptible(1); | 2001 | mutex_unlock(&root->log_mutex); |
| 2001 | mutex_lock(&root->log_mutex); | 2002 | schedule_timeout_uninterruptible(1); |
| 2002 | 2003 | mutex_lock(&root->log_mutex); | |
| 2004 | } | ||
| 2003 | wait_for_writer(trans, root); | 2005 | wait_for_writer(trans, root); |
| 2004 | if (batch == root->log_batch) | 2006 | if (batch == root->log_batch) |
| 2005 | break; | 2007 | break; |
| @@ -2012,12 +2014,16 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 2012 | goto out; | 2014 | goto out; |
| 2013 | } | 2015 | } |
| 2014 | 2016 | ||
| 2015 | ret = btrfs_write_and_wait_marked_extents(log, &log->dirty_log_pages); | 2017 | /* we start IO on all the marked extents here, but we don't actually |
| 2018 | * wait for them until later. | ||
| 2019 | */ | ||
| 2020 | ret = btrfs_write_marked_extents(log, &log->dirty_log_pages); | ||
| 2016 | BUG_ON(ret); | 2021 | BUG_ON(ret); |
| 2017 | 2022 | ||
| 2018 | btrfs_set_root_node(&log->root_item, log->node); | 2023 | btrfs_set_root_node(&log->root_item, log->node); |
| 2019 | 2024 | ||
| 2020 | root->log_batch = 0; | 2025 | root->log_batch = 0; |
| 2026 | log_transid = root->log_transid; | ||
| 2021 | root->log_transid++; | 2027 | root->log_transid++; |
| 2022 | log->log_transid = root->log_transid; | 2028 | log->log_transid = root->log_transid; |
| 2023 | root->log_start_pid = 0; | 2029 | root->log_start_pid = 0; |
| @@ -2046,6 +2052,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 2046 | 2052 | ||
| 2047 | index2 = log_root_tree->log_transid % 2; | 2053 | index2 = log_root_tree->log_transid % 2; |
| 2048 | if (atomic_read(&log_root_tree->log_commit[index2])) { | 2054 | if (atomic_read(&log_root_tree->log_commit[index2])) { |
| 2055 | btrfs_wait_marked_extents(log, &log->dirty_log_pages); | ||
| 2049 | wait_log_commit(trans, log_root_tree, | 2056 | wait_log_commit(trans, log_root_tree, |
| 2050 | log_root_tree->log_transid); | 2057 | log_root_tree->log_transid); |
| 2051 | mutex_unlock(&log_root_tree->log_mutex); | 2058 | mutex_unlock(&log_root_tree->log_mutex); |
| @@ -2065,6 +2072,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 2065 | * check the full commit flag again | 2072 | * check the full commit flag again |
| 2066 | */ | 2073 | */ |
| 2067 | if (root->fs_info->last_trans_log_full_commit == trans->transid) { | 2074 | if (root->fs_info->last_trans_log_full_commit == trans->transid) { |
| 2075 | btrfs_wait_marked_extents(log, &log->dirty_log_pages); | ||
| 2068 | mutex_unlock(&log_root_tree->log_mutex); | 2076 | mutex_unlock(&log_root_tree->log_mutex); |
| 2069 | ret = -EAGAIN; | 2077 | ret = -EAGAIN; |
| 2070 | goto out_wake_log_root; | 2078 | goto out_wake_log_root; |
| @@ -2073,6 +2081,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 2073 | ret = btrfs_write_and_wait_marked_extents(log_root_tree, | 2081 | ret = btrfs_write_and_wait_marked_extents(log_root_tree, |
| 2074 | &log_root_tree->dirty_log_pages); | 2082 | &log_root_tree->dirty_log_pages); |
| 2075 | BUG_ON(ret); | 2083 | BUG_ON(ret); |
| 2084 | btrfs_wait_marked_extents(log, &log->dirty_log_pages); | ||
| 2076 | 2085 | ||
| 2077 | btrfs_set_super_log_root(&root->fs_info->super_for_commit, | 2086 | btrfs_set_super_log_root(&root->fs_info->super_for_commit, |
| 2078 | log_root_tree->node->start); | 2087 | log_root_tree->node->start); |
| @@ -2092,9 +2101,14 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 2092 | * the running transaction open, so a full commit can't hop | 2101 | * the running transaction open, so a full commit can't hop |
| 2093 | * in and cause problems either. | 2102 | * in and cause problems either. |
| 2094 | */ | 2103 | */ |
| 2095 | write_ctree_super(trans, root->fs_info->tree_root, 2); | 2104 | write_ctree_super(trans, root->fs_info->tree_root, 1); |
| 2096 | ret = 0; | 2105 | ret = 0; |
| 2097 | 2106 | ||
| 2107 | mutex_lock(&root->log_mutex); | ||
| 2108 | if (root->last_log_commit < log_transid) | ||
| 2109 | root->last_log_commit = log_transid; | ||
| 2110 | mutex_unlock(&root->log_mutex); | ||
| 2111 | |||
| 2098 | out_wake_log_root: | 2112 | out_wake_log_root: |
| 2099 | atomic_set(&log_root_tree->log_commit[index2], 0); | 2113 | atomic_set(&log_root_tree->log_commit[index2], 0); |
| 2100 | smp_mb(); | 2114 | smp_mb(); |
| @@ -2862,6 +2876,21 @@ out: | |||
| 2862 | return ret; | 2876 | return ret; |
| 2863 | } | 2877 | } |
| 2864 | 2878 | ||
| 2879 | static int inode_in_log(struct btrfs_trans_handle *trans, | ||
| 2880 | struct inode *inode) | ||
| 2881 | { | ||
| 2882 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
| 2883 | int ret = 0; | ||
| 2884 | |||
| 2885 | mutex_lock(&root->log_mutex); | ||
| 2886 | if (BTRFS_I(inode)->logged_trans == trans->transid && | ||
| 2887 | BTRFS_I(inode)->last_sub_trans <= root->last_log_commit) | ||
| 2888 | ret = 1; | ||
| 2889 | mutex_unlock(&root->log_mutex); | ||
| 2890 | return ret; | ||
| 2891 | } | ||
| 2892 | |||
| 2893 | |||
| 2865 | /* | 2894 | /* |
| 2866 | * helper function around btrfs_log_inode to make sure newly created | 2895 | * helper function around btrfs_log_inode to make sure newly created |
| 2867 | * parent directories also end up in the log. A minimal inode and backref | 2896 | * parent directories also end up in the log. A minimal inode and backref |
| @@ -2901,6 +2930,11 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, | |||
| 2901 | if (ret) | 2930 | if (ret) |
| 2902 | goto end_no_trans; | 2931 | goto end_no_trans; |
| 2903 | 2932 | ||
| 2933 | if (inode_in_log(trans, inode)) { | ||
| 2934 | ret = BTRFS_NO_LOG_SYNC; | ||
| 2935 | goto end_no_trans; | ||
| 2936 | } | ||
| 2937 | |||
| 2904 | start_log_trans(trans, root); | 2938 | start_log_trans(trans, root); |
| 2905 | 2939 | ||
| 2906 | ret = btrfs_log_inode(trans, root, inode, inode_only); | 2940 | ret = btrfs_log_inode(trans, root, inode, inode_only); |
diff --git a/fs/btrfs/tree-log.h b/fs/btrfs/tree-log.h index d09c7609e16b..0776eacb5083 100644 --- a/fs/btrfs/tree-log.h +++ b/fs/btrfs/tree-log.h | |||
| @@ -19,6 +19,9 @@ | |||
| 19 | #ifndef __TREE_LOG_ | 19 | #ifndef __TREE_LOG_ |
| 20 | #define __TREE_LOG_ | 20 | #define __TREE_LOG_ |
| 21 | 21 | ||
| 22 | /* return value for btrfs_log_dentry_safe that means we don't need to log it at all */ | ||
| 23 | #define BTRFS_NO_LOG_SYNC 256 | ||
| 24 | |||
| 22 | int btrfs_sync_log(struct btrfs_trans_handle *trans, | 25 | int btrfs_sync_log(struct btrfs_trans_handle *trans, |
| 23 | struct btrfs_root *root); | 26 | struct btrfs_root *root); |
| 24 | int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root); | 27 | int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root); |
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index b0fc93f95fd0..b6dd5967c48a 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
| @@ -260,7 +260,7 @@ err: | |||
| 260 | * attributes are handled directly. | 260 | * attributes are handled directly. |
| 261 | */ | 261 | */ |
| 262 | struct xattr_handler *btrfs_xattr_handlers[] = { | 262 | struct xattr_handler *btrfs_xattr_handlers[] = { |
| 263 | #ifdef CONFIG_BTRFS_POSIX_ACL | 263 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL |
| 264 | &btrfs_xattr_acl_access_handler, | 264 | &btrfs_xattr_acl_access_handler, |
| 265 | &btrfs_xattr_acl_default_handler, | 265 | &btrfs_xattr_acl_default_handler, |
| 266 | #endif | 266 | #endif |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 43003e0bef18..b09098079916 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -1577,7 +1577,8 @@ cifs_get_tcp_session(struct smb_vol *volume_info) | |||
| 1577 | 1577 | ||
| 1578 | out_err: | 1578 | out_err: |
| 1579 | if (tcp_ses) { | 1579 | if (tcp_ses) { |
| 1580 | kfree(tcp_ses->hostname); | 1580 | if (!IS_ERR(tcp_ses->hostname)) |
| 1581 | kfree(tcp_ses->hostname); | ||
| 1581 | if (tcp_ses->ssocket) | 1582 | if (tcp_ses->ssocket) |
| 1582 | sock_release(tcp_ses->ssocket); | 1583 | sock_release(tcp_ses->ssocket); |
| 1583 | kfree(tcp_ses); | 1584 | kfree(tcp_ses); |
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 240cef14fe58..70736eb4b516 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c | |||
| @@ -316,6 +316,10 @@ int dlm_lowcomms_connect_node(int nodeid) | |||
| 316 | { | 316 | { |
| 317 | struct connection *con; | 317 | struct connection *con; |
| 318 | 318 | ||
| 319 | /* with sctp there's no connecting without sending */ | ||
| 320 | if (dlm_config.ci_protocol != 0) | ||
| 321 | return 0; | ||
| 322 | |||
| 319 | if (nodeid == dlm_our_nodeid()) | 323 | if (nodeid == dlm_our_nodeid()) |
| 320 | return 0; | 324 | return 0; |
| 321 | 325 | ||
| @@ -455,9 +459,9 @@ static void process_sctp_notification(struct connection *con, | |||
| 455 | int prim_len, ret; | 459 | int prim_len, ret; |
| 456 | int addr_len; | 460 | int addr_len; |
| 457 | struct connection *new_con; | 461 | struct connection *new_con; |
| 458 | struct file *file; | ||
| 459 | sctp_peeloff_arg_t parg; | 462 | sctp_peeloff_arg_t parg; |
| 460 | int parglen = sizeof(parg); | 463 | int parglen = sizeof(parg); |
| 464 | int err; | ||
| 461 | 465 | ||
| 462 | /* | 466 | /* |
| 463 | * We get this before any data for an association. | 467 | * We get this before any data for an association. |
| @@ -512,19 +516,22 @@ static void process_sctp_notification(struct connection *con, | |||
| 512 | ret = kernel_getsockopt(con->sock, IPPROTO_SCTP, | 516 | ret = kernel_getsockopt(con->sock, IPPROTO_SCTP, |
| 513 | SCTP_SOCKOPT_PEELOFF, | 517 | SCTP_SOCKOPT_PEELOFF, |
| 514 | (void *)&parg, &parglen); | 518 | (void *)&parg, &parglen); |
| 515 | if (ret) { | 519 | if (ret < 0) { |
| 516 | log_print("Can't peel off a socket for " | 520 | log_print("Can't peel off a socket for " |
| 517 | "connection %d to node %d: err=%d\n", | 521 | "connection %d to node %d: err=%d", |
| 518 | parg.associd, nodeid, ret); | 522 | parg.associd, nodeid, ret); |
| 523 | return; | ||
| 524 | } | ||
| 525 | new_con->sock = sockfd_lookup(parg.sd, &err); | ||
| 526 | if (!new_con->sock) { | ||
| 527 | log_print("sockfd_lookup error %d", err); | ||
| 528 | return; | ||
| 519 | } | 529 | } |
| 520 | file = fget(parg.sd); | ||
| 521 | new_con->sock = SOCKET_I(file->f_dentry->d_inode); | ||
| 522 | add_sock(new_con->sock, new_con); | 530 | add_sock(new_con->sock, new_con); |
| 523 | fput(file); | 531 | sockfd_put(new_con->sock); |
| 524 | put_unused_fd(parg.sd); | ||
| 525 | 532 | ||
| 526 | log_print("got new/restarted association %d nodeid %d", | 533 | log_print("connecting to %d sctp association %d", |
| 527 | (int)sn->sn_assoc_change.sac_assoc_id, nodeid); | 534 | nodeid, (int)sn->sn_assoc_change.sac_assoc_id); |
| 528 | 535 | ||
| 529 | /* Send any pending writes */ | 536 | /* Send any pending writes */ |
| 530 | clear_bit(CF_CONNECT_PENDING, &new_con->flags); | 537 | clear_bit(CF_CONNECT_PENDING, &new_con->flags); |
| @@ -837,8 +844,6 @@ static void sctp_init_assoc(struct connection *con) | |||
| 837 | if (con->retries++ > MAX_CONNECT_RETRIES) | 844 | if (con->retries++ > MAX_CONNECT_RETRIES) |
| 838 | return; | 845 | return; |
| 839 | 846 | ||
| 840 | log_print("Initiating association with node %d", con->nodeid); | ||
| 841 | |||
| 842 | if (nodeid_to_addr(con->nodeid, (struct sockaddr *)&rem_addr)) { | 847 | if (nodeid_to_addr(con->nodeid, (struct sockaddr *)&rem_addr)) { |
| 843 | log_print("no address for nodeid %d", con->nodeid); | 848 | log_print("no address for nodeid %d", con->nodeid); |
| 844 | return; | 849 | return; |
| @@ -855,11 +860,14 @@ static void sctp_init_assoc(struct connection *con) | |||
| 855 | outmessage.msg_flags = MSG_EOR; | 860 | outmessage.msg_flags = MSG_EOR; |
| 856 | 861 | ||
| 857 | spin_lock(&con->writequeue_lock); | 862 | spin_lock(&con->writequeue_lock); |
| 858 | e = list_entry(con->writequeue.next, struct writequeue_entry, | ||
| 859 | list); | ||
| 860 | 863 | ||
| 861 | BUG_ON((struct list_head *) e == &con->writequeue); | 864 | if (list_empty(&con->writequeue)) { |
| 865 | spin_unlock(&con->writequeue_lock); | ||
| 866 | log_print("writequeue empty for nodeid %d", con->nodeid); | ||
| 867 | return; | ||
| 868 | } | ||
| 862 | 869 | ||
| 870 | e = list_first_entry(&con->writequeue, struct writequeue_entry, list); | ||
| 863 | len = e->len; | 871 | len = e->len; |
| 864 | offset = e->offset; | 872 | offset = e->offset; |
| 865 | spin_unlock(&con->writequeue_lock); | 873 | spin_unlock(&con->writequeue_lock); |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 72743d360509..7a520a862f49 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
| @@ -2321,7 +2321,18 @@ static int ext3_commit_super(struct super_block *sb, | |||
| 2321 | 2321 | ||
| 2322 | if (!sbh) | 2322 | if (!sbh) |
| 2323 | return error; | 2323 | return error; |
| 2324 | es->s_wtime = cpu_to_le32(get_seconds()); | 2324 | /* |
| 2325 | * If the file system is mounted read-only, don't update the | ||
| 2326 | * superblock write time. This avoids updating the superblock | ||
| 2327 | * write time when we are mounting the root file system | ||
| 2328 | * read/only but we need to replay the journal; at that point, | ||
| 2329 | * for people who are east of GMT and who make their clock | ||
| 2330 | * tick in localtime for Windows bug-for-bug compatibility, | ||
| 2331 | * the clock is set in the future, and this will cause e2fsck | ||
| 2332 | * to complain and force a full file system check. | ||
| 2333 | */ | ||
| 2334 | if (!(sb->s_flags & MS_RDONLY)) | ||
| 2335 | es->s_wtime = cpu_to_le32(get_seconds()); | ||
| 2325 | es->s_free_blocks_count = cpu_to_le32(ext3_count_free_blocks(sb)); | 2336 | es->s_free_blocks_count = cpu_to_le32(ext3_count_free_blocks(sb)); |
| 2326 | es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb)); | 2337 | es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb)); |
| 2327 | BUFFER_TRACE(sbh, "marking dirty"); | 2338 | BUFFER_TRACE(sbh, "marking dirty"); |
diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c index 9b9d6395bad3..052f214ea6f0 100644 --- a/fs/hfs/btree.c +++ b/fs/hfs/btree.c | |||
| @@ -58,6 +58,11 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke | |||
| 58 | } | 58 | } |
| 59 | unlock_new_inode(tree->inode); | 59 | unlock_new_inode(tree->inode); |
| 60 | 60 | ||
| 61 | if (!HFS_I(tree->inode)->first_blocks) { | ||
| 62 | printk(KERN_ERR "hfs: invalid btree extent records (0 size).\n"); | ||
| 63 | goto free_inode; | ||
| 64 | } | ||
| 65 | |||
| 61 | mapping = tree->inode->i_mapping; | 66 | mapping = tree->inode->i_mapping; |
| 62 | page = read_mapping_page(mapping, 0, NULL); | 67 | page = read_mapping_page(mapping, 0, NULL); |
| 63 | if (IS_ERR(page)) | 68 | if (IS_ERR(page)) |
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index 175d08eacc86..bed78ac8f6d1 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c | |||
| @@ -99,6 +99,10 @@ int hfsplus_read_wrapper(struct super_block *sb) | |||
| 99 | 99 | ||
| 100 | if (hfsplus_get_last_session(sb, &part_start, &part_size)) | 100 | if (hfsplus_get_last_session(sb, &part_start, &part_size)) |
| 101 | return -EINVAL; | 101 | return -EINVAL; |
| 102 | if ((u64)part_start + part_size > 0x100000000ULL) { | ||
| 103 | pr_err("hfs: volumes larger than 2TB are not supported yet\n"); | ||
| 104 | return -EINVAL; | ||
| 105 | } | ||
| 102 | while (1) { | 106 | while (1) { |
| 103 | bh = sb_bread512(sb, part_start + HFSPLUS_VOLHEAD_SECTOR, vhdr); | 107 | bh = sb_bread512(sb, part_start + HFSPLUS_VOLHEAD_SECTOR, vhdr); |
| 104 | if (!bh) | 108 | if (!bh) |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 32062c33c859..7cb298525eef 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -1536,6 +1536,8 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) | |||
| 1536 | old_dentry->d_parent->d_name.name, old_dentry->d_name.name, | 1536 | old_dentry->d_parent->d_name.name, old_dentry->d_name.name, |
| 1537 | dentry->d_parent->d_name.name, dentry->d_name.name); | 1537 | dentry->d_parent->d_name.name, dentry->d_name.name); |
| 1538 | 1538 | ||
| 1539 | nfs_inode_return_delegation(inode); | ||
| 1540 | |||
| 1539 | d_drop(dentry); | 1541 | d_drop(dentry); |
| 1540 | error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name); | 1542 | error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name); |
| 1541 | if (error == 0) { | 1543 | if (error == 0) { |
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 6c3210099d51..e1d415e97849 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
| @@ -457,6 +457,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) | |||
| 457 | }; | 457 | }; |
| 458 | struct rpc_task_setup task_setup_data = { | 458 | struct rpc_task_setup task_setup_data = { |
| 459 | .rpc_client = NFS_CLIENT(inode), | 459 | .rpc_client = NFS_CLIENT(inode), |
| 460 | .rpc_message = &msg, | ||
| 460 | .callback_ops = &nfs_write_direct_ops, | 461 | .callback_ops = &nfs_write_direct_ops, |
| 461 | .workqueue = nfsiod_workqueue, | 462 | .workqueue = nfsiod_workqueue, |
| 462 | .flags = RPC_TASK_ASYNC, | 463 | .flags = RPC_TASK_ASYNC, |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index ed7c269e2514..ff37454fa783 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -72,12 +72,17 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, | |||
| 72 | /* Prevent leaks of NFSv4 errors into userland */ | 72 | /* Prevent leaks of NFSv4 errors into userland */ |
| 73 | static int nfs4_map_errors(int err) | 73 | static int nfs4_map_errors(int err) |
| 74 | { | 74 | { |
| 75 | if (err < -1000) { | 75 | if (err >= -1000) |
| 76 | return err; | ||
| 77 | switch (err) { | ||
| 78 | case -NFS4ERR_RESOURCE: | ||
| 79 | return -EREMOTEIO; | ||
| 80 | default: | ||
| 76 | dprintk("%s could not handle NFSv4 error %d\n", | 81 | dprintk("%s could not handle NFSv4 error %d\n", |
| 77 | __func__, -err); | 82 | __func__, -err); |
| 78 | return -EIO; | 83 | break; |
| 79 | } | 84 | } |
| 80 | return err; | 85 | return -EIO; |
| 81 | } | 86 | } |
| 82 | 87 | ||
| 83 | /* | 88 | /* |
| @@ -3060,9 +3065,6 @@ static void nfs4_renew_done(struct rpc_task *task, void *data) | |||
| 3060 | if (time_before(clp->cl_last_renewal,timestamp)) | 3065 | if (time_before(clp->cl_last_renewal,timestamp)) |
| 3061 | clp->cl_last_renewal = timestamp; | 3066 | clp->cl_last_renewal = timestamp; |
| 3062 | spin_unlock(&clp->cl_lock); | 3067 | spin_unlock(&clp->cl_lock); |
| 3063 | dprintk("%s calling put_rpccred on rpc_cred %p\n", __func__, | ||
| 3064 | task->tk_msg.rpc_cred); | ||
| 3065 | put_rpccred(task->tk_msg.rpc_cred); | ||
| 3066 | } | 3068 | } |
| 3067 | 3069 | ||
| 3068 | static const struct rpc_call_ops nfs4_renew_ops = { | 3070 | static const struct rpc_call_ops nfs4_renew_ops = { |
| @@ -4877,7 +4879,6 @@ void nfs41_sequence_call_done(struct rpc_task *task, void *data) | |||
| 4877 | nfs41_sequence_free_slot(clp, task->tk_msg.rpc_resp); | 4879 | nfs41_sequence_free_slot(clp, task->tk_msg.rpc_resp); |
| 4878 | dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred); | 4880 | dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred); |
| 4879 | 4881 | ||
| 4880 | put_rpccred(task->tk_msg.rpc_cred); | ||
| 4881 | kfree(task->tk_msg.rpc_argp); | 4882 | kfree(task->tk_msg.rpc_argp); |
| 4882 | kfree(task->tk_msg.rpc_resp); | 4883 | kfree(task->tk_msg.rpc_resp); |
| 4883 | 4884 | ||
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 83ad47cbdd8a..20b4e30e6c82 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
| @@ -5681,7 +5681,6 @@ static struct { | |||
| 5681 | { NFS4ERR_SERVERFAULT, -ESERVERFAULT }, | 5681 | { NFS4ERR_SERVERFAULT, -ESERVERFAULT }, |
| 5682 | { NFS4ERR_BADTYPE, -EBADTYPE }, | 5682 | { NFS4ERR_BADTYPE, -EBADTYPE }, |
| 5683 | { NFS4ERR_LOCKED, -EAGAIN }, | 5683 | { NFS4ERR_LOCKED, -EAGAIN }, |
| 5684 | { NFS4ERR_RESOURCE, -EREMOTEIO }, | ||
| 5685 | { NFS4ERR_SYMLINK, -ELOOP }, | 5684 | { NFS4ERR_SYMLINK, -ELOOP }, |
| 5686 | { NFS4ERR_OP_ILLEGAL, -EOPNOTSUPP }, | 5685 | { NFS4ERR_OP_ILLEGAL, -EOPNOTSUPP }, |
| 5687 | { NFS4ERR_DEADLOCK, -EDEADLK }, | 5686 | { NFS4ERR_DEADLOCK, -EDEADLK }, |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 6dabf6feec94..90be551b80c1 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
| @@ -1253,6 +1253,7 @@ static int nfs_parse_mount_options(char *raw, | |||
| 1253 | default: | 1253 | default: |
| 1254 | dfprintk(MOUNT, "NFS: unrecognized " | 1254 | dfprintk(MOUNT, "NFS: unrecognized " |
| 1255 | "transport protocol\n"); | 1255 | "transport protocol\n"); |
| 1256 | kfree(string); | ||
| 1256 | return 0; | 1257 | return 0; |
| 1257 | } | 1258 | } |
| 1258 | break; | 1259 | break; |
| @@ -1848,8 +1849,8 @@ nfs_compare_remount_data(struct nfs_server *nfss, | |||
| 1848 | data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) || | 1849 | data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) || |
| 1849 | data->nfs_server.port != nfss->port || | 1850 | data->nfs_server.port != nfss->port || |
| 1850 | data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen || | 1851 | data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen || |
| 1851 | !rpc_cmp_addr(&data->nfs_server.address, | 1852 | !rpc_cmp_addr((struct sockaddr *)&data->nfs_server.address, |
| 1852 | &nfss->nfs_client->cl_addr)) | 1853 | (struct sockaddr *)&nfss->nfs_client->cl_addr)) |
| 1853 | return -EINVAL; | 1854 | return -EINVAL; |
| 1854 | 1855 | ||
| 1855 | return 0; | 1856 | return 0; |
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 828a889be909..7e54e52964dd 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c | |||
| @@ -91,6 +91,7 @@ static int dnotify_handle_event(struct fsnotify_group *group, | |||
| 91 | struct dnotify_struct *dn; | 91 | struct dnotify_struct *dn; |
| 92 | struct dnotify_struct **prev; | 92 | struct dnotify_struct **prev; |
| 93 | struct fown_struct *fown; | 93 | struct fown_struct *fown; |
| 94 | __u32 test_mask = event->mask & ~FS_EVENT_ON_CHILD; | ||
| 94 | 95 | ||
| 95 | to_tell = event->to_tell; | 96 | to_tell = event->to_tell; |
| 96 | 97 | ||
| @@ -106,7 +107,7 @@ static int dnotify_handle_event(struct fsnotify_group *group, | |||
| 106 | spin_lock(&entry->lock); | 107 | spin_lock(&entry->lock); |
| 107 | prev = &dnentry->dn; | 108 | prev = &dnentry->dn; |
| 108 | while ((dn = *prev) != NULL) { | 109 | while ((dn = *prev) != NULL) { |
| 109 | if ((dn->dn_mask & event->mask) == 0) { | 110 | if ((dn->dn_mask & test_mask) == 0) { |
| 110 | prev = &dn->dn_next; | 111 | prev = &dn->dn_next; |
| 111 | continue; | 112 | continue; |
| 112 | } | 113 | } |
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c index c8a07c65482b..3165d85aada2 100644 --- a/fs/notify/inode_mark.c +++ b/fs/notify/inode_mark.c | |||
| @@ -324,11 +324,11 @@ int fsnotify_add_mark(struct fsnotify_mark_entry *entry, | |||
| 324 | spin_lock(&group->mark_lock); | 324 | spin_lock(&group->mark_lock); |
| 325 | spin_lock(&inode->i_lock); | 325 | spin_lock(&inode->i_lock); |
| 326 | 326 | ||
| 327 | entry->group = group; | ||
| 328 | entry->inode = inode; | ||
| 329 | |||
| 330 | lentry = fsnotify_find_mark_entry(group, inode); | 327 | lentry = fsnotify_find_mark_entry(group, inode); |
| 331 | if (!lentry) { | 328 | if (!lentry) { |
| 329 | entry->group = group; | ||
| 330 | entry->inode = inode; | ||
| 331 | |||
| 332 | hlist_add_head(&entry->i_list, &inode->i_fsnotify_mark_entries); | 332 | hlist_add_head(&entry->i_list, &inode->i_fsnotify_mark_entries); |
| 333 | list_add(&entry->g_list, &group->mark_entries); | 333 | list_add(&entry->g_list, &group->mark_entries); |
| 334 | 334 | ||
diff --git a/fs/notify/notification.c b/fs/notify/notification.c index 3816d5750dd5..b8bf53b4c108 100644 --- a/fs/notify/notification.c +++ b/fs/notify/notification.c | |||
| @@ -143,7 +143,7 @@ static bool event_compare(struct fsnotify_event *old, struct fsnotify_event *new | |||
| 143 | /* remember, after old was put on the wait_q we aren't | 143 | /* remember, after old was put on the wait_q we aren't |
| 144 | * allowed to look at the inode any more, only thing | 144 | * allowed to look at the inode any more, only thing |
| 145 | * left to check was if the file_name is the same */ | 145 | * left to check was if the file_name is the same */ |
| 146 | if (old->name_len && | 146 | if (!old->name_len || |
| 147 | !strcmp(old->file_name, new->file_name)) | 147 | !strcmp(old->file_name, new->file_name)) |
| 148 | return true; | 148 | return true; |
| 149 | break; | 149 | break; |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index f38fee0311a7..7b685e10cbad 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
| @@ -248,11 +248,19 @@ ssize_t part_stat_show(struct device *dev, | |||
| 248 | part_stat_read(p, merges[WRITE]), | 248 | part_stat_read(p, merges[WRITE]), |
| 249 | (unsigned long long)part_stat_read(p, sectors[WRITE]), | 249 | (unsigned long long)part_stat_read(p, sectors[WRITE]), |
| 250 | jiffies_to_msecs(part_stat_read(p, ticks[WRITE])), | 250 | jiffies_to_msecs(part_stat_read(p, ticks[WRITE])), |
| 251 | p->in_flight, | 251 | part_in_flight(p), |
| 252 | jiffies_to_msecs(part_stat_read(p, io_ticks)), | 252 | jiffies_to_msecs(part_stat_read(p, io_ticks)), |
| 253 | jiffies_to_msecs(part_stat_read(p, time_in_queue))); | 253 | jiffies_to_msecs(part_stat_read(p, time_in_queue))); |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | ssize_t part_inflight_show(struct device *dev, | ||
| 257 | struct device_attribute *attr, char *buf) | ||
| 258 | { | ||
| 259 | struct hd_struct *p = dev_to_part(dev); | ||
| 260 | |||
| 261 | return sprintf(buf, "%8u %8u\n", p->in_flight[0], p->in_flight[1]); | ||
| 262 | } | ||
| 263 | |||
| 256 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 264 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
| 257 | ssize_t part_fail_show(struct device *dev, | 265 | ssize_t part_fail_show(struct device *dev, |
| 258 | struct device_attribute *attr, char *buf) | 266 | struct device_attribute *attr, char *buf) |
| @@ -281,6 +289,7 @@ static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); | |||
| 281 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); | 289 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); |
| 282 | static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL); | 290 | static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL); |
| 283 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); | 291 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); |
| 292 | static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL); | ||
| 284 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 293 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
| 285 | static struct device_attribute dev_attr_fail = | 294 | static struct device_attribute dev_attr_fail = |
| 286 | __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); | 295 | __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store); |
| @@ -292,6 +301,7 @@ static struct attribute *part_attrs[] = { | |||
| 292 | &dev_attr_size.attr, | 301 | &dev_attr_size.attr, |
| 293 | &dev_attr_alignment_offset.attr, | 302 | &dev_attr_alignment_offset.attr, |
| 294 | &dev_attr_stat.attr, | 303 | &dev_attr_stat.attr, |
| 304 | &dev_attr_inflight.attr, | ||
| 295 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 305 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
| 296 | &dev_attr_fail.attr, | 306 | &dev_attr_fail.attr, |
| 297 | #endif | 307 | #endif |
| @@ -777,36 +777,55 @@ pipe_rdwr_release(struct inode *inode, struct file *filp) | |||
| 777 | static int | 777 | static int |
| 778 | pipe_read_open(struct inode *inode, struct file *filp) | 778 | pipe_read_open(struct inode *inode, struct file *filp) |
| 779 | { | 779 | { |
| 780 | /* We could have perhaps used atomic_t, but this and friends | 780 | int ret = -ENOENT; |
| 781 | below are the only places. So it doesn't seem worthwhile. */ | 781 | |
| 782 | mutex_lock(&inode->i_mutex); | 782 | mutex_lock(&inode->i_mutex); |
| 783 | inode->i_pipe->readers++; | 783 | |
| 784 | if (inode->i_pipe) { | ||
| 785 | ret = 0; | ||
| 786 | inode->i_pipe->readers++; | ||
| 787 | } | ||
| 788 | |||
| 784 | mutex_unlock(&inode->i_mutex); | 789 | mutex_unlock(&inode->i_mutex); |
| 785 | 790 | ||
| 786 | return 0; | 791 | return ret; |
| 787 | } | 792 | } |
| 788 | 793 | ||
| 789 | static int | 794 | static int |
| 790 | pipe_write_open(struct inode *inode, struct file *filp) | 795 | pipe_write_open(struct inode *inode, struct file *filp) |
| 791 | { | 796 | { |
| 797 | int ret = -ENOENT; | ||
| 798 | |||
| 792 | mutex_lock(&inode->i_mutex); | 799 | mutex_lock(&inode->i_mutex); |
| 793 | inode->i_pipe->writers++; | 800 | |
| 801 | if (inode->i_pipe) { | ||
| 802 | ret = 0; | ||
| 803 | inode->i_pipe->writers++; | ||
| 804 | } | ||
| 805 | |||
| 794 | mutex_unlock(&inode->i_mutex); | 806 | mutex_unlock(&inode->i_mutex); |
| 795 | 807 | ||
| 796 | return 0; | 808 | return ret; |
| 797 | } | 809 | } |
| 798 | 810 | ||
| 799 | static int | 811 | static int |
| 800 | pipe_rdwr_open(struct inode *inode, struct file *filp) | 812 | pipe_rdwr_open(struct inode *inode, struct file *filp) |
| 801 | { | 813 | { |
| 814 | int ret = -ENOENT; | ||
| 815 | |||
| 802 | mutex_lock(&inode->i_mutex); | 816 | mutex_lock(&inode->i_mutex); |
| 803 | if (filp->f_mode & FMODE_READ) | 817 | |
| 804 | inode->i_pipe->readers++; | 818 | if (inode->i_pipe) { |
| 805 | if (filp->f_mode & FMODE_WRITE) | 819 | ret = 0; |
| 806 | inode->i_pipe->writers++; | 820 | if (filp->f_mode & FMODE_READ) |
| 821 | inode->i_pipe->readers++; | ||
| 822 | if (filp->f_mode & FMODE_WRITE) | ||
| 823 | inode->i_pipe->writers++; | ||
| 824 | } | ||
| 825 | |||
| 807 | mutex_unlock(&inode->i_mutex); | 826 | mutex_unlock(&inode->i_mutex); |
| 808 | 827 | ||
| 809 | return 0; | 828 | return ret; |
| 810 | } | 829 | } |
| 811 | 830 | ||
| 812 | /* | 831 | /* |
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index c7bff4f603ff..a65239cfd97e 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c | |||
| @@ -99,7 +99,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
| 99 | "VmallocUsed: %8lu kB\n" | 99 | "VmallocUsed: %8lu kB\n" |
| 100 | "VmallocChunk: %8lu kB\n" | 100 | "VmallocChunk: %8lu kB\n" |
| 101 | #ifdef CONFIG_MEMORY_FAILURE | 101 | #ifdef CONFIG_MEMORY_FAILURE |
| 102 | "HardwareCorrupted: %8lu kB\n" | 102 | "HardwareCorrupted: %5lu kB\n" |
| 103 | #endif | 103 | #endif |
| 104 | , | 104 | , |
| 105 | K(i.totalram), | 105 | K(i.totalram), |
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 0050fc40e8c9..5fad489ce5bc 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
| @@ -894,7 +894,8 @@ int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj) | |||
| 894 | 894 | ||
| 895 | mutex_lock(&sysfs_rename_mutex); | 895 | mutex_lock(&sysfs_rename_mutex); |
| 896 | BUG_ON(!sd->s_parent); | 896 | BUG_ON(!sd->s_parent); |
| 897 | new_parent_sd = new_parent_kobj->sd ? new_parent_kobj->sd : &sysfs_root; | 897 | new_parent_sd = (new_parent_kobj && new_parent_kobj->sd) ? |
| 898 | new_parent_kobj->sd : &sysfs_root; | ||
| 898 | 899 | ||
| 899 | error = 0; | 900 | error = 0; |
| 900 | if (sd->s_parent == new_parent_sd) | 901 | if (sd->s_parent == new_parent_sd) |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 561a9c050cef..f5ea4680f15f 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
| @@ -268,7 +268,7 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd, | |||
| 268 | struct sysfs_open_dirent *od, *new_od = NULL; | 268 | struct sysfs_open_dirent *od, *new_od = NULL; |
| 269 | 269 | ||
| 270 | retry: | 270 | retry: |
| 271 | spin_lock(&sysfs_open_dirent_lock); | 271 | spin_lock_irq(&sysfs_open_dirent_lock); |
| 272 | 272 | ||
| 273 | if (!sd->s_attr.open && new_od) { | 273 | if (!sd->s_attr.open && new_od) { |
| 274 | sd->s_attr.open = new_od; | 274 | sd->s_attr.open = new_od; |
| @@ -281,7 +281,7 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd, | |||
| 281 | list_add_tail(&buffer->list, &od->buffers); | 281 | list_add_tail(&buffer->list, &od->buffers); |
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | spin_unlock(&sysfs_open_dirent_lock); | 284 | spin_unlock_irq(&sysfs_open_dirent_lock); |
| 285 | 285 | ||
| 286 | if (od) { | 286 | if (od) { |
| 287 | kfree(new_od); | 287 | kfree(new_od); |
| @@ -315,8 +315,9 @@ static void sysfs_put_open_dirent(struct sysfs_dirent *sd, | |||
| 315 | struct sysfs_buffer *buffer) | 315 | struct sysfs_buffer *buffer) |
| 316 | { | 316 | { |
| 317 | struct sysfs_open_dirent *od = sd->s_attr.open; | 317 | struct sysfs_open_dirent *od = sd->s_attr.open; |
| 318 | unsigned long flags; | ||
| 318 | 319 | ||
| 319 | spin_lock(&sysfs_open_dirent_lock); | 320 | spin_lock_irqsave(&sysfs_open_dirent_lock, flags); |
| 320 | 321 | ||
| 321 | list_del(&buffer->list); | 322 | list_del(&buffer->list); |
| 322 | if (atomic_dec_and_test(&od->refcnt)) | 323 | if (atomic_dec_and_test(&od->refcnt)) |
| @@ -324,7 +325,7 @@ static void sysfs_put_open_dirent(struct sysfs_dirent *sd, | |||
| 324 | else | 325 | else |
| 325 | od = NULL; | 326 | od = NULL; |
| 326 | 327 | ||
| 327 | spin_unlock(&sysfs_open_dirent_lock); | 328 | spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags); |
| 328 | 329 | ||
| 329 | kfree(od); | 330 | kfree(od); |
| 330 | } | 331 | } |
| @@ -456,8 +457,9 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait) | |||
| 456 | void sysfs_notify_dirent(struct sysfs_dirent *sd) | 457 | void sysfs_notify_dirent(struct sysfs_dirent *sd) |
| 457 | { | 458 | { |
| 458 | struct sysfs_open_dirent *od; | 459 | struct sysfs_open_dirent *od; |
| 460 | unsigned long flags; | ||
| 459 | 461 | ||
| 460 | spin_lock(&sysfs_open_dirent_lock); | 462 | spin_lock_irqsave(&sysfs_open_dirent_lock, flags); |
| 461 | 463 | ||
| 462 | od = sd->s_attr.open; | 464 | od = sd->s_attr.open; |
| 463 | if (od) { | 465 | if (od) { |
| @@ -465,7 +467,7 @@ void sysfs_notify_dirent(struct sysfs_dirent *sd) | |||
| 465 | wake_up_interruptible(&od->poll); | 467 | wake_up_interruptible(&od->poll); |
| 466 | } | 468 | } |
| 467 | 469 | ||
| 468 | spin_unlock(&sysfs_open_dirent_lock); | 470 | spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags); |
| 469 | } | 471 | } |
| 470 | EXPORT_SYMBOL_GPL(sysfs_notify_dirent); | 472 | EXPORT_SYMBOL_GPL(sysfs_notify_dirent); |
| 471 | 473 | ||
diff --git a/fs/xfs/linux-2.6/xfs_quotaops.c b/fs/xfs/linux-2.6/xfs_quotaops.c index 9e41f91aa269..3d4a0c84d634 100644 --- a/fs/xfs/linux-2.6/xfs_quotaops.c +++ b/fs/xfs/linux-2.6/xfs_quotaops.c | |||
| @@ -80,7 +80,7 @@ xfs_fs_set_xstate( | |||
| 80 | 80 | ||
| 81 | if (sb->s_flags & MS_RDONLY) | 81 | if (sb->s_flags & MS_RDONLY) |
| 82 | return -EROFS; | 82 | return -EROFS; |
| 83 | if (!XFS_IS_QUOTA_RUNNING(mp)) | 83 | if (op != Q_XQUOTARM && !XFS_IS_QUOTA_RUNNING(mp)) |
| 84 | return -ENOSYS; | 84 | return -ENOSYS; |
| 85 | if (!capable(CAP_SYS_ADMIN)) | 85 | if (!capable(CAP_SYS_ADMIN)) |
| 86 | return -EPERM; | 86 | return -EPERM; |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 4e4276b956e8..5d1a3b98a6e6 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
| @@ -876,7 +876,6 @@ xfs_dqrele_inode( | |||
| 876 | ip->i_gdquot = NULL; | 876 | ip->i_gdquot = NULL; |
| 877 | } | 877 | } |
| 878 | xfs_iput(ip, XFS_ILOCK_EXCL); | 878 | xfs_iput(ip, XFS_ILOCK_EXCL); |
| 879 | IRELE(ip); | ||
| 880 | 879 | ||
| 881 | return 0; | 880 | return 0; |
| 882 | } | 881 | } |
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index ab64f3efb43b..0785797db828 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
| @@ -880,6 +880,7 @@ nextag: | |||
| 880 | * Not in range - save last search | 880 | * Not in range - save last search |
| 881 | * location and allocate a new inode | 881 | * location and allocate a new inode |
| 882 | */ | 882 | */ |
| 883 | xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR); | ||
| 883 | pag->pagl_leftrec = trec.ir_startino; | 884 | pag->pagl_leftrec = trec.ir_startino; |
| 884 | pag->pagl_rightrec = rec.ir_startino; | 885 | pag->pagl_rightrec = rec.ir_startino; |
| 885 | pag->pagl_pagino = pagino; | 886 | pag->pagl_pagino = pagino; |
