diff options
Diffstat (limited to 'fs')
33 files changed, 790 insertions, 302 deletions
| @@ -1021,6 +1021,7 @@ void aio_complete(struct kiocb *iocb, long res, long res2) | |||
| 1021 | 1021 | ||
| 1022 | /* everything turned out well, dispose of the aiocb. */ | 1022 | /* everything turned out well, dispose of the aiocb. */ |
| 1023 | kiocb_free(iocb); | 1023 | kiocb_free(iocb); |
| 1024 | put_reqs_available(ctx, 1); | ||
| 1024 | 1025 | ||
| 1025 | /* | 1026 | /* |
| 1026 | * We have to order our ring_info tail store above and test | 1027 | * We have to order our ring_info tail store above and test |
| @@ -1062,6 +1063,9 @@ static long aio_read_events_ring(struct kioctx *ctx, | |||
| 1062 | if (head == tail) | 1063 | if (head == tail) |
| 1063 | goto out; | 1064 | goto out; |
| 1064 | 1065 | ||
| 1066 | head %= ctx->nr_events; | ||
| 1067 | tail %= ctx->nr_events; | ||
| 1068 | |||
| 1065 | while (ret < nr) { | 1069 | while (ret < nr) { |
| 1066 | long avail; | 1070 | long avail; |
| 1067 | struct io_event *ev; | 1071 | struct io_event *ev; |
| @@ -1100,8 +1104,6 @@ static long aio_read_events_ring(struct kioctx *ctx, | |||
| 1100 | flush_dcache_page(ctx->ring_pages[0]); | 1104 | flush_dcache_page(ctx->ring_pages[0]); |
| 1101 | 1105 | ||
| 1102 | pr_debug("%li h%u t%u\n", ret, head, tail); | 1106 | pr_debug("%li h%u t%u\n", ret, head, tail); |
| 1103 | |||
| 1104 | put_reqs_available(ctx, ret); | ||
| 1105 | out: | 1107 | out: |
| 1106 | mutex_unlock(&ctx->ring_lock); | 1108 | mutex_unlock(&ctx->ring_lock); |
| 1107 | 1109 | ||
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index b7e2c1c1ef36..be91397f4e92 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -1259,11 +1259,19 @@ struct btrfs_block_group_cache { | |||
| 1259 | spinlock_t lock; | 1259 | spinlock_t lock; |
| 1260 | u64 pinned; | 1260 | u64 pinned; |
| 1261 | u64 reserved; | 1261 | u64 reserved; |
| 1262 | u64 delalloc_bytes; | ||
| 1262 | u64 bytes_super; | 1263 | u64 bytes_super; |
| 1263 | u64 flags; | 1264 | u64 flags; |
| 1264 | u64 sectorsize; | 1265 | u64 sectorsize; |
| 1265 | u64 cache_generation; | 1266 | u64 cache_generation; |
| 1266 | 1267 | ||
| 1268 | /* | ||
| 1269 | * It is just used for the delayed data space allocation because | ||
| 1270 | * only the data space allocation and the relative metadata update | ||
| 1271 | * can be done cross the transaction. | ||
| 1272 | */ | ||
| 1273 | struct rw_semaphore data_rwsem; | ||
| 1274 | |||
| 1267 | /* for raid56, this is a full stripe, without parity */ | 1275 | /* for raid56, this is a full stripe, without parity */ |
| 1268 | unsigned long full_stripe_len; | 1276 | unsigned long full_stripe_len; |
| 1269 | 1277 | ||
| @@ -3316,7 +3324,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, | |||
| 3316 | struct btrfs_key *ins); | 3324 | struct btrfs_key *ins); |
| 3317 | int btrfs_reserve_extent(struct btrfs_root *root, u64 num_bytes, | 3325 | int btrfs_reserve_extent(struct btrfs_root *root, u64 num_bytes, |
| 3318 | u64 min_alloc_size, u64 empty_size, u64 hint_byte, | 3326 | u64 min_alloc_size, u64 empty_size, u64 hint_byte, |
| 3319 | struct btrfs_key *ins, int is_data); | 3327 | struct btrfs_key *ins, int is_data, int delalloc); |
| 3320 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 3328 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
| 3321 | struct extent_buffer *buf, int full_backref, int no_quota); | 3329 | struct extent_buffer *buf, int full_backref, int no_quota); |
| 3322 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 3330 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
| @@ -3330,7 +3338,8 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
| 3330 | u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, | 3338 | u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, |
| 3331 | u64 owner, u64 offset, int no_quota); | 3339 | u64 owner, u64 offset, int no_quota); |
| 3332 | 3340 | ||
| 3333 | int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len); | 3341 | int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len, |
| 3342 | int delalloc); | ||
| 3334 | int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root, | 3343 | int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root, |
| 3335 | u64 start, u64 len); | 3344 | u64 start, u64 len); |
| 3336 | void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, | 3345 | void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index fafb3e53ecde..99c253918208 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -105,7 +105,8 @@ static int find_next_key(struct btrfs_path *path, int level, | |||
| 105 | static void dump_space_info(struct btrfs_space_info *info, u64 bytes, | 105 | static void dump_space_info(struct btrfs_space_info *info, u64 bytes, |
| 106 | int dump_block_groups); | 106 | int dump_block_groups); |
| 107 | static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, | 107 | static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, |
| 108 | u64 num_bytes, int reserve); | 108 | u64 num_bytes, int reserve, |
| 109 | int delalloc); | ||
| 109 | static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv, | 110 | static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv, |
| 110 | u64 num_bytes); | 111 | u64 num_bytes); |
| 111 | int btrfs_pin_extent(struct btrfs_root *root, | 112 | int btrfs_pin_extent(struct btrfs_root *root, |
| @@ -3260,7 +3261,8 @@ again: | |||
| 3260 | 3261 | ||
| 3261 | spin_lock(&block_group->lock); | 3262 | spin_lock(&block_group->lock); |
| 3262 | if (block_group->cached != BTRFS_CACHE_FINISHED || | 3263 | if (block_group->cached != BTRFS_CACHE_FINISHED || |
| 3263 | !btrfs_test_opt(root, SPACE_CACHE)) { | 3264 | !btrfs_test_opt(root, SPACE_CACHE) || |
| 3265 | block_group->delalloc_bytes) { | ||
| 3264 | /* | 3266 | /* |
| 3265 | * don't bother trying to write stuff out _if_ | 3267 | * don't bother trying to write stuff out _if_ |
| 3266 | * a) we're not cached, | 3268 | * a) we're not cached, |
| @@ -5613,6 +5615,7 @@ int btrfs_exclude_logged_extents(struct btrfs_root *log, | |||
| 5613 | * @cache: The cache we are manipulating | 5615 | * @cache: The cache we are manipulating |
| 5614 | * @num_bytes: The number of bytes in question | 5616 | * @num_bytes: The number of bytes in question |
| 5615 | * @reserve: One of the reservation enums | 5617 | * @reserve: One of the reservation enums |
| 5618 | * @delalloc: The blocks are allocated for the delalloc write | ||
| 5616 | * | 5619 | * |
| 5617 | * This is called by the allocator when it reserves space, or by somebody who is | 5620 | * This is called by the allocator when it reserves space, or by somebody who is |
| 5618 | * freeing space that was never actually used on disk. For example if you | 5621 | * freeing space that was never actually used on disk. For example if you |
| @@ -5631,7 +5634,7 @@ int btrfs_exclude_logged_extents(struct btrfs_root *log, | |||
| 5631 | * succeeds. | 5634 | * succeeds. |
| 5632 | */ | 5635 | */ |
| 5633 | static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, | 5636 | static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, |
| 5634 | u64 num_bytes, int reserve) | 5637 | u64 num_bytes, int reserve, int delalloc) |
| 5635 | { | 5638 | { |
| 5636 | struct btrfs_space_info *space_info = cache->space_info; | 5639 | struct btrfs_space_info *space_info = cache->space_info; |
| 5637 | int ret = 0; | 5640 | int ret = 0; |
| @@ -5650,12 +5653,18 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, | |||
| 5650 | num_bytes, 0); | 5653 | num_bytes, 0); |
| 5651 | space_info->bytes_may_use -= num_bytes; | 5654 | space_info->bytes_may_use -= num_bytes; |
| 5652 | } | 5655 | } |
| 5656 | |||
| 5657 | if (delalloc) | ||
| 5658 | cache->delalloc_bytes += num_bytes; | ||
| 5653 | } | 5659 | } |
| 5654 | } else { | 5660 | } else { |
| 5655 | if (cache->ro) | 5661 | if (cache->ro) |
| 5656 | space_info->bytes_readonly += num_bytes; | 5662 | space_info->bytes_readonly += num_bytes; |
| 5657 | cache->reserved -= num_bytes; | 5663 | cache->reserved -= num_bytes; |
| 5658 | space_info->bytes_reserved -= num_bytes; | 5664 | space_info->bytes_reserved -= num_bytes; |
| 5665 | |||
| 5666 | if (delalloc) | ||
| 5667 | cache->delalloc_bytes -= num_bytes; | ||
| 5659 | } | 5668 | } |
| 5660 | spin_unlock(&cache->lock); | 5669 | spin_unlock(&cache->lock); |
| 5661 | spin_unlock(&space_info->lock); | 5670 | spin_unlock(&space_info->lock); |
| @@ -6206,7 +6215,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans, | |||
| 6206 | WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)); | 6215 | WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)); |
| 6207 | 6216 | ||
| 6208 | btrfs_add_free_space(cache, buf->start, buf->len); | 6217 | btrfs_add_free_space(cache, buf->start, buf->len); |
| 6209 | btrfs_update_reserved_bytes(cache, buf->len, RESERVE_FREE); | 6218 | btrfs_update_reserved_bytes(cache, buf->len, RESERVE_FREE, 0); |
| 6210 | trace_btrfs_reserved_extent_free(root, buf->start, buf->len); | 6219 | trace_btrfs_reserved_extent_free(root, buf->start, buf->len); |
| 6211 | pin = 0; | 6220 | pin = 0; |
| 6212 | } | 6221 | } |
| @@ -6365,6 +6374,70 @@ enum btrfs_loop_type { | |||
| 6365 | LOOP_NO_EMPTY_SIZE = 3, | 6374 | LOOP_NO_EMPTY_SIZE = 3, |
| 6366 | }; | 6375 | }; |
| 6367 | 6376 | ||
| 6377 | static inline void | ||
| 6378 | btrfs_lock_block_group(struct btrfs_block_group_cache *cache, | ||
| 6379 | int delalloc) | ||
| 6380 | { | ||
| 6381 | if (delalloc) | ||
| 6382 | down_read(&cache->data_rwsem); | ||
| 6383 | } | ||
| 6384 | |||
| 6385 | static inline void | ||
| 6386 | btrfs_grab_block_group(struct btrfs_block_group_cache *cache, | ||
| 6387 | int delalloc) | ||
| 6388 | { | ||
| 6389 | btrfs_get_block_group(cache); | ||
| 6390 | if (delalloc) | ||
| 6391 | down_read(&cache->data_rwsem); | ||
| 6392 | } | ||
| 6393 | |||
| 6394 | static struct btrfs_block_group_cache * | ||
| 6395 | btrfs_lock_cluster(struct btrfs_block_group_cache *block_group, | ||
| 6396 | struct btrfs_free_cluster *cluster, | ||
| 6397 | int delalloc) | ||
| 6398 | { | ||
| 6399 | struct btrfs_block_group_cache *used_bg; | ||
| 6400 | bool locked = false; | ||
| 6401 | again: | ||
| 6402 | spin_lock(&cluster->refill_lock); | ||
| 6403 | if (locked) { | ||
| 6404 | if (used_bg == cluster->block_group) | ||
| 6405 | return used_bg; | ||
| 6406 | |||
| 6407 | up_read(&used_bg->data_rwsem); | ||
| 6408 | btrfs_put_block_group(used_bg); | ||
| 6409 | } | ||
| 6410 | |||
| 6411 | used_bg = cluster->block_group; | ||
| 6412 | if (!used_bg) | ||
| 6413 | return NULL; | ||
| 6414 | |||
| 6415 | if (used_bg == block_group) | ||
| 6416 | return used_bg; | ||
| 6417 | |||
| 6418 | btrfs_get_block_group(used_bg); | ||
| 6419 | |||
| 6420 | if (!delalloc) | ||
| 6421 | return used_bg; | ||
| 6422 | |||
| 6423 | if (down_read_trylock(&used_bg->data_rwsem)) | ||
| 6424 | return used_bg; | ||
| 6425 | |||
| 6426 | spin_unlock(&cluster->refill_lock); | ||
| 6427 | down_read(&used_bg->data_rwsem); | ||
| 6428 | locked = true; | ||
| 6429 | goto again; | ||
| 6430 | } | ||
| 6431 | |||
| 6432 | static inline void | ||
| 6433 | btrfs_release_block_group(struct btrfs_block_group_cache *cache, | ||
| 6434 | int delalloc) | ||
| 6435 | { | ||
| 6436 | if (delalloc) | ||
| 6437 | up_read(&cache->data_rwsem); | ||
| 6438 | btrfs_put_block_group(cache); | ||
| 6439 | } | ||
| 6440 | |||
| 6368 | /* | 6441 | /* |
| 6369 | * walks the btree of allocated extents and find a hole of a given size. | 6442 | * walks the btree of allocated extents and find a hole of a given size. |
| 6370 | * The key ins is changed to record the hole: | 6443 | * The key ins is changed to record the hole: |
| @@ -6379,7 +6452,7 @@ enum btrfs_loop_type { | |||
| 6379 | static noinline int find_free_extent(struct btrfs_root *orig_root, | 6452 | static noinline int find_free_extent(struct btrfs_root *orig_root, |
| 6380 | u64 num_bytes, u64 empty_size, | 6453 | u64 num_bytes, u64 empty_size, |
| 6381 | u64 hint_byte, struct btrfs_key *ins, | 6454 | u64 hint_byte, struct btrfs_key *ins, |
| 6382 | u64 flags) | 6455 | u64 flags, int delalloc) |
| 6383 | { | 6456 | { |
| 6384 | int ret = 0; | 6457 | int ret = 0; |
| 6385 | struct btrfs_root *root = orig_root->fs_info->extent_root; | 6458 | struct btrfs_root *root = orig_root->fs_info->extent_root; |
| @@ -6467,6 +6540,7 @@ static noinline int find_free_extent(struct btrfs_root *orig_root, | |||
| 6467 | up_read(&space_info->groups_sem); | 6540 | up_read(&space_info->groups_sem); |
| 6468 | } else { | 6541 | } else { |
| 6469 | index = get_block_group_index(block_group); | 6542 | index = get_block_group_index(block_group); |
| 6543 | btrfs_lock_block_group(block_group, delalloc); | ||
| 6470 | goto have_block_group; | 6544 | goto have_block_group; |
| 6471 | } | 6545 | } |
| 6472 | } else if (block_group) { | 6546 | } else if (block_group) { |
| @@ -6481,7 +6555,7 @@ search: | |||
| 6481 | u64 offset; | 6555 | u64 offset; |
| 6482 | int cached; | 6556 | int cached; |
| 6483 | 6557 | ||
| 6484 | btrfs_get_block_group(block_group); | 6558 | btrfs_grab_block_group(block_group, delalloc); |
| 6485 | search_start = block_group->key.objectid; | 6559 | search_start = block_group->key.objectid; |
| 6486 | 6560 | ||
| 6487 | /* | 6561 | /* |
| @@ -6529,16 +6603,16 @@ have_block_group: | |||
| 6529 | * the refill lock keeps out other | 6603 | * the refill lock keeps out other |
| 6530 | * people trying to start a new cluster | 6604 | * people trying to start a new cluster |
| 6531 | */ | 6605 | */ |
| 6532 | spin_lock(&last_ptr->refill_lock); | 6606 | used_block_group = btrfs_lock_cluster(block_group, |
| 6533 | used_block_group = last_ptr->block_group; | 6607 | last_ptr, |
| 6534 | if (used_block_group != block_group && | 6608 | delalloc); |
| 6535 | (!used_block_group || | 6609 | if (!used_block_group) |
| 6536 | used_block_group->ro || | ||
| 6537 | !block_group_bits(used_block_group, flags))) | ||
| 6538 | goto refill_cluster; | 6610 | goto refill_cluster; |
| 6539 | 6611 | ||
| 6540 | if (used_block_group != block_group) | 6612 | if (used_block_group != block_group && |
| 6541 | btrfs_get_block_group(used_block_group); | 6613 | (used_block_group->ro || |
| 6614 | !block_group_bits(used_block_group, flags))) | ||
| 6615 | goto release_cluster; | ||
| 6542 | 6616 | ||
| 6543 | offset = btrfs_alloc_from_cluster(used_block_group, | 6617 | offset = btrfs_alloc_from_cluster(used_block_group, |
| 6544 | last_ptr, | 6618 | last_ptr, |
| @@ -6552,16 +6626,15 @@ have_block_group: | |||
| 6552 | used_block_group, | 6626 | used_block_group, |
| 6553 | search_start, num_bytes); | 6627 | search_start, num_bytes); |
| 6554 | if (used_block_group != block_group) { | 6628 | if (used_block_group != block_group) { |
| 6555 | btrfs_put_block_group(block_group); | 6629 | btrfs_release_block_group(block_group, |
| 6630 | delalloc); | ||
| 6556 | block_group = used_block_group; | 6631 | block_group = used_block_group; |
| 6557 | } | 6632 | } |
| 6558 | goto checks; | 6633 | goto checks; |
| 6559 | } | 6634 | } |
| 6560 | 6635 | ||
| 6561 | WARN_ON(last_ptr->block_group != used_block_group); | 6636 | WARN_ON(last_ptr->block_group != used_block_group); |
| 6562 | if (used_block_group != block_group) | 6637 | release_cluster: |
| 6563 | btrfs_put_block_group(used_block_group); | ||
| 6564 | refill_cluster: | ||
| 6565 | /* If we are on LOOP_NO_EMPTY_SIZE, we can't | 6638 | /* If we are on LOOP_NO_EMPTY_SIZE, we can't |
| 6566 | * set up a new clusters, so lets just skip it | 6639 | * set up a new clusters, so lets just skip it |
| 6567 | * and let the allocator find whatever block | 6640 | * and let the allocator find whatever block |
| @@ -6578,8 +6651,10 @@ refill_cluster: | |||
| 6578 | * succeeding in the unclustered | 6651 | * succeeding in the unclustered |
| 6579 | * allocation. */ | 6652 | * allocation. */ |
| 6580 | if (loop >= LOOP_NO_EMPTY_SIZE && | 6653 | if (loop >= LOOP_NO_EMPTY_SIZE && |
| 6581 | last_ptr->block_group != block_group) { | 6654 | used_block_group != block_group) { |
| 6582 | spin_unlock(&last_ptr->refill_lock); | 6655 | spin_unlock(&last_ptr->refill_lock); |
| 6656 | btrfs_release_block_group(used_block_group, | ||
| 6657 | delalloc); | ||
| 6583 | goto unclustered_alloc; | 6658 | goto unclustered_alloc; |
| 6584 | } | 6659 | } |
| 6585 | 6660 | ||
| @@ -6589,6 +6664,10 @@ refill_cluster: | |||
| 6589 | */ | 6664 | */ |
| 6590 | btrfs_return_cluster_to_free_space(NULL, last_ptr); | 6665 | btrfs_return_cluster_to_free_space(NULL, last_ptr); |
| 6591 | 6666 | ||
| 6667 | if (used_block_group != block_group) | ||
| 6668 | btrfs_release_block_group(used_block_group, | ||
| 6669 | delalloc); | ||
| 6670 | refill_cluster: | ||
| 6592 | if (loop >= LOOP_NO_EMPTY_SIZE) { | 6671 | if (loop >= LOOP_NO_EMPTY_SIZE) { |
| 6593 | spin_unlock(&last_ptr->refill_lock); | 6672 | spin_unlock(&last_ptr->refill_lock); |
| 6594 | goto unclustered_alloc; | 6673 | goto unclustered_alloc; |
| @@ -6696,7 +6775,7 @@ checks: | |||
| 6696 | BUG_ON(offset > search_start); | 6775 | BUG_ON(offset > search_start); |
| 6697 | 6776 | ||
| 6698 | ret = btrfs_update_reserved_bytes(block_group, num_bytes, | 6777 | ret = btrfs_update_reserved_bytes(block_group, num_bytes, |
| 6699 | alloc_type); | 6778 | alloc_type, delalloc); |
| 6700 | if (ret == -EAGAIN) { | 6779 | if (ret == -EAGAIN) { |
| 6701 | btrfs_add_free_space(block_group, offset, num_bytes); | 6780 | btrfs_add_free_space(block_group, offset, num_bytes); |
| 6702 | goto loop; | 6781 | goto loop; |
| @@ -6708,13 +6787,13 @@ checks: | |||
| 6708 | 6787 | ||
| 6709 | trace_btrfs_reserve_extent(orig_root, block_group, | 6788 | trace_btrfs_reserve_extent(orig_root, block_group, |
| 6710 | search_start, num_bytes); | 6789 | search_start, num_bytes); |
| 6711 | btrfs_put_block_group(block_group); | 6790 | btrfs_release_block_group(block_group, delalloc); |
| 6712 | break; | 6791 | break; |
| 6713 | loop: | 6792 | loop: |
| 6714 | failed_cluster_refill = false; | 6793 | failed_cluster_refill = false; |
| 6715 | failed_alloc = false; | 6794 | failed_alloc = false; |
| 6716 | BUG_ON(index != get_block_group_index(block_group)); | 6795 | BUG_ON(index != get_block_group_index(block_group)); |
| 6717 | btrfs_put_block_group(block_group); | 6796 | btrfs_release_block_group(block_group, delalloc); |
| 6718 | } | 6797 | } |
| 6719 | up_read(&space_info->groups_sem); | 6798 | up_read(&space_info->groups_sem); |
| 6720 | 6799 | ||
| @@ -6827,7 +6906,7 @@ again: | |||
| 6827 | int btrfs_reserve_extent(struct btrfs_root *root, | 6906 | int btrfs_reserve_extent(struct btrfs_root *root, |
| 6828 | u64 num_bytes, u64 min_alloc_size, | 6907 | u64 num_bytes, u64 min_alloc_size, |
| 6829 | u64 empty_size, u64 hint_byte, | 6908 | u64 empty_size, u64 hint_byte, |
| 6830 | struct btrfs_key *ins, int is_data) | 6909 | struct btrfs_key *ins, int is_data, int delalloc) |
| 6831 | { | 6910 | { |
| 6832 | bool final_tried = false; | 6911 | bool final_tried = false; |
| 6833 | u64 flags; | 6912 | u64 flags; |
| @@ -6837,7 +6916,7 @@ int btrfs_reserve_extent(struct btrfs_root *root, | |||
| 6837 | again: | 6916 | again: |
| 6838 | WARN_ON(num_bytes < root->sectorsize); | 6917 | WARN_ON(num_bytes < root->sectorsize); |
| 6839 | ret = find_free_extent(root, num_bytes, empty_size, hint_byte, ins, | 6918 | ret = find_free_extent(root, num_bytes, empty_size, hint_byte, ins, |
| 6840 | flags); | 6919 | flags, delalloc); |
| 6841 | 6920 | ||
| 6842 | if (ret == -ENOSPC) { | 6921 | if (ret == -ENOSPC) { |
| 6843 | if (!final_tried && ins->offset) { | 6922 | if (!final_tried && ins->offset) { |
| @@ -6862,7 +6941,8 @@ again: | |||
| 6862 | } | 6941 | } |
| 6863 | 6942 | ||
| 6864 | static int __btrfs_free_reserved_extent(struct btrfs_root *root, | 6943 | static int __btrfs_free_reserved_extent(struct btrfs_root *root, |
| 6865 | u64 start, u64 len, int pin) | 6944 | u64 start, u64 len, |
| 6945 | int pin, int delalloc) | ||
| 6866 | { | 6946 | { |
| 6867 | struct btrfs_block_group_cache *cache; | 6947 | struct btrfs_block_group_cache *cache; |
| 6868 | int ret = 0; | 6948 | int ret = 0; |
| @@ -6881,7 +6961,7 @@ static int __btrfs_free_reserved_extent(struct btrfs_root *root, | |||
| 6881 | pin_down_extent(root, cache, start, len, 1); | 6961 | pin_down_extent(root, cache, start, len, 1); |
| 6882 | else { | 6962 | else { |
| 6883 | btrfs_add_free_space(cache, start, len); | 6963 | btrfs_add_free_space(cache, start, len); |
| 6884 | btrfs_update_reserved_bytes(cache, len, RESERVE_FREE); | 6964 | btrfs_update_reserved_bytes(cache, len, RESERVE_FREE, delalloc); |
| 6885 | } | 6965 | } |
| 6886 | btrfs_put_block_group(cache); | 6966 | btrfs_put_block_group(cache); |
| 6887 | 6967 | ||
| @@ -6891,15 +6971,15 @@ static int __btrfs_free_reserved_extent(struct btrfs_root *root, | |||
| 6891 | } | 6971 | } |
| 6892 | 6972 | ||
| 6893 | int btrfs_free_reserved_extent(struct btrfs_root *root, | 6973 | int btrfs_free_reserved_extent(struct btrfs_root *root, |
| 6894 | u64 start, u64 len) | 6974 | u64 start, u64 len, int delalloc) |
| 6895 | { | 6975 | { |
| 6896 | return __btrfs_free_reserved_extent(root, start, len, 0); | 6976 | return __btrfs_free_reserved_extent(root, start, len, 0, delalloc); |
| 6897 | } | 6977 | } |
| 6898 | 6978 | ||
| 6899 | int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root, | 6979 | int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root, |
| 6900 | u64 start, u64 len) | 6980 | u64 start, u64 len) |
| 6901 | { | 6981 | { |
| 6902 | return __btrfs_free_reserved_extent(root, start, len, 1); | 6982 | return __btrfs_free_reserved_extent(root, start, len, 1, 0); |
| 6903 | } | 6983 | } |
| 6904 | 6984 | ||
| 6905 | static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans, | 6985 | static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans, |
| @@ -7114,7 +7194,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, | |||
| 7114 | return -EINVAL; | 7194 | return -EINVAL; |
| 7115 | 7195 | ||
| 7116 | ret = btrfs_update_reserved_bytes(block_group, ins->offset, | 7196 | ret = btrfs_update_reserved_bytes(block_group, ins->offset, |
| 7117 | RESERVE_ALLOC_NO_ACCOUNT); | 7197 | RESERVE_ALLOC_NO_ACCOUNT, 0); |
| 7118 | BUG_ON(ret); /* logic error */ | 7198 | BUG_ON(ret); /* logic error */ |
| 7119 | ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, | 7199 | ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, |
| 7120 | 0, owner, offset, ins, 1); | 7200 | 0, owner, offset, ins, 1); |
| @@ -7256,7 +7336,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
| 7256 | return ERR_CAST(block_rsv); | 7336 | return ERR_CAST(block_rsv); |
| 7257 | 7337 | ||
| 7258 | ret = btrfs_reserve_extent(root, blocksize, blocksize, | 7338 | ret = btrfs_reserve_extent(root, blocksize, blocksize, |
| 7259 | empty_size, hint, &ins, 0); | 7339 | empty_size, hint, &ins, 0, 0); |
| 7260 | if (ret) { | 7340 | if (ret) { |
| 7261 | unuse_block_rsv(root->fs_info, block_rsv, blocksize); | 7341 | unuse_block_rsv(root->fs_info, block_rsv, blocksize); |
| 7262 | return ERR_PTR(ret); | 7342 | return ERR_PTR(ret); |
| @@ -8659,6 +8739,7 @@ btrfs_create_block_group_cache(struct btrfs_root *root, u64 start, u64 size) | |||
| 8659 | start); | 8739 | start); |
| 8660 | atomic_set(&cache->count, 1); | 8740 | atomic_set(&cache->count, 1); |
| 8661 | spin_lock_init(&cache->lock); | 8741 | spin_lock_init(&cache->lock); |
| 8742 | init_rwsem(&cache->data_rwsem); | ||
| 8662 | INIT_LIST_HEAD(&cache->list); | 8743 | INIT_LIST_HEAD(&cache->list); |
| 8663 | INIT_LIST_HEAD(&cache->cluster_list); | 8744 | INIT_LIST_HEAD(&cache->cluster_list); |
| 8664 | INIT_LIST_HEAD(&cache->new_bg_list); | 8745 | INIT_LIST_HEAD(&cache->new_bg_list); |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 15ce5f2a2b62..ccc264e7bde1 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
| @@ -158,7 +158,6 @@ struct extent_buffer { | |||
| 158 | * to unlock | 158 | * to unlock |
| 159 | */ | 159 | */ |
| 160 | wait_queue_head_t read_lock_wq; | 160 | wait_queue_head_t read_lock_wq; |
| 161 | wait_queue_head_t lock_wq; | ||
| 162 | struct page *pages[INLINE_EXTENT_BUFFER_PAGES]; | 161 | struct page *pages[INLINE_EXTENT_BUFFER_PAGES]; |
| 163 | #ifdef CONFIG_BTRFS_DEBUG | 162 | #ifdef CONFIG_BTRFS_DEBUG |
| 164 | struct list_head leak_list; | 163 | struct list_head leak_list; |
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 1874aee69c86..225302b39afb 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c | |||
| @@ -75,6 +75,8 @@ void free_extent_map(struct extent_map *em) | |||
| 75 | if (atomic_dec_and_test(&em->refs)) { | 75 | if (atomic_dec_and_test(&em->refs)) { |
| 76 | WARN_ON(extent_map_in_tree(em)); | 76 | WARN_ON(extent_map_in_tree(em)); |
| 77 | WARN_ON(!list_empty(&em->list)); | 77 | WARN_ON(!list_empty(&em->list)); |
| 78 | if (test_bit(EXTENT_FLAG_FS_MAPPING, &em->flags)) | ||
| 79 | kfree(em->bdev); | ||
| 78 | kmem_cache_free(extent_map_cache, em); | 80 | kmem_cache_free(extent_map_cache, em); |
| 79 | } | 81 | } |
| 80 | } | 82 | } |
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index e7fd8a56a140..b2991fd8583e 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #define EXTENT_FLAG_PREALLOC 3 /* pre-allocated extent */ | 15 | #define EXTENT_FLAG_PREALLOC 3 /* pre-allocated extent */ |
| 16 | #define EXTENT_FLAG_LOGGING 4 /* Logging this extent */ | 16 | #define EXTENT_FLAG_LOGGING 4 /* Logging this extent */ |
| 17 | #define EXTENT_FLAG_FILLING 5 /* Filling in a preallocated extent */ | 17 | #define EXTENT_FLAG_FILLING 5 /* Filling in a preallocated extent */ |
| 18 | #define EXTENT_FLAG_FS_MAPPING 6 /* filesystem extent mapping type */ | ||
| 18 | 19 | ||
| 19 | struct extent_map { | 20 | struct extent_map { |
| 20 | struct rb_node rb_node; | 21 | struct rb_node rb_node; |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 372b05ff1943..2b0a627cb5f9 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
| @@ -274,18 +274,32 @@ struct io_ctl { | |||
| 274 | }; | 274 | }; |
| 275 | 275 | ||
| 276 | static int io_ctl_init(struct io_ctl *io_ctl, struct inode *inode, | 276 | static int io_ctl_init(struct io_ctl *io_ctl, struct inode *inode, |
| 277 | struct btrfs_root *root) | 277 | struct btrfs_root *root, int write) |
| 278 | { | 278 | { |
| 279 | int num_pages; | ||
| 280 | int check_crcs = 0; | ||
| 281 | |||
| 282 | num_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> | ||
| 283 | PAGE_CACHE_SHIFT; | ||
| 284 | |||
| 285 | if (btrfs_ino(inode) != BTRFS_FREE_INO_OBJECTID) | ||
| 286 | check_crcs = 1; | ||
| 287 | |||
| 288 | /* Make sure we can fit our crcs into the first page */ | ||
| 289 | if (write && check_crcs && | ||
| 290 | (num_pages * sizeof(u32)) >= PAGE_CACHE_SIZE) | ||
| 291 | return -ENOSPC; | ||
| 292 | |||
| 279 | memset(io_ctl, 0, sizeof(struct io_ctl)); | 293 | memset(io_ctl, 0, sizeof(struct io_ctl)); |
| 280 | io_ctl->num_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> | 294 | |
| 281 | PAGE_CACHE_SHIFT; | 295 | io_ctl->pages = kzalloc(sizeof(struct page *) * num_pages, GFP_NOFS); |
| 282 | io_ctl->pages = kzalloc(sizeof(struct page *) * io_ctl->num_pages, | ||
| 283 | GFP_NOFS); | ||
| 284 | if (!io_ctl->pages) | 296 | if (!io_ctl->pages) |
| 285 | return -ENOMEM; | 297 | return -ENOMEM; |
| 298 | |||
| 299 | io_ctl->num_pages = num_pages; | ||
| 286 | io_ctl->root = root; | 300 | io_ctl->root = root; |
| 287 | if (btrfs_ino(inode) != BTRFS_FREE_INO_OBJECTID) | 301 | io_ctl->check_crcs = check_crcs; |
| 288 | io_ctl->check_crcs = 1; | 302 | |
| 289 | return 0; | 303 | return 0; |
| 290 | } | 304 | } |
| 291 | 305 | ||
| @@ -666,6 +680,13 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, | |||
| 666 | generation = btrfs_free_space_generation(leaf, header); | 680 | generation = btrfs_free_space_generation(leaf, header); |
| 667 | btrfs_release_path(path); | 681 | btrfs_release_path(path); |
| 668 | 682 | ||
| 683 | if (!BTRFS_I(inode)->generation) { | ||
| 684 | btrfs_info(root->fs_info, | ||
| 685 | "The free space cache file (%llu) is invalid. skip it\n", | ||
| 686 | offset); | ||
| 687 | return 0; | ||
| 688 | } | ||
| 689 | |||
| 669 | if (BTRFS_I(inode)->generation != generation) { | 690 | if (BTRFS_I(inode)->generation != generation) { |
| 670 | btrfs_err(root->fs_info, | 691 | btrfs_err(root->fs_info, |
| 671 | "free space inode generation (%llu) " | 692 | "free space inode generation (%llu) " |
| @@ -677,7 +698,7 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode, | |||
| 677 | if (!num_entries) | 698 | if (!num_entries) |
| 678 | return 0; | 699 | return 0; |
| 679 | 700 | ||
| 680 | ret = io_ctl_init(&io_ctl, inode, root); | 701 | ret = io_ctl_init(&io_ctl, inode, root, 0); |
| 681 | if (ret) | 702 | if (ret) |
| 682 | return ret; | 703 | return ret; |
| 683 | 704 | ||
| @@ -957,19 +978,18 @@ fail: | |||
| 957 | } | 978 | } |
| 958 | 979 | ||
| 959 | static noinline_for_stack int | 980 | static noinline_for_stack int |
| 960 | add_ioctl_entries(struct btrfs_root *root, | 981 | write_pinned_extent_entries(struct btrfs_root *root, |
| 961 | struct inode *inode, | 982 | struct btrfs_block_group_cache *block_group, |
| 962 | struct btrfs_block_group_cache *block_group, | 983 | struct io_ctl *io_ctl, |
| 963 | struct io_ctl *io_ctl, | 984 | int *entries) |
| 964 | struct extent_state **cached_state, | ||
| 965 | struct list_head *bitmap_list, | ||
| 966 | int *entries) | ||
| 967 | { | 985 | { |
| 968 | u64 start, extent_start, extent_end, len; | 986 | u64 start, extent_start, extent_end, len; |
| 969 | struct list_head *pos, *n; | ||
| 970 | struct extent_io_tree *unpin = NULL; | 987 | struct extent_io_tree *unpin = NULL; |
| 971 | int ret; | 988 | int ret; |
| 972 | 989 | ||
| 990 | if (!block_group) | ||
| 991 | return 0; | ||
| 992 | |||
| 973 | /* | 993 | /* |
| 974 | * We want to add any pinned extents to our free space cache | 994 | * We want to add any pinned extents to our free space cache |
| 975 | * so we don't leak the space | 995 | * so we don't leak the space |
| @@ -979,23 +999,19 @@ add_ioctl_entries(struct btrfs_root *root, | |||
| 979 | */ | 999 | */ |
| 980 | unpin = root->fs_info->pinned_extents; | 1000 | unpin = root->fs_info->pinned_extents; |
| 981 | 1001 | ||
| 982 | if (block_group) | 1002 | start = block_group->key.objectid; |
| 983 | start = block_group->key.objectid; | ||
| 984 | 1003 | ||
| 985 | while (block_group && (start < block_group->key.objectid + | 1004 | while (start < block_group->key.objectid + block_group->key.offset) { |
| 986 | block_group->key.offset)) { | ||
| 987 | ret = find_first_extent_bit(unpin, start, | 1005 | ret = find_first_extent_bit(unpin, start, |
| 988 | &extent_start, &extent_end, | 1006 | &extent_start, &extent_end, |
| 989 | EXTENT_DIRTY, NULL); | 1007 | EXTENT_DIRTY, NULL); |
| 990 | if (ret) { | 1008 | if (ret) |
| 991 | ret = 0; | 1009 | return 0; |
| 992 | break; | ||
| 993 | } | ||
| 994 | 1010 | ||
| 995 | /* This pinned extent is out of our range */ | 1011 | /* This pinned extent is out of our range */ |
| 996 | if (extent_start >= block_group->key.objectid + | 1012 | if (extent_start >= block_group->key.objectid + |
| 997 | block_group->key.offset) | 1013 | block_group->key.offset) |
| 998 | break; | 1014 | return 0; |
| 999 | 1015 | ||
| 1000 | extent_start = max(extent_start, start); | 1016 | extent_start = max(extent_start, start); |
| 1001 | extent_end = min(block_group->key.objectid + | 1017 | extent_end = min(block_group->key.objectid + |
| @@ -1005,11 +1021,20 @@ add_ioctl_entries(struct btrfs_root *root, | |||
| 1005 | *entries += 1; | 1021 | *entries += 1; |
| 1006 | ret = io_ctl_add_entry(io_ctl, extent_start, len, NULL); | 1022 | ret = io_ctl_add_entry(io_ctl, extent_start, len, NULL); |
| 1007 | if (ret) | 1023 | if (ret) |
| 1008 | goto out_nospc; | 1024 | return -ENOSPC; |
| 1009 | 1025 | ||
| 1010 | start = extent_end; | 1026 | start = extent_end; |
| 1011 | } | 1027 | } |
| 1012 | 1028 | ||
| 1029 | return 0; | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | static noinline_for_stack int | ||
| 1033 | write_bitmap_entries(struct io_ctl *io_ctl, struct list_head *bitmap_list) | ||
| 1034 | { | ||
| 1035 | struct list_head *pos, *n; | ||
| 1036 | int ret; | ||
| 1037 | |||
| 1013 | /* Write out the bitmaps */ | 1038 | /* Write out the bitmaps */ |
| 1014 | list_for_each_safe(pos, n, bitmap_list) { | 1039 | list_for_each_safe(pos, n, bitmap_list) { |
| 1015 | struct btrfs_free_space *entry = | 1040 | struct btrfs_free_space *entry = |
| @@ -1017,36 +1042,24 @@ add_ioctl_entries(struct btrfs_root *root, | |||
| 1017 | 1042 | ||
| 1018 | ret = io_ctl_add_bitmap(io_ctl, entry->bitmap); | 1043 | ret = io_ctl_add_bitmap(io_ctl, entry->bitmap); |
| 1019 | if (ret) | 1044 | if (ret) |
| 1020 | goto out_nospc; | 1045 | return -ENOSPC; |
| 1021 | list_del_init(&entry->list); | 1046 | list_del_init(&entry->list); |
| 1022 | } | 1047 | } |
| 1023 | 1048 | ||
| 1024 | /* Zero out the rest of the pages just to make sure */ | 1049 | return 0; |
| 1025 | io_ctl_zero_remaining_pages(io_ctl); | 1050 | } |
| 1026 | |||
| 1027 | ret = btrfs_dirty_pages(root, inode, io_ctl->pages, io_ctl->num_pages, | ||
| 1028 | 0, i_size_read(inode), cached_state); | ||
| 1029 | io_ctl_drop_pages(io_ctl); | ||
| 1030 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, | ||
| 1031 | i_size_read(inode) - 1, cached_state, GFP_NOFS); | ||
| 1032 | 1051 | ||
| 1033 | if (ret) | 1052 | static int flush_dirty_cache(struct inode *inode) |
| 1034 | goto fail; | 1053 | { |
| 1054 | int ret; | ||
| 1035 | 1055 | ||
| 1036 | ret = btrfs_wait_ordered_range(inode, 0, (u64)-1); | 1056 | ret = btrfs_wait_ordered_range(inode, 0, (u64)-1); |
| 1037 | if (ret) { | 1057 | if (ret) |
| 1038 | clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, inode->i_size - 1, | 1058 | clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, inode->i_size - 1, |
| 1039 | EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, NULL, | 1059 | EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, NULL, |
| 1040 | GFP_NOFS); | 1060 | GFP_NOFS); |
| 1041 | goto fail; | ||
| 1042 | } | ||
| 1043 | return 0; | ||
| 1044 | 1061 | ||
| 1045 | fail: | 1062 | return ret; |
| 1046 | return -1; | ||
| 1047 | |||
| 1048 | out_nospc: | ||
| 1049 | return -ENOSPC; | ||
| 1050 | } | 1063 | } |
| 1051 | 1064 | ||
| 1052 | static void noinline_for_stack | 1065 | static void noinline_for_stack |
| @@ -1056,6 +1069,7 @@ cleanup_write_cache_enospc(struct inode *inode, | |||
| 1056 | struct list_head *bitmap_list) | 1069 | struct list_head *bitmap_list) |
| 1057 | { | 1070 | { |
| 1058 | struct list_head *pos, *n; | 1071 | struct list_head *pos, *n; |
| 1072 | |||
| 1059 | list_for_each_safe(pos, n, bitmap_list) { | 1073 | list_for_each_safe(pos, n, bitmap_list) { |
| 1060 | struct btrfs_free_space *entry = | 1074 | struct btrfs_free_space *entry = |
| 1061 | list_entry(pos, struct btrfs_free_space, list); | 1075 | list_entry(pos, struct btrfs_free_space, list); |
| @@ -1088,64 +1102,104 @@ static int __btrfs_write_out_cache(struct btrfs_root *root, struct inode *inode, | |||
| 1088 | { | 1102 | { |
| 1089 | struct extent_state *cached_state = NULL; | 1103 | struct extent_state *cached_state = NULL; |
| 1090 | struct io_ctl io_ctl; | 1104 | struct io_ctl io_ctl; |
| 1091 | struct list_head bitmap_list; | 1105 | LIST_HEAD(bitmap_list); |
| 1092 | int entries = 0; | 1106 | int entries = 0; |
| 1093 | int bitmaps = 0; | 1107 | int bitmaps = 0; |
| 1094 | int ret; | 1108 | int ret; |
| 1095 | int err = -1; | ||
| 1096 | |||
| 1097 | INIT_LIST_HEAD(&bitmap_list); | ||
| 1098 | 1109 | ||
| 1099 | if (!i_size_read(inode)) | 1110 | if (!i_size_read(inode)) |
| 1100 | return -1; | 1111 | return -1; |
| 1101 | 1112 | ||
| 1102 | ret = io_ctl_init(&io_ctl, inode, root); | 1113 | ret = io_ctl_init(&io_ctl, inode, root, 1); |
| 1103 | if (ret) | 1114 | if (ret) |
| 1104 | return -1; | 1115 | return -1; |
| 1105 | 1116 | ||
| 1117 | if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)) { | ||
| 1118 | down_write(&block_group->data_rwsem); | ||
| 1119 | spin_lock(&block_group->lock); | ||
| 1120 | if (block_group->delalloc_bytes) { | ||
| 1121 | block_group->disk_cache_state = BTRFS_DC_WRITTEN; | ||
| 1122 | spin_unlock(&block_group->lock); | ||
| 1123 | up_write(&block_group->data_rwsem); | ||
| 1124 | BTRFS_I(inode)->generation = 0; | ||
| 1125 | ret = 0; | ||
| 1126 | goto out; | ||
| 1127 | } | ||
| 1128 | spin_unlock(&block_group->lock); | ||
| 1129 | } | ||
| 1130 | |||
| 1106 | /* Lock all pages first so we can lock the extent safely. */ | 1131 | /* Lock all pages first so we can lock the extent safely. */ |
| 1107 | io_ctl_prepare_pages(&io_ctl, inode, 0); | 1132 | io_ctl_prepare_pages(&io_ctl, inode, 0); |
| 1108 | 1133 | ||
| 1109 | lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1, | 1134 | lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1, |
| 1110 | 0, &cached_state); | 1135 | 0, &cached_state); |
| 1111 | 1136 | ||
| 1112 | |||
| 1113 | /* Make sure we can fit our crcs into the first page */ | ||
| 1114 | if (io_ctl.check_crcs && | ||
| 1115 | (io_ctl.num_pages * sizeof(u32)) >= PAGE_CACHE_SIZE) | ||
| 1116 | goto out_nospc; | ||
| 1117 | |||
| 1118 | io_ctl_set_generation(&io_ctl, trans->transid); | 1137 | io_ctl_set_generation(&io_ctl, trans->transid); |
| 1119 | 1138 | ||
| 1139 | /* Write out the extent entries in the free space cache */ | ||
| 1120 | ret = write_cache_extent_entries(&io_ctl, ctl, | 1140 | ret = write_cache_extent_entries(&io_ctl, ctl, |
| 1121 | block_group, &entries, &bitmaps, | 1141 | block_group, &entries, &bitmaps, |
| 1122 | &bitmap_list); | 1142 | &bitmap_list); |
| 1123 | if (ret) | 1143 | if (ret) |
| 1124 | goto out_nospc; | 1144 | goto out_nospc; |
| 1125 | 1145 | ||
| 1126 | ret = add_ioctl_entries(root, inode, block_group, &io_ctl, | 1146 | /* |
| 1127 | &cached_state, &bitmap_list, &entries); | 1147 | * Some spaces that are freed in the current transaction are pinned, |
| 1148 | * they will be added into free space cache after the transaction is | ||
| 1149 | * committed, we shouldn't lose them. | ||
| 1150 | */ | ||
| 1151 | ret = write_pinned_extent_entries(root, block_group, &io_ctl, &entries); | ||
| 1152 | if (ret) | ||
| 1153 | goto out_nospc; | ||
| 1128 | 1154 | ||
| 1129 | if (ret == -ENOSPC) | 1155 | /* At last, we write out all the bitmaps. */ |
| 1156 | ret = write_bitmap_entries(&io_ctl, &bitmap_list); | ||
| 1157 | if (ret) | ||
| 1130 | goto out_nospc; | 1158 | goto out_nospc; |
| 1131 | else if (ret) | 1159 | |
| 1160 | /* Zero out the rest of the pages just to make sure */ | ||
| 1161 | io_ctl_zero_remaining_pages(&io_ctl); | ||
| 1162 | |||
| 1163 | /* Everything is written out, now we dirty the pages in the file. */ | ||
| 1164 | ret = btrfs_dirty_pages(root, inode, io_ctl.pages, io_ctl.num_pages, | ||
| 1165 | 0, i_size_read(inode), &cached_state); | ||
| 1166 | if (ret) | ||
| 1167 | goto out_nospc; | ||
| 1168 | |||
| 1169 | if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)) | ||
| 1170 | up_write(&block_group->data_rwsem); | ||
| 1171 | /* | ||
| 1172 | * Release the pages and unlock the extent, we will flush | ||
| 1173 | * them out later | ||
| 1174 | */ | ||
| 1175 | io_ctl_drop_pages(&io_ctl); | ||
| 1176 | |||
| 1177 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, 0, | ||
| 1178 | i_size_read(inode) - 1, &cached_state, GFP_NOFS); | ||
| 1179 | |||
| 1180 | /* Flush the dirty pages in the cache file. */ | ||
| 1181 | ret = flush_dirty_cache(inode); | ||
| 1182 | if (ret) | ||
| 1132 | goto out; | 1183 | goto out; |
| 1133 | 1184 | ||
| 1134 | err = update_cache_item(trans, root, inode, path, offset, | 1185 | /* Update the cache item to tell everyone this cache file is valid. */ |
| 1186 | ret = update_cache_item(trans, root, inode, path, offset, | ||
| 1135 | entries, bitmaps); | 1187 | entries, bitmaps); |
| 1136 | |||
| 1137 | out: | 1188 | out: |
| 1138 | io_ctl_free(&io_ctl); | 1189 | io_ctl_free(&io_ctl); |
| 1139 | if (err) { | 1190 | if (ret) { |
| 1140 | invalidate_inode_pages2(inode->i_mapping); | 1191 | invalidate_inode_pages2(inode->i_mapping); |
| 1141 | BTRFS_I(inode)->generation = 0; | 1192 | BTRFS_I(inode)->generation = 0; |
| 1142 | } | 1193 | } |
| 1143 | btrfs_update_inode(trans, root, inode); | 1194 | btrfs_update_inode(trans, root, inode); |
| 1144 | return err; | 1195 | return ret; |
| 1145 | 1196 | ||
| 1146 | out_nospc: | 1197 | out_nospc: |
| 1147 | |||
| 1148 | cleanup_write_cache_enospc(inode, &io_ctl, &cached_state, &bitmap_list); | 1198 | cleanup_write_cache_enospc(inode, &io_ctl, &cached_state, &bitmap_list); |
| 1199 | |||
| 1200 | if (block_group && (block_group->flags & BTRFS_BLOCK_GROUP_DATA)) | ||
| 1201 | up_write(&block_group->data_rwsem); | ||
| 1202 | |||
| 1149 | goto out; | 1203 | goto out; |
| 1150 | } | 1204 | } |
| 1151 | 1205 | ||
| @@ -1165,6 +1219,12 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 1165 | spin_unlock(&block_group->lock); | 1219 | spin_unlock(&block_group->lock); |
| 1166 | return 0; | 1220 | return 0; |
| 1167 | } | 1221 | } |
| 1222 | |||
| 1223 | if (block_group->delalloc_bytes) { | ||
| 1224 | block_group->disk_cache_state = BTRFS_DC_WRITTEN; | ||
| 1225 | spin_unlock(&block_group->lock); | ||
| 1226 | return 0; | ||
| 1227 | } | ||
| 1168 | spin_unlock(&block_group->lock); | 1228 | spin_unlock(&block_group->lock); |
| 1169 | 1229 | ||
| 1170 | inode = lookup_free_space_inode(root, block_group, path); | 1230 | inode = lookup_free_space_inode(root, block_group, path); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8925f66a1411..3668048e16f8 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -693,7 +693,7 @@ retry: | |||
| 693 | ret = btrfs_reserve_extent(root, | 693 | ret = btrfs_reserve_extent(root, |
| 694 | async_extent->compressed_size, | 694 | async_extent->compressed_size, |
| 695 | async_extent->compressed_size, | 695 | async_extent->compressed_size, |
| 696 | 0, alloc_hint, &ins, 1); | 696 | 0, alloc_hint, &ins, 1, 1); |
| 697 | if (ret) { | 697 | if (ret) { |
| 698 | int i; | 698 | int i; |
| 699 | 699 | ||
| @@ -794,7 +794,7 @@ retry: | |||
| 794 | out: | 794 | out: |
| 795 | return ret; | 795 | return ret; |
| 796 | out_free_reserve: | 796 | out_free_reserve: |
| 797 | btrfs_free_reserved_extent(root, ins.objectid, ins.offset); | 797 | btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1); |
| 798 | out_free: | 798 | out_free: |
| 799 | extent_clear_unlock_delalloc(inode, async_extent->start, | 799 | extent_clear_unlock_delalloc(inode, async_extent->start, |
| 800 | async_extent->start + | 800 | async_extent->start + |
| @@ -917,7 +917,7 @@ static noinline int cow_file_range(struct inode *inode, | |||
| 917 | cur_alloc_size = disk_num_bytes; | 917 | cur_alloc_size = disk_num_bytes; |
| 918 | ret = btrfs_reserve_extent(root, cur_alloc_size, | 918 | ret = btrfs_reserve_extent(root, cur_alloc_size, |
| 919 | root->sectorsize, 0, alloc_hint, | 919 | root->sectorsize, 0, alloc_hint, |
| 920 | &ins, 1); | 920 | &ins, 1, 1); |
| 921 | if (ret < 0) | 921 | if (ret < 0) |
| 922 | goto out_unlock; | 922 | goto out_unlock; |
| 923 | 923 | ||
| @@ -995,7 +995,7 @@ out: | |||
| 995 | return ret; | 995 | return ret; |
| 996 | 996 | ||
| 997 | out_reserve: | 997 | out_reserve: |
| 998 | btrfs_free_reserved_extent(root, ins.objectid, ins.offset); | 998 | btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1); |
| 999 | out_unlock: | 999 | out_unlock: |
| 1000 | extent_clear_unlock_delalloc(inode, start, end, locked_page, | 1000 | extent_clear_unlock_delalloc(inode, start, end, locked_page, |
| 1001 | EXTENT_LOCKED | EXTENT_DO_ACCOUNTING | | 1001 | EXTENT_LOCKED | EXTENT_DO_ACCOUNTING | |
| @@ -2599,6 +2599,21 @@ out_kfree: | |||
| 2599 | return NULL; | 2599 | return NULL; |
| 2600 | } | 2600 | } |
| 2601 | 2601 | ||
| 2602 | static void btrfs_release_delalloc_bytes(struct btrfs_root *root, | ||
| 2603 | u64 start, u64 len) | ||
| 2604 | { | ||
| 2605 | struct btrfs_block_group_cache *cache; | ||
| 2606 | |||
| 2607 | cache = btrfs_lookup_block_group(root->fs_info, start); | ||
| 2608 | ASSERT(cache); | ||
| 2609 | |||
| 2610 | spin_lock(&cache->lock); | ||
| 2611 | cache->delalloc_bytes -= len; | ||
| 2612 | spin_unlock(&cache->lock); | ||
| 2613 | |||
| 2614 | btrfs_put_block_group(cache); | ||
| 2615 | } | ||
| 2616 | |||
| 2602 | /* as ordered data IO finishes, this gets called so we can finish | 2617 | /* as ordered data IO finishes, this gets called so we can finish |
| 2603 | * an ordered extent if the range of bytes in the file it covers are | 2618 | * an ordered extent if the range of bytes in the file it covers are |
| 2604 | * fully written. | 2619 | * fully written. |
| @@ -2698,6 +2713,10 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) | |||
| 2698 | logical_len, logical_len, | 2713 | logical_len, logical_len, |
| 2699 | compress_type, 0, 0, | 2714 | compress_type, 0, 0, |
| 2700 | BTRFS_FILE_EXTENT_REG); | 2715 | BTRFS_FILE_EXTENT_REG); |
| 2716 | if (!ret) | ||
| 2717 | btrfs_release_delalloc_bytes(root, | ||
| 2718 | ordered_extent->start, | ||
| 2719 | ordered_extent->disk_len); | ||
| 2701 | } | 2720 | } |
| 2702 | unpin_extent_cache(&BTRFS_I(inode)->extent_tree, | 2721 | unpin_extent_cache(&BTRFS_I(inode)->extent_tree, |
| 2703 | ordered_extent->file_offset, ordered_extent->len, | 2722 | ordered_extent->file_offset, ordered_extent->len, |
| @@ -2750,7 +2769,7 @@ out: | |||
| 2750 | !test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags) && | 2769 | !test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags) && |
| 2751 | !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) | 2770 | !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) |
| 2752 | btrfs_free_reserved_extent(root, ordered_extent->start, | 2771 | btrfs_free_reserved_extent(root, ordered_extent->start, |
| 2753 | ordered_extent->disk_len); | 2772 | ordered_extent->disk_len, 1); |
| 2754 | } | 2773 | } |
| 2755 | 2774 | ||
| 2756 | 2775 | ||
| @@ -6535,21 +6554,21 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode, | |||
| 6535 | 6554 | ||
| 6536 | alloc_hint = get_extent_allocation_hint(inode, start, len); | 6555 | alloc_hint = get_extent_allocation_hint(inode, start, len); |
| 6537 | ret = btrfs_reserve_extent(root, len, root->sectorsize, 0, | 6556 | ret = btrfs_reserve_extent(root, len, root->sectorsize, 0, |
| 6538 | alloc_hint, &ins, 1); | 6557 | alloc_hint, &ins, 1, 1); |
| 6539 | if (ret) | 6558 | if (ret) |
| 6540 | return ERR_PTR(ret); | 6559 | return ERR_PTR(ret); |
| 6541 | 6560 | ||
| 6542 | em = create_pinned_em(inode, start, ins.offset, start, ins.objectid, | 6561 | em = create_pinned_em(inode, start, ins.offset, start, ins.objectid, |
| 6543 | ins.offset, ins.offset, ins.offset, 0); | 6562 | ins.offset, ins.offset, ins.offset, 0); |
| 6544 | if (IS_ERR(em)) { | 6563 | if (IS_ERR(em)) { |
| 6545 | btrfs_free_reserved_extent(root, ins.objectid, ins.offset); | 6564 | btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1); |
| 6546 | return em; | 6565 | return em; |
| 6547 | } | 6566 | } |
| 6548 | 6567 | ||
| 6549 | ret = btrfs_add_ordered_extent_dio(inode, start, ins.objectid, | 6568 | ret = btrfs_add_ordered_extent_dio(inode, start, ins.objectid, |
| 6550 | ins.offset, ins.offset, 0); | 6569 | ins.offset, ins.offset, 0); |
| 6551 | if (ret) { | 6570 | if (ret) { |
| 6552 | btrfs_free_reserved_extent(root, ins.objectid, ins.offset); | 6571 | btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 1); |
| 6553 | free_extent_map(em); | 6572 | free_extent_map(em); |
| 6554 | return ERR_PTR(ret); | 6573 | return ERR_PTR(ret); |
| 6555 | } | 6574 | } |
| @@ -7437,7 +7456,7 @@ free_ordered: | |||
| 7437 | if (!test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags) && | 7456 | if (!test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags) && |
| 7438 | !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) | 7457 | !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) |
| 7439 | btrfs_free_reserved_extent(root, ordered->start, | 7458 | btrfs_free_reserved_extent(root, ordered->start, |
| 7440 | ordered->disk_len); | 7459 | ordered->disk_len, 1); |
| 7441 | btrfs_put_ordered_extent(ordered); | 7460 | btrfs_put_ordered_extent(ordered); |
| 7442 | btrfs_put_ordered_extent(ordered); | 7461 | btrfs_put_ordered_extent(ordered); |
| 7443 | } | 7462 | } |
| @@ -8808,7 +8827,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, | |||
| 8808 | cur_bytes = min(num_bytes, 256ULL * 1024 * 1024); | 8827 | cur_bytes = min(num_bytes, 256ULL * 1024 * 1024); |
| 8809 | cur_bytes = max(cur_bytes, min_size); | 8828 | cur_bytes = max(cur_bytes, min_size); |
| 8810 | ret = btrfs_reserve_extent(root, cur_bytes, min_size, 0, | 8829 | ret = btrfs_reserve_extent(root, cur_bytes, min_size, 0, |
| 8811 | *alloc_hint, &ins, 1); | 8830 | *alloc_hint, &ins, 1, 0); |
| 8812 | if (ret) { | 8831 | if (ret) { |
| 8813 | if (own_trans) | 8832 | if (own_trans) |
| 8814 | btrfs_end_transaction(trans, root); | 8833 | btrfs_end_transaction(trans, root); |
| @@ -8822,7 +8841,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, | |||
| 8822 | BTRFS_FILE_EXTENT_PREALLOC); | 8841 | BTRFS_FILE_EXTENT_PREALLOC); |
| 8823 | if (ret) { | 8842 | if (ret) { |
| 8824 | btrfs_free_reserved_extent(root, ins.objectid, | 8843 | btrfs_free_reserved_extent(root, ins.objectid, |
| 8825 | ins.offset); | 8844 | ins.offset, 0); |
| 8826 | btrfs_abort_transaction(trans, root, ret); | 8845 | btrfs_abort_transaction(trans, root, ret); |
| 8827 | if (own_trans) | 8846 | if (own_trans) |
| 8828 | btrfs_end_transaction(trans, root); | 8847 | btrfs_end_transaction(trans, root); |
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index 01277b8f2373..5665d2149249 100644 --- a/fs/btrfs/locking.c +++ b/fs/btrfs/locking.c | |||
| @@ -33,14 +33,14 @@ static void btrfs_assert_tree_read_locked(struct extent_buffer *eb); | |||
| 33 | */ | 33 | */ |
| 34 | void btrfs_set_lock_blocking_rw(struct extent_buffer *eb, int rw) | 34 | void btrfs_set_lock_blocking_rw(struct extent_buffer *eb, int rw) |
| 35 | { | 35 | { |
| 36 | if (eb->lock_nested) { | 36 | /* |
| 37 | read_lock(&eb->lock); | 37 | * no lock is required. The lock owner may change if |
| 38 | if (eb->lock_nested && current->pid == eb->lock_owner) { | 38 | * we have a read lock, but it won't change to or away |
| 39 | read_unlock(&eb->lock); | 39 | * from us. If we have the write lock, we are the owner |
| 40 | return; | 40 | * and it'll never change. |
| 41 | } | 41 | */ |
| 42 | read_unlock(&eb->lock); | 42 | if (eb->lock_nested && current->pid == eb->lock_owner) |
| 43 | } | 43 | return; |
| 44 | if (rw == BTRFS_WRITE_LOCK) { | 44 | if (rw == BTRFS_WRITE_LOCK) { |
| 45 | if (atomic_read(&eb->blocking_writers) == 0) { | 45 | if (atomic_read(&eb->blocking_writers) == 0) { |
| 46 | WARN_ON(atomic_read(&eb->spinning_writers) != 1); | 46 | WARN_ON(atomic_read(&eb->spinning_writers) != 1); |
| @@ -65,14 +65,15 @@ void btrfs_set_lock_blocking_rw(struct extent_buffer *eb, int rw) | |||
| 65 | */ | 65 | */ |
| 66 | void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw) | 66 | void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw) |
| 67 | { | 67 | { |
| 68 | if (eb->lock_nested) { | 68 | /* |
| 69 | read_lock(&eb->lock); | 69 | * no lock is required. The lock owner may change if |
| 70 | if (eb->lock_nested && current->pid == eb->lock_owner) { | 70 | * we have a read lock, but it won't change to or away |
| 71 | read_unlock(&eb->lock); | 71 | * from us. If we have the write lock, we are the owner |
| 72 | return; | 72 | * and it'll never change. |
| 73 | } | 73 | */ |
| 74 | read_unlock(&eb->lock); | 74 | if (eb->lock_nested && current->pid == eb->lock_owner) |
| 75 | } | 75 | return; |
| 76 | |||
| 76 | if (rw == BTRFS_WRITE_LOCK_BLOCKING) { | 77 | if (rw == BTRFS_WRITE_LOCK_BLOCKING) { |
| 77 | BUG_ON(atomic_read(&eb->blocking_writers) != 1); | 78 | BUG_ON(atomic_read(&eb->blocking_writers) != 1); |
| 78 | write_lock(&eb->lock); | 79 | write_lock(&eb->lock); |
| @@ -99,6 +100,9 @@ void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw) | |||
| 99 | void btrfs_tree_read_lock(struct extent_buffer *eb) | 100 | void btrfs_tree_read_lock(struct extent_buffer *eb) |
| 100 | { | 101 | { |
| 101 | again: | 102 | again: |
| 103 | BUG_ON(!atomic_read(&eb->blocking_writers) && | ||
| 104 | current->pid == eb->lock_owner); | ||
| 105 | |||
| 102 | read_lock(&eb->lock); | 106 | read_lock(&eb->lock); |
| 103 | if (atomic_read(&eb->blocking_writers) && | 107 | if (atomic_read(&eb->blocking_writers) && |
| 104 | current->pid == eb->lock_owner) { | 108 | current->pid == eb->lock_owner) { |
| @@ -132,7 +136,9 @@ int btrfs_try_tree_read_lock(struct extent_buffer *eb) | |||
| 132 | if (atomic_read(&eb->blocking_writers)) | 136 | if (atomic_read(&eb->blocking_writers)) |
| 133 | return 0; | 137 | return 0; |
| 134 | 138 | ||
| 135 | read_lock(&eb->lock); | 139 | if (!read_trylock(&eb->lock)) |
| 140 | return 0; | ||
| 141 | |||
| 136 | if (atomic_read(&eb->blocking_writers)) { | 142 | if (atomic_read(&eb->blocking_writers)) { |
| 137 | read_unlock(&eb->lock); | 143 | read_unlock(&eb->lock); |
| 138 | return 0; | 144 | return 0; |
| @@ -151,7 +157,10 @@ int btrfs_try_tree_write_lock(struct extent_buffer *eb) | |||
| 151 | if (atomic_read(&eb->blocking_writers) || | 157 | if (atomic_read(&eb->blocking_writers) || |
| 152 | atomic_read(&eb->blocking_readers)) | 158 | atomic_read(&eb->blocking_readers)) |
| 153 | return 0; | 159 | return 0; |
| 154 | write_lock(&eb->lock); | 160 | |
| 161 | if (!write_trylock(&eb->lock)) | ||
| 162 | return 0; | ||
| 163 | |||
| 155 | if (atomic_read(&eb->blocking_writers) || | 164 | if (atomic_read(&eb->blocking_writers) || |
| 156 | atomic_read(&eb->blocking_readers)) { | 165 | atomic_read(&eb->blocking_readers)) { |
| 157 | write_unlock(&eb->lock); | 166 | write_unlock(&eb->lock); |
| @@ -168,14 +177,15 @@ int btrfs_try_tree_write_lock(struct extent_buffer *eb) | |||
| 168 | */ | 177 | */ |
| 169 | void btrfs_tree_read_unlock(struct extent_buffer *eb) | 178 | void btrfs_tree_read_unlock(struct extent_buffer *eb) |
| 170 | { | 179 | { |
| 171 | if (eb->lock_nested) { | 180 | /* |
| 172 | read_lock(&eb->lock); | 181 | * if we're nested, we have the write lock. No new locking |
| 173 | if (eb->lock_nested && current->pid == eb->lock_owner) { | 182 | * is needed as long as we are the lock owner. |
| 174 | eb->lock_nested = 0; | 183 | * The write unlock will do a barrier for us, and the lock_nested |
| 175 | read_unlock(&eb->lock); | 184 | * field only matters to the lock owner. |
| 176 | return; | 185 | */ |
| 177 | } | 186 | if (eb->lock_nested && current->pid == eb->lock_owner) { |
| 178 | read_unlock(&eb->lock); | 187 | eb->lock_nested = 0; |
| 188 | return; | ||
| 179 | } | 189 | } |
| 180 | btrfs_assert_tree_read_locked(eb); | 190 | btrfs_assert_tree_read_locked(eb); |
| 181 | WARN_ON(atomic_read(&eb->spinning_readers) == 0); | 191 | WARN_ON(atomic_read(&eb->spinning_readers) == 0); |
| @@ -189,14 +199,15 @@ void btrfs_tree_read_unlock(struct extent_buffer *eb) | |||
| 189 | */ | 199 | */ |
| 190 | void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb) | 200 | void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb) |
| 191 | { | 201 | { |
| 192 | if (eb->lock_nested) { | 202 | /* |
| 193 | read_lock(&eb->lock); | 203 | * if we're nested, we have the write lock. No new locking |
| 194 | if (eb->lock_nested && current->pid == eb->lock_owner) { | 204 | * is needed as long as we are the lock owner. |
| 195 | eb->lock_nested = 0; | 205 | * The write unlock will do a barrier for us, and the lock_nested |
| 196 | read_unlock(&eb->lock); | 206 | * field only matters to the lock owner. |
| 197 | return; | 207 | */ |
| 198 | } | 208 | if (eb->lock_nested && current->pid == eb->lock_owner) { |
| 199 | read_unlock(&eb->lock); | 209 | eb->lock_nested = 0; |
| 210 | return; | ||
| 200 | } | 211 | } |
| 201 | btrfs_assert_tree_read_locked(eb); | 212 | btrfs_assert_tree_read_locked(eb); |
| 202 | WARN_ON(atomic_read(&eb->blocking_readers) == 0); | 213 | WARN_ON(atomic_read(&eb->blocking_readers) == 0); |
| @@ -244,6 +255,7 @@ void btrfs_tree_unlock(struct extent_buffer *eb) | |||
| 244 | BUG_ON(blockers > 1); | 255 | BUG_ON(blockers > 1); |
| 245 | 256 | ||
| 246 | btrfs_assert_tree_locked(eb); | 257 | btrfs_assert_tree_locked(eb); |
| 258 | eb->lock_owner = 0; | ||
| 247 | atomic_dec(&eb->write_locks); | 259 | atomic_dec(&eb->write_locks); |
| 248 | 260 | ||
| 249 | if (blockers) { | 261 | if (blockers) { |
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index ac80188eec88..b6d198f5181e 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
| @@ -2725,11 +2725,8 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, | |||
| 2725 | dev_extent = btrfs_item_ptr(l, slot, struct btrfs_dev_extent); | 2725 | dev_extent = btrfs_item_ptr(l, slot, struct btrfs_dev_extent); |
| 2726 | length = btrfs_dev_extent_length(l, dev_extent); | 2726 | length = btrfs_dev_extent_length(l, dev_extent); |
| 2727 | 2727 | ||
| 2728 | if (found_key.offset + length <= start) { | 2728 | if (found_key.offset + length <= start) |
| 2729 | key.offset = found_key.offset + length; | 2729 | goto skip; |
| 2730 | btrfs_release_path(path); | ||
| 2731 | continue; | ||
| 2732 | } | ||
| 2733 | 2730 | ||
| 2734 | chunk_tree = btrfs_dev_extent_chunk_tree(l, dev_extent); | 2731 | chunk_tree = btrfs_dev_extent_chunk_tree(l, dev_extent); |
| 2735 | chunk_objectid = btrfs_dev_extent_chunk_objectid(l, dev_extent); | 2732 | chunk_objectid = btrfs_dev_extent_chunk_objectid(l, dev_extent); |
| @@ -2740,10 +2737,12 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, | |||
| 2740 | * the chunk from going away while we scrub it | 2737 | * the chunk from going away while we scrub it |
| 2741 | */ | 2738 | */ |
| 2742 | cache = btrfs_lookup_block_group(fs_info, chunk_offset); | 2739 | cache = btrfs_lookup_block_group(fs_info, chunk_offset); |
| 2743 | if (!cache) { | 2740 | |
| 2744 | ret = -ENOENT; | 2741 | /* some chunks are removed but not committed to disk yet, |
| 2745 | break; | 2742 | * continue scrubbing */ |
| 2746 | } | 2743 | if (!cache) |
| 2744 | goto skip; | ||
| 2745 | |||
| 2747 | dev_replace->cursor_right = found_key.offset + length; | 2746 | dev_replace->cursor_right = found_key.offset + length; |
| 2748 | dev_replace->cursor_left = found_key.offset; | 2747 | dev_replace->cursor_left = found_key.offset; |
| 2749 | dev_replace->item_needs_writeback = 1; | 2748 | dev_replace->item_needs_writeback = 1; |
| @@ -2802,7 +2801,7 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, | |||
| 2802 | 2801 | ||
| 2803 | dev_replace->cursor_left = dev_replace->cursor_right; | 2802 | dev_replace->cursor_left = dev_replace->cursor_right; |
| 2804 | dev_replace->item_needs_writeback = 1; | 2803 | dev_replace->item_needs_writeback = 1; |
| 2805 | 2804 | skip: | |
| 2806 | key.offset = found_key.offset + length; | 2805 | key.offset = found_key.offset + length; |
| 2807 | btrfs_release_path(path); | 2806 | btrfs_release_path(path); |
| 2808 | } | 2807 | } |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index ffeed6d6326f..c83b24251e53 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -2543,9 +2543,6 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, | |||
| 2543 | remove_extent_mapping(em_tree, em); | 2543 | remove_extent_mapping(em_tree, em); |
| 2544 | write_unlock(&em_tree->lock); | 2544 | write_unlock(&em_tree->lock); |
| 2545 | 2545 | ||
| 2546 | kfree(map); | ||
| 2547 | em->bdev = NULL; | ||
| 2548 | |||
| 2549 | /* once for the tree */ | 2546 | /* once for the tree */ |
| 2550 | free_extent_map(em); | 2547 | free_extent_map(em); |
| 2551 | /* once for us */ | 2548 | /* once for us */ |
| @@ -4301,9 +4298,11 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, | |||
| 4301 | 4298 | ||
| 4302 | em = alloc_extent_map(); | 4299 | em = alloc_extent_map(); |
| 4303 | if (!em) { | 4300 | if (!em) { |
| 4301 | kfree(map); | ||
| 4304 | ret = -ENOMEM; | 4302 | ret = -ENOMEM; |
| 4305 | goto error; | 4303 | goto error; |
| 4306 | } | 4304 | } |
| 4305 | set_bit(EXTENT_FLAG_FS_MAPPING, &em->flags); | ||
| 4307 | em->bdev = (struct block_device *)map; | 4306 | em->bdev = (struct block_device *)map; |
| 4308 | em->start = start; | 4307 | em->start = start; |
| 4309 | em->len = num_bytes; | 4308 | em->len = num_bytes; |
| @@ -4346,7 +4345,6 @@ error_del_extent: | |||
| 4346 | /* One for the tree reference */ | 4345 | /* One for the tree reference */ |
| 4347 | free_extent_map(em); | 4346 | free_extent_map(em); |
| 4348 | error: | 4347 | error: |
| 4349 | kfree(map); | ||
| 4350 | kfree(devices_info); | 4348 | kfree(devices_info); |
| 4351 | return ret; | 4349 | return ret; |
| 4352 | } | 4350 | } |
| @@ -4558,7 +4556,6 @@ void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree) | |||
| 4558 | write_unlock(&tree->map_tree.lock); | 4556 | write_unlock(&tree->map_tree.lock); |
| 4559 | if (!em) | 4557 | if (!em) |
| 4560 | break; | 4558 | break; |
| 4561 | kfree(em->bdev); | ||
| 4562 | /* once for us */ | 4559 | /* once for us */ |
| 4563 | free_extent_map(em); | 4560 | free_extent_map(em); |
| 4564 | /* once for the tree */ | 4561 | /* once for the tree */ |
| @@ -5362,6 +5359,15 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, | |||
| 5362 | return 0; | 5359 | return 0; |
| 5363 | } | 5360 | } |
| 5364 | 5361 | ||
| 5362 | static inline void btrfs_end_bbio(struct btrfs_bio *bbio, struct bio *bio, int err) | ||
| 5363 | { | ||
| 5364 | if (likely(bbio->flags & BTRFS_BIO_ORIG_BIO_SUBMITTED)) | ||
| 5365 | bio_endio_nodec(bio, err); | ||
| 5366 | else | ||
| 5367 | bio_endio(bio, err); | ||
| 5368 | kfree(bbio); | ||
| 5369 | } | ||
| 5370 | |||
| 5365 | static void btrfs_end_bio(struct bio *bio, int err) | 5371 | static void btrfs_end_bio(struct bio *bio, int err) |
| 5366 | { | 5372 | { |
| 5367 | struct btrfs_bio *bbio = bio->bi_private; | 5373 | struct btrfs_bio *bbio = bio->bi_private; |
| @@ -5402,12 +5408,6 @@ static void btrfs_end_bio(struct bio *bio, int err) | |||
| 5402 | bio = bbio->orig_bio; | 5408 | bio = bbio->orig_bio; |
| 5403 | } | 5409 | } |
| 5404 | 5410 | ||
| 5405 | /* | ||
| 5406 | * We have original bio now. So increment bi_remaining to | ||
| 5407 | * account for it in endio | ||
| 5408 | */ | ||
| 5409 | atomic_inc(&bio->bi_remaining); | ||
| 5410 | |||
| 5411 | bio->bi_private = bbio->private; | 5411 | bio->bi_private = bbio->private; |
| 5412 | bio->bi_end_io = bbio->end_io; | 5412 | bio->bi_end_io = bbio->end_io; |
| 5413 | btrfs_io_bio(bio)->mirror_num = bbio->mirror_num; | 5413 | btrfs_io_bio(bio)->mirror_num = bbio->mirror_num; |
| @@ -5424,9 +5424,8 @@ static void btrfs_end_bio(struct bio *bio, int err) | |||
| 5424 | set_bit(BIO_UPTODATE, &bio->bi_flags); | 5424 | set_bit(BIO_UPTODATE, &bio->bi_flags); |
| 5425 | err = 0; | 5425 | err = 0; |
| 5426 | } | 5426 | } |
| 5427 | kfree(bbio); | ||
| 5428 | 5427 | ||
| 5429 | bio_endio(bio, err); | 5428 | btrfs_end_bbio(bbio, bio, err); |
| 5430 | } else if (!is_orig_bio) { | 5429 | } else if (!is_orig_bio) { |
| 5431 | bio_put(bio); | 5430 | bio_put(bio); |
| 5432 | } | 5431 | } |
| @@ -5589,12 +5588,15 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical) | |||
| 5589 | { | 5588 | { |
| 5590 | atomic_inc(&bbio->error); | 5589 | atomic_inc(&bbio->error); |
| 5591 | if (atomic_dec_and_test(&bbio->stripes_pending)) { | 5590 | if (atomic_dec_and_test(&bbio->stripes_pending)) { |
| 5591 | /* Shoud be the original bio. */ | ||
| 5592 | WARN_ON(bio != bbio->orig_bio); | ||
| 5593 | |||
| 5592 | bio->bi_private = bbio->private; | 5594 | bio->bi_private = bbio->private; |
| 5593 | bio->bi_end_io = bbio->end_io; | 5595 | bio->bi_end_io = bbio->end_io; |
| 5594 | btrfs_io_bio(bio)->mirror_num = bbio->mirror_num; | 5596 | btrfs_io_bio(bio)->mirror_num = bbio->mirror_num; |
| 5595 | bio->bi_iter.bi_sector = logical >> 9; | 5597 | bio->bi_iter.bi_sector = logical >> 9; |
| 5596 | kfree(bbio); | 5598 | |
| 5597 | bio_endio(bio, -EIO); | 5599 | btrfs_end_bbio(bbio, bio, -EIO); |
| 5598 | } | 5600 | } |
| 5599 | } | 5601 | } |
| 5600 | 5602 | ||
| @@ -5681,6 +5683,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, | |||
| 5681 | BUG_ON(!bio); /* -ENOMEM */ | 5683 | BUG_ON(!bio); /* -ENOMEM */ |
| 5682 | } else { | 5684 | } else { |
| 5683 | bio = first_bio; | 5685 | bio = first_bio; |
| 5686 | bbio->flags |= BTRFS_BIO_ORIG_BIO_SUBMITTED; | ||
| 5684 | } | 5687 | } |
| 5685 | 5688 | ||
| 5686 | submit_stripe_bio(root, bbio, bio, | 5689 | submit_stripe_bio(root, bbio, bio, |
| @@ -5822,6 +5825,7 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, | |||
| 5822 | return -ENOMEM; | 5825 | return -ENOMEM; |
| 5823 | } | 5826 | } |
| 5824 | 5827 | ||
| 5828 | set_bit(EXTENT_FLAG_FS_MAPPING, &em->flags); | ||
| 5825 | em->bdev = (struct block_device *)map; | 5829 | em->bdev = (struct block_device *)map; |
| 5826 | em->start = logical; | 5830 | em->start = logical; |
| 5827 | em->len = length; | 5831 | em->len = length; |
| @@ -5846,7 +5850,6 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, | |||
| 5846 | map->stripes[i].dev = btrfs_find_device(root->fs_info, devid, | 5850 | map->stripes[i].dev = btrfs_find_device(root->fs_info, devid, |
| 5847 | uuid, NULL); | 5851 | uuid, NULL); |
| 5848 | if (!map->stripes[i].dev && !btrfs_test_opt(root, DEGRADED)) { | 5852 | if (!map->stripes[i].dev && !btrfs_test_opt(root, DEGRADED)) { |
| 5849 | kfree(map); | ||
| 5850 | free_extent_map(em); | 5853 | free_extent_map(em); |
| 5851 | return -EIO; | 5854 | return -EIO; |
| 5852 | } | 5855 | } |
| @@ -5854,7 +5857,6 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, | |||
| 5854 | map->stripes[i].dev = | 5857 | map->stripes[i].dev = |
| 5855 | add_missing_dev(root, devid, uuid); | 5858 | add_missing_dev(root, devid, uuid); |
| 5856 | if (!map->stripes[i].dev) { | 5859 | if (!map->stripes[i].dev) { |
| 5857 | kfree(map); | ||
| 5858 | free_extent_map(em); | 5860 | free_extent_map(em); |
| 5859 | return -EIO; | 5861 | return -EIO; |
| 5860 | } | 5862 | } |
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 1a15bbeb65e2..2aaa00c47816 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
| @@ -190,11 +190,14 @@ struct btrfs_bio_stripe { | |||
| 190 | struct btrfs_bio; | 190 | struct btrfs_bio; |
| 191 | typedef void (btrfs_bio_end_io_t) (struct btrfs_bio *bio, int err); | 191 | typedef void (btrfs_bio_end_io_t) (struct btrfs_bio *bio, int err); |
| 192 | 192 | ||
| 193 | #define BTRFS_BIO_ORIG_BIO_SUBMITTED 0x1 | ||
| 194 | |||
| 193 | struct btrfs_bio { | 195 | struct btrfs_bio { |
| 194 | atomic_t stripes_pending; | 196 | atomic_t stripes_pending; |
| 195 | struct btrfs_fs_info *fs_info; | 197 | struct btrfs_fs_info *fs_info; |
| 196 | bio_end_io_t *end_io; | 198 | bio_end_io_t *end_io; |
| 197 | struct bio *orig_bio; | 199 | struct bio *orig_bio; |
| 200 | unsigned long flags; | ||
| 198 | void *private; | 201 | void *private; |
| 199 | atomic_t error; | 202 | atomic_t error; |
| 200 | int max_errors; | 203 | int max_errors; |
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index 0227b45ef00a..15e9505aa35f 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c | |||
| @@ -290,7 +290,8 @@ int | |||
| 290 | cifsConvertToUTF16(__le16 *target, const char *source, int srclen, | 290 | cifsConvertToUTF16(__le16 *target, const char *source, int srclen, |
| 291 | const struct nls_table *cp, int mapChars) | 291 | const struct nls_table *cp, int mapChars) |
| 292 | { | 292 | { |
| 293 | int i, j, charlen; | 293 | int i, charlen; |
| 294 | int j = 0; | ||
| 294 | char src_char; | 295 | char src_char; |
| 295 | __le16 dst_char; | 296 | __le16 dst_char; |
| 296 | wchar_t tmp; | 297 | wchar_t tmp; |
| @@ -298,12 +299,11 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen, | |||
| 298 | if (!mapChars) | 299 | if (!mapChars) |
| 299 | return cifs_strtoUTF16(target, source, PATH_MAX, cp); | 300 | return cifs_strtoUTF16(target, source, PATH_MAX, cp); |
| 300 | 301 | ||
| 301 | for (i = 0, j = 0; i < srclen; j++) { | 302 | for (i = 0; i < srclen; j++) { |
| 302 | src_char = source[i]; | 303 | src_char = source[i]; |
| 303 | charlen = 1; | 304 | charlen = 1; |
| 304 | switch (src_char) { | 305 | switch (src_char) { |
| 305 | case 0: | 306 | case 0: |
| 306 | put_unaligned(0, &target[j]); | ||
| 307 | goto ctoUTF16_out; | 307 | goto ctoUTF16_out; |
| 308 | case ':': | 308 | case ':': |
| 309 | dst_char = cpu_to_le16(UNI_COLON); | 309 | dst_char = cpu_to_le16(UNI_COLON); |
| @@ -350,6 +350,7 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen, | |||
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | ctoUTF16_out: | 352 | ctoUTF16_out: |
| 353 | put_unaligned(0, &target[j]); /* Null terminate target unicode string */ | ||
| 353 | return j; | 354 | return j; |
| 354 | } | 355 | } |
| 355 | 356 | ||
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 2c90d07c0b3a..888398067420 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -725,6 +725,19 @@ out_nls: | |||
| 725 | goto out; | 725 | goto out; |
| 726 | } | 726 | } |
| 727 | 727 | ||
| 728 | static ssize_t | ||
| 729 | cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter) | ||
| 730 | { | ||
| 731 | ssize_t rc; | ||
| 732 | struct inode *inode = file_inode(iocb->ki_filp); | ||
| 733 | |||
| 734 | rc = cifs_revalidate_mapping(inode); | ||
| 735 | if (rc) | ||
| 736 | return rc; | ||
| 737 | |||
| 738 | return generic_file_read_iter(iocb, iter); | ||
| 739 | } | ||
| 740 | |||
| 728 | static ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | 741 | static ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) |
| 729 | { | 742 | { |
| 730 | struct inode *inode = file_inode(iocb->ki_filp); | 743 | struct inode *inode = file_inode(iocb->ki_filp); |
| @@ -881,7 +894,7 @@ const struct inode_operations cifs_symlink_inode_ops = { | |||
| 881 | const struct file_operations cifs_file_ops = { | 894 | const struct file_operations cifs_file_ops = { |
| 882 | .read = new_sync_read, | 895 | .read = new_sync_read, |
| 883 | .write = new_sync_write, | 896 | .write = new_sync_write, |
| 884 | .read_iter = generic_file_read_iter, | 897 | .read_iter = cifs_loose_read_iter, |
| 885 | .write_iter = cifs_file_write_iter, | 898 | .write_iter = cifs_file_write_iter, |
| 886 | .open = cifs_open, | 899 | .open = cifs_open, |
| 887 | .release = cifs_close, | 900 | .release = cifs_close, |
| @@ -939,7 +952,7 @@ const struct file_operations cifs_file_direct_ops = { | |||
| 939 | const struct file_operations cifs_file_nobrl_ops = { | 952 | const struct file_operations cifs_file_nobrl_ops = { |
| 940 | .read = new_sync_read, | 953 | .read = new_sync_read, |
| 941 | .write = new_sync_write, | 954 | .write = new_sync_write, |
| 942 | .read_iter = generic_file_read_iter, | 955 | .read_iter = cifs_loose_read_iter, |
| 943 | .write_iter = cifs_file_write_iter, | 956 | .write_iter = cifs_file_write_iter, |
| 944 | .open = cifs_open, | 957 | .open = cifs_open, |
| 945 | .release = cifs_close, | 958 | .release = cifs_close, |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 264ece71bdb2..68559fd557fb 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
| @@ -374,7 +374,7 @@ cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, | |||
| 374 | oparms.cifs_sb = cifs_sb; | 374 | oparms.cifs_sb = cifs_sb; |
| 375 | oparms.desired_access = GENERIC_WRITE; | 375 | oparms.desired_access = GENERIC_WRITE; |
| 376 | oparms.create_options = create_options; | 376 | oparms.create_options = create_options; |
| 377 | oparms.disposition = FILE_OPEN; | 377 | oparms.disposition = FILE_CREATE; |
| 378 | oparms.path = path; | 378 | oparms.path = path; |
| 379 | oparms.fid = &fid; | 379 | oparms.fid = &fid; |
| 380 | oparms.reconnect = false; | 380 | oparms.reconnect = false; |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index b73e0621ce9e..b10b48c2a7af 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
| @@ -910,7 +910,7 @@ static const struct file_operations eventpoll_fops = { | |||
| 910 | void eventpoll_release_file(struct file *file) | 910 | void eventpoll_release_file(struct file *file) |
| 911 | { | 911 | { |
| 912 | struct eventpoll *ep; | 912 | struct eventpoll *ep; |
| 913 | struct epitem *epi; | 913 | struct epitem *epi, *next; |
| 914 | 914 | ||
| 915 | /* | 915 | /* |
| 916 | * We don't want to get "file->f_lock" because it is not | 916 | * We don't want to get "file->f_lock" because it is not |
| @@ -926,7 +926,7 @@ void eventpoll_release_file(struct file *file) | |||
| 926 | * Besides, ep_remove() acquires the lock, so we can't hold it here. | 926 | * Besides, ep_remove() acquires the lock, so we can't hold it here. |
| 927 | */ | 927 | */ |
| 928 | mutex_lock(&epmutex); | 928 | mutex_lock(&epmutex); |
| 929 | list_for_each_entry_rcu(epi, &file->f_ep_links, fllink) { | 929 | list_for_each_entry_safe(epi, next, &file->f_ep_links, fllink) { |
| 930 | ep = epi->ep; | 930 | ep = epi->ep; |
| 931 | mutex_lock_nested(&ep->mtx, 0); | 931 | mutex_lock_nested(&ep->mtx, 0); |
| 932 | ep_remove(ep, epi); | 932 | ep_remove(ep, epi); |
diff --git a/fs/locks.c b/fs/locks.c index da57c9b7e844..717fbc404e6b 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
| @@ -431,7 +431,7 @@ static int lease_init(struct file *filp, long type, struct file_lock *fl) | |||
| 431 | if (assign_type(fl, type) != 0) | 431 | if (assign_type(fl, type) != 0) |
| 432 | return -EINVAL; | 432 | return -EINVAL; |
| 433 | 433 | ||
| 434 | fl->fl_owner = (fl_owner_t)filp; | 434 | fl->fl_owner = (fl_owner_t)current->files; |
| 435 | fl->fl_pid = current->tgid; | 435 | fl->fl_pid = current->tgid; |
| 436 | 436 | ||
| 437 | fl->fl_file = filp; | 437 | fl->fl_file = filp; |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index c496f8a74639..9927913c97c2 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
| @@ -147,6 +147,17 @@ int nfs_sync_mapping(struct address_space *mapping) | |||
| 147 | return ret; | 147 | return ret; |
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) | ||
| 151 | { | ||
| 152 | struct nfs_inode *nfsi = NFS_I(inode); | ||
| 153 | |||
| 154 | if (inode->i_mapping->nrpages == 0) | ||
| 155 | flags &= ~NFS_INO_INVALID_DATA; | ||
| 156 | nfsi->cache_validity |= flags; | ||
| 157 | if (flags & NFS_INO_INVALID_DATA) | ||
| 158 | nfs_fscache_invalidate(inode); | ||
| 159 | } | ||
| 160 | |||
| 150 | /* | 161 | /* |
| 151 | * Invalidate the local caches | 162 | * Invalidate the local caches |
| 152 | */ | 163 | */ |
| @@ -162,17 +173,16 @@ static void nfs_zap_caches_locked(struct inode *inode) | |||
| 162 | 173 | ||
| 163 | memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf)); | 174 | memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf)); |
| 164 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) { | 175 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) { |
| 165 | nfs_fscache_invalidate(inode); | 176 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR |
| 166 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | ||
| 167 | | NFS_INO_INVALID_DATA | 177 | | NFS_INO_INVALID_DATA |
| 168 | | NFS_INO_INVALID_ACCESS | 178 | | NFS_INO_INVALID_ACCESS |
| 169 | | NFS_INO_INVALID_ACL | 179 | | NFS_INO_INVALID_ACL |
| 170 | | NFS_INO_REVAL_PAGECACHE; | 180 | | NFS_INO_REVAL_PAGECACHE); |
| 171 | } else | 181 | } else |
| 172 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | 182 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR |
| 173 | | NFS_INO_INVALID_ACCESS | 183 | | NFS_INO_INVALID_ACCESS |
| 174 | | NFS_INO_INVALID_ACL | 184 | | NFS_INO_INVALID_ACL |
| 175 | | NFS_INO_REVAL_PAGECACHE; | 185 | | NFS_INO_REVAL_PAGECACHE); |
| 176 | nfs_zap_label_cache_locked(nfsi); | 186 | nfs_zap_label_cache_locked(nfsi); |
| 177 | } | 187 | } |
| 178 | 188 | ||
| @@ -187,8 +197,7 @@ void nfs_zap_mapping(struct inode *inode, struct address_space *mapping) | |||
| 187 | { | 197 | { |
| 188 | if (mapping->nrpages != 0) { | 198 | if (mapping->nrpages != 0) { |
| 189 | spin_lock(&inode->i_lock); | 199 | spin_lock(&inode->i_lock); |
| 190 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; | 200 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA); |
| 191 | nfs_fscache_invalidate(inode); | ||
| 192 | spin_unlock(&inode->i_lock); | 201 | spin_unlock(&inode->i_lock); |
| 193 | } | 202 | } |
| 194 | } | 203 | } |
| @@ -209,7 +218,7 @@ EXPORT_SYMBOL_GPL(nfs_zap_acl_cache); | |||
| 209 | void nfs_invalidate_atime(struct inode *inode) | 218 | void nfs_invalidate_atime(struct inode *inode) |
| 210 | { | 219 | { |
| 211 | spin_lock(&inode->i_lock); | 220 | spin_lock(&inode->i_lock); |
| 212 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; | 221 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATIME); |
| 213 | spin_unlock(&inode->i_lock); | 222 | spin_unlock(&inode->i_lock); |
| 214 | } | 223 | } |
| 215 | EXPORT_SYMBOL_GPL(nfs_invalidate_atime); | 224 | EXPORT_SYMBOL_GPL(nfs_invalidate_atime); |
| @@ -369,7 +378,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st | |||
| 369 | inode->i_mode = fattr->mode; | 378 | inode->i_mode = fattr->mode; |
| 370 | if ((fattr->valid & NFS_ATTR_FATTR_MODE) == 0 | 379 | if ((fattr->valid & NFS_ATTR_FATTR_MODE) == 0 |
| 371 | && nfs_server_capable(inode, NFS_CAP_MODE)) | 380 | && nfs_server_capable(inode, NFS_CAP_MODE)) |
| 372 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 381 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
| 373 | /* Why so? Because we want revalidate for devices/FIFOs, and | 382 | /* Why so? Because we want revalidate for devices/FIFOs, and |
| 374 | * that's precisely what we have in nfs_file_inode_operations. | 383 | * that's precisely what we have in nfs_file_inode_operations. |
| 375 | */ | 384 | */ |
| @@ -415,36 +424,36 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st | |||
| 415 | if (fattr->valid & NFS_ATTR_FATTR_ATIME) | 424 | if (fattr->valid & NFS_ATTR_FATTR_ATIME) |
| 416 | inode->i_atime = fattr->atime; | 425 | inode->i_atime = fattr->atime; |
| 417 | else if (nfs_server_capable(inode, NFS_CAP_ATIME)) | 426 | else if (nfs_server_capable(inode, NFS_CAP_ATIME)) |
| 418 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 427 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
| 419 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) | 428 | if (fattr->valid & NFS_ATTR_FATTR_MTIME) |
| 420 | inode->i_mtime = fattr->mtime; | 429 | inode->i_mtime = fattr->mtime; |
| 421 | else if (nfs_server_capable(inode, NFS_CAP_MTIME)) | 430 | else if (nfs_server_capable(inode, NFS_CAP_MTIME)) |
| 422 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 431 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
| 423 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) | 432 | if (fattr->valid & NFS_ATTR_FATTR_CTIME) |
| 424 | inode->i_ctime = fattr->ctime; | 433 | inode->i_ctime = fattr->ctime; |
| 425 | else if (nfs_server_capable(inode, NFS_CAP_CTIME)) | 434 | else if (nfs_server_capable(inode, NFS_CAP_CTIME)) |
| 426 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 435 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
| 427 | if (fattr->valid & NFS_ATTR_FATTR_CHANGE) | 436 | if (fattr->valid & NFS_ATTR_FATTR_CHANGE) |
| 428 | inode->i_version = fattr->change_attr; | 437 | inode->i_version = fattr->change_attr; |
| 429 | else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR)) | 438 | else if (nfs_server_capable(inode, NFS_CAP_CHANGE_ATTR)) |
| 430 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 439 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
| 431 | if (fattr->valid & NFS_ATTR_FATTR_SIZE) | 440 | if (fattr->valid & NFS_ATTR_FATTR_SIZE) |
| 432 | inode->i_size = nfs_size_to_loff_t(fattr->size); | 441 | inode->i_size = nfs_size_to_loff_t(fattr->size); |
| 433 | else | 442 | else |
| 434 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | 443 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR |
| 435 | | NFS_INO_REVAL_PAGECACHE; | 444 | | NFS_INO_REVAL_PAGECACHE); |
| 436 | if (fattr->valid & NFS_ATTR_FATTR_NLINK) | 445 | if (fattr->valid & NFS_ATTR_FATTR_NLINK) |
| 437 | set_nlink(inode, fattr->nlink); | 446 | set_nlink(inode, fattr->nlink); |
| 438 | else if (nfs_server_capable(inode, NFS_CAP_NLINK)) | 447 | else if (nfs_server_capable(inode, NFS_CAP_NLINK)) |
| 439 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 448 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
| 440 | if (fattr->valid & NFS_ATTR_FATTR_OWNER) | 449 | if (fattr->valid & NFS_ATTR_FATTR_OWNER) |
| 441 | inode->i_uid = fattr->uid; | 450 | inode->i_uid = fattr->uid; |
| 442 | else if (nfs_server_capable(inode, NFS_CAP_OWNER)) | 451 | else if (nfs_server_capable(inode, NFS_CAP_OWNER)) |
| 443 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 452 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
| 444 | if (fattr->valid & NFS_ATTR_FATTR_GROUP) | 453 | if (fattr->valid & NFS_ATTR_FATTR_GROUP) |
| 445 | inode->i_gid = fattr->gid; | 454 | inode->i_gid = fattr->gid; |
| 446 | else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP)) | 455 | else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP)) |
| 447 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | 456 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR); |
| 448 | if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED) | 457 | if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED) |
| 449 | inode->i_blocks = fattr->du.nfs2.blocks; | 458 | inode->i_blocks = fattr->du.nfs2.blocks; |
| 450 | if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { | 459 | if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { |
| @@ -550,6 +559,9 @@ static int nfs_vmtruncate(struct inode * inode, loff_t offset) | |||
| 550 | 559 | ||
| 551 | spin_lock(&inode->i_lock); | 560 | spin_lock(&inode->i_lock); |
| 552 | i_size_write(inode, offset); | 561 | i_size_write(inode, offset); |
| 562 | /* Optimisation */ | ||
| 563 | if (offset == 0) | ||
| 564 | NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_DATA; | ||
| 553 | spin_unlock(&inode->i_lock); | 565 | spin_unlock(&inode->i_lock); |
| 554 | 566 | ||
| 555 | truncate_pagecache(inode, offset); | 567 | truncate_pagecache(inode, offset); |
| @@ -578,7 +590,8 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr) | |||
| 578 | inode->i_uid = attr->ia_uid; | 590 | inode->i_uid = attr->ia_uid; |
| 579 | if ((attr->ia_valid & ATTR_GID) != 0) | 591 | if ((attr->ia_valid & ATTR_GID) != 0) |
| 580 | inode->i_gid = attr->ia_gid; | 592 | inode->i_gid = attr->ia_gid; |
| 581 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 593 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_ACCESS |
| 594 | | NFS_INO_INVALID_ACL); | ||
| 582 | spin_unlock(&inode->i_lock); | 595 | spin_unlock(&inode->i_lock); |
| 583 | } | 596 | } |
| 584 | if ((attr->ia_valid & ATTR_SIZE) != 0) { | 597 | if ((attr->ia_valid & ATTR_SIZE) != 0) { |
| @@ -1101,7 +1114,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr | |||
| 1101 | && inode->i_version == fattr->pre_change_attr) { | 1114 | && inode->i_version == fattr->pre_change_attr) { |
| 1102 | inode->i_version = fattr->change_attr; | 1115 | inode->i_version = fattr->change_attr; |
| 1103 | if (S_ISDIR(inode->i_mode)) | 1116 | if (S_ISDIR(inode->i_mode)) |
| 1104 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; | 1117 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA); |
| 1105 | ret |= NFS_INO_INVALID_ATTR; | 1118 | ret |= NFS_INO_INVALID_ATTR; |
| 1106 | } | 1119 | } |
| 1107 | /* If we have atomic WCC data, we may update some attributes */ | 1120 | /* If we have atomic WCC data, we may update some attributes */ |
| @@ -1117,7 +1130,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr | |||
| 1117 | && timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) { | 1130 | && timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) { |
| 1118 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); | 1131 | memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); |
| 1119 | if (S_ISDIR(inode->i_mode)) | 1132 | if (S_ISDIR(inode->i_mode)) |
| 1120 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; | 1133 | nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA); |
| 1121 | ret |= NFS_INO_INVALID_ATTR; | 1134 | ret |= NFS_INO_INVALID_ATTR; |
| 1122 | } | 1135 | } |
| 1123 | if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE) | 1136 | if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE) |
| @@ -1128,9 +1141,6 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr | |||
| 1128 | ret |= NFS_INO_INVALID_ATTR; | 1141 | ret |= NFS_INO_INVALID_ATTR; |
| 1129 | } | 1142 | } |
| 1130 | 1143 | ||
| 1131 | if (nfsi->cache_validity & NFS_INO_INVALID_DATA) | ||
| 1132 | nfs_fscache_invalidate(inode); | ||
| 1133 | |||
| 1134 | return ret; | 1144 | return ret; |
| 1135 | } | 1145 | } |
| 1136 | 1146 | ||
| @@ -1189,7 +1199,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat | |||
| 1189 | invalid |= NFS_INO_INVALID_ATIME; | 1199 | invalid |= NFS_INO_INVALID_ATIME; |
| 1190 | 1200 | ||
| 1191 | if (invalid != 0) | 1201 | if (invalid != 0) |
| 1192 | nfsi->cache_validity |= invalid; | 1202 | nfs_set_cache_invalid(inode, invalid); |
| 1193 | 1203 | ||
| 1194 | nfsi->read_cache_jiffies = fattr->time_start; | 1204 | nfsi->read_cache_jiffies = fattr->time_start; |
| 1195 | return 0; | 1205 | return 0; |
| @@ -1402,13 +1412,11 @@ EXPORT_SYMBOL_GPL(nfs_refresh_inode); | |||
| 1402 | 1412 | ||
| 1403 | static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr) | 1413 | static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr) |
| 1404 | { | 1414 | { |
| 1405 | struct nfs_inode *nfsi = NFS_I(inode); | 1415 | unsigned long invalid = NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; |
| 1406 | 1416 | ||
| 1407 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE; | 1417 | if (S_ISDIR(inode->i_mode)) |
| 1408 | if (S_ISDIR(inode->i_mode)) { | 1418 | invalid |= NFS_INO_INVALID_DATA; |
| 1409 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; | 1419 | nfs_set_cache_invalid(inode, invalid); |
| 1410 | nfs_fscache_invalidate(inode); | ||
| 1411 | } | ||
| 1412 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) | 1420 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) |
| 1413 | return 0; | 1421 | return 0; |
| 1414 | return nfs_refresh_inode_locked(inode, fattr); | 1422 | return nfs_refresh_inode_locked(inode, fattr); |
| @@ -1601,6 +1609,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
| 1601 | if ((nfsi->npages == 0) || new_isize > cur_isize) { | 1609 | if ((nfsi->npages == 0) || new_isize > cur_isize) { |
| 1602 | i_size_write(inode, new_isize); | 1610 | i_size_write(inode, new_isize); |
| 1603 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1611 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; |
| 1612 | invalid &= ~NFS_INO_REVAL_PAGECACHE; | ||
| 1604 | } | 1613 | } |
| 1605 | dprintk("NFS: isize change on server for file %s/%ld " | 1614 | dprintk("NFS: isize change on server for file %s/%ld " |
| 1606 | "(%Ld to %Ld)\n", | 1615 | "(%Ld to %Ld)\n", |
| @@ -1702,10 +1711,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
| 1702 | invalid &= ~NFS_INO_INVALID_DATA; | 1711 | invalid &= ~NFS_INO_INVALID_DATA; |
| 1703 | if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ) || | 1712 | if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ) || |
| 1704 | (save_cache_validity & NFS_INO_REVAL_FORCED)) | 1713 | (save_cache_validity & NFS_INO_REVAL_FORCED)) |
| 1705 | nfsi->cache_validity |= invalid; | 1714 | nfs_set_cache_invalid(inode, invalid); |
| 1706 | |||
| 1707 | if (invalid & NFS_INO_INVALID_DATA) | ||
| 1708 | nfs_fscache_invalidate(inode); | ||
| 1709 | 1715 | ||
| 1710 | return 0; | 1716 | return 0; |
| 1711 | out_err: | 1717 | out_err: |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index f63cb87cd730..ba2affa51941 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
| @@ -230,7 +230,7 @@ int nfs_atomic_open(struct inode *, struct dentry *, struct file *, | |||
| 230 | extern struct file_system_type nfs4_fs_type; | 230 | extern struct file_system_type nfs4_fs_type; |
| 231 | 231 | ||
| 232 | /* nfs4namespace.c */ | 232 | /* nfs4namespace.c */ |
| 233 | struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *); | 233 | struct rpc_clnt *nfs4_negotiate_security(struct rpc_clnt *, struct inode *, struct qstr *); |
| 234 | struct vfsmount *nfs4_submount(struct nfs_server *, struct dentry *, | 234 | struct vfsmount *nfs4_submount(struct nfs_server *, struct dentry *, |
| 235 | struct nfs_fh *, struct nfs_fattr *); | 235 | struct nfs_fh *, struct nfs_fattr *); |
| 236 | int nfs4_replace_transport(struct nfs_server *server, | 236 | int nfs4_replace_transport(struct nfs_server *server, |
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index 3d5dbf80d46a..3d83cb1fdc70 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c | |||
| @@ -139,16 +139,22 @@ static size_t nfs_parse_server_name(char *string, size_t len, | |||
| 139 | * @server: NFS server struct | 139 | * @server: NFS server struct |
| 140 | * @flavors: List of security tuples returned by SECINFO procedure | 140 | * @flavors: List of security tuples returned by SECINFO procedure |
| 141 | * | 141 | * |
| 142 | * Return the pseudoflavor of the first security mechanism in | 142 | * Return an rpc client that uses the first security mechanism in |
| 143 | * "flavors" that is locally supported. Return RPC_AUTH_UNIX if | 143 | * "flavors" that is locally supported. The "flavors" array |
| 144 | * no matching flavor is found in the array. The "flavors" array | ||
| 145 | * is searched in the order returned from the server, per RFC 3530 | 144 | * is searched in the order returned from the server, per RFC 3530 |
| 146 | * recommendation. | 145 | * recommendation and each flavor is checked for membership in the |
| 146 | * sec= mount option list if it exists. | ||
| 147 | * | ||
| 148 | * Return -EPERM if no matching flavor is found in the array. | ||
| 149 | * | ||
| 150 | * Please call rpc_shutdown_client() when you are done with this rpc client. | ||
| 151 | * | ||
| 147 | */ | 152 | */ |
| 148 | static rpc_authflavor_t nfs_find_best_sec(struct nfs_server *server, | 153 | static struct rpc_clnt *nfs_find_best_sec(struct rpc_clnt *clnt, |
| 154 | struct nfs_server *server, | ||
| 149 | struct nfs4_secinfo_flavors *flavors) | 155 | struct nfs4_secinfo_flavors *flavors) |
| 150 | { | 156 | { |
| 151 | rpc_authflavor_t pseudoflavor; | 157 | rpc_authflavor_t pflavor; |
| 152 | struct nfs4_secinfo4 *secinfo; | 158 | struct nfs4_secinfo4 *secinfo; |
| 153 | unsigned int i; | 159 | unsigned int i; |
| 154 | 160 | ||
| @@ -159,62 +165,73 @@ static rpc_authflavor_t nfs_find_best_sec(struct nfs_server *server, | |||
| 159 | case RPC_AUTH_NULL: | 165 | case RPC_AUTH_NULL: |
| 160 | case RPC_AUTH_UNIX: | 166 | case RPC_AUTH_UNIX: |
| 161 | case RPC_AUTH_GSS: | 167 | case RPC_AUTH_GSS: |
| 162 | pseudoflavor = rpcauth_get_pseudoflavor(secinfo->flavor, | 168 | pflavor = rpcauth_get_pseudoflavor(secinfo->flavor, |
| 163 | &secinfo->flavor_info); | 169 | &secinfo->flavor_info); |
| 164 | /* make sure pseudoflavor matches sec= mount opt */ | 170 | /* does the pseudoflavor match a sec= mount opt? */ |
| 165 | if (pseudoflavor != RPC_AUTH_MAXFLAVOR && | 171 | if (pflavor != RPC_AUTH_MAXFLAVOR && |
| 166 | nfs_auth_info_match(&server->auth_info, | 172 | nfs_auth_info_match(&server->auth_info, pflavor)) { |
| 167 | pseudoflavor)) | 173 | struct rpc_clnt *new; |
| 168 | return pseudoflavor; | 174 | struct rpc_cred *cred; |
| 169 | break; | 175 | |
| 176 | /* Cloning creates an rpc_auth for the flavor */ | ||
| 177 | new = rpc_clone_client_set_auth(clnt, pflavor); | ||
| 178 | if (IS_ERR(new)) | ||
| 179 | continue; | ||
| 180 | /** | ||
| 181 | * Check that the user actually can use the | ||
| 182 | * flavor. This is mostly for RPC_AUTH_GSS | ||
| 183 | * where cr_init obtains a gss context | ||
| 184 | */ | ||
| 185 | cred = rpcauth_lookupcred(new->cl_auth, 0); | ||
| 186 | if (IS_ERR(cred)) { | ||
| 187 | rpc_shutdown_client(new); | ||
| 188 | continue; | ||
| 189 | } | ||
| 190 | put_rpccred(cred); | ||
| 191 | return new; | ||
| 192 | } | ||
| 170 | } | 193 | } |
| 171 | } | 194 | } |
| 172 | 195 | return ERR_PTR(-EPERM); | |
| 173 | /* if there were any sec= options then nothing matched */ | ||
| 174 | if (server->auth_info.flavor_len > 0) | ||
| 175 | return -EPERM; | ||
| 176 | |||
| 177 | return RPC_AUTH_UNIX; | ||
| 178 | } | 196 | } |
| 179 | 197 | ||
| 180 | static rpc_authflavor_t nfs4_negotiate_security(struct inode *inode, struct qstr *name) | 198 | /** |
| 199 | * nfs4_negotiate_security - in response to an NFS4ERR_WRONGSEC on lookup, | ||
| 200 | * return an rpc_clnt that uses the best available security flavor with | ||
| 201 | * respect to the secinfo flavor list and the sec= mount options. | ||
| 202 | * | ||
| 203 | * @clnt: RPC client to clone | ||
| 204 | * @inode: directory inode | ||
| 205 | * @name: lookup name | ||
| 206 | * | ||
| 207 | * Please call rpc_shutdown_client() when you are done with this rpc client. | ||
| 208 | */ | ||
| 209 | struct rpc_clnt * | ||
| 210 | nfs4_negotiate_security(struct rpc_clnt *clnt, struct inode *inode, | ||
| 211 | struct qstr *name) | ||
| 181 | { | 212 | { |
| 182 | struct page *page; | 213 | struct page *page; |
| 183 | struct nfs4_secinfo_flavors *flavors; | 214 | struct nfs4_secinfo_flavors *flavors; |
| 184 | rpc_authflavor_t flavor; | 215 | struct rpc_clnt *new; |
| 185 | int err; | 216 | int err; |
| 186 | 217 | ||
| 187 | page = alloc_page(GFP_KERNEL); | 218 | page = alloc_page(GFP_KERNEL); |
| 188 | if (!page) | 219 | if (!page) |
| 189 | return -ENOMEM; | 220 | return ERR_PTR(-ENOMEM); |
| 221 | |||
| 190 | flavors = page_address(page); | 222 | flavors = page_address(page); |
| 191 | 223 | ||
| 192 | err = nfs4_proc_secinfo(inode, name, flavors); | 224 | err = nfs4_proc_secinfo(inode, name, flavors); |
| 193 | if (err < 0) { | 225 | if (err < 0) { |
| 194 | flavor = err; | 226 | new = ERR_PTR(err); |
| 195 | goto out; | 227 | goto out; |
| 196 | } | 228 | } |
| 197 | 229 | ||
| 198 | flavor = nfs_find_best_sec(NFS_SERVER(inode), flavors); | 230 | new = nfs_find_best_sec(clnt, NFS_SERVER(inode), flavors); |
| 199 | 231 | ||
| 200 | out: | 232 | out: |
| 201 | put_page(page); | 233 | put_page(page); |
| 202 | return flavor; | 234 | return new; |
| 203 | } | ||
| 204 | |||
| 205 | /* | ||
| 206 | * Please call rpc_shutdown_client() when you are done with this client. | ||
| 207 | */ | ||
| 208 | struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *clnt, struct inode *inode, | ||
| 209 | struct qstr *name) | ||
| 210 | { | ||
| 211 | rpc_authflavor_t flavor; | ||
| 212 | |||
| 213 | flavor = nfs4_negotiate_security(inode, name); | ||
| 214 | if ((int)flavor < 0) | ||
| 215 | return ERR_PTR((int)flavor); | ||
| 216 | |||
| 217 | return rpc_clone_client_set_auth(clnt, flavor); | ||
| 218 | } | 235 | } |
| 219 | 236 | ||
| 220 | static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, | 237 | static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, |
| @@ -397,11 +414,6 @@ struct vfsmount *nfs4_submount(struct nfs_server *server, struct dentry *dentry, | |||
| 397 | 414 | ||
| 398 | if (client->cl_auth->au_flavor != flavor) | 415 | if (client->cl_auth->au_flavor != flavor) |
| 399 | flavor = client->cl_auth->au_flavor; | 416 | flavor = client->cl_auth->au_flavor; |
| 400 | else { | ||
| 401 | rpc_authflavor_t new = nfs4_negotiate_security(dir, name); | ||
| 402 | if ((int)new >= 0) | ||
| 403 | flavor = new; | ||
| 404 | } | ||
| 405 | mnt = nfs_do_submount(dentry, fh, fattr, flavor); | 417 | mnt = nfs_do_submount(dentry, fh, fattr, flavor); |
| 406 | out: | 418 | out: |
| 407 | rpc_shutdown_client(client); | 419 | rpc_shutdown_client(client); |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 285ad5334018..4bf3d97cc5a0 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -3247,7 +3247,7 @@ static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir, | |||
| 3247 | err = -EPERM; | 3247 | err = -EPERM; |
| 3248 | if (client != *clnt) | 3248 | if (client != *clnt) |
| 3249 | goto out; | 3249 | goto out; |
| 3250 | client = nfs4_create_sec_client(client, dir, name); | 3250 | client = nfs4_negotiate_security(client, dir, name); |
| 3251 | if (IS_ERR(client)) | 3251 | if (IS_ERR(client)) |
| 3252 | return PTR_ERR(client); | 3252 | return PTR_ERR(client); |
| 3253 | 3253 | ||
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 3ee5af4e738e..98ff061ccaf3 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
| @@ -934,12 +934,14 @@ static bool nfs_write_pageuptodate(struct page *page, struct inode *inode) | |||
| 934 | 934 | ||
| 935 | if (nfs_have_delegated_attributes(inode)) | 935 | if (nfs_have_delegated_attributes(inode)) |
| 936 | goto out; | 936 | goto out; |
| 937 | if (nfsi->cache_validity & (NFS_INO_INVALID_DATA|NFS_INO_REVAL_PAGECACHE)) | 937 | if (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) |
| 938 | return false; | 938 | return false; |
| 939 | smp_rmb(); | 939 | smp_rmb(); |
| 940 | if (test_bit(NFS_INO_INVALIDATING, &nfsi->flags)) | 940 | if (test_bit(NFS_INO_INVALIDATING, &nfsi->flags)) |
| 941 | return false; | 941 | return false; |
| 942 | out: | 942 | out: |
| 943 | if (nfsi->cache_validity & NFS_INO_INVALID_DATA) | ||
| 944 | return false; | ||
| 943 | return PageUptodate(page) != 0; | 945 | return PageUptodate(page) != 0; |
| 944 | } | 946 | } |
| 945 | 947 | ||
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index c0d45cec9958..2204e1fe5725 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #include <linux/ratelimit.h> | 41 | #include <linux/ratelimit.h> |
| 42 | #include <linux/sunrpc/svcauth_gss.h> | 42 | #include <linux/sunrpc/svcauth_gss.h> |
| 43 | #include <linux/sunrpc/addr.h> | 43 | #include <linux/sunrpc/addr.h> |
| 44 | #include <linux/hash.h> | ||
| 44 | #include "xdr4.h" | 45 | #include "xdr4.h" |
| 45 | #include "xdr4cb.h" | 46 | #include "xdr4cb.h" |
| 46 | #include "vfs.h" | 47 | #include "vfs.h" |
| @@ -364,6 +365,79 @@ static struct nfs4_ol_stateid * nfs4_alloc_stateid(struct nfs4_client *clp) | |||
| 364 | return openlockstateid(nfs4_alloc_stid(clp, stateid_slab)); | 365 | return openlockstateid(nfs4_alloc_stid(clp, stateid_slab)); |
| 365 | } | 366 | } |
| 366 | 367 | ||
| 368 | /* | ||
| 369 | * When we recall a delegation, we should be careful not to hand it | ||
| 370 | * out again straight away. | ||
| 371 | * To ensure this we keep a pair of bloom filters ('new' and 'old') | ||
| 372 | * in which the filehandles of recalled delegations are "stored". | ||
| 373 | * If a filehandle appear in either filter, a delegation is blocked. | ||
| 374 | * When a delegation is recalled, the filehandle is stored in the "new" | ||
| 375 | * filter. | ||
| 376 | * Every 30 seconds we swap the filters and clear the "new" one, | ||
| 377 | * unless both are empty of course. | ||
| 378 | * | ||
| 379 | * Each filter is 256 bits. We hash the filehandle to 32bit and use the | ||
| 380 | * low 3 bytes as hash-table indices. | ||
| 381 | * | ||
| 382 | * 'state_lock', which is always held when block_delegations() is called, | ||
| 383 | * is used to manage concurrent access. Testing does not need the lock | ||
| 384 | * except when swapping the two filters. | ||
| 385 | */ | ||
| 386 | static struct bloom_pair { | ||
| 387 | int entries, old_entries; | ||
| 388 | time_t swap_time; | ||
| 389 | int new; /* index into 'set' */ | ||
| 390 | DECLARE_BITMAP(set[2], 256); | ||
| 391 | } blocked_delegations; | ||
| 392 | |||
| 393 | static int delegation_blocked(struct knfsd_fh *fh) | ||
| 394 | { | ||
| 395 | u32 hash; | ||
| 396 | struct bloom_pair *bd = &blocked_delegations; | ||
| 397 | |||
| 398 | if (bd->entries == 0) | ||
| 399 | return 0; | ||
| 400 | if (seconds_since_boot() - bd->swap_time > 30) { | ||
| 401 | spin_lock(&state_lock); | ||
| 402 | if (seconds_since_boot() - bd->swap_time > 30) { | ||
| 403 | bd->entries -= bd->old_entries; | ||
| 404 | bd->old_entries = bd->entries; | ||
| 405 | memset(bd->set[bd->new], 0, | ||
| 406 | sizeof(bd->set[0])); | ||
| 407 | bd->new = 1-bd->new; | ||
| 408 | bd->swap_time = seconds_since_boot(); | ||
| 409 | } | ||
| 410 | spin_unlock(&state_lock); | ||
| 411 | } | ||
| 412 | hash = arch_fast_hash(&fh->fh_base, fh->fh_size, 0); | ||
| 413 | if (test_bit(hash&255, bd->set[0]) && | ||
| 414 | test_bit((hash>>8)&255, bd->set[0]) && | ||
| 415 | test_bit((hash>>16)&255, bd->set[0])) | ||
| 416 | return 1; | ||
| 417 | |||
| 418 | if (test_bit(hash&255, bd->set[1]) && | ||
| 419 | test_bit((hash>>8)&255, bd->set[1]) && | ||
| 420 | test_bit((hash>>16)&255, bd->set[1])) | ||
| 421 | return 1; | ||
| 422 | |||
| 423 | return 0; | ||
| 424 | } | ||
| 425 | |||
| 426 | static void block_delegations(struct knfsd_fh *fh) | ||
| 427 | { | ||
| 428 | u32 hash; | ||
| 429 | struct bloom_pair *bd = &blocked_delegations; | ||
| 430 | |||
| 431 | hash = arch_fast_hash(&fh->fh_base, fh->fh_size, 0); | ||
| 432 | |||
| 433 | __set_bit(hash&255, bd->set[bd->new]); | ||
| 434 | __set_bit((hash>>8)&255, bd->set[bd->new]); | ||
| 435 | __set_bit((hash>>16)&255, bd->set[bd->new]); | ||
| 436 | if (bd->entries == 0) | ||
| 437 | bd->swap_time = seconds_since_boot(); | ||
| 438 | bd->entries += 1; | ||
| 439 | } | ||
| 440 | |||
| 367 | static struct nfs4_delegation * | 441 | static struct nfs4_delegation * |
| 368 | alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh) | 442 | alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct svc_fh *current_fh) |
| 369 | { | 443 | { |
| @@ -372,6 +446,8 @@ alloc_init_deleg(struct nfs4_client *clp, struct nfs4_ol_stateid *stp, struct sv | |||
| 372 | dprintk("NFSD alloc_init_deleg\n"); | 446 | dprintk("NFSD alloc_init_deleg\n"); |
| 373 | if (num_delegations > max_delegations) | 447 | if (num_delegations > max_delegations) |
| 374 | return NULL; | 448 | return NULL; |
| 449 | if (delegation_blocked(¤t_fh->fh_handle)) | ||
| 450 | return NULL; | ||
| 375 | dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab)); | 451 | dp = delegstateid(nfs4_alloc_stid(clp, deleg_slab)); |
| 376 | if (dp == NULL) | 452 | if (dp == NULL) |
| 377 | return dp; | 453 | return dp; |
| @@ -2770,6 +2846,8 @@ static void nfsd_break_one_deleg(struct nfs4_delegation *dp) | |||
| 2770 | /* Only place dl_time is set; protected by i_lock: */ | 2846 | /* Only place dl_time is set; protected by i_lock: */ |
| 2771 | dp->dl_time = get_seconds(); | 2847 | dp->dl_time = get_seconds(); |
| 2772 | 2848 | ||
| 2849 | block_delegations(&dp->dl_fh); | ||
| 2850 | |||
| 2773 | nfsd4_cb_recall(dp); | 2851 | nfsd4_cb_recall(dp); |
| 2774 | } | 2852 | } |
| 2775 | 2853 | ||
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 2d305a121f37..83baf2bfe9e9 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
| @@ -2687,6 +2687,7 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | |||
| 2687 | nfserr = nfserr_toosmall; | 2687 | nfserr = nfserr_toosmall; |
| 2688 | goto fail; | 2688 | goto fail; |
| 2689 | case nfserr_noent: | 2689 | case nfserr_noent: |
| 2690 | xdr_truncate_encode(xdr, start_offset); | ||
| 2690 | goto skip_entry; | 2691 | goto skip_entry; |
| 2691 | default: | 2692 | default: |
| 2692 | /* | 2693 | /* |
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index a106b3f2b22a..fae17c640df3 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h | |||
| @@ -331,6 +331,7 @@ struct dlm_lock_resource | |||
| 331 | u16 state; | 331 | u16 state; |
| 332 | char lvb[DLM_LVB_LEN]; | 332 | char lvb[DLM_LVB_LEN]; |
| 333 | unsigned int inflight_locks; | 333 | unsigned int inflight_locks; |
| 334 | unsigned int inflight_assert_workers; | ||
| 334 | unsigned long refmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; | 335 | unsigned long refmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; |
| 335 | }; | 336 | }; |
| 336 | 337 | ||
| @@ -910,6 +911,9 @@ void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm, | |||
| 910 | void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm, | 911 | void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm, |
| 911 | struct dlm_lock_resource *res); | 912 | struct dlm_lock_resource *res); |
| 912 | 913 | ||
| 914 | void __dlm_lockres_grab_inflight_worker(struct dlm_ctxt *dlm, | ||
| 915 | struct dlm_lock_resource *res); | ||
| 916 | |||
| 913 | void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock); | 917 | void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock); |
| 914 | void dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock); | 918 | void dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock); |
| 915 | void __dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock); | 919 | void __dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock); |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 3087a21d32f9..82abf0cc9a12 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
| @@ -581,6 +581,7 @@ static void dlm_init_lockres(struct dlm_ctxt *dlm, | |||
| 581 | atomic_set(&res->asts_reserved, 0); | 581 | atomic_set(&res->asts_reserved, 0); |
| 582 | res->migration_pending = 0; | 582 | res->migration_pending = 0; |
| 583 | res->inflight_locks = 0; | 583 | res->inflight_locks = 0; |
| 584 | res->inflight_assert_workers = 0; | ||
| 584 | 585 | ||
| 585 | res->dlm = dlm; | 586 | res->dlm = dlm; |
| 586 | 587 | ||
| @@ -683,6 +684,43 @@ void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm, | |||
| 683 | wake_up(&res->wq); | 684 | wake_up(&res->wq); |
| 684 | } | 685 | } |
| 685 | 686 | ||
| 687 | void __dlm_lockres_grab_inflight_worker(struct dlm_ctxt *dlm, | ||
| 688 | struct dlm_lock_resource *res) | ||
| 689 | { | ||
| 690 | assert_spin_locked(&res->spinlock); | ||
| 691 | res->inflight_assert_workers++; | ||
| 692 | mlog(0, "%s:%.*s: inflight assert worker++: now %u\n", | ||
| 693 | dlm->name, res->lockname.len, res->lockname.name, | ||
| 694 | res->inflight_assert_workers); | ||
| 695 | } | ||
| 696 | |||
| 697 | static void dlm_lockres_grab_inflight_worker(struct dlm_ctxt *dlm, | ||
| 698 | struct dlm_lock_resource *res) | ||
| 699 | { | ||
| 700 | spin_lock(&res->spinlock); | ||
| 701 | __dlm_lockres_grab_inflight_worker(dlm, res); | ||
| 702 | spin_unlock(&res->spinlock); | ||
| 703 | } | ||
| 704 | |||
| 705 | static void __dlm_lockres_drop_inflight_worker(struct dlm_ctxt *dlm, | ||
| 706 | struct dlm_lock_resource *res) | ||
| 707 | { | ||
| 708 | assert_spin_locked(&res->spinlock); | ||
| 709 | BUG_ON(res->inflight_assert_workers == 0); | ||
| 710 | res->inflight_assert_workers--; | ||
| 711 | mlog(0, "%s:%.*s: inflight assert worker--: now %u\n", | ||
| 712 | dlm->name, res->lockname.len, res->lockname.name, | ||
| 713 | res->inflight_assert_workers); | ||
| 714 | } | ||
| 715 | |||
| 716 | static void dlm_lockres_drop_inflight_worker(struct dlm_ctxt *dlm, | ||
| 717 | struct dlm_lock_resource *res) | ||
| 718 | { | ||
| 719 | spin_lock(&res->spinlock); | ||
| 720 | __dlm_lockres_drop_inflight_worker(dlm, res); | ||
| 721 | spin_unlock(&res->spinlock); | ||
| 722 | } | ||
| 723 | |||
| 686 | /* | 724 | /* |
| 687 | * lookup a lock resource by name. | 725 | * lookup a lock resource by name. |
| 688 | * may already exist in the hashtable. | 726 | * may already exist in the hashtable. |
| @@ -1603,7 +1641,8 @@ send_response: | |||
| 1603 | mlog(ML_ERROR, "failed to dispatch assert master work\n"); | 1641 | mlog(ML_ERROR, "failed to dispatch assert master work\n"); |
| 1604 | response = DLM_MASTER_RESP_ERROR; | 1642 | response = DLM_MASTER_RESP_ERROR; |
| 1605 | dlm_lockres_put(res); | 1643 | dlm_lockres_put(res); |
| 1606 | } | 1644 | } else |
| 1645 | dlm_lockres_grab_inflight_worker(dlm, res); | ||
| 1607 | } else { | 1646 | } else { |
| 1608 | if (res) | 1647 | if (res) |
| 1609 | dlm_lockres_put(res); | 1648 | dlm_lockres_put(res); |
| @@ -2118,6 +2157,8 @@ static void dlm_assert_master_worker(struct dlm_work_item *item, void *data) | |||
| 2118 | dlm_lockres_release_ast(dlm, res); | 2157 | dlm_lockres_release_ast(dlm, res); |
| 2119 | 2158 | ||
| 2120 | put: | 2159 | put: |
| 2160 | dlm_lockres_drop_inflight_worker(dlm, res); | ||
| 2161 | |||
| 2121 | dlm_lockres_put(res); | 2162 | dlm_lockres_put(res); |
| 2122 | 2163 | ||
| 2123 | mlog(0, "finished with dlm_assert_master_worker\n"); | 2164 | mlog(0, "finished with dlm_assert_master_worker\n"); |
| @@ -3088,11 +3129,15 @@ static int dlm_add_migration_mle(struct dlm_ctxt *dlm, | |||
| 3088 | /* remove it so that only one mle will be found */ | 3129 | /* remove it so that only one mle will be found */ |
| 3089 | __dlm_unlink_mle(dlm, tmp); | 3130 | __dlm_unlink_mle(dlm, tmp); |
| 3090 | __dlm_mle_detach_hb_events(dlm, tmp); | 3131 | __dlm_mle_detach_hb_events(dlm, tmp); |
| 3091 | ret = DLM_MIGRATE_RESPONSE_MASTERY_REF; | 3132 | if (tmp->type == DLM_MLE_MASTER) { |
| 3092 | mlog(0, "%s:%.*s: master=%u, newmaster=%u, " | 3133 | ret = DLM_MIGRATE_RESPONSE_MASTERY_REF; |
| 3093 | "telling master to get ref for cleared out mle " | 3134 | mlog(0, "%s:%.*s: master=%u, newmaster=%u, " |
| 3094 | "during migration\n", dlm->name, namelen, name, | 3135 | "telling master to get ref " |
| 3095 | master, new_master); | 3136 | "for cleared out mle during " |
| 3137 | "migration\n", dlm->name, | ||
| 3138 | namelen, name, master, | ||
| 3139 | new_master); | ||
| 3140 | } | ||
| 3096 | } | 3141 | } |
| 3097 | spin_unlock(&tmp->spinlock); | 3142 | spin_unlock(&tmp->spinlock); |
| 3098 | } | 3143 | } |
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 5de019437ea5..45067faf5695 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
| @@ -1708,7 +1708,8 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data, | |||
| 1708 | mlog_errno(-ENOMEM); | 1708 | mlog_errno(-ENOMEM); |
| 1709 | /* retry!? */ | 1709 | /* retry!? */ |
| 1710 | BUG(); | 1710 | BUG(); |
| 1711 | } | 1711 | } else |
| 1712 | __dlm_lockres_grab_inflight_worker(dlm, res); | ||
| 1712 | } else /* put.. incase we are not the master */ | 1713 | } else /* put.. incase we are not the master */ |
| 1713 | dlm_lockres_put(res); | 1714 | dlm_lockres_put(res); |
| 1714 | spin_unlock(&res->spinlock); | 1715 | spin_unlock(&res->spinlock); |
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index 9db869de829d..69aac6f088ad 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c | |||
| @@ -259,12 +259,15 @@ static void dlm_run_purge_list(struct dlm_ctxt *dlm, | |||
| 259 | * refs on it. */ | 259 | * refs on it. */ |
| 260 | unused = __dlm_lockres_unused(lockres); | 260 | unused = __dlm_lockres_unused(lockres); |
| 261 | if (!unused || | 261 | if (!unused || |
| 262 | (lockres->state & DLM_LOCK_RES_MIGRATING)) { | 262 | (lockres->state & DLM_LOCK_RES_MIGRATING) || |
| 263 | (lockres->inflight_assert_workers != 0)) { | ||
| 263 | mlog(0, "%s: res %.*s is in use or being remastered, " | 264 | mlog(0, "%s: res %.*s is in use or being remastered, " |
| 264 | "used %d, state %d\n", dlm->name, | 265 | "used %d, state %d, assert master workers %u\n", |
| 265 | lockres->lockname.len, lockres->lockname.name, | 266 | dlm->name, lockres->lockname.len, |
| 266 | !unused, lockres->state); | 267 | lockres->lockname.name, |
| 267 | list_move_tail(&dlm->purge_list, &lockres->purge); | 268 | !unused, lockres->state, |
| 269 | lockres->inflight_assert_workers); | ||
| 270 | list_move_tail(&lockres->purge, &dlm->purge_list); | ||
| 268 | spin_unlock(&lockres->spinlock); | 271 | spin_unlock(&lockres->spinlock); |
| 269 | continue; | 272 | continue; |
| 270 | } | 273 | } |
diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c index 5698b52cf5c9..2e3c9dbab68c 100644 --- a/fs/ocfs2/dlm/dlmunlock.c +++ b/fs/ocfs2/dlm/dlmunlock.c | |||
| @@ -191,7 +191,9 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, | |||
| 191 | DLM_UNLOCK_CLEAR_CONVERT_TYPE); | 191 | DLM_UNLOCK_CLEAR_CONVERT_TYPE); |
| 192 | } else if (status == DLM_RECOVERING || | 192 | } else if (status == DLM_RECOVERING || |
| 193 | status == DLM_MIGRATING || | 193 | status == DLM_MIGRATING || |
| 194 | status == DLM_FORWARD) { | 194 | status == DLM_FORWARD || |
| 195 | status == DLM_NOLOCKMGR | ||
| 196 | ) { | ||
| 195 | /* must clear the actions because this unlock | 197 | /* must clear the actions because this unlock |
| 196 | * is about to be retried. cannot free or do | 198 | * is about to be retried. cannot free or do |
| 197 | * any list manipulation. */ | 199 | * any list manipulation. */ |
| @@ -200,7 +202,8 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, | |||
| 200 | res->lockname.name, | 202 | res->lockname.name, |
| 201 | status==DLM_RECOVERING?"recovering": | 203 | status==DLM_RECOVERING?"recovering": |
| 202 | (status==DLM_MIGRATING?"migrating": | 204 | (status==DLM_MIGRATING?"migrating": |
| 203 | "forward")); | 205 | (status == DLM_FORWARD ? "forward" : |
| 206 | "nolockmanager"))); | ||
| 204 | actions = 0; | 207 | actions = 0; |
| 205 | } | 208 | } |
| 206 | if (flags & LKM_CANCEL) | 209 | if (flags & LKM_CANCEL) |
| @@ -364,7 +367,10 @@ static enum dlm_status dlm_send_remote_unlock_request(struct dlm_ctxt *dlm, | |||
| 364 | * updated state to the recovery master. this thread | 367 | * updated state to the recovery master. this thread |
| 365 | * just needs to finish out the operation and call | 368 | * just needs to finish out the operation and call |
| 366 | * the unlockast. */ | 369 | * the unlockast. */ |
| 367 | ret = DLM_NORMAL; | 370 | if (dlm_is_node_dead(dlm, owner)) |
| 371 | ret = DLM_NORMAL; | ||
| 372 | else | ||
| 373 | ret = DLM_NOLOCKMGR; | ||
| 368 | } else { | 374 | } else { |
| 369 | /* something bad. this will BUG in ocfs2 */ | 375 | /* something bad. this will BUG in ocfs2 */ |
| 370 | ret = dlm_err_to_dlm_status(tmpret); | 376 | ret = dlm_err_to_dlm_status(tmpret); |
| @@ -638,7 +644,9 @@ retry: | |||
| 638 | 644 | ||
| 639 | if (status == DLM_RECOVERING || | 645 | if (status == DLM_RECOVERING || |
| 640 | status == DLM_MIGRATING || | 646 | status == DLM_MIGRATING || |
| 641 | status == DLM_FORWARD) { | 647 | status == DLM_FORWARD || |
| 648 | status == DLM_NOLOCKMGR) { | ||
| 649 | |||
| 642 | /* We want to go away for a tiny bit to allow recovery | 650 | /* We want to go away for a tiny bit to allow recovery |
| 643 | * / migration to complete on this resource. I don't | 651 | * / migration to complete on this resource. I don't |
| 644 | * know of any wait queue we could sleep on as this | 652 | * know of any wait queue we could sleep on as this |
| @@ -650,7 +658,7 @@ retry: | |||
| 650 | msleep(50); | 658 | msleep(50); |
| 651 | 659 | ||
| 652 | mlog(0, "retrying unlock due to pending recovery/" | 660 | mlog(0, "retrying unlock due to pending recovery/" |
| 653 | "migration/in-progress\n"); | 661 | "migration/in-progress/reconnect\n"); |
| 654 | goto retry; | 662 | goto retry; |
| 655 | } | 663 | } |
| 656 | 664 | ||
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 2060fc398445..8add6f1030d7 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
| @@ -205,6 +205,21 @@ static struct inode *ocfs2_get_init_inode(struct inode *dir, umode_t mode) | |||
| 205 | return inode; | 205 | return inode; |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | static void ocfs2_cleanup_add_entry_failure(struct ocfs2_super *osb, | ||
| 209 | struct dentry *dentry, struct inode *inode) | ||
| 210 | { | ||
| 211 | struct ocfs2_dentry_lock *dl = dentry->d_fsdata; | ||
| 212 | |||
| 213 | ocfs2_simple_drop_lockres(osb, &dl->dl_lockres); | ||
| 214 | ocfs2_lock_res_free(&dl->dl_lockres); | ||
| 215 | BUG_ON(dl->dl_count != 1); | ||
| 216 | spin_lock(&dentry_attach_lock); | ||
| 217 | dentry->d_fsdata = NULL; | ||
| 218 | spin_unlock(&dentry_attach_lock); | ||
| 219 | kfree(dl); | ||
| 220 | iput(inode); | ||
| 221 | } | ||
| 222 | |||
| 208 | static int ocfs2_mknod(struct inode *dir, | 223 | static int ocfs2_mknod(struct inode *dir, |
| 209 | struct dentry *dentry, | 224 | struct dentry *dentry, |
| 210 | umode_t mode, | 225 | umode_t mode, |
| @@ -231,6 +246,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
| 231 | sigset_t oldset; | 246 | sigset_t oldset; |
| 232 | int did_block_signals = 0; | 247 | int did_block_signals = 0; |
| 233 | struct posix_acl *default_acl = NULL, *acl = NULL; | 248 | struct posix_acl *default_acl = NULL, *acl = NULL; |
| 249 | struct ocfs2_dentry_lock *dl = NULL; | ||
| 234 | 250 | ||
| 235 | trace_ocfs2_mknod(dir, dentry, dentry->d_name.len, dentry->d_name.name, | 251 | trace_ocfs2_mknod(dir, dentry, dentry->d_name.len, dentry->d_name.name, |
| 236 | (unsigned long long)OCFS2_I(dir)->ip_blkno, | 252 | (unsigned long long)OCFS2_I(dir)->ip_blkno, |
| @@ -423,6 +439,8 @@ static int ocfs2_mknod(struct inode *dir, | |||
| 423 | goto leave; | 439 | goto leave; |
| 424 | } | 440 | } |
| 425 | 441 | ||
| 442 | dl = dentry->d_fsdata; | ||
| 443 | |||
| 426 | status = ocfs2_add_entry(handle, dentry, inode, | 444 | status = ocfs2_add_entry(handle, dentry, inode, |
| 427 | OCFS2_I(inode)->ip_blkno, parent_fe_bh, | 445 | OCFS2_I(inode)->ip_blkno, parent_fe_bh, |
| 428 | &lookup); | 446 | &lookup); |
| @@ -469,6 +487,9 @@ leave: | |||
| 469 | * ocfs2_delete_inode will mutex_lock again. | 487 | * ocfs2_delete_inode will mutex_lock again. |
| 470 | */ | 488 | */ |
| 471 | if ((status < 0) && inode) { | 489 | if ((status < 0) && inode) { |
| 490 | if (dl) | ||
| 491 | ocfs2_cleanup_add_entry_failure(osb, dentry, inode); | ||
| 492 | |||
| 472 | OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR; | 493 | OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR; |
| 473 | clear_nlink(inode); | 494 | clear_nlink(inode); |
| 474 | iput(inode); | 495 | iput(inode); |
| @@ -991,6 +1012,65 @@ leave: | |||
| 991 | return status; | 1012 | return status; |
| 992 | } | 1013 | } |
| 993 | 1014 | ||
| 1015 | static int ocfs2_check_if_ancestor(struct ocfs2_super *osb, | ||
| 1016 | u64 src_inode_no, u64 dest_inode_no) | ||
| 1017 | { | ||
| 1018 | int ret = 0, i = 0; | ||
| 1019 | u64 parent_inode_no = 0; | ||
| 1020 | u64 child_inode_no = src_inode_no; | ||
| 1021 | struct inode *child_inode; | ||
| 1022 | |||
| 1023 | #define MAX_LOOKUP_TIMES 32 | ||
| 1024 | while (1) { | ||
| 1025 | child_inode = ocfs2_iget(osb, child_inode_no, 0, 0); | ||
| 1026 | if (IS_ERR(child_inode)) { | ||
| 1027 | ret = PTR_ERR(child_inode); | ||
| 1028 | break; | ||
| 1029 | } | ||
| 1030 | |||
| 1031 | ret = ocfs2_inode_lock(child_inode, NULL, 0); | ||
| 1032 | if (ret < 0) { | ||
| 1033 | iput(child_inode); | ||
| 1034 | if (ret != -ENOENT) | ||
| 1035 | mlog_errno(ret); | ||
| 1036 | break; | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | ret = ocfs2_lookup_ino_from_name(child_inode, "..", 2, | ||
| 1040 | &parent_inode_no); | ||
| 1041 | ocfs2_inode_unlock(child_inode, 0); | ||
| 1042 | iput(child_inode); | ||
| 1043 | if (ret < 0) { | ||
| 1044 | ret = -ENOENT; | ||
| 1045 | break; | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | if (parent_inode_no == dest_inode_no) { | ||
| 1049 | ret = 1; | ||
| 1050 | break; | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | if (parent_inode_no == osb->root_inode->i_ino) { | ||
| 1054 | ret = 0; | ||
| 1055 | break; | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | child_inode_no = parent_inode_no; | ||
| 1059 | |||
| 1060 | if (++i >= MAX_LOOKUP_TIMES) { | ||
| 1061 | mlog(ML_NOTICE, "max lookup times reached, filesystem " | ||
| 1062 | "may have nested directories, " | ||
| 1063 | "src inode: %llu, dest inode: %llu.\n", | ||
| 1064 | (unsigned long long)src_inode_no, | ||
| 1065 | (unsigned long long)dest_inode_no); | ||
| 1066 | ret = 0; | ||
| 1067 | break; | ||
| 1068 | } | ||
| 1069 | } | ||
| 1070 | |||
| 1071 | return ret; | ||
| 1072 | } | ||
| 1073 | |||
| 994 | /* | 1074 | /* |
| 995 | * The only place this should be used is rename! | 1075 | * The only place this should be used is rename! |
| 996 | * if they have the same id, then the 1st one is the only one locked. | 1076 | * if they have the same id, then the 1st one is the only one locked. |
| @@ -1002,6 +1082,7 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, | |||
| 1002 | struct inode *inode2) | 1082 | struct inode *inode2) |
| 1003 | { | 1083 | { |
| 1004 | int status; | 1084 | int status; |
| 1085 | int inode1_is_ancestor, inode2_is_ancestor; | ||
| 1005 | struct ocfs2_inode_info *oi1 = OCFS2_I(inode1); | 1086 | struct ocfs2_inode_info *oi1 = OCFS2_I(inode1); |
| 1006 | struct ocfs2_inode_info *oi2 = OCFS2_I(inode2); | 1087 | struct ocfs2_inode_info *oi2 = OCFS2_I(inode2); |
| 1007 | struct buffer_head **tmpbh; | 1088 | struct buffer_head **tmpbh; |
| @@ -1015,9 +1096,26 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, | |||
| 1015 | if (*bh2) | 1096 | if (*bh2) |
| 1016 | *bh2 = NULL; | 1097 | *bh2 = NULL; |
| 1017 | 1098 | ||
| 1018 | /* we always want to lock the one with the lower lockid first. */ | 1099 | /* we always want to lock the one with the lower lockid first. |
| 1100 | * and if they are nested, we lock ancestor first */ | ||
| 1019 | if (oi1->ip_blkno != oi2->ip_blkno) { | 1101 | if (oi1->ip_blkno != oi2->ip_blkno) { |
| 1020 | if (oi1->ip_blkno < oi2->ip_blkno) { | 1102 | inode1_is_ancestor = ocfs2_check_if_ancestor(osb, oi2->ip_blkno, |
| 1103 | oi1->ip_blkno); | ||
| 1104 | if (inode1_is_ancestor < 0) { | ||
| 1105 | status = inode1_is_ancestor; | ||
| 1106 | goto bail; | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | inode2_is_ancestor = ocfs2_check_if_ancestor(osb, oi1->ip_blkno, | ||
| 1110 | oi2->ip_blkno); | ||
| 1111 | if (inode2_is_ancestor < 0) { | ||
| 1112 | status = inode2_is_ancestor; | ||
| 1113 | goto bail; | ||
| 1114 | } | ||
| 1115 | |||
| 1116 | if ((inode1_is_ancestor == 1) || | ||
| 1117 | (oi1->ip_blkno < oi2->ip_blkno && | ||
| 1118 | inode2_is_ancestor == 0)) { | ||
| 1021 | /* switch id1 and id2 around */ | 1119 | /* switch id1 and id2 around */ |
| 1022 | tmpbh = bh2; | 1120 | tmpbh = bh2; |
| 1023 | bh2 = bh1; | 1121 | bh2 = bh1; |
| @@ -1098,6 +1196,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
| 1098 | struct ocfs2_dir_lookup_result old_entry_lookup = { NULL, }; | 1196 | struct ocfs2_dir_lookup_result old_entry_lookup = { NULL, }; |
| 1099 | struct ocfs2_dir_lookup_result orphan_insert = { NULL, }; | 1197 | struct ocfs2_dir_lookup_result orphan_insert = { NULL, }; |
| 1100 | struct ocfs2_dir_lookup_result target_insert = { NULL, }; | 1198 | struct ocfs2_dir_lookup_result target_insert = { NULL, }; |
| 1199 | bool should_add_orphan = false; | ||
| 1101 | 1200 | ||
| 1102 | /* At some point it might be nice to break this function up a | 1201 | /* At some point it might be nice to break this function up a |
| 1103 | * bit. */ | 1202 | * bit. */ |
| @@ -1134,6 +1233,21 @@ static int ocfs2_rename(struct inode *old_dir, | |||
| 1134 | goto bail; | 1233 | goto bail; |
| 1135 | } | 1234 | } |
| 1136 | rename_lock = 1; | 1235 | rename_lock = 1; |
| 1236 | |||
| 1237 | /* here we cannot guarantee the inodes haven't just been | ||
| 1238 | * changed, so check if they are nested again */ | ||
| 1239 | status = ocfs2_check_if_ancestor(osb, new_dir->i_ino, | ||
| 1240 | old_inode->i_ino); | ||
| 1241 | if (status < 0) { | ||
| 1242 | mlog_errno(status); | ||
| 1243 | goto bail; | ||
| 1244 | } else if (status == 1) { | ||
| 1245 | status = -EPERM; | ||
| 1246 | trace_ocfs2_rename_not_permitted( | ||
| 1247 | (unsigned long long)old_inode->i_ino, | ||
| 1248 | (unsigned long long)new_dir->i_ino); | ||
| 1249 | goto bail; | ||
| 1250 | } | ||
| 1137 | } | 1251 | } |
| 1138 | 1252 | ||
| 1139 | /* if old and new are the same, this'll just do one lock. */ | 1253 | /* if old and new are the same, this'll just do one lock. */ |
| @@ -1304,6 +1418,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
| 1304 | mlog_errno(status); | 1418 | mlog_errno(status); |
| 1305 | goto bail; | 1419 | goto bail; |
| 1306 | } | 1420 | } |
| 1421 | should_add_orphan = true; | ||
| 1307 | } | 1422 | } |
| 1308 | } else { | 1423 | } else { |
| 1309 | BUG_ON(new_dentry->d_parent->d_inode != new_dir); | 1424 | BUG_ON(new_dentry->d_parent->d_inode != new_dir); |
| @@ -1348,17 +1463,6 @@ static int ocfs2_rename(struct inode *old_dir, | |||
| 1348 | goto bail; | 1463 | goto bail; |
| 1349 | } | 1464 | } |
| 1350 | 1465 | ||
| 1351 | if (S_ISDIR(new_inode->i_mode) || | ||
| 1352 | (ocfs2_read_links_count(newfe) == 1)) { | ||
| 1353 | status = ocfs2_orphan_add(osb, handle, new_inode, | ||
| 1354 | newfe_bh, orphan_name, | ||
| 1355 | &orphan_insert, orphan_dir); | ||
| 1356 | if (status < 0) { | ||
| 1357 | mlog_errno(status); | ||
| 1358 | goto bail; | ||
| 1359 | } | ||
| 1360 | } | ||
| 1361 | |||
| 1362 | /* change the dirent to point to the correct inode */ | 1466 | /* change the dirent to point to the correct inode */ |
| 1363 | status = ocfs2_update_entry(new_dir, handle, &target_lookup_res, | 1467 | status = ocfs2_update_entry(new_dir, handle, &target_lookup_res, |
| 1364 | old_inode); | 1468 | old_inode); |
| @@ -1373,6 +1477,15 @@ static int ocfs2_rename(struct inode *old_dir, | |||
| 1373 | else | 1477 | else |
| 1374 | ocfs2_add_links_count(newfe, -1); | 1478 | ocfs2_add_links_count(newfe, -1); |
| 1375 | ocfs2_journal_dirty(handle, newfe_bh); | 1479 | ocfs2_journal_dirty(handle, newfe_bh); |
| 1480 | if (should_add_orphan) { | ||
| 1481 | status = ocfs2_orphan_add(osb, handle, new_inode, | ||
| 1482 | newfe_bh, orphan_name, | ||
| 1483 | &orphan_insert, orphan_dir); | ||
| 1484 | if (status < 0) { | ||
| 1485 | mlog_errno(status); | ||
| 1486 | goto bail; | ||
| 1487 | } | ||
| 1488 | } | ||
| 1376 | } else { | 1489 | } else { |
| 1377 | /* if the name was not found in new_dir, add it now */ | 1490 | /* if the name was not found in new_dir, add it now */ |
| 1378 | status = ocfs2_add_entry(handle, new_dentry, old_inode, | 1491 | status = ocfs2_add_entry(handle, new_dentry, old_inode, |
| @@ -1642,6 +1755,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
| 1642 | struct ocfs2_dir_lookup_result lookup = { NULL, }; | 1755 | struct ocfs2_dir_lookup_result lookup = { NULL, }; |
| 1643 | sigset_t oldset; | 1756 | sigset_t oldset; |
| 1644 | int did_block_signals = 0; | 1757 | int did_block_signals = 0; |
| 1758 | struct ocfs2_dentry_lock *dl = NULL; | ||
| 1645 | 1759 | ||
| 1646 | trace_ocfs2_symlink_begin(dir, dentry, symname, | 1760 | trace_ocfs2_symlink_begin(dir, dentry, symname, |
| 1647 | dentry->d_name.len, dentry->d_name.name); | 1761 | dentry->d_name.len, dentry->d_name.name); |
| @@ -1830,6 +1944,8 @@ static int ocfs2_symlink(struct inode *dir, | |||
| 1830 | goto bail; | 1944 | goto bail; |
| 1831 | } | 1945 | } |
| 1832 | 1946 | ||
| 1947 | dl = dentry->d_fsdata; | ||
| 1948 | |||
| 1833 | status = ocfs2_add_entry(handle, dentry, inode, | 1949 | status = ocfs2_add_entry(handle, dentry, inode, |
| 1834 | le64_to_cpu(fe->i_blkno), parent_fe_bh, | 1950 | le64_to_cpu(fe->i_blkno), parent_fe_bh, |
| 1835 | &lookup); | 1951 | &lookup); |
| @@ -1864,6 +1980,9 @@ bail: | |||
| 1864 | if (xattr_ac) | 1980 | if (xattr_ac) |
| 1865 | ocfs2_free_alloc_context(xattr_ac); | 1981 | ocfs2_free_alloc_context(xattr_ac); |
| 1866 | if ((status < 0) && inode) { | 1982 | if ((status < 0) && inode) { |
| 1983 | if (dl) | ||
| 1984 | ocfs2_cleanup_add_entry_failure(osb, dentry, inode); | ||
| 1985 | |||
| 1867 | OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR; | 1986 | OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR; |
| 1868 | clear_nlink(inode); | 1987 | clear_nlink(inode); |
| 1869 | iput(inode); | 1988 | iput(inode); |
diff --git a/fs/ocfs2/ocfs2_trace.h b/fs/ocfs2/ocfs2_trace.h index 1b60c62aa9d6..6cb019b7c6a8 100644 --- a/fs/ocfs2/ocfs2_trace.h +++ b/fs/ocfs2/ocfs2_trace.h | |||
| @@ -2292,6 +2292,8 @@ TRACE_EVENT(ocfs2_rename, | |||
| 2292 | __entry->new_len, __get_str(new_name)) | 2292 | __entry->new_len, __get_str(new_name)) |
| 2293 | ); | 2293 | ); |
| 2294 | 2294 | ||
| 2295 | DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_rename_not_permitted); | ||
| 2296 | |||
| 2295 | TRACE_EVENT(ocfs2_rename_target_exists, | 2297 | TRACE_EVENT(ocfs2_rename_target_exists, |
| 2296 | TP_PROTO(int new_len, const char *new_name), | 2298 | TP_PROTO(int new_len, const char *new_name), |
| 2297 | TP_ARGS(new_len, new_name), | 2299 | TP_ARGS(new_len, new_name), |
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 714e53b9cc66..636aab69ead5 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
| @@ -4288,9 +4288,16 @@ static int ocfs2_reflink(struct dentry *old_dentry, struct inode *dir, | |||
| 4288 | goto out; | 4288 | goto out; |
| 4289 | } | 4289 | } |
| 4290 | 4290 | ||
| 4291 | error = ocfs2_rw_lock(inode, 1); | ||
| 4292 | if (error) { | ||
| 4293 | mlog_errno(error); | ||
| 4294 | goto out; | ||
| 4295 | } | ||
| 4296 | |||
| 4291 | error = ocfs2_inode_lock(inode, &old_bh, 1); | 4297 | error = ocfs2_inode_lock(inode, &old_bh, 1); |
| 4292 | if (error) { | 4298 | if (error) { |
| 4293 | mlog_errno(error); | 4299 | mlog_errno(error); |
| 4300 | ocfs2_rw_unlock(inode, 1); | ||
| 4294 | goto out; | 4301 | goto out; |
| 4295 | } | 4302 | } |
| 4296 | 4303 | ||
| @@ -4302,6 +4309,7 @@ static int ocfs2_reflink(struct dentry *old_dentry, struct inode *dir, | |||
| 4302 | up_write(&OCFS2_I(inode)->ip_xattr_sem); | 4309 | up_write(&OCFS2_I(inode)->ip_xattr_sem); |
| 4303 | 4310 | ||
| 4304 | ocfs2_inode_unlock(inode, 1); | 4311 | ocfs2_inode_unlock(inode, 1); |
| 4312 | ocfs2_rw_unlock(inode, 1); | ||
| 4305 | brelse(old_bh); | 4313 | brelse(old_bh); |
| 4306 | 4314 | ||
| 4307 | if (error) { | 4315 | if (error) { |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index c7a89cea5c5d..ddb662b32447 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
| @@ -1925,15 +1925,11 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) | |||
| 1925 | 1925 | ||
| 1926 | ocfs2_shutdown_local_alloc(osb); | 1926 | ocfs2_shutdown_local_alloc(osb); |
| 1927 | 1927 | ||
| 1928 | ocfs2_truncate_log_shutdown(osb); | ||
| 1929 | |||
| 1928 | /* This will disable recovery and flush any recovery work. */ | 1930 | /* This will disable recovery and flush any recovery work. */ |
| 1929 | ocfs2_recovery_exit(osb); | 1931 | ocfs2_recovery_exit(osb); |
| 1930 | 1932 | ||
| 1931 | /* | ||
| 1932 | * During dismount, when it recovers another node it will call | ||
| 1933 | * ocfs2_recover_orphans and queue delayed work osb_truncate_log_wq. | ||
| 1934 | */ | ||
| 1935 | ocfs2_truncate_log_shutdown(osb); | ||
| 1936 | |||
| 1937 | ocfs2_journal_shutdown(osb); | 1933 | ocfs2_journal_shutdown(osb); |
| 1938 | 1934 | ||
| 1939 | ocfs2_sync_blockdev(sb); | 1935 | ocfs2_sync_blockdev(sb); |
