diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/aio.c | 36 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 10 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 3 | ||||
| -rw-r--r-- | fs/btrfs/relocation.c | 9 | ||||
| -rw-r--r-- | fs/ceph/locks.c | 73 | ||||
| -rw-r--r-- | fs/ceph/mds_client.c | 65 | ||||
| -rw-r--r-- | fs/ceph/super.h | 9 | ||||
| -rw-r--r-- | fs/file_table.c | 19 | ||||
| -rw-r--r-- | fs/namei.c | 4 | ||||
| -rw-r--r-- | fs/ncpfs/dir.c | 9 | ||||
| -rw-r--r-- | fs/ocfs2/dlm/dlmrecovery.c | 1 | ||||
| -rw-r--r-- | fs/ocfs2/namei.c | 4 | ||||
| -rw-r--r-- | fs/proc/kmsg.c | 10 | ||||
| -rw-r--r-- | fs/xfs/xfs_attr_leaf.h | 1 | ||||
| -rw-r--r-- | fs/xfs/xfs_btree.c | 10 | ||||
| -rw-r--r-- | fs/xfs/xfs_dir2_format.h | 5 | ||||
| -rw-r--r-- | fs/xfs/xfs_log_recover.c | 19 | ||||
| -rw-r--r-- | fs/xfs/xfs_mount.c | 18 |
18 files changed, 180 insertions, 125 deletions
| @@ -141,9 +141,6 @@ static void aio_free_ring(struct kioctx *ctx) | |||
| 141 | for (i = 0; i < ctx->nr_pages; i++) | 141 | for (i = 0; i < ctx->nr_pages; i++) |
| 142 | put_page(ctx->ring_pages[i]); | 142 | put_page(ctx->ring_pages[i]); |
| 143 | 143 | ||
| 144 | if (ctx->mmap_size) | ||
| 145 | vm_munmap(ctx->mmap_base, ctx->mmap_size); | ||
| 146 | |||
| 147 | if (ctx->ring_pages && ctx->ring_pages != ctx->internal_pages) | 144 | if (ctx->ring_pages && ctx->ring_pages != ctx->internal_pages) |
| 148 | kfree(ctx->ring_pages); | 145 | kfree(ctx->ring_pages); |
| 149 | } | 146 | } |
| @@ -322,11 +319,6 @@ static void free_ioctx(struct kioctx *ctx) | |||
| 322 | 319 | ||
| 323 | aio_free_ring(ctx); | 320 | aio_free_ring(ctx); |
| 324 | 321 | ||
| 325 | spin_lock(&aio_nr_lock); | ||
| 326 | BUG_ON(aio_nr - ctx->max_reqs > aio_nr); | ||
| 327 | aio_nr -= ctx->max_reqs; | ||
| 328 | spin_unlock(&aio_nr_lock); | ||
| 329 | |||
| 330 | pr_debug("freeing %p\n", ctx); | 322 | pr_debug("freeing %p\n", ctx); |
| 331 | 323 | ||
| 332 | /* | 324 | /* |
| @@ -435,17 +427,24 @@ static void kill_ioctx(struct kioctx *ctx) | |||
| 435 | { | 427 | { |
| 436 | if (!atomic_xchg(&ctx->dead, 1)) { | 428 | if (!atomic_xchg(&ctx->dead, 1)) { |
| 437 | hlist_del_rcu(&ctx->list); | 429 | hlist_del_rcu(&ctx->list); |
| 438 | /* Between hlist_del_rcu() and dropping the initial ref */ | ||
| 439 | synchronize_rcu(); | ||
| 440 | 430 | ||
| 441 | /* | 431 | /* |
| 442 | * We can't punt to workqueue here because put_ioctx() -> | 432 | * It'd be more correct to do this in free_ioctx(), after all |
| 443 | * free_ioctx() will unmap the ringbuffer, and that has to be | 433 | * the outstanding kiocbs have finished - but by then io_destroy |
| 444 | * done in the original process's context. kill_ioctx_rcu/work() | 434 | * has already returned, so io_setup() could potentially return |
| 445 | * exist for exit_aio(), as in that path free_ioctx() won't do | 435 | * -EAGAIN with no ioctxs actually in use (as far as userspace |
| 446 | * the unmap. | 436 | * could tell). |
| 447 | */ | 437 | */ |
| 448 | kill_ioctx_work(&ctx->rcu_work); | 438 | spin_lock(&aio_nr_lock); |
| 439 | BUG_ON(aio_nr - ctx->max_reqs > aio_nr); | ||
| 440 | aio_nr -= ctx->max_reqs; | ||
| 441 | spin_unlock(&aio_nr_lock); | ||
| 442 | |||
| 443 | if (ctx->mmap_size) | ||
| 444 | vm_munmap(ctx->mmap_base, ctx->mmap_size); | ||
| 445 | |||
| 446 | /* Between hlist_del_rcu() and dropping the initial ref */ | ||
| 447 | call_rcu(&ctx->rcu_head, kill_ioctx_rcu); | ||
| 449 | } | 448 | } |
| 450 | } | 449 | } |
| 451 | 450 | ||
| @@ -495,10 +494,7 @@ void exit_aio(struct mm_struct *mm) | |||
| 495 | */ | 494 | */ |
| 496 | ctx->mmap_size = 0; | 495 | ctx->mmap_size = 0; |
| 497 | 496 | ||
| 498 | if (!atomic_xchg(&ctx->dead, 1)) { | 497 | kill_ioctx(ctx); |
| 499 | hlist_del_rcu(&ctx->list); | ||
| 500 | call_rcu(&ctx->rcu_head, kill_ioctx_rcu); | ||
| 501 | } | ||
| 502 | } | 498 | } |
| 503 | } | 499 | } |
| 504 | 500 | ||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index e7b3cb5286a5..b8b60b660c8f 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -2859,8 +2859,8 @@ fail_qgroup: | |||
| 2859 | btrfs_free_qgroup_config(fs_info); | 2859 | btrfs_free_qgroup_config(fs_info); |
| 2860 | fail_trans_kthread: | 2860 | fail_trans_kthread: |
| 2861 | kthread_stop(fs_info->transaction_kthread); | 2861 | kthread_stop(fs_info->transaction_kthread); |
| 2862 | del_fs_roots(fs_info); | ||
| 2863 | btrfs_cleanup_transaction(fs_info->tree_root); | 2862 | btrfs_cleanup_transaction(fs_info->tree_root); |
| 2863 | del_fs_roots(fs_info); | ||
| 2864 | fail_cleaner: | 2864 | fail_cleaner: |
| 2865 | kthread_stop(fs_info->cleaner_kthread); | 2865 | kthread_stop(fs_info->cleaner_kthread); |
| 2866 | 2866 | ||
| @@ -3512,15 +3512,15 @@ int close_ctree(struct btrfs_root *root) | |||
| 3512 | percpu_counter_sum(&fs_info->delalloc_bytes)); | 3512 | percpu_counter_sum(&fs_info->delalloc_bytes)); |
| 3513 | } | 3513 | } |
| 3514 | 3514 | ||
| 3515 | free_root_pointers(fs_info, 1); | ||
| 3516 | |||
| 3517 | btrfs_free_block_groups(fs_info); | 3515 | btrfs_free_block_groups(fs_info); |
| 3518 | 3516 | ||
| 3517 | btrfs_stop_all_workers(fs_info); | ||
| 3518 | |||
| 3519 | del_fs_roots(fs_info); | 3519 | del_fs_roots(fs_info); |
| 3520 | 3520 | ||
| 3521 | iput(fs_info->btree_inode); | 3521 | free_root_pointers(fs_info, 1); |
| 3522 | 3522 | ||
| 3523 | btrfs_stop_all_workers(fs_info); | 3523 | iput(fs_info->btree_inode); |
| 3524 | 3524 | ||
| 3525 | #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY | 3525 | #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY |
| 3526 | if (btrfs_test_opt(root, CHECK_INTEGRITY)) | 3526 | if (btrfs_test_opt(root, CHECK_INTEGRITY)) |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index af978f7682b3..17f3064b4a3e 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -8012,6 +8012,9 @@ int btrfs_drop_inode(struct inode *inode) | |||
| 8012 | { | 8012 | { |
| 8013 | struct btrfs_root *root = BTRFS_I(inode)->root; | 8013 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 8014 | 8014 | ||
| 8015 | if (root == NULL) | ||
| 8016 | return 1; | ||
| 8017 | |||
| 8015 | /* the snap/subvol tree is on deleting */ | 8018 | /* the snap/subvol tree is on deleting */ |
| 8016 | if (btrfs_root_refs(&root->root_item) == 0 && | 8019 | if (btrfs_root_refs(&root->root_item) == 0 && |
| 8017 | root != root->fs_info->tree_root) | 8020 | root != root->fs_info->tree_root) |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 395b82031a42..4febca4fc2de 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
| @@ -4082,7 +4082,7 @@ out: | |||
| 4082 | return inode; | 4082 | return inode; |
| 4083 | } | 4083 | } |
| 4084 | 4084 | ||
| 4085 | static struct reloc_control *alloc_reloc_control(void) | 4085 | static struct reloc_control *alloc_reloc_control(struct btrfs_fs_info *fs_info) |
| 4086 | { | 4086 | { |
| 4087 | struct reloc_control *rc; | 4087 | struct reloc_control *rc; |
| 4088 | 4088 | ||
| @@ -4093,7 +4093,8 @@ static struct reloc_control *alloc_reloc_control(void) | |||
| 4093 | INIT_LIST_HEAD(&rc->reloc_roots); | 4093 | INIT_LIST_HEAD(&rc->reloc_roots); |
| 4094 | backref_cache_init(&rc->backref_cache); | 4094 | backref_cache_init(&rc->backref_cache); |
| 4095 | mapping_tree_init(&rc->reloc_root_tree); | 4095 | mapping_tree_init(&rc->reloc_root_tree); |
| 4096 | extent_io_tree_init(&rc->processed_blocks, NULL); | 4096 | extent_io_tree_init(&rc->processed_blocks, |
| 4097 | fs_info->btree_inode->i_mapping); | ||
| 4097 | return rc; | 4098 | return rc; |
| 4098 | } | 4099 | } |
| 4099 | 4100 | ||
| @@ -4110,7 +4111,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start) | |||
| 4110 | int rw = 0; | 4111 | int rw = 0; |
| 4111 | int err = 0; | 4112 | int err = 0; |
| 4112 | 4113 | ||
| 4113 | rc = alloc_reloc_control(); | 4114 | rc = alloc_reloc_control(fs_info); |
| 4114 | if (!rc) | 4115 | if (!rc) |
| 4115 | return -ENOMEM; | 4116 | return -ENOMEM; |
| 4116 | 4117 | ||
| @@ -4311,7 +4312,7 @@ int btrfs_recover_relocation(struct btrfs_root *root) | |||
| 4311 | if (list_empty(&reloc_roots)) | 4312 | if (list_empty(&reloc_roots)) |
| 4312 | goto out; | 4313 | goto out; |
| 4313 | 4314 | ||
| 4314 | rc = alloc_reloc_control(); | 4315 | rc = alloc_reloc_control(root->fs_info); |
| 4315 | if (!rc) { | 4316 | if (!rc) { |
| 4316 | err = -ENOMEM; | 4317 | err = -ENOMEM; |
| 4317 | goto out; | 4318 | goto out; |
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index 202dd3d68be0..ebbf680378e2 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
| @@ -191,27 +191,23 @@ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count) | |||
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | /** | 193 | /** |
| 194 | * Encode the flock and fcntl locks for the given inode into the pagelist. | 194 | * Encode the flock and fcntl locks for the given inode into the ceph_filelock |
| 195 | * Format is: #fcntl locks, sequential fcntl locks, #flock locks, | 195 | * array. Must be called with lock_flocks() already held. |
| 196 | * sequential flock locks. | 196 | * If we encounter more of a specific lock type than expected, return -ENOSPC. |
| 197 | * Must be called with lock_flocks() already held. | ||
| 198 | * If we encounter more of a specific lock type than expected, | ||
| 199 | * we return the value 1. | ||
| 200 | */ | 197 | */ |
| 201 | int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, | 198 | int ceph_encode_locks_to_buffer(struct inode *inode, |
| 202 | int num_fcntl_locks, int num_flock_locks) | 199 | struct ceph_filelock *flocks, |
| 200 | int num_fcntl_locks, int num_flock_locks) | ||
| 203 | { | 201 | { |
| 204 | struct file_lock *lock; | 202 | struct file_lock *lock; |
| 205 | struct ceph_filelock cephlock; | ||
| 206 | int err = 0; | 203 | int err = 0; |
| 207 | int seen_fcntl = 0; | 204 | int seen_fcntl = 0; |
| 208 | int seen_flock = 0; | 205 | int seen_flock = 0; |
| 206 | int l = 0; | ||
| 209 | 207 | ||
| 210 | dout("encoding %d flock and %d fcntl locks", num_flock_locks, | 208 | dout("encoding %d flock and %d fcntl locks", num_flock_locks, |
| 211 | num_fcntl_locks); | 209 | num_fcntl_locks); |
| 212 | err = ceph_pagelist_append(pagelist, &num_fcntl_locks, sizeof(u32)); | 210 | |
| 213 | if (err) | ||
| 214 | goto fail; | ||
| 215 | for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) { | 211 | for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) { |
| 216 | if (lock->fl_flags & FL_POSIX) { | 212 | if (lock->fl_flags & FL_POSIX) { |
| 217 | ++seen_fcntl; | 213 | ++seen_fcntl; |
| @@ -219,19 +215,12 @@ int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, | |||
| 219 | err = -ENOSPC; | 215 | err = -ENOSPC; |
| 220 | goto fail; | 216 | goto fail; |
| 221 | } | 217 | } |
| 222 | err = lock_to_ceph_filelock(lock, &cephlock); | 218 | err = lock_to_ceph_filelock(lock, &flocks[l]); |
| 223 | if (err) | 219 | if (err) |
| 224 | goto fail; | 220 | goto fail; |
| 225 | err = ceph_pagelist_append(pagelist, &cephlock, | 221 | ++l; |
| 226 | sizeof(struct ceph_filelock)); | ||
| 227 | } | 222 | } |
| 228 | if (err) | ||
| 229 | goto fail; | ||
| 230 | } | 223 | } |
| 231 | |||
| 232 | err = ceph_pagelist_append(pagelist, &num_flock_locks, sizeof(u32)); | ||
| 233 | if (err) | ||
| 234 | goto fail; | ||
| 235 | for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) { | 224 | for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) { |
| 236 | if (lock->fl_flags & FL_FLOCK) { | 225 | if (lock->fl_flags & FL_FLOCK) { |
| 237 | ++seen_flock; | 226 | ++seen_flock; |
| @@ -239,19 +228,51 @@ int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist, | |||
| 239 | err = -ENOSPC; | 228 | err = -ENOSPC; |
| 240 | goto fail; | 229 | goto fail; |
| 241 | } | 230 | } |
| 242 | err = lock_to_ceph_filelock(lock, &cephlock); | 231 | err = lock_to_ceph_filelock(lock, &flocks[l]); |
| 243 | if (err) | 232 | if (err) |
| 244 | goto fail; | 233 | goto fail; |
| 245 | err = ceph_pagelist_append(pagelist, &cephlock, | 234 | ++l; |
| 246 | sizeof(struct ceph_filelock)); | ||
| 247 | } | 235 | } |
| 248 | if (err) | ||
| 249 | goto fail; | ||
| 250 | } | 236 | } |
| 251 | fail: | 237 | fail: |
| 252 | return err; | 238 | return err; |
| 253 | } | 239 | } |
| 254 | 240 | ||
| 241 | /** | ||
| 242 | * Copy the encoded flock and fcntl locks into the pagelist. | ||
| 243 | * Format is: #fcntl locks, sequential fcntl locks, #flock locks, | ||
| 244 | * sequential flock locks. | ||
| 245 | * Returns zero on success. | ||
| 246 | */ | ||
| 247 | int ceph_locks_to_pagelist(struct ceph_filelock *flocks, | ||
| 248 | struct ceph_pagelist *pagelist, | ||
| 249 | int num_fcntl_locks, int num_flock_locks) | ||
| 250 | { | ||
| 251 | int err = 0; | ||
| 252 | __le32 nlocks; | ||
| 253 | |||
| 254 | nlocks = cpu_to_le32(num_fcntl_locks); | ||
| 255 | err = ceph_pagelist_append(pagelist, &nlocks, sizeof(nlocks)); | ||
| 256 | if (err) | ||
| 257 | goto out_fail; | ||
| 258 | |||
| 259 | err = ceph_pagelist_append(pagelist, flocks, | ||
| 260 | num_fcntl_locks * sizeof(*flocks)); | ||
| 261 | if (err) | ||
| 262 | goto out_fail; | ||
| 263 | |||
| 264 | nlocks = cpu_to_le32(num_flock_locks); | ||
| 265 | err = ceph_pagelist_append(pagelist, &nlocks, sizeof(nlocks)); | ||
| 266 | if (err) | ||
| 267 | goto out_fail; | ||
| 268 | |||
| 269 | err = ceph_pagelist_append(pagelist, | ||
| 270 | &flocks[num_fcntl_locks], | ||
| 271 | num_flock_locks * sizeof(*flocks)); | ||
| 272 | out_fail: | ||
| 273 | return err; | ||
| 274 | } | ||
| 275 | |||
| 255 | /* | 276 | /* |
| 256 | * Given a pointer to a lock, convert it to a ceph filelock | 277 | * Given a pointer to a lock, convert it to a ceph filelock |
| 257 | */ | 278 | */ |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 4f22671a5bd4..4d2920304be8 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
| @@ -2478,39 +2478,44 @@ static int encode_caps_cb(struct inode *inode, struct ceph_cap *cap, | |||
| 2478 | 2478 | ||
| 2479 | if (recon_state->flock) { | 2479 | if (recon_state->flock) { |
| 2480 | int num_fcntl_locks, num_flock_locks; | 2480 | int num_fcntl_locks, num_flock_locks; |
| 2481 | struct ceph_pagelist_cursor trunc_point; | 2481 | struct ceph_filelock *flocks; |
| 2482 | 2482 | ||
| 2483 | ceph_pagelist_set_cursor(pagelist, &trunc_point); | 2483 | encode_again: |
| 2484 | do { | 2484 | lock_flocks(); |
| 2485 | lock_flocks(); | 2485 | ceph_count_locks(inode, &num_fcntl_locks, &num_flock_locks); |
| 2486 | ceph_count_locks(inode, &num_fcntl_locks, | 2486 | unlock_flocks(); |
| 2487 | &num_flock_locks); | 2487 | flocks = kmalloc((num_fcntl_locks+num_flock_locks) * |
| 2488 | rec.v2.flock_len = (2*sizeof(u32) + | 2488 | sizeof(struct ceph_filelock), GFP_NOFS); |
| 2489 | (num_fcntl_locks+num_flock_locks) * | 2489 | if (!flocks) { |
| 2490 | sizeof(struct ceph_filelock)); | 2490 | err = -ENOMEM; |
| 2491 | unlock_flocks(); | 2491 | goto out_free; |
| 2492 | 2492 | } | |
| 2493 | /* pre-alloc pagelist */ | 2493 | lock_flocks(); |
| 2494 | ceph_pagelist_truncate(pagelist, &trunc_point); | 2494 | err = ceph_encode_locks_to_buffer(inode, flocks, |
| 2495 | err = ceph_pagelist_append(pagelist, &rec, reclen); | 2495 | num_fcntl_locks, |
| 2496 | if (!err) | 2496 | num_flock_locks); |
| 2497 | err = ceph_pagelist_reserve(pagelist, | 2497 | unlock_flocks(); |
| 2498 | rec.v2.flock_len); | 2498 | if (err) { |
| 2499 | 2499 | kfree(flocks); | |
| 2500 | /* encode locks */ | 2500 | if (err == -ENOSPC) |
| 2501 | if (!err) { | 2501 | goto encode_again; |
| 2502 | lock_flocks(); | 2502 | goto out_free; |
| 2503 | err = ceph_encode_locks(inode, | 2503 | } |
| 2504 | pagelist, | 2504 | /* |
| 2505 | num_fcntl_locks, | 2505 | * number of encoded locks is stable, so copy to pagelist |
| 2506 | num_flock_locks); | 2506 | */ |
| 2507 | unlock_flocks(); | 2507 | rec.v2.flock_len = cpu_to_le32(2*sizeof(u32) + |
| 2508 | } | 2508 | (num_fcntl_locks+num_flock_locks) * |
| 2509 | } while (err == -ENOSPC); | 2509 | sizeof(struct ceph_filelock)); |
| 2510 | err = ceph_pagelist_append(pagelist, &rec, reclen); | ||
| 2511 | if (!err) | ||
| 2512 | err = ceph_locks_to_pagelist(flocks, pagelist, | ||
| 2513 | num_fcntl_locks, | ||
| 2514 | num_flock_locks); | ||
| 2515 | kfree(flocks); | ||
| 2510 | } else { | 2516 | } else { |
| 2511 | err = ceph_pagelist_append(pagelist, &rec, reclen); | 2517 | err = ceph_pagelist_append(pagelist, &rec, reclen); |
| 2512 | } | 2518 | } |
| 2513 | |||
| 2514 | out_free: | 2519 | out_free: |
| 2515 | kfree(path); | 2520 | kfree(path); |
| 2516 | out_dput: | 2521 | out_dput: |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 8696be2ff679..7ccfdb4aea2e 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
| @@ -822,8 +822,13 @@ extern const struct export_operations ceph_export_ops; | |||
| 822 | extern int ceph_lock(struct file *file, int cmd, struct file_lock *fl); | 822 | extern int ceph_lock(struct file *file, int cmd, struct file_lock *fl); |
| 823 | extern int ceph_flock(struct file *file, int cmd, struct file_lock *fl); | 823 | extern int ceph_flock(struct file *file, int cmd, struct file_lock *fl); |
| 824 | extern void ceph_count_locks(struct inode *inode, int *p_num, int *f_num); | 824 | extern void ceph_count_locks(struct inode *inode, int *p_num, int *f_num); |
| 825 | extern int ceph_encode_locks(struct inode *i, struct ceph_pagelist *p, | 825 | extern int ceph_encode_locks_to_buffer(struct inode *inode, |
| 826 | int p_locks, int f_locks); | 826 | struct ceph_filelock *flocks, |
| 827 | int num_fcntl_locks, | ||
| 828 | int num_flock_locks); | ||
| 829 | extern int ceph_locks_to_pagelist(struct ceph_filelock *flocks, | ||
| 830 | struct ceph_pagelist *pagelist, | ||
| 831 | int num_fcntl_locks, int num_flock_locks); | ||
| 827 | extern int lock_to_ceph_filelock(struct file_lock *fl, struct ceph_filelock *c); | 832 | extern int lock_to_ceph_filelock(struct file_lock *fl, struct ceph_filelock *c); |
| 828 | 833 | ||
| 829 | /* debugfs.c */ | 834 | /* debugfs.c */ |
diff --git a/fs/file_table.c b/fs/file_table.c index cd4d87a82951..485dc0eddd67 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
| @@ -306,17 +306,18 @@ void fput(struct file *file) | |||
| 306 | { | 306 | { |
| 307 | if (atomic_long_dec_and_test(&file->f_count)) { | 307 | if (atomic_long_dec_and_test(&file->f_count)) { |
| 308 | struct task_struct *task = current; | 308 | struct task_struct *task = current; |
| 309 | unsigned long flags; | ||
| 310 | |||
| 309 | file_sb_list_del(file); | 311 | file_sb_list_del(file); |
| 310 | if (unlikely(in_interrupt() || task->flags & PF_KTHREAD)) { | 312 | if (likely(!in_interrupt() && !(task->flags & PF_KTHREAD))) { |
| 311 | unsigned long flags; | 313 | init_task_work(&file->f_u.fu_rcuhead, ____fput); |
| 312 | spin_lock_irqsave(&delayed_fput_lock, flags); | 314 | if (!task_work_add(task, &file->f_u.fu_rcuhead, true)) |
| 313 | list_add(&file->f_u.fu_list, &delayed_fput_list); | 315 | return; |
| 314 | schedule_work(&delayed_fput_work); | ||
| 315 | spin_unlock_irqrestore(&delayed_fput_lock, flags); | ||
| 316 | return; | ||
| 317 | } | 316 | } |
| 318 | init_task_work(&file->f_u.fu_rcuhead, ____fput); | 317 | spin_lock_irqsave(&delayed_fput_lock, flags); |
| 319 | task_work_add(task, &file->f_u.fu_rcuhead, true); | 318 | list_add(&file->f_u.fu_list, &delayed_fput_list); |
| 319 | schedule_work(&delayed_fput_work); | ||
| 320 | spin_unlock_irqrestore(&delayed_fput_lock, flags); | ||
| 320 | } | 321 | } |
| 321 | } | 322 | } |
| 322 | 323 | ||
diff --git a/fs/namei.c b/fs/namei.c index 85e40d1c0a8f..9ed9361223c0 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -1976,7 +1976,7 @@ static int path_lookupat(int dfd, const char *name, | |||
| 1976 | err = complete_walk(nd); | 1976 | err = complete_walk(nd); |
| 1977 | 1977 | ||
| 1978 | if (!err && nd->flags & LOOKUP_DIRECTORY) { | 1978 | if (!err && nd->flags & LOOKUP_DIRECTORY) { |
| 1979 | if (!nd->inode->i_op->lookup) { | 1979 | if (!can_lookup(nd->inode)) { |
| 1980 | path_put(&nd->path); | 1980 | path_put(&nd->path); |
| 1981 | err = -ENOTDIR; | 1981 | err = -ENOTDIR; |
| 1982 | } | 1982 | } |
| @@ -2850,7 +2850,7 @@ finish_lookup: | |||
| 2850 | if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode)) | 2850 | if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode)) |
| 2851 | goto out; | 2851 | goto out; |
| 2852 | error = -ENOTDIR; | 2852 | error = -ENOTDIR; |
| 2853 | if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup) | 2853 | if ((nd->flags & LOOKUP_DIRECTORY) && !can_lookup(nd->inode)) |
| 2854 | goto out; | 2854 | goto out; |
| 2855 | audit_inode(name, nd->path.dentry, 0); | 2855 | audit_inode(name, nd->path.dentry, 0); |
| 2856 | finish_open: | 2856 | finish_open: |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 816326093656..6792ce11f2bf 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
| @@ -1029,15 +1029,6 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry) | |||
| 1029 | DPRINTK("ncp_rmdir: removing %s/%s\n", | 1029 | DPRINTK("ncp_rmdir: removing %s/%s\n", |
| 1030 | dentry->d_parent->d_name.name, dentry->d_name.name); | 1030 | dentry->d_parent->d_name.name, dentry->d_name.name); |
| 1031 | 1031 | ||
| 1032 | /* | ||
| 1033 | * fail with EBUSY if there are still references to this | ||
| 1034 | * directory. | ||
| 1035 | */ | ||
| 1036 | dentry_unhash(dentry); | ||
| 1037 | error = -EBUSY; | ||
| 1038 | if (!d_unhashed(dentry)) | ||
| 1039 | goto out; | ||
| 1040 | |||
| 1041 | len = sizeof(__name); | 1032 | len = sizeof(__name); |
| 1042 | error = ncp_io2vol(server, __name, &len, dentry->d_name.name, | 1033 | error = ncp_io2vol(server, __name, &len, dentry->d_name.name, |
| 1043 | dentry->d_name.len, !ncp_preserve_case(dir)); | 1034 | dentry->d_name.len, !ncp_preserve_case(dir)); |
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index b3fdd1a323d6..e68588e6b1e8 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
| @@ -1408,6 +1408,7 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 1408 | mres->lockname_len, mres->lockname); | 1408 | mres->lockname_len, mres->lockname); |
| 1409 | ret = -EFAULT; | 1409 | ret = -EFAULT; |
| 1410 | spin_unlock(&res->spinlock); | 1410 | spin_unlock(&res->spinlock); |
| 1411 | dlm_lockres_put(res); | ||
| 1411 | goto leave; | 1412 | goto leave; |
| 1412 | } | 1413 | } |
| 1413 | res->state |= DLM_LOCK_RES_MIGRATING; | 1414 | res->state |= DLM_LOCK_RES_MIGRATING; |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 04ee1b57c243..b4a5cdf9dbc5 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
| @@ -947,7 +947,7 @@ leave: | |||
| 947 | ocfs2_free_dir_lookup_result(&orphan_insert); | 947 | ocfs2_free_dir_lookup_result(&orphan_insert); |
| 948 | ocfs2_free_dir_lookup_result(&lookup); | 948 | ocfs2_free_dir_lookup_result(&lookup); |
| 949 | 949 | ||
| 950 | if (status) | 950 | if (status && (status != -ENOTEMPTY)) |
| 951 | mlog_errno(status); | 951 | mlog_errno(status); |
| 952 | 952 | ||
| 953 | return status; | 953 | return status; |
| @@ -2216,7 +2216,7 @@ out: | |||
| 2216 | 2216 | ||
| 2217 | brelse(orphan_dir_bh); | 2217 | brelse(orphan_dir_bh); |
| 2218 | 2218 | ||
| 2219 | return 0; | 2219 | return ret; |
| 2220 | } | 2220 | } |
| 2221 | 2221 | ||
| 2222 | int ocfs2_create_inode_in_orphan(struct inode *dir, | 2222 | int ocfs2_create_inode_in_orphan(struct inode *dir, |
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c index bd4b5a740ff1..bdfabdaefdce 100644 --- a/fs/proc/kmsg.c +++ b/fs/proc/kmsg.c | |||
| @@ -21,12 +21,12 @@ extern wait_queue_head_t log_wait; | |||
| 21 | 21 | ||
| 22 | static int kmsg_open(struct inode * inode, struct file * file) | 22 | static int kmsg_open(struct inode * inode, struct file * file) |
| 23 | { | 23 | { |
| 24 | return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, SYSLOG_FROM_FILE); | 24 | return do_syslog(SYSLOG_ACTION_OPEN, NULL, 0, SYSLOG_FROM_PROC); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | static int kmsg_release(struct inode * inode, struct file * file) | 27 | static int kmsg_release(struct inode * inode, struct file * file) |
| 28 | { | 28 | { |
| 29 | (void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, SYSLOG_FROM_FILE); | 29 | (void) do_syslog(SYSLOG_ACTION_CLOSE, NULL, 0, SYSLOG_FROM_PROC); |
| 30 | return 0; | 30 | return 0; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| @@ -34,15 +34,15 @@ static ssize_t kmsg_read(struct file *file, char __user *buf, | |||
| 34 | size_t count, loff_t *ppos) | 34 | size_t count, loff_t *ppos) |
| 35 | { | 35 | { |
| 36 | if ((file->f_flags & O_NONBLOCK) && | 36 | if ((file->f_flags & O_NONBLOCK) && |
| 37 | !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE)) | 37 | !do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_PROC)) |
| 38 | return -EAGAIN; | 38 | return -EAGAIN; |
| 39 | return do_syslog(SYSLOG_ACTION_READ, buf, count, SYSLOG_FROM_FILE); | 39 | return do_syslog(SYSLOG_ACTION_READ, buf, count, SYSLOG_FROM_PROC); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | static unsigned int kmsg_poll(struct file *file, poll_table *wait) | 42 | static unsigned int kmsg_poll(struct file *file, poll_table *wait) |
| 43 | { | 43 | { |
| 44 | poll_wait(file, &log_wait, wait); | 44 | poll_wait(file, &log_wait, wait); |
| 45 | if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_FILE)) | 45 | if (do_syslog(SYSLOG_ACTION_SIZE_UNREAD, NULL, 0, SYSLOG_FROM_PROC)) |
| 46 | return POLLIN | POLLRDNORM; | 46 | return POLLIN | POLLRDNORM; |
| 47 | return 0; | 47 | return 0; |
| 48 | } | 48 | } |
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h index f9d7846097e2..444a7704596c 100644 --- a/fs/xfs/xfs_attr_leaf.h +++ b/fs/xfs/xfs_attr_leaf.h | |||
| @@ -128,6 +128,7 @@ struct xfs_attr3_leaf_hdr { | |||
| 128 | __u8 holes; | 128 | __u8 holes; |
| 129 | __u8 pad1; | 129 | __u8 pad1; |
| 130 | struct xfs_attr_leaf_map freemap[XFS_ATTR_LEAF_MAPSIZE]; | 130 | struct xfs_attr_leaf_map freemap[XFS_ATTR_LEAF_MAPSIZE]; |
| 131 | __be32 pad2; /* 64 bit alignment */ | ||
| 131 | }; | 132 | }; |
| 132 | 133 | ||
| 133 | #define XFS_ATTR3_LEAF_CRC_OFF (offsetof(struct xfs_attr3_leaf_hdr, info.crc)) | 134 | #define XFS_ATTR3_LEAF_CRC_OFF (offsetof(struct xfs_attr3_leaf_hdr, info.crc)) |
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 8804b8a3c310..0903960410a2 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c | |||
| @@ -2544,7 +2544,17 @@ xfs_btree_new_iroot( | |||
| 2544 | if (error) | 2544 | if (error) |
| 2545 | goto error0; | 2545 | goto error0; |
| 2546 | 2546 | ||
| 2547 | /* | ||
| 2548 | * we can't just memcpy() the root in for CRC enabled btree blocks. | ||
| 2549 | * In that case have to also ensure the blkno remains correct | ||
| 2550 | */ | ||
| 2547 | memcpy(cblock, block, xfs_btree_block_len(cur)); | 2551 | memcpy(cblock, block, xfs_btree_block_len(cur)); |
| 2552 | if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) { | ||
| 2553 | if (cur->bc_flags & XFS_BTREE_LONG_PTRS) | ||
| 2554 | cblock->bb_u.l.bb_blkno = cpu_to_be64(cbp->b_bn); | ||
| 2555 | else | ||
| 2556 | cblock->bb_u.s.bb_blkno = cpu_to_be64(cbp->b_bn); | ||
| 2557 | } | ||
| 2548 | 2558 | ||
| 2549 | be16_add_cpu(&block->bb_level, 1); | 2559 | be16_add_cpu(&block->bb_level, 1); |
| 2550 | xfs_btree_set_numrecs(block, 1); | 2560 | xfs_btree_set_numrecs(block, 1); |
diff --git a/fs/xfs/xfs_dir2_format.h b/fs/xfs/xfs_dir2_format.h index 995f1f505a52..7826782b8d78 100644 --- a/fs/xfs/xfs_dir2_format.h +++ b/fs/xfs/xfs_dir2_format.h | |||
| @@ -266,6 +266,7 @@ struct xfs_dir3_blk_hdr { | |||
| 266 | struct xfs_dir3_data_hdr { | 266 | struct xfs_dir3_data_hdr { |
| 267 | struct xfs_dir3_blk_hdr hdr; | 267 | struct xfs_dir3_blk_hdr hdr; |
| 268 | xfs_dir2_data_free_t best_free[XFS_DIR2_DATA_FD_COUNT]; | 268 | xfs_dir2_data_free_t best_free[XFS_DIR2_DATA_FD_COUNT]; |
| 269 | __be32 pad; /* 64 bit alignment */ | ||
| 269 | }; | 270 | }; |
| 270 | 271 | ||
| 271 | #define XFS_DIR3_DATA_CRC_OFF offsetof(struct xfs_dir3_data_hdr, hdr.crc) | 272 | #define XFS_DIR3_DATA_CRC_OFF offsetof(struct xfs_dir3_data_hdr, hdr.crc) |
| @@ -477,7 +478,7 @@ struct xfs_dir3_leaf_hdr { | |||
| 477 | struct xfs_da3_blkinfo info; /* header for da routines */ | 478 | struct xfs_da3_blkinfo info; /* header for da routines */ |
| 478 | __be16 count; /* count of entries */ | 479 | __be16 count; /* count of entries */ |
| 479 | __be16 stale; /* count of stale entries */ | 480 | __be16 stale; /* count of stale entries */ |
| 480 | __be32 pad; | 481 | __be32 pad; /* 64 bit alignment */ |
| 481 | }; | 482 | }; |
| 482 | 483 | ||
| 483 | struct xfs_dir3_icleaf_hdr { | 484 | struct xfs_dir3_icleaf_hdr { |
| @@ -715,7 +716,7 @@ struct xfs_dir3_free_hdr { | |||
| 715 | __be32 firstdb; /* db of first entry */ | 716 | __be32 firstdb; /* db of first entry */ |
| 716 | __be32 nvalid; /* count of valid entries */ | 717 | __be32 nvalid; /* count of valid entries */ |
| 717 | __be32 nused; /* count of used entries */ | 718 | __be32 nused; /* count of used entries */ |
| 718 | __be32 pad; /* 64 bit alignment. */ | 719 | __be32 pad; /* 64 bit alignment */ |
| 719 | }; | 720 | }; |
| 720 | 721 | ||
| 721 | struct xfs_dir3_free { | 722 | struct xfs_dir3_free { |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 45a85ff84da1..7cf5e4eafe28 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
| @@ -1845,7 +1845,13 @@ xlog_recover_do_inode_buffer( | |||
| 1845 | xfs_agino_t *buffer_nextp; | 1845 | xfs_agino_t *buffer_nextp; |
| 1846 | 1846 | ||
| 1847 | trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f); | 1847 | trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f); |
| 1848 | bp->b_ops = &xfs_inode_buf_ops; | 1848 | |
| 1849 | /* | ||
| 1850 | * Post recovery validation only works properly on CRC enabled | ||
| 1851 | * filesystems. | ||
| 1852 | */ | ||
| 1853 | if (xfs_sb_version_hascrc(&mp->m_sb)) | ||
| 1854 | bp->b_ops = &xfs_inode_buf_ops; | ||
| 1849 | 1855 | ||
| 1850 | inodes_per_buf = BBTOB(bp->b_io_length) >> mp->m_sb.sb_inodelog; | 1856 | inodes_per_buf = BBTOB(bp->b_io_length) >> mp->m_sb.sb_inodelog; |
| 1851 | for (i = 0; i < inodes_per_buf; i++) { | 1857 | for (i = 0; i < inodes_per_buf; i++) { |
| @@ -2205,7 +2211,16 @@ xlog_recover_do_reg_buffer( | |||
| 2205 | /* Shouldn't be any more regions */ | 2211 | /* Shouldn't be any more regions */ |
| 2206 | ASSERT(i == item->ri_total); | 2212 | ASSERT(i == item->ri_total); |
| 2207 | 2213 | ||
| 2208 | xlog_recovery_validate_buf_type(mp, bp, buf_f); | 2214 | /* |
| 2215 | * We can only do post recovery validation on items on CRC enabled | ||
| 2216 | * fielsystems as we need to know when the buffer was written to be able | ||
| 2217 | * to determine if we should have replayed the item. If we replay old | ||
| 2218 | * metadata over a newer buffer, then it will enter a temporarily | ||
| 2219 | * inconsistent state resulting in verification failures. Hence for now | ||
| 2220 | * just avoid the verification stage for non-crc filesystems | ||
| 2221 | */ | ||
| 2222 | if (xfs_sb_version_hascrc(&mp->m_sb)) | ||
| 2223 | xlog_recovery_validate_buf_type(mp, bp, buf_f); | ||
| 2209 | } | 2224 | } |
| 2210 | 2225 | ||
| 2211 | /* | 2226 | /* |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index f6bfbd734669..e8e310c05097 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
| @@ -314,7 +314,8 @@ STATIC int | |||
| 314 | xfs_mount_validate_sb( | 314 | xfs_mount_validate_sb( |
| 315 | xfs_mount_t *mp, | 315 | xfs_mount_t *mp, |
| 316 | xfs_sb_t *sbp, | 316 | xfs_sb_t *sbp, |
| 317 | bool check_inprogress) | 317 | bool check_inprogress, |
| 318 | bool check_version) | ||
| 318 | { | 319 | { |
| 319 | 320 | ||
| 320 | /* | 321 | /* |
| @@ -337,9 +338,10 @@ xfs_mount_validate_sb( | |||
| 337 | 338 | ||
| 338 | /* | 339 | /* |
| 339 | * Version 5 superblock feature mask validation. Reject combinations the | 340 | * Version 5 superblock feature mask validation. Reject combinations the |
| 340 | * kernel cannot support up front before checking anything else. | 341 | * kernel cannot support up front before checking anything else. For |
| 342 | * write validation, we don't need to check feature masks. | ||
| 341 | */ | 343 | */ |
| 342 | if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) { | 344 | if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) { |
| 343 | xfs_alert(mp, | 345 | xfs_alert(mp, |
| 344 | "Version 5 superblock detected. This kernel has EXPERIMENTAL support enabled!\n" | 346 | "Version 5 superblock detected. This kernel has EXPERIMENTAL support enabled!\n" |
| 345 | "Use of these features in this kernel is at your own risk!"); | 347 | "Use of these features in this kernel is at your own risk!"); |
| @@ -675,7 +677,8 @@ xfs_sb_to_disk( | |||
| 675 | 677 | ||
| 676 | static int | 678 | static int |
| 677 | xfs_sb_verify( | 679 | xfs_sb_verify( |
| 678 | struct xfs_buf *bp) | 680 | struct xfs_buf *bp, |
| 681 | bool check_version) | ||
| 679 | { | 682 | { |
| 680 | struct xfs_mount *mp = bp->b_target->bt_mount; | 683 | struct xfs_mount *mp = bp->b_target->bt_mount; |
| 681 | struct xfs_sb sb; | 684 | struct xfs_sb sb; |
| @@ -686,7 +689,8 @@ xfs_sb_verify( | |||
| 686 | * Only check the in progress field for the primary superblock as | 689 | * Only check the in progress field for the primary superblock as |
| 687 | * mkfs.xfs doesn't clear it from secondary superblocks. | 690 | * mkfs.xfs doesn't clear it from secondary superblocks. |
| 688 | */ | 691 | */ |
| 689 | return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR); | 692 | return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR, |
| 693 | check_version); | ||
| 690 | } | 694 | } |
| 691 | 695 | ||
| 692 | /* | 696 | /* |
| @@ -719,7 +723,7 @@ xfs_sb_read_verify( | |||
| 719 | goto out_error; | 723 | goto out_error; |
| 720 | } | 724 | } |
| 721 | } | 725 | } |
| 722 | error = xfs_sb_verify(bp); | 726 | error = xfs_sb_verify(bp, true); |
| 723 | 727 | ||
| 724 | out_error: | 728 | out_error: |
| 725 | if (error) { | 729 | if (error) { |
| @@ -758,7 +762,7 @@ xfs_sb_write_verify( | |||
| 758 | struct xfs_buf_log_item *bip = bp->b_fspriv; | 762 | struct xfs_buf_log_item *bip = bp->b_fspriv; |
| 759 | int error; | 763 | int error; |
| 760 | 764 | ||
| 761 | error = xfs_sb_verify(bp); | 765 | error = xfs_sb_verify(bp, false); |
| 762 | if (error) { | 766 | if (error) { |
| 763 | XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); | 767 | XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr); |
| 764 | xfs_buf_ioerror(bp, error); | 768 | xfs_buf_ioerror(bp, error); |
