diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-12-12 18:19:40 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-12-12 18:19:53 -0500 |
commit | 007d00d4c11b30b8fd7ff23b9d5aed3743e41f74 (patch) | |
tree | d5c307ba2ee0e2f56fbc284db21b8bccf95d8a40 /fs | |
parent | c91043adaf50ef13609003120f3471783460fb71 (diff) | |
parent | 68d3e668d245bb8300c7c6ddbc8508ddfe352e0f (diff) |
Merge branch 'for-next/dwc3' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
* 'for-next/dwc3' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb: (392 commits)
usb: dwc3: ep0: fix for possible early delayed_status
usb: dwc3: gadget: fix stream enable bit
usb: dwc3: ep0: fix GetStatus handling (again)
usb: dwc3: ep0: use dwc3_request for ep0 requsts instead of usb_request
usb: dwc3: use correct hwparam register for power mgm check
usb: dwc3: omap: move to module_platform_driver
usb: dwc3: workaround: missing disconnect event
usb: dwc3: workaround: missing USB3 Reset event
usb: dwc3: workaround: U1/U2 -> U0 transiton
usb: dwc3: gadget: return early in dwc3_cleanup_done_reqs()
usb: dwc3: ep0: handle delayed_status again
usb: dwc3: ep0: push ep0state into xfernotready processing
usb: dwc3: fix sparse errors
usb: dwc3: fix few coding style problems
usb: dwc3: move generic dwc3 code from gadget into core
usb: dwc3: use a helper function for operation mode setting
usb: dwc3: ep0: don't use ep0in for transfers
usb: dwc3: ep0: use proper endianess in SetFeature for wIndex
usb: dwc3: core: drop DWC3_EVENT_BUFFERS_MAX
usb: dwc3: omap: add multiple instances support to OMAP
...
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 100 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 24 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 2 | ||||
-rw-r--r-- | fs/cifs/connect.c | 2 | ||||
-rw-r--r-- | fs/cifs/file.c | 26 | ||||
-rw-r--r-- | fs/cifs/readdir.c | 10 | ||||
-rw-r--r-- | fs/cifs/smbencrypt.c | 6 | ||||
-rw-r--r-- | fs/dcache.c | 71 | ||||
-rw-r--r-- | fs/namespace.c | 20 | ||||
-rw-r--r-- | fs/proc/meminfo.c | 7 | ||||
-rw-r--r-- | fs/proc/stat.c | 4 | ||||
-rw-r--r-- | fs/seq_file.c | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_acl.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_attr_leaf.c | 64 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.c | 20 | ||||
-rw-r--r-- | fs/xfs/xfs_export.c | 8 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 21 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_log.c | 348 | ||||
-rw-r--r-- | fs/xfs/xfs_sync.c | 11 | ||||
-rw-r--r-- | fs/xfs/xfs_trace.h | 12 |
21 files changed, 443 insertions, 322 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index f0d5718d2587..2ad813674d77 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -5107,11 +5107,11 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
5107 | struct btrfs_root *root = orig_root->fs_info->extent_root; | 5107 | struct btrfs_root *root = orig_root->fs_info->extent_root; |
5108 | struct btrfs_free_cluster *last_ptr = NULL; | 5108 | struct btrfs_free_cluster *last_ptr = NULL; |
5109 | struct btrfs_block_group_cache *block_group = NULL; | 5109 | struct btrfs_block_group_cache *block_group = NULL; |
5110 | struct btrfs_block_group_cache *used_block_group; | ||
5110 | int empty_cluster = 2 * 1024 * 1024; | 5111 | int empty_cluster = 2 * 1024 * 1024; |
5111 | int allowed_chunk_alloc = 0; | 5112 | int allowed_chunk_alloc = 0; |
5112 | int done_chunk_alloc = 0; | 5113 | int done_chunk_alloc = 0; |
5113 | struct btrfs_space_info *space_info; | 5114 | struct btrfs_space_info *space_info; |
5114 | int last_ptr_loop = 0; | ||
5115 | int loop = 0; | 5115 | int loop = 0; |
5116 | int index = 0; | 5116 | int index = 0; |
5117 | int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? | 5117 | int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? |
@@ -5173,6 +5173,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
5173 | ideal_cache: | 5173 | ideal_cache: |
5174 | block_group = btrfs_lookup_block_group(root->fs_info, | 5174 | block_group = btrfs_lookup_block_group(root->fs_info, |
5175 | search_start); | 5175 | search_start); |
5176 | used_block_group = block_group; | ||
5176 | /* | 5177 | /* |
5177 | * we don't want to use the block group if it doesn't match our | 5178 | * we don't want to use the block group if it doesn't match our |
5178 | * allocation bits, or if its not cached. | 5179 | * allocation bits, or if its not cached. |
@@ -5210,6 +5211,7 @@ search: | |||
5210 | u64 offset; | 5211 | u64 offset; |
5211 | int cached; | 5212 | int cached; |
5212 | 5213 | ||
5214 | used_block_group = block_group; | ||
5213 | btrfs_get_block_group(block_group); | 5215 | btrfs_get_block_group(block_group); |
5214 | search_start = block_group->key.objectid; | 5216 | search_start = block_group->key.objectid; |
5215 | 5217 | ||
@@ -5286,71 +5288,62 @@ alloc: | |||
5286 | spin_unlock(&block_group->free_space_ctl->tree_lock); | 5288 | spin_unlock(&block_group->free_space_ctl->tree_lock); |
5287 | 5289 | ||
5288 | /* | 5290 | /* |
5289 | * Ok we want to try and use the cluster allocator, so lets look | 5291 | * Ok we want to try and use the cluster allocator, so |
5290 | * there, unless we are on LOOP_NO_EMPTY_SIZE, since we will | 5292 | * lets look there |
5291 | * have tried the cluster allocator plenty of times at this | ||
5292 | * point and not have found anything, so we are likely way too | ||
5293 | * fragmented for the clustering stuff to find anything, so lets | ||
5294 | * just skip it and let the allocator find whatever block it can | ||
5295 | * find | ||
5296 | */ | 5293 | */ |
5297 | if (last_ptr && loop < LOOP_NO_EMPTY_SIZE) { | 5294 | if (last_ptr) { |
5298 | /* | 5295 | /* |
5299 | * the refill lock keeps out other | 5296 | * the refill lock keeps out other |
5300 | * people trying to start a new cluster | 5297 | * people trying to start a new cluster |
5301 | */ | 5298 | */ |
5302 | spin_lock(&last_ptr->refill_lock); | 5299 | spin_lock(&last_ptr->refill_lock); |
5303 | if (!last_ptr->block_group || | 5300 | used_block_group = last_ptr->block_group; |
5304 | last_ptr->block_group->ro || | 5301 | if (used_block_group != block_group && |
5305 | !block_group_bits(last_ptr->block_group, data)) | 5302 | (!used_block_group || |
5303 | used_block_group->ro || | ||
5304 | !block_group_bits(used_block_group, data))) { | ||
5305 | used_block_group = block_group; | ||
5306 | goto refill_cluster; | 5306 | goto refill_cluster; |
5307 | } | ||
5308 | |||
5309 | if (used_block_group != block_group) | ||
5310 | btrfs_get_block_group(used_block_group); | ||
5307 | 5311 | ||
5308 | offset = btrfs_alloc_from_cluster(block_group, last_ptr, | 5312 | offset = btrfs_alloc_from_cluster(used_block_group, |
5309 | num_bytes, search_start); | 5313 | last_ptr, num_bytes, used_block_group->key.objectid); |
5310 | if (offset) { | 5314 | if (offset) { |
5311 | /* we have a block, we're done */ | 5315 | /* we have a block, we're done */ |
5312 | spin_unlock(&last_ptr->refill_lock); | 5316 | spin_unlock(&last_ptr->refill_lock); |
5313 | goto checks; | 5317 | goto checks; |
5314 | } | 5318 | } |
5315 | 5319 | ||
5316 | spin_lock(&last_ptr->lock); | 5320 | WARN_ON(last_ptr->block_group != used_block_group); |
5317 | /* | 5321 | if (used_block_group != block_group) { |
5318 | * whoops, this cluster doesn't actually point to | 5322 | btrfs_put_block_group(used_block_group); |
5319 | * this block group. Get a ref on the block | 5323 | used_block_group = block_group; |
5320 | * group is does point to and try again | ||
5321 | */ | ||
5322 | if (!last_ptr_loop && last_ptr->block_group && | ||
5323 | last_ptr->block_group != block_group && | ||
5324 | index <= | ||
5325 | get_block_group_index(last_ptr->block_group)) { | ||
5326 | |||
5327 | btrfs_put_block_group(block_group); | ||
5328 | block_group = last_ptr->block_group; | ||
5329 | btrfs_get_block_group(block_group); | ||
5330 | spin_unlock(&last_ptr->lock); | ||
5331 | spin_unlock(&last_ptr->refill_lock); | ||
5332 | |||
5333 | last_ptr_loop = 1; | ||
5334 | search_start = block_group->key.objectid; | ||
5335 | /* | ||
5336 | * we know this block group is properly | ||
5337 | * in the list because | ||
5338 | * btrfs_remove_block_group, drops the | ||
5339 | * cluster before it removes the block | ||
5340 | * group from the list | ||
5341 | */ | ||
5342 | goto have_block_group; | ||
5343 | } | 5324 | } |
5344 | spin_unlock(&last_ptr->lock); | ||
5345 | refill_cluster: | 5325 | refill_cluster: |
5326 | BUG_ON(used_block_group != block_group); | ||
5327 | /* If we are on LOOP_NO_EMPTY_SIZE, we can't | ||
5328 | * set up a new clusters, so lets just skip it | ||
5329 | * and let the allocator find whatever block | ||
5330 | * it can find. If we reach this point, we | ||
5331 | * will have tried the cluster allocator | ||
5332 | * plenty of times and not have found | ||
5333 | * anything, so we are likely way too | ||
5334 | * fragmented for the clustering stuff to find | ||
5335 | * anything. */ | ||
5336 | if (loop >= LOOP_NO_EMPTY_SIZE) { | ||
5337 | spin_unlock(&last_ptr->refill_lock); | ||
5338 | goto unclustered_alloc; | ||
5339 | } | ||
5340 | |||
5346 | /* | 5341 | /* |
5347 | * this cluster didn't work out, free it and | 5342 | * this cluster didn't work out, free it and |
5348 | * start over | 5343 | * start over |
5349 | */ | 5344 | */ |
5350 | btrfs_return_cluster_to_free_space(NULL, last_ptr); | 5345 | btrfs_return_cluster_to_free_space(NULL, last_ptr); |
5351 | 5346 | ||
5352 | last_ptr_loop = 0; | ||
5353 | |||
5354 | /* allocate a cluster in this block group */ | 5347 | /* allocate a cluster in this block group */ |
5355 | ret = btrfs_find_space_cluster(trans, root, | 5348 | ret = btrfs_find_space_cluster(trans, root, |
5356 | block_group, last_ptr, | 5349 | block_group, last_ptr, |
@@ -5390,6 +5383,7 @@ refill_cluster: | |||
5390 | goto loop; | 5383 | goto loop; |
5391 | } | 5384 | } |
5392 | 5385 | ||
5386 | unclustered_alloc: | ||
5393 | offset = btrfs_find_space_for_alloc(block_group, search_start, | 5387 | offset = btrfs_find_space_for_alloc(block_group, search_start, |
5394 | num_bytes, empty_size); | 5388 | num_bytes, empty_size); |
5395 | /* | 5389 | /* |
@@ -5416,14 +5410,14 @@ checks: | |||
5416 | search_start = stripe_align(root, offset); | 5410 | search_start = stripe_align(root, offset); |
5417 | /* move on to the next group */ | 5411 | /* move on to the next group */ |
5418 | if (search_start + num_bytes >= search_end) { | 5412 | if (search_start + num_bytes >= search_end) { |
5419 | btrfs_add_free_space(block_group, offset, num_bytes); | 5413 | btrfs_add_free_space(used_block_group, offset, num_bytes); |
5420 | goto loop; | 5414 | goto loop; |
5421 | } | 5415 | } |
5422 | 5416 | ||
5423 | /* move on to the next group */ | 5417 | /* move on to the next group */ |
5424 | if (search_start + num_bytes > | 5418 | if (search_start + num_bytes > |
5425 | block_group->key.objectid + block_group->key.offset) { | 5419 | used_block_group->key.objectid + used_block_group->key.offset) { |
5426 | btrfs_add_free_space(block_group, offset, num_bytes); | 5420 | btrfs_add_free_space(used_block_group, offset, num_bytes); |
5427 | goto loop; | 5421 | goto loop; |
5428 | } | 5422 | } |
5429 | 5423 | ||
@@ -5431,14 +5425,14 @@ checks: | |||
5431 | ins->offset = num_bytes; | 5425 | ins->offset = num_bytes; |
5432 | 5426 | ||
5433 | if (offset < search_start) | 5427 | if (offset < search_start) |
5434 | btrfs_add_free_space(block_group, offset, | 5428 | btrfs_add_free_space(used_block_group, offset, |
5435 | search_start - offset); | 5429 | search_start - offset); |
5436 | BUG_ON(offset > search_start); | 5430 | BUG_ON(offset > search_start); |
5437 | 5431 | ||
5438 | ret = btrfs_update_reserved_bytes(block_group, num_bytes, | 5432 | ret = btrfs_update_reserved_bytes(used_block_group, num_bytes, |
5439 | alloc_type); | 5433 | alloc_type); |
5440 | if (ret == -EAGAIN) { | 5434 | if (ret == -EAGAIN) { |
5441 | btrfs_add_free_space(block_group, offset, num_bytes); | 5435 | btrfs_add_free_space(used_block_group, offset, num_bytes); |
5442 | goto loop; | 5436 | goto loop; |
5443 | } | 5437 | } |
5444 | 5438 | ||
@@ -5447,15 +5441,19 @@ checks: | |||
5447 | ins->offset = num_bytes; | 5441 | ins->offset = num_bytes; |
5448 | 5442 | ||
5449 | if (offset < search_start) | 5443 | if (offset < search_start) |
5450 | btrfs_add_free_space(block_group, offset, | 5444 | btrfs_add_free_space(used_block_group, offset, |
5451 | search_start - offset); | 5445 | search_start - offset); |
5452 | BUG_ON(offset > search_start); | 5446 | BUG_ON(offset > search_start); |
5447 | if (used_block_group != block_group) | ||
5448 | btrfs_put_block_group(used_block_group); | ||
5453 | btrfs_put_block_group(block_group); | 5449 | btrfs_put_block_group(block_group); |
5454 | break; | 5450 | break; |
5455 | loop: | 5451 | loop: |
5456 | failed_cluster_refill = false; | 5452 | failed_cluster_refill = false; |
5457 | failed_alloc = false; | 5453 | failed_alloc = false; |
5458 | BUG_ON(index != get_block_group_index(block_group)); | 5454 | BUG_ON(index != get_block_group_index(block_group)); |
5455 | if (used_block_group != block_group) | ||
5456 | btrfs_put_block_group(used_block_group); | ||
5459 | btrfs_put_block_group(block_group); | 5457 | btrfs_put_block_group(block_group); |
5460 | } | 5458 | } |
5461 | up_read(&space_info->groups_sem); | 5459 | up_read(&space_info->groups_sem); |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index be1bf627a14b..49f3c9dc09f4 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -935,8 +935,10 @@ again: | |||
935 | node = tree_search(tree, start); | 935 | node = tree_search(tree, start); |
936 | if (!node) { | 936 | if (!node) { |
937 | prealloc = alloc_extent_state_atomic(prealloc); | 937 | prealloc = alloc_extent_state_atomic(prealloc); |
938 | if (!prealloc) | 938 | if (!prealloc) { |
939 | return -ENOMEM; | 939 | err = -ENOMEM; |
940 | goto out; | ||
941 | } | ||
940 | err = insert_state(tree, prealloc, start, end, &bits); | 942 | err = insert_state(tree, prealloc, start, end, &bits); |
941 | prealloc = NULL; | 943 | prealloc = NULL; |
942 | BUG_ON(err == -EEXIST); | 944 | BUG_ON(err == -EEXIST); |
@@ -992,8 +994,10 @@ hit_next: | |||
992 | */ | 994 | */ |
993 | if (state->start < start) { | 995 | if (state->start < start) { |
994 | prealloc = alloc_extent_state_atomic(prealloc); | 996 | prealloc = alloc_extent_state_atomic(prealloc); |
995 | if (!prealloc) | 997 | if (!prealloc) { |
996 | return -ENOMEM; | 998 | err = -ENOMEM; |
999 | goto out; | ||
1000 | } | ||
997 | err = split_state(tree, state, prealloc, start); | 1001 | err = split_state(tree, state, prealloc, start); |
998 | BUG_ON(err == -EEXIST); | 1002 | BUG_ON(err == -EEXIST); |
999 | prealloc = NULL; | 1003 | prealloc = NULL; |
@@ -1024,8 +1028,10 @@ hit_next: | |||
1024 | this_end = last_start - 1; | 1028 | this_end = last_start - 1; |
1025 | 1029 | ||
1026 | prealloc = alloc_extent_state_atomic(prealloc); | 1030 | prealloc = alloc_extent_state_atomic(prealloc); |
1027 | if (!prealloc) | 1031 | if (!prealloc) { |
1028 | return -ENOMEM; | 1032 | err = -ENOMEM; |
1033 | goto out; | ||
1034 | } | ||
1029 | 1035 | ||
1030 | /* | 1036 | /* |
1031 | * Avoid to free 'prealloc' if it can be merged with | 1037 | * Avoid to free 'prealloc' if it can be merged with |
@@ -1051,8 +1057,10 @@ hit_next: | |||
1051 | */ | 1057 | */ |
1052 | if (state->start <= end && state->end > end) { | 1058 | if (state->start <= end && state->end > end) { |
1053 | prealloc = alloc_extent_state_atomic(prealloc); | 1059 | prealloc = alloc_extent_state_atomic(prealloc); |
1054 | if (!prealloc) | 1060 | if (!prealloc) { |
1055 | return -ENOMEM; | 1061 | err = -ENOMEM; |
1062 | goto out; | ||
1063 | } | ||
1056 | 1064 | ||
1057 | err = split_state(tree, state, prealloc, end + 1); | 1065 | err = split_state(tree, state, prealloc, end + 1); |
1058 | BUG_ON(err == -EEXIST); | 1066 | BUG_ON(err == -EEXIST); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index c37433d3cd82..0a8c8f8304b1 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1611,7 +1611,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1611 | if ((sb->s_flags & MS_RDONLY) && !root->fs_info->fs_devices->seeding) | 1611 | if ((sb->s_flags & MS_RDONLY) && !root->fs_info->fs_devices->seeding) |
1612 | return -EINVAL; | 1612 | return -EINVAL; |
1613 | 1613 | ||
1614 | bdev = blkdev_get_by_path(device_path, FMODE_EXCL, | 1614 | bdev = blkdev_get_by_path(device_path, FMODE_WRITE | FMODE_EXCL, |
1615 | root->fs_info->bdev_holder); | 1615 | root->fs_info->bdev_holder); |
1616 | if (IS_ERR(bdev)) | 1616 | if (IS_ERR(bdev)) |
1617 | return PTR_ERR(bdev); | 1617 | return PTR_ERR(bdev); |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index d6a972df0338..8cd4b52d4217 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -441,6 +441,8 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig, | |||
441 | smb_msg.msg_controllen = 0; | 441 | smb_msg.msg_controllen = 0; |
442 | 442 | ||
443 | for (total_read = 0; to_read; total_read += length, to_read -= length) { | 443 | for (total_read = 0; to_read; total_read += length, to_read -= length) { |
444 | try_to_freeze(); | ||
445 | |||
444 | if (server_unresponsive(server)) { | 446 | if (server_unresponsive(server)) { |
445 | total_read = -EAGAIN; | 447 | total_read = -EAGAIN; |
446 | break; | 448 | break; |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index cf0b1539b321..4dd9283885e7 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -702,6 +702,13 @@ cifs_find_lock_conflict(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock, | |||
702 | lock->type, lock->netfid, conf_lock); | 702 | lock->type, lock->netfid, conf_lock); |
703 | } | 703 | } |
704 | 704 | ||
705 | /* | ||
706 | * Check if there is another lock that prevents us to set the lock (mandatory | ||
707 | * style). If such a lock exists, update the flock structure with its | ||
708 | * properties. Otherwise, set the flock type to F_UNLCK if we can cache brlocks | ||
709 | * or leave it the same if we can't. Returns 0 if we don't need to request to | ||
710 | * the server or 1 otherwise. | ||
711 | */ | ||
705 | static int | 712 | static int |
706 | cifs_lock_test(struct cifsInodeInfo *cinode, __u64 offset, __u64 length, | 713 | cifs_lock_test(struct cifsInodeInfo *cinode, __u64 offset, __u64 length, |
707 | __u8 type, __u16 netfid, struct file_lock *flock) | 714 | __u8 type, __u16 netfid, struct file_lock *flock) |
@@ -739,6 +746,12 @@ cifs_lock_add(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock) | |||
739 | mutex_unlock(&cinode->lock_mutex); | 746 | mutex_unlock(&cinode->lock_mutex); |
740 | } | 747 | } |
741 | 748 | ||
749 | /* | ||
750 | * Set the byte-range lock (mandatory style). Returns: | ||
751 | * 1) 0, if we set the lock and don't need to request to the server; | ||
752 | * 2) 1, if no locks prevent us but we need to request to the server; | ||
753 | * 3) -EACCESS, if there is a lock that prevents us and wait is false. | ||
754 | */ | ||
742 | static int | 755 | static int |
743 | cifs_lock_add_if(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock, | 756 | cifs_lock_add_if(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock, |
744 | bool wait) | 757 | bool wait) |
@@ -778,6 +791,13 @@ try_again: | |||
778 | return rc; | 791 | return rc; |
779 | } | 792 | } |
780 | 793 | ||
794 | /* | ||
795 | * Check if there is another lock that prevents us to set the lock (posix | ||
796 | * style). If such a lock exists, update the flock structure with its | ||
797 | * properties. Otherwise, set the flock type to F_UNLCK if we can cache brlocks | ||
798 | * or leave it the same if we can't. Returns 0 if we don't need to request to | ||
799 | * the server or 1 otherwise. | ||
800 | */ | ||
781 | static int | 801 | static int |
782 | cifs_posix_lock_test(struct file *file, struct file_lock *flock) | 802 | cifs_posix_lock_test(struct file *file, struct file_lock *flock) |
783 | { | 803 | { |
@@ -800,6 +820,12 @@ cifs_posix_lock_test(struct file *file, struct file_lock *flock) | |||
800 | return rc; | 820 | return rc; |
801 | } | 821 | } |
802 | 822 | ||
823 | /* | ||
824 | * Set the byte-range lock (posix style). Returns: | ||
825 | * 1) 0, if we set the lock and don't need to request to the server; | ||
826 | * 2) 1, if we need to request to the server; | ||
827 | * 3) <0, if the error occurs while setting the lock. | ||
828 | */ | ||
803 | static int | 829 | static int |
804 | cifs_posix_lock_set(struct file *file, struct file_lock *flock) | 830 | cifs_posix_lock_set(struct file *file, struct file_lock *flock) |
805 | { | 831 | { |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 5de03ec20144..a090bbe6ee29 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -554,7 +554,10 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon, | |||
554 | rc); | 554 | rc); |
555 | return rc; | 555 | return rc; |
556 | } | 556 | } |
557 | cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile); | 557 | /* FindFirst/Next set last_entry to NULL on malformed reply */ |
558 | if (cifsFile->srch_inf.last_entry) | ||
559 | cifs_save_resume_key(cifsFile->srch_inf.last_entry, | ||
560 | cifsFile); | ||
558 | } | 561 | } |
559 | 562 | ||
560 | while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && | 563 | while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && |
@@ -562,7 +565,10 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon, | |||
562 | cFYI(1, "calling findnext2"); | 565 | cFYI(1, "calling findnext2"); |
563 | rc = CIFSFindNext(xid, pTcon, cifsFile->netfid, | 566 | rc = CIFSFindNext(xid, pTcon, cifsFile->netfid, |
564 | &cifsFile->srch_inf); | 567 | &cifsFile->srch_inf); |
565 | cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile); | 568 | /* FindFirst/Next set last_entry to NULL on malformed reply */ |
569 | if (cifsFile->srch_inf.last_entry) | ||
570 | cifs_save_resume_key(cifsFile->srch_inf.last_entry, | ||
571 | cifsFile); | ||
566 | if (rc) | 572 | if (rc) |
567 | return -ENOENT; | 573 | return -ENOENT; |
568 | } | 574 | } |
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c index 7cacba12b8f1..80d850881938 100644 --- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c | |||
@@ -209,7 +209,7 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16, | |||
209 | { | 209 | { |
210 | int rc; | 210 | int rc; |
211 | int len; | 211 | int len; |
212 | __u16 wpwd[129]; | 212 | __le16 wpwd[129]; |
213 | 213 | ||
214 | /* Password cannot be longer than 128 characters */ | 214 | /* Password cannot be longer than 128 characters */ |
215 | if (passwd) /* Password must be converted to NT unicode */ | 215 | if (passwd) /* Password must be converted to NT unicode */ |
@@ -219,8 +219,8 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16, | |||
219 | *wpwd = 0; /* Ensure string is null terminated */ | 219 | *wpwd = 0; /* Ensure string is null terminated */ |
220 | } | 220 | } |
221 | 221 | ||
222 | rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__u16)); | 222 | rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__le16)); |
223 | memset(wpwd, 0, 129 * sizeof(__u16)); | 223 | memset(wpwd, 0, 129 * sizeof(__le16)); |
224 | 224 | ||
225 | return rc; | 225 | return rc; |
226 | } | 226 | } |
diff --git a/fs/dcache.c b/fs/dcache.c index 10ba92def3f6..89509b5a090e 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -2439,16 +2439,14 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name) | |||
2439 | /** | 2439 | /** |
2440 | * prepend_path - Prepend path string to a buffer | 2440 | * prepend_path - Prepend path string to a buffer |
2441 | * @path: the dentry/vfsmount to report | 2441 | * @path: the dentry/vfsmount to report |
2442 | * @root: root vfsmnt/dentry (may be modified by this function) | 2442 | * @root: root vfsmnt/dentry |
2443 | * @buffer: pointer to the end of the buffer | 2443 | * @buffer: pointer to the end of the buffer |
2444 | * @buflen: pointer to buffer length | 2444 | * @buflen: pointer to buffer length |
2445 | * | 2445 | * |
2446 | * Caller holds the rename_lock. | 2446 | * Caller holds the rename_lock. |
2447 | * | ||
2448 | * If path is not reachable from the supplied root, then the value of | ||
2449 | * root is changed (without modifying refcounts). | ||
2450 | */ | 2447 | */ |
2451 | static int prepend_path(const struct path *path, struct path *root, | 2448 | static int prepend_path(const struct path *path, |
2449 | const struct path *root, | ||
2452 | char **buffer, int *buflen) | 2450 | char **buffer, int *buflen) |
2453 | { | 2451 | { |
2454 | struct dentry *dentry = path->dentry; | 2452 | struct dentry *dentry = path->dentry; |
@@ -2483,10 +2481,10 @@ static int prepend_path(const struct path *path, struct path *root, | |||
2483 | dentry = parent; | 2481 | dentry = parent; |
2484 | } | 2482 | } |
2485 | 2483 | ||
2486 | out: | ||
2487 | if (!error && !slash) | 2484 | if (!error && !slash) |
2488 | error = prepend(buffer, buflen, "/", 1); | 2485 | error = prepend(buffer, buflen, "/", 1); |
2489 | 2486 | ||
2487 | out: | ||
2490 | br_read_unlock(vfsmount_lock); | 2488 | br_read_unlock(vfsmount_lock); |
2491 | return error; | 2489 | return error; |
2492 | 2490 | ||
@@ -2500,15 +2498,17 @@ global_root: | |||
2500 | WARN(1, "Root dentry has weird name <%.*s>\n", | 2498 | WARN(1, "Root dentry has weird name <%.*s>\n", |
2501 | (int) dentry->d_name.len, dentry->d_name.name); | 2499 | (int) dentry->d_name.len, dentry->d_name.name); |
2502 | } | 2500 | } |
2503 | root->mnt = vfsmnt; | 2501 | if (!slash) |
2504 | root->dentry = dentry; | 2502 | error = prepend(buffer, buflen, "/", 1); |
2503 | if (!error) | ||
2504 | error = vfsmnt->mnt_ns ? 1 : 2; | ||
2505 | goto out; | 2505 | goto out; |
2506 | } | 2506 | } |
2507 | 2507 | ||
2508 | /** | 2508 | /** |
2509 | * __d_path - return the path of a dentry | 2509 | * __d_path - return the path of a dentry |
2510 | * @path: the dentry/vfsmount to report | 2510 | * @path: the dentry/vfsmount to report |
2511 | * @root: root vfsmnt/dentry (may be modified by this function) | 2511 | * @root: root vfsmnt/dentry |
2512 | * @buf: buffer to return value in | 2512 | * @buf: buffer to return value in |
2513 | * @buflen: buffer length | 2513 | * @buflen: buffer length |
2514 | * | 2514 | * |
@@ -2519,10 +2519,10 @@ global_root: | |||
2519 | * | 2519 | * |
2520 | * "buflen" should be positive. | 2520 | * "buflen" should be positive. |
2521 | * | 2521 | * |
2522 | * If path is not reachable from the supplied root, then the value of | 2522 | * If the path is not reachable from the supplied root, return %NULL. |
2523 | * root is changed (without modifying refcounts). | ||
2524 | */ | 2523 | */ |
2525 | char *__d_path(const struct path *path, struct path *root, | 2524 | char *__d_path(const struct path *path, |
2525 | const struct path *root, | ||
2526 | char *buf, int buflen) | 2526 | char *buf, int buflen) |
2527 | { | 2527 | { |
2528 | char *res = buf + buflen; | 2528 | char *res = buf + buflen; |
@@ -2533,7 +2533,28 @@ char *__d_path(const struct path *path, struct path *root, | |||
2533 | error = prepend_path(path, root, &res, &buflen); | 2533 | error = prepend_path(path, root, &res, &buflen); |
2534 | write_sequnlock(&rename_lock); | 2534 | write_sequnlock(&rename_lock); |
2535 | 2535 | ||
2536 | if (error) | 2536 | if (error < 0) |
2537 | return ERR_PTR(error); | ||
2538 | if (error > 0) | ||
2539 | return NULL; | ||
2540 | return res; | ||
2541 | } | ||
2542 | |||
2543 | char *d_absolute_path(const struct path *path, | ||
2544 | char *buf, int buflen) | ||
2545 | { | ||
2546 | struct path root = {}; | ||
2547 | char *res = buf + buflen; | ||
2548 | int error; | ||
2549 | |||
2550 | prepend(&res, &buflen, "\0", 1); | ||
2551 | write_seqlock(&rename_lock); | ||
2552 | error = prepend_path(path, &root, &res, &buflen); | ||
2553 | write_sequnlock(&rename_lock); | ||
2554 | |||
2555 | if (error > 1) | ||
2556 | error = -EINVAL; | ||
2557 | if (error < 0) | ||
2537 | return ERR_PTR(error); | 2558 | return ERR_PTR(error); |
2538 | return res; | 2559 | return res; |
2539 | } | 2560 | } |
@@ -2541,8 +2562,9 @@ char *__d_path(const struct path *path, struct path *root, | |||
2541 | /* | 2562 | /* |
2542 | * same as __d_path but appends "(deleted)" for unlinked files. | 2563 | * same as __d_path but appends "(deleted)" for unlinked files. |
2543 | */ | 2564 | */ |
2544 | static int path_with_deleted(const struct path *path, struct path *root, | 2565 | static int path_with_deleted(const struct path *path, |
2545 | char **buf, int *buflen) | 2566 | const struct path *root, |
2567 | char **buf, int *buflen) | ||
2546 | { | 2568 | { |
2547 | prepend(buf, buflen, "\0", 1); | 2569 | prepend(buf, buflen, "\0", 1); |
2548 | if (d_unlinked(path->dentry)) { | 2570 | if (d_unlinked(path->dentry)) { |
@@ -2579,7 +2601,6 @@ char *d_path(const struct path *path, char *buf, int buflen) | |||
2579 | { | 2601 | { |
2580 | char *res = buf + buflen; | 2602 | char *res = buf + buflen; |
2581 | struct path root; | 2603 | struct path root; |
2582 | struct path tmp; | ||
2583 | int error; | 2604 | int error; |
2584 | 2605 | ||
2585 | /* | 2606 | /* |
@@ -2594,9 +2615,8 @@ char *d_path(const struct path *path, char *buf, int buflen) | |||
2594 | 2615 | ||
2595 | get_fs_root(current->fs, &root); | 2616 | get_fs_root(current->fs, &root); |
2596 | write_seqlock(&rename_lock); | 2617 | write_seqlock(&rename_lock); |
2597 | tmp = root; | 2618 | error = path_with_deleted(path, &root, &res, &buflen); |
2598 | error = path_with_deleted(path, &tmp, &res, &buflen); | 2619 | if (error < 0) |
2599 | if (error) | ||
2600 | res = ERR_PTR(error); | 2620 | res = ERR_PTR(error); |
2601 | write_sequnlock(&rename_lock); | 2621 | write_sequnlock(&rename_lock); |
2602 | path_put(&root); | 2622 | path_put(&root); |
@@ -2617,7 +2637,6 @@ char *d_path_with_unreachable(const struct path *path, char *buf, int buflen) | |||
2617 | { | 2637 | { |
2618 | char *res = buf + buflen; | 2638 | char *res = buf + buflen; |
2619 | struct path root; | 2639 | struct path root; |
2620 | struct path tmp; | ||
2621 | int error; | 2640 | int error; |
2622 | 2641 | ||
2623 | if (path->dentry->d_op && path->dentry->d_op->d_dname) | 2642 | if (path->dentry->d_op && path->dentry->d_op->d_dname) |
@@ -2625,9 +2644,8 @@ char *d_path_with_unreachable(const struct path *path, char *buf, int buflen) | |||
2625 | 2644 | ||
2626 | get_fs_root(current->fs, &root); | 2645 | get_fs_root(current->fs, &root); |
2627 | write_seqlock(&rename_lock); | 2646 | write_seqlock(&rename_lock); |
2628 | tmp = root; | 2647 | error = path_with_deleted(path, &root, &res, &buflen); |
2629 | error = path_with_deleted(path, &tmp, &res, &buflen); | 2648 | if (error > 0) |
2630 | if (!error && !path_equal(&tmp, &root)) | ||
2631 | error = prepend_unreachable(&res, &buflen); | 2649 | error = prepend_unreachable(&res, &buflen); |
2632 | write_sequnlock(&rename_lock); | 2650 | write_sequnlock(&rename_lock); |
2633 | path_put(&root); | 2651 | path_put(&root); |
@@ -2758,19 +2776,18 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) | |||
2758 | write_seqlock(&rename_lock); | 2776 | write_seqlock(&rename_lock); |
2759 | if (!d_unlinked(pwd.dentry)) { | 2777 | if (!d_unlinked(pwd.dentry)) { |
2760 | unsigned long len; | 2778 | unsigned long len; |
2761 | struct path tmp = root; | ||
2762 | char *cwd = page + PAGE_SIZE; | 2779 | char *cwd = page + PAGE_SIZE; |
2763 | int buflen = PAGE_SIZE; | 2780 | int buflen = PAGE_SIZE; |
2764 | 2781 | ||
2765 | prepend(&cwd, &buflen, "\0", 1); | 2782 | prepend(&cwd, &buflen, "\0", 1); |
2766 | error = prepend_path(&pwd, &tmp, &cwd, &buflen); | 2783 | error = prepend_path(&pwd, &root, &cwd, &buflen); |
2767 | write_sequnlock(&rename_lock); | 2784 | write_sequnlock(&rename_lock); |
2768 | 2785 | ||
2769 | if (error) | 2786 | if (error < 0) |
2770 | goto out; | 2787 | goto out; |
2771 | 2788 | ||
2772 | /* Unreachable from current root */ | 2789 | /* Unreachable from current root */ |
2773 | if (!path_equal(&tmp, &root)) { | 2790 | if (error > 0) { |
2774 | error = prepend_unreachable(&cwd, &buflen); | 2791 | error = prepend_unreachable(&cwd, &buflen); |
2775 | if (error) | 2792 | if (error) |
2776 | goto out; | 2793 | goto out; |
diff --git a/fs/namespace.c b/fs/namespace.c index 6d3a1963879b..cfc6d4448aa5 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -1048,15 +1048,12 @@ static int show_mountinfo(struct seq_file *m, void *v) | |||
1048 | if (err) | 1048 | if (err) |
1049 | goto out; | 1049 | goto out; |
1050 | seq_putc(m, ' '); | 1050 | seq_putc(m, ' '); |
1051 | seq_path_root(m, &mnt_path, &root, " \t\n\\"); | 1051 | |
1052 | if (root.mnt != p->root.mnt || root.dentry != p->root.dentry) { | 1052 | /* mountpoints outside of chroot jail will give SEQ_SKIP on this */ |
1053 | /* | 1053 | err = seq_path_root(m, &mnt_path, &root, " \t\n\\"); |
1054 | * Mountpoint is outside root, discard that one. Ugly, | 1054 | if (err) |
1055 | * but less so than trying to do that in iterator in a | 1055 | goto out; |
1056 | * race-free way (due to renames). | 1056 | |
1057 | */ | ||
1058 | return SEQ_SKIP; | ||
1059 | } | ||
1060 | seq_puts(m, mnt->mnt_flags & MNT_READONLY ? " ro" : " rw"); | 1057 | seq_puts(m, mnt->mnt_flags & MNT_READONLY ? " ro" : " rw"); |
1061 | show_mnt_opts(m, mnt); | 1058 | show_mnt_opts(m, mnt); |
1062 | 1059 | ||
@@ -2776,3 +2773,8 @@ void kern_unmount(struct vfsmount *mnt) | |||
2776 | } | 2773 | } |
2777 | } | 2774 | } |
2778 | EXPORT_SYMBOL(kern_unmount); | 2775 | EXPORT_SYMBOL(kern_unmount); |
2776 | |||
2777 | bool our_mnt(struct vfsmount *mnt) | ||
2778 | { | ||
2779 | return check_mnt(mnt); | ||
2780 | } | ||
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c index 586174168e2a..80e4645f7990 100644 --- a/fs/proc/meminfo.c +++ b/fs/proc/meminfo.c | |||
@@ -131,12 +131,13 @@ static int meminfo_proc_show(struct seq_file *m, void *v) | |||
131 | K(i.freeswap), | 131 | K(i.freeswap), |
132 | K(global_page_state(NR_FILE_DIRTY)), | 132 | K(global_page_state(NR_FILE_DIRTY)), |
133 | K(global_page_state(NR_WRITEBACK)), | 133 | K(global_page_state(NR_WRITEBACK)), |
134 | K(global_page_state(NR_ANON_PAGES) | ||
135 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 134 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
135 | K(global_page_state(NR_ANON_PAGES) | ||
136 | + global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * | 136 | + global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * |
137 | HPAGE_PMD_NR | 137 | HPAGE_PMD_NR), |
138 | #else | ||
139 | K(global_page_state(NR_ANON_PAGES)), | ||
138 | #endif | 140 | #endif |
139 | ), | ||
140 | K(global_page_state(NR_FILE_MAPPED)), | 141 | K(global_page_state(NR_FILE_MAPPED)), |
141 | K(global_page_state(NR_SHMEM)), | 142 | K(global_page_state(NR_SHMEM)), |
142 | K(global_page_state(NR_SLAB_RECLAIMABLE) + | 143 | K(global_page_state(NR_SLAB_RECLAIMABLE) + |
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index 42b274da92c3..2a30d67dd6b8 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c | |||
@@ -32,7 +32,7 @@ static cputime64_t get_idle_time(int cpu) | |||
32 | idle = kstat_cpu(cpu).cpustat.idle; | 32 | idle = kstat_cpu(cpu).cpustat.idle; |
33 | idle = cputime64_add(idle, arch_idle_time(cpu)); | 33 | idle = cputime64_add(idle, arch_idle_time(cpu)); |
34 | } else | 34 | } else |
35 | idle = usecs_to_cputime(idle_time); | 35 | idle = nsecs_to_jiffies64(1000 * idle_time); |
36 | 36 | ||
37 | return idle; | 37 | return idle; |
38 | } | 38 | } |
@@ -46,7 +46,7 @@ static cputime64_t get_iowait_time(int cpu) | |||
46 | /* !NO_HZ so we can rely on cpustat.iowait */ | 46 | /* !NO_HZ so we can rely on cpustat.iowait */ |
47 | iowait = kstat_cpu(cpu).cpustat.iowait; | 47 | iowait = kstat_cpu(cpu).cpustat.iowait; |
48 | else | 48 | else |
49 | iowait = usecs_to_cputime(iowait_time); | 49 | iowait = nsecs_to_jiffies64(1000 * iowait_time); |
50 | 50 | ||
51 | return iowait; | 51 | return iowait; |
52 | } | 52 | } |
diff --git a/fs/seq_file.c b/fs/seq_file.c index 05d6b0e78c95..dba43c3ea3af 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
@@ -449,8 +449,6 @@ EXPORT_SYMBOL(seq_path); | |||
449 | 449 | ||
450 | /* | 450 | /* |
451 | * Same as seq_path, but relative to supplied root. | 451 | * Same as seq_path, but relative to supplied root. |
452 | * | ||
453 | * root may be changed, see __d_path(). | ||
454 | */ | 452 | */ |
455 | int seq_path_root(struct seq_file *m, struct path *path, struct path *root, | 453 | int seq_path_root(struct seq_file *m, struct path *path, struct path *root, |
456 | char *esc) | 454 | char *esc) |
@@ -463,6 +461,8 @@ int seq_path_root(struct seq_file *m, struct path *path, struct path *root, | |||
463 | char *p; | 461 | char *p; |
464 | 462 | ||
465 | p = __d_path(path, root, buf, size); | 463 | p = __d_path(path, root, buf, size); |
464 | if (!p) | ||
465 | return SEQ_SKIP; | ||
466 | res = PTR_ERR(p); | 466 | res = PTR_ERR(p); |
467 | if (!IS_ERR(p)) { | 467 | if (!IS_ERR(p)) { |
468 | char *end = mangle_path(buf, p, esc); | 468 | char *end = mangle_path(buf, p, esc); |
@@ -474,7 +474,7 @@ int seq_path_root(struct seq_file *m, struct path *path, struct path *root, | |||
474 | } | 474 | } |
475 | seq_commit(m, res); | 475 | seq_commit(m, res); |
476 | 476 | ||
477 | return res < 0 ? res : 0; | 477 | return res < 0 && res != -ENAMETOOLONG ? res : 0; |
478 | } | 478 | } |
479 | 479 | ||
480 | /* | 480 | /* |
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index b6c4b3795c4a..76e4266d2e7e 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c | |||
@@ -42,6 +42,8 @@ xfs_acl_from_disk(struct xfs_acl *aclp) | |||
42 | int count, i; | 42 | int count, i; |
43 | 43 | ||
44 | count = be32_to_cpu(aclp->acl_cnt); | 44 | count = be32_to_cpu(aclp->acl_cnt); |
45 | if (count > XFS_ACL_MAX_ENTRIES) | ||
46 | return ERR_PTR(-EFSCORRUPTED); | ||
45 | 47 | ||
46 | acl = posix_acl_alloc(count, GFP_KERNEL); | 48 | acl = posix_acl_alloc(count, GFP_KERNEL); |
47 | if (!acl) | 49 | if (!acl) |
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index d4906e7c9787..c1b55e596551 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c | |||
@@ -110,6 +110,7 @@ xfs_attr_namesp_match(int arg_flags, int ondisk_flags) | |||
110 | /* | 110 | /* |
111 | * Query whether the requested number of additional bytes of extended | 111 | * Query whether the requested number of additional bytes of extended |
112 | * attribute space will be able to fit inline. | 112 | * attribute space will be able to fit inline. |
113 | * | ||
113 | * Returns zero if not, else the di_forkoff fork offset to be used in the | 114 | * Returns zero if not, else the di_forkoff fork offset to be used in the |
114 | * literal area for attribute data once the new bytes have been added. | 115 | * literal area for attribute data once the new bytes have been added. |
115 | * | 116 | * |
@@ -122,7 +123,7 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes) | |||
122 | int offset; | 123 | int offset; |
123 | int minforkoff; /* lower limit on valid forkoff locations */ | 124 | int minforkoff; /* lower limit on valid forkoff locations */ |
124 | int maxforkoff; /* upper limit on valid forkoff locations */ | 125 | int maxforkoff; /* upper limit on valid forkoff locations */ |
125 | int dsize; | 126 | int dsize; |
126 | xfs_mount_t *mp = dp->i_mount; | 127 | xfs_mount_t *mp = dp->i_mount; |
127 | 128 | ||
128 | offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */ | 129 | offset = (XFS_LITINO(mp) - bytes) >> 3; /* rounded down */ |
@@ -136,47 +137,60 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes) | |||
136 | return (offset >= minforkoff) ? minforkoff : 0; | 137 | return (offset >= minforkoff) ? minforkoff : 0; |
137 | } | 138 | } |
138 | 139 | ||
139 | if (!(mp->m_flags & XFS_MOUNT_ATTR2)) { | 140 | /* |
140 | if (bytes <= XFS_IFORK_ASIZE(dp)) | 141 | * If the requested numbers of bytes is smaller or equal to the |
141 | return dp->i_d.di_forkoff; | 142 | * current attribute fork size we can always proceed. |
143 | * | ||
144 | * Note that if_bytes in the data fork might actually be larger than | ||
145 | * the current data fork size is due to delalloc extents. In that | ||
146 | * case either the extent count will go down when they are converted | ||
147 | * to real extents, or the delalloc conversion will take care of the | ||
148 | * literal area rebalancing. | ||
149 | */ | ||
150 | if (bytes <= XFS_IFORK_ASIZE(dp)) | ||
151 | return dp->i_d.di_forkoff; | ||
152 | |||
153 | /* | ||
154 | * For attr2 we can try to move the forkoff if there is space in the | ||
155 | * literal area, but for the old format we are done if there is no | ||
156 | * space in the fixed attribute fork. | ||
157 | */ | ||
158 | if (!(mp->m_flags & XFS_MOUNT_ATTR2)) | ||
142 | return 0; | 159 | return 0; |
143 | } | ||
144 | 160 | ||
145 | dsize = dp->i_df.if_bytes; | 161 | dsize = dp->i_df.if_bytes; |
146 | 162 | ||
147 | switch (dp->i_d.di_format) { | 163 | switch (dp->i_d.di_format) { |
148 | case XFS_DINODE_FMT_EXTENTS: | 164 | case XFS_DINODE_FMT_EXTENTS: |
149 | /* | 165 | /* |
150 | * If there is no attr fork and the data fork is extents, | 166 | * If there is no attr fork and the data fork is extents, |
151 | * determine if creating the default attr fork will result | 167 | * determine if creating the default attr fork will result |
152 | * in the extents form migrating to btree. If so, the | 168 | * in the extents form migrating to btree. If so, the |
153 | * minimum offset only needs to be the space required for | 169 | * minimum offset only needs to be the space required for |
154 | * the btree root. | 170 | * the btree root. |
155 | */ | 171 | */ |
156 | if (!dp->i_d.di_forkoff && dp->i_df.if_bytes > | 172 | if (!dp->i_d.di_forkoff && dp->i_df.if_bytes > |
157 | xfs_default_attroffset(dp)) | 173 | xfs_default_attroffset(dp)) |
158 | dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS); | 174 | dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS); |
159 | break; | 175 | break; |
160 | |||
161 | case XFS_DINODE_FMT_BTREE: | 176 | case XFS_DINODE_FMT_BTREE: |
162 | /* | 177 | /* |
163 | * If have data btree then keep forkoff if we have one, | 178 | * If we have a data btree then keep forkoff if we have one, |
164 | * otherwise we are adding a new attr, so then we set | 179 | * otherwise we are adding a new attr, so then we set |
165 | * minforkoff to where the btree root can finish so we have | 180 | * minforkoff to where the btree root can finish so we have |
166 | * plenty of room for attrs | 181 | * plenty of room for attrs |
167 | */ | 182 | */ |
168 | if (dp->i_d.di_forkoff) { | 183 | if (dp->i_d.di_forkoff) { |
169 | if (offset < dp->i_d.di_forkoff) | 184 | if (offset < dp->i_d.di_forkoff) |
170 | return 0; | 185 | return 0; |
171 | else | 186 | return dp->i_d.di_forkoff; |
172 | return dp->i_d.di_forkoff; | 187 | } |
173 | } else | 188 | dsize = XFS_BMAP_BROOT_SPACE(dp->i_df.if_broot); |
174 | dsize = XFS_BMAP_BROOT_SPACE(dp->i_df.if_broot); | ||
175 | break; | 189 | break; |
176 | } | 190 | } |
177 | 191 | ||
178 | /* | 192 | /* |
179 | * A data fork btree root must have space for at least | 193 | * A data fork btree root must have space for at least |
180 | * MINDBTPTRS key/ptr pairs if the data fork is small or empty. | 194 | * MINDBTPTRS key/ptr pairs if the data fork is small or empty. |
181 | */ | 195 | */ |
182 | minforkoff = MAX(dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS)); | 196 | minforkoff = MAX(dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS)); |
@@ -186,10 +200,10 @@ xfs_attr_shortform_bytesfit(xfs_inode_t *dp, int bytes) | |||
186 | maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS); | 200 | maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS); |
187 | maxforkoff = maxforkoff >> 3; /* rounded down */ | 201 | maxforkoff = maxforkoff >> 3; /* rounded down */ |
188 | 202 | ||
189 | if (offset >= minforkoff && offset < maxforkoff) | ||
190 | return offset; | ||
191 | if (offset >= maxforkoff) | 203 | if (offset >= maxforkoff) |
192 | return maxforkoff; | 204 | return maxforkoff; |
205 | if (offset >= minforkoff) | ||
206 | return offset; | ||
193 | return 0; | 207 | return 0; |
194 | } | 208 | } |
195 | 209 | ||
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index c68baeb0974a..d0ab78837057 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -2383,6 +2383,8 @@ xfs_bmap_btalloc( | |||
2383 | int tryagain; | 2383 | int tryagain; |
2384 | int error; | 2384 | int error; |
2385 | 2385 | ||
2386 | ASSERT(ap->length); | ||
2387 | |||
2386 | mp = ap->ip->i_mount; | 2388 | mp = ap->ip->i_mount; |
2387 | align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0; | 2389 | align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0; |
2388 | if (unlikely(align)) { | 2390 | if (unlikely(align)) { |
@@ -4629,6 +4631,8 @@ xfs_bmapi_allocate( | |||
4629 | int error; | 4631 | int error; |
4630 | int rt; | 4632 | int rt; |
4631 | 4633 | ||
4634 | ASSERT(bma->length > 0); | ||
4635 | |||
4632 | rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(bma->ip); | 4636 | rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(bma->ip); |
4633 | 4637 | ||
4634 | /* | 4638 | /* |
@@ -4849,6 +4853,7 @@ xfs_bmapi_write( | |||
4849 | ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); | 4853 | ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); |
4850 | ASSERT(!(flags & XFS_BMAPI_IGSTATE)); | 4854 | ASSERT(!(flags & XFS_BMAPI_IGSTATE)); |
4851 | ASSERT(tp != NULL); | 4855 | ASSERT(tp != NULL); |
4856 | ASSERT(len > 0); | ||
4852 | 4857 | ||
4853 | whichfork = (flags & XFS_BMAPI_ATTRFORK) ? | 4858 | whichfork = (flags & XFS_BMAPI_ATTRFORK) ? |
4854 | XFS_ATTR_FORK : XFS_DATA_FORK; | 4859 | XFS_ATTR_FORK : XFS_DATA_FORK; |
@@ -4918,9 +4923,22 @@ xfs_bmapi_write( | |||
4918 | bma.eof = eof; | 4923 | bma.eof = eof; |
4919 | bma.conv = !!(flags & XFS_BMAPI_CONVERT); | 4924 | bma.conv = !!(flags & XFS_BMAPI_CONVERT); |
4920 | bma.wasdel = wasdelay; | 4925 | bma.wasdel = wasdelay; |
4921 | bma.length = len; | ||
4922 | bma.offset = bno; | 4926 | bma.offset = bno; |
4923 | 4927 | ||
4928 | /* | ||
4929 | * There's a 32/64 bit type mismatch between the | ||
4930 | * allocation length request (which can be 64 bits in | ||
4931 | * length) and the bma length request, which is | ||
4932 | * xfs_extlen_t and therefore 32 bits. Hence we have to | ||
4933 | * check for 32-bit overflows and handle them here. | ||
4934 | */ | ||
4935 | if (len > (xfs_filblks_t)MAXEXTLEN) | ||
4936 | bma.length = MAXEXTLEN; | ||
4937 | else | ||
4938 | bma.length = len; | ||
4939 | |||
4940 | ASSERT(len > 0); | ||
4941 | ASSERT(bma.length > 0); | ||
4924 | error = xfs_bmapi_allocate(&bma, flags); | 4942 | error = xfs_bmapi_allocate(&bma, flags); |
4925 | if (error) | 4943 | if (error) |
4926 | goto error0; | 4944 | goto error0; |
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c index da108977b21f..558910f5e3c0 100644 --- a/fs/xfs/xfs_export.c +++ b/fs/xfs/xfs_export.c | |||
@@ -98,22 +98,22 @@ xfs_fs_encode_fh( | |||
98 | switch (fileid_type) { | 98 | switch (fileid_type) { |
99 | case FILEID_INO32_GEN_PARENT: | 99 | case FILEID_INO32_GEN_PARENT: |
100 | spin_lock(&dentry->d_lock); | 100 | spin_lock(&dentry->d_lock); |
101 | fid->i32.parent_ino = dentry->d_parent->d_inode->i_ino; | 101 | fid->i32.parent_ino = XFS_I(dentry->d_parent->d_inode)->i_ino; |
102 | fid->i32.parent_gen = dentry->d_parent->d_inode->i_generation; | 102 | fid->i32.parent_gen = dentry->d_parent->d_inode->i_generation; |
103 | spin_unlock(&dentry->d_lock); | 103 | spin_unlock(&dentry->d_lock); |
104 | /*FALLTHRU*/ | 104 | /*FALLTHRU*/ |
105 | case FILEID_INO32_GEN: | 105 | case FILEID_INO32_GEN: |
106 | fid->i32.ino = inode->i_ino; | 106 | fid->i32.ino = XFS_I(inode)->i_ino; |
107 | fid->i32.gen = inode->i_generation; | 107 | fid->i32.gen = inode->i_generation; |
108 | break; | 108 | break; |
109 | case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG: | 109 | case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG: |
110 | spin_lock(&dentry->d_lock); | 110 | spin_lock(&dentry->d_lock); |
111 | fid64->parent_ino = dentry->d_parent->d_inode->i_ino; | 111 | fid64->parent_ino = XFS_I(dentry->d_parent->d_inode)->i_ino; |
112 | fid64->parent_gen = dentry->d_parent->d_inode->i_generation; | 112 | fid64->parent_gen = dentry->d_parent->d_inode->i_generation; |
113 | spin_unlock(&dentry->d_lock); | 113 | spin_unlock(&dentry->d_lock); |
114 | /*FALLTHRU*/ | 114 | /*FALLTHRU*/ |
115 | case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG: | 115 | case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG: |
116 | fid64->ino = inode->i_ino; | 116 | fid64->ino = XFS_I(inode)->i_ino; |
117 | fid64->gen = inode->i_generation; | 117 | fid64->gen = inode->i_generation; |
118 | break; | 118 | break; |
119 | } | 119 | } |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index c0237c602f11..755ee8164880 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -2835,6 +2835,27 @@ corrupt_out: | |||
2835 | return XFS_ERROR(EFSCORRUPTED); | 2835 | return XFS_ERROR(EFSCORRUPTED); |
2836 | } | 2836 | } |
2837 | 2837 | ||
2838 | void | ||
2839 | xfs_promote_inode( | ||
2840 | struct xfs_inode *ip) | ||
2841 | { | ||
2842 | struct xfs_buf *bp; | ||
2843 | |||
2844 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); | ||
2845 | |||
2846 | bp = xfs_incore(ip->i_mount->m_ddev_targp, ip->i_imap.im_blkno, | ||
2847 | ip->i_imap.im_len, XBF_TRYLOCK); | ||
2848 | if (!bp) | ||
2849 | return; | ||
2850 | |||
2851 | if (XFS_BUF_ISDELAYWRITE(bp)) { | ||
2852 | xfs_buf_delwri_promote(bp); | ||
2853 | wake_up_process(ip->i_mount->m_ddev_targp->bt_task); | ||
2854 | } | ||
2855 | |||
2856 | xfs_buf_relse(bp); | ||
2857 | } | ||
2858 | |||
2838 | /* | 2859 | /* |
2839 | * Return a pointer to the extent record at file index idx. | 2860 | * Return a pointer to the extent record at file index idx. |
2840 | */ | 2861 | */ |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 760140d1dd66..b4cd4739f98e 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -498,6 +498,7 @@ int xfs_iunlink(struct xfs_trans *, xfs_inode_t *); | |||
498 | void xfs_iext_realloc(xfs_inode_t *, int, int); | 498 | void xfs_iext_realloc(xfs_inode_t *, int, int); |
499 | void xfs_iunpin_wait(xfs_inode_t *); | 499 | void xfs_iunpin_wait(xfs_inode_t *); |
500 | int xfs_iflush(xfs_inode_t *, uint); | 500 | int xfs_iflush(xfs_inode_t *, uint); |
501 | void xfs_promote_inode(struct xfs_inode *); | ||
501 | void xfs_lock_inodes(xfs_inode_t **, int, uint); | 502 | void xfs_lock_inodes(xfs_inode_t **, int, uint); |
502 | void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); | 503 | void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); |
503 | 504 | ||
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index a14cd89fe465..34817adf4b9e 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -150,6 +150,117 @@ xlog_grant_add_space( | |||
150 | } while (head_val != old); | 150 | } while (head_val != old); |
151 | } | 151 | } |
152 | 152 | ||
153 | STATIC bool | ||
154 | xlog_reserveq_wake( | ||
155 | struct log *log, | ||
156 | int *free_bytes) | ||
157 | { | ||
158 | struct xlog_ticket *tic; | ||
159 | int need_bytes; | ||
160 | |||
161 | list_for_each_entry(tic, &log->l_reserveq, t_queue) { | ||
162 | if (tic->t_flags & XLOG_TIC_PERM_RESERV) | ||
163 | need_bytes = tic->t_unit_res * tic->t_cnt; | ||
164 | else | ||
165 | need_bytes = tic->t_unit_res; | ||
166 | |||
167 | if (*free_bytes < need_bytes) | ||
168 | return false; | ||
169 | *free_bytes -= need_bytes; | ||
170 | |||
171 | trace_xfs_log_grant_wake_up(log, tic); | ||
172 | wake_up(&tic->t_wait); | ||
173 | } | ||
174 | |||
175 | return true; | ||
176 | } | ||
177 | |||
178 | STATIC bool | ||
179 | xlog_writeq_wake( | ||
180 | struct log *log, | ||
181 | int *free_bytes) | ||
182 | { | ||
183 | struct xlog_ticket *tic; | ||
184 | int need_bytes; | ||
185 | |||
186 | list_for_each_entry(tic, &log->l_writeq, t_queue) { | ||
187 | ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV); | ||
188 | |||
189 | need_bytes = tic->t_unit_res; | ||
190 | |||
191 | if (*free_bytes < need_bytes) | ||
192 | return false; | ||
193 | *free_bytes -= need_bytes; | ||
194 | |||
195 | trace_xfs_log_regrant_write_wake_up(log, tic); | ||
196 | wake_up(&tic->t_wait); | ||
197 | } | ||
198 | |||
199 | return true; | ||
200 | } | ||
201 | |||
202 | STATIC int | ||
203 | xlog_reserveq_wait( | ||
204 | struct log *log, | ||
205 | struct xlog_ticket *tic, | ||
206 | int need_bytes) | ||
207 | { | ||
208 | list_add_tail(&tic->t_queue, &log->l_reserveq); | ||
209 | |||
210 | do { | ||
211 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
212 | goto shutdown; | ||
213 | xlog_grant_push_ail(log, need_bytes); | ||
214 | |||
215 | XFS_STATS_INC(xs_sleep_logspace); | ||
216 | trace_xfs_log_grant_sleep(log, tic); | ||
217 | |||
218 | xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock); | ||
219 | trace_xfs_log_grant_wake(log, tic); | ||
220 | |||
221 | spin_lock(&log->l_grant_reserve_lock); | ||
222 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
223 | goto shutdown; | ||
224 | } while (xlog_space_left(log, &log->l_grant_reserve_head) < need_bytes); | ||
225 | |||
226 | list_del_init(&tic->t_queue); | ||
227 | return 0; | ||
228 | shutdown: | ||
229 | list_del_init(&tic->t_queue); | ||
230 | return XFS_ERROR(EIO); | ||
231 | } | ||
232 | |||
233 | STATIC int | ||
234 | xlog_writeq_wait( | ||
235 | struct log *log, | ||
236 | struct xlog_ticket *tic, | ||
237 | int need_bytes) | ||
238 | { | ||
239 | list_add_tail(&tic->t_queue, &log->l_writeq); | ||
240 | |||
241 | do { | ||
242 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
243 | goto shutdown; | ||
244 | xlog_grant_push_ail(log, need_bytes); | ||
245 | |||
246 | XFS_STATS_INC(xs_sleep_logspace); | ||
247 | trace_xfs_log_regrant_write_sleep(log, tic); | ||
248 | |||
249 | xlog_wait(&tic->t_wait, &log->l_grant_write_lock); | ||
250 | trace_xfs_log_regrant_write_wake(log, tic); | ||
251 | |||
252 | spin_lock(&log->l_grant_write_lock); | ||
253 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
254 | goto shutdown; | ||
255 | } while (xlog_space_left(log, &log->l_grant_write_head) < need_bytes); | ||
256 | |||
257 | list_del_init(&tic->t_queue); | ||
258 | return 0; | ||
259 | shutdown: | ||
260 | list_del_init(&tic->t_queue); | ||
261 | return XFS_ERROR(EIO); | ||
262 | } | ||
263 | |||
153 | static void | 264 | static void |
154 | xlog_tic_reset_res(xlog_ticket_t *tic) | 265 | xlog_tic_reset_res(xlog_ticket_t *tic) |
155 | { | 266 | { |
@@ -350,8 +461,19 @@ xfs_log_reserve( | |||
350 | retval = xlog_grant_log_space(log, internal_ticket); | 461 | retval = xlog_grant_log_space(log, internal_ticket); |
351 | } | 462 | } |
352 | 463 | ||
464 | if (unlikely(retval)) { | ||
465 | /* | ||
466 | * If we are failing, make sure the ticket doesn't have any | ||
467 | * current reservations. We don't want to add this back | ||
468 | * when the ticket/ transaction gets cancelled. | ||
469 | */ | ||
470 | internal_ticket->t_curr_res = 0; | ||
471 | /* ungrant will give back unit_res * t_cnt. */ | ||
472 | internal_ticket->t_cnt = 0; | ||
473 | } | ||
474 | |||
353 | return retval; | 475 | return retval; |
354 | } /* xfs_log_reserve */ | 476 | } |
355 | 477 | ||
356 | 478 | ||
357 | /* | 479 | /* |
@@ -2481,8 +2603,8 @@ restart: | |||
2481 | /* | 2603 | /* |
2482 | * Atomically get the log space required for a log ticket. | 2604 | * Atomically get the log space required for a log ticket. |
2483 | * | 2605 | * |
2484 | * Once a ticket gets put onto the reserveq, it will only return after | 2606 | * Once a ticket gets put onto the reserveq, it will only return after the |
2485 | * the needed reservation is satisfied. | 2607 | * needed reservation is satisfied. |
2486 | * | 2608 | * |
2487 | * This function is structured so that it has a lock free fast path. This is | 2609 | * This function is structured so that it has a lock free fast path. This is |
2488 | * necessary because every new transaction reservation will come through this | 2610 | * necessary because every new transaction reservation will come through this |
@@ -2490,113 +2612,53 @@ restart: | |||
2490 | * every pass. | 2612 | * every pass. |
2491 | * | 2613 | * |
2492 | * As tickets are only ever moved on and off the reserveq under the | 2614 | * As tickets are only ever moved on and off the reserveq under the |
2493 | * l_grant_reserve_lock, we only need to take that lock if we are going | 2615 | * l_grant_reserve_lock, we only need to take that lock if we are going to add |
2494 | * to add the ticket to the queue and sleep. We can avoid taking the lock if the | 2616 | * the ticket to the queue and sleep. We can avoid taking the lock if the ticket |
2495 | * ticket was never added to the reserveq because the t_queue list head will be | 2617 | * was never added to the reserveq because the t_queue list head will be empty |
2496 | * empty and we hold the only reference to it so it can safely be checked | 2618 | * and we hold the only reference to it so it can safely be checked unlocked. |
2497 | * unlocked. | ||
2498 | */ | 2619 | */ |
2499 | STATIC int | 2620 | STATIC int |
2500 | xlog_grant_log_space(xlog_t *log, | 2621 | xlog_grant_log_space( |
2501 | xlog_ticket_t *tic) | 2622 | struct log *log, |
2623 | struct xlog_ticket *tic) | ||
2502 | { | 2624 | { |
2503 | int free_bytes; | 2625 | int free_bytes, need_bytes; |
2504 | int need_bytes; | 2626 | int error = 0; |
2505 | 2627 | ||
2506 | #ifdef DEBUG | 2628 | ASSERT(!(log->l_flags & XLOG_ACTIVE_RECOVERY)); |
2507 | if (log->l_flags & XLOG_ACTIVE_RECOVERY) | ||
2508 | panic("grant Recovery problem"); | ||
2509 | #endif | ||
2510 | 2629 | ||
2511 | trace_xfs_log_grant_enter(log, tic); | 2630 | trace_xfs_log_grant_enter(log, tic); |
2512 | 2631 | ||
2632 | /* | ||
2633 | * If there are other waiters on the queue then give them a chance at | ||
2634 | * logspace before us. Wake up the first waiters, if we do not wake | ||
2635 | * up all the waiters then go to sleep waiting for more free space, | ||
2636 | * otherwise try to get some space for this transaction. | ||
2637 | */ | ||
2513 | need_bytes = tic->t_unit_res; | 2638 | need_bytes = tic->t_unit_res; |
2514 | if (tic->t_flags & XFS_LOG_PERM_RESERV) | 2639 | if (tic->t_flags & XFS_LOG_PERM_RESERV) |
2515 | need_bytes *= tic->t_ocnt; | 2640 | need_bytes *= tic->t_ocnt; |
2516 | |||
2517 | /* something is already sleeping; insert new transaction at end */ | ||
2518 | if (!list_empty_careful(&log->l_reserveq)) { | ||
2519 | spin_lock(&log->l_grant_reserve_lock); | ||
2520 | /* recheck the queue now we are locked */ | ||
2521 | if (list_empty(&log->l_reserveq)) { | ||
2522 | spin_unlock(&log->l_grant_reserve_lock); | ||
2523 | goto redo; | ||
2524 | } | ||
2525 | list_add_tail(&tic->t_queue, &log->l_reserveq); | ||
2526 | |||
2527 | trace_xfs_log_grant_sleep1(log, tic); | ||
2528 | |||
2529 | /* | ||
2530 | * Gotta check this before going to sleep, while we're | ||
2531 | * holding the grant lock. | ||
2532 | */ | ||
2533 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
2534 | goto error_return; | ||
2535 | |||
2536 | XFS_STATS_INC(xs_sleep_logspace); | ||
2537 | xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock); | ||
2538 | |||
2539 | /* | ||
2540 | * If we got an error, and the filesystem is shutting down, | ||
2541 | * we'll catch it down below. So just continue... | ||
2542 | */ | ||
2543 | trace_xfs_log_grant_wake1(log, tic); | ||
2544 | } | ||
2545 | |||
2546 | redo: | ||
2547 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
2548 | goto error_return_unlocked; | ||
2549 | |||
2550 | free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); | 2641 | free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); |
2551 | if (free_bytes < need_bytes) { | 2642 | if (!list_empty_careful(&log->l_reserveq)) { |
2552 | spin_lock(&log->l_grant_reserve_lock); | 2643 | spin_lock(&log->l_grant_reserve_lock); |
2553 | if (list_empty(&tic->t_queue)) | 2644 | if (!xlog_reserveq_wake(log, &free_bytes) || |
2554 | list_add_tail(&tic->t_queue, &log->l_reserveq); | 2645 | free_bytes < need_bytes) |
2555 | 2646 | error = xlog_reserveq_wait(log, tic, need_bytes); | |
2556 | trace_xfs_log_grant_sleep2(log, tic); | 2647 | spin_unlock(&log->l_grant_reserve_lock); |
2557 | 2648 | } else if (free_bytes < need_bytes) { | |
2558 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
2559 | goto error_return; | ||
2560 | |||
2561 | xlog_grant_push_ail(log, need_bytes); | ||
2562 | |||
2563 | XFS_STATS_INC(xs_sleep_logspace); | ||
2564 | xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock); | ||
2565 | |||
2566 | trace_xfs_log_grant_wake2(log, tic); | ||
2567 | goto redo; | ||
2568 | } | ||
2569 | |||
2570 | if (!list_empty(&tic->t_queue)) { | ||
2571 | spin_lock(&log->l_grant_reserve_lock); | 2649 | spin_lock(&log->l_grant_reserve_lock); |
2572 | list_del_init(&tic->t_queue); | 2650 | error = xlog_reserveq_wait(log, tic, need_bytes); |
2573 | spin_unlock(&log->l_grant_reserve_lock); | 2651 | spin_unlock(&log->l_grant_reserve_lock); |
2574 | } | 2652 | } |
2653 | if (error) | ||
2654 | return error; | ||
2575 | 2655 | ||
2576 | /* we've got enough space */ | ||
2577 | xlog_grant_add_space(log, &log->l_grant_reserve_head, need_bytes); | 2656 | xlog_grant_add_space(log, &log->l_grant_reserve_head, need_bytes); |
2578 | xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); | 2657 | xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); |
2579 | trace_xfs_log_grant_exit(log, tic); | 2658 | trace_xfs_log_grant_exit(log, tic); |
2580 | xlog_verify_grant_tail(log); | 2659 | xlog_verify_grant_tail(log); |
2581 | return 0; | 2660 | return 0; |
2582 | 2661 | } | |
2583 | error_return_unlocked: | ||
2584 | spin_lock(&log->l_grant_reserve_lock); | ||
2585 | error_return: | ||
2586 | list_del_init(&tic->t_queue); | ||
2587 | spin_unlock(&log->l_grant_reserve_lock); | ||
2588 | trace_xfs_log_grant_error(log, tic); | ||
2589 | |||
2590 | /* | ||
2591 | * If we are failing, make sure the ticket doesn't have any | ||
2592 | * current reservations. We don't want to add this back when | ||
2593 | * the ticket/transaction gets cancelled. | ||
2594 | */ | ||
2595 | tic->t_curr_res = 0; | ||
2596 | tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */ | ||
2597 | return XFS_ERROR(EIO); | ||
2598 | } /* xlog_grant_log_space */ | ||
2599 | |||
2600 | 2662 | ||
2601 | /* | 2663 | /* |
2602 | * Replenish the byte reservation required by moving the grant write head. | 2664 | * Replenish the byte reservation required by moving the grant write head. |
@@ -2605,10 +2667,12 @@ error_return: | |||
2605 | * free fast path. | 2667 | * free fast path. |
2606 | */ | 2668 | */ |
2607 | STATIC int | 2669 | STATIC int |
2608 | xlog_regrant_write_log_space(xlog_t *log, | 2670 | xlog_regrant_write_log_space( |
2609 | xlog_ticket_t *tic) | 2671 | struct log *log, |
2672 | struct xlog_ticket *tic) | ||
2610 | { | 2673 | { |
2611 | int free_bytes, need_bytes; | 2674 | int free_bytes, need_bytes; |
2675 | int error = 0; | ||
2612 | 2676 | ||
2613 | tic->t_curr_res = tic->t_unit_res; | 2677 | tic->t_curr_res = tic->t_unit_res; |
2614 | xlog_tic_reset_res(tic); | 2678 | xlog_tic_reset_res(tic); |
@@ -2616,104 +2680,38 @@ xlog_regrant_write_log_space(xlog_t *log, | |||
2616 | if (tic->t_cnt > 0) | 2680 | if (tic->t_cnt > 0) |
2617 | return 0; | 2681 | return 0; |
2618 | 2682 | ||
2619 | #ifdef DEBUG | 2683 | ASSERT(!(log->l_flags & XLOG_ACTIVE_RECOVERY)); |
2620 | if (log->l_flags & XLOG_ACTIVE_RECOVERY) | ||
2621 | panic("regrant Recovery problem"); | ||
2622 | #endif | ||
2623 | 2684 | ||
2624 | trace_xfs_log_regrant_write_enter(log, tic); | 2685 | trace_xfs_log_regrant_write_enter(log, tic); |
2625 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
2626 | goto error_return_unlocked; | ||
2627 | 2686 | ||
2628 | /* If there are other waiters on the queue then give them a | 2687 | /* |
2629 | * chance at logspace before us. Wake up the first waiters, | 2688 | * If there are other waiters on the queue then give them a chance at |
2630 | * if we do not wake up all the waiters then go to sleep waiting | 2689 | * logspace before us. Wake up the first waiters, if we do not wake |
2631 | * for more free space, otherwise try to get some space for | 2690 | * up all the waiters then go to sleep waiting for more free space, |
2632 | * this transaction. | 2691 | * otherwise try to get some space for this transaction. |
2633 | */ | 2692 | */ |
2634 | need_bytes = tic->t_unit_res; | 2693 | need_bytes = tic->t_unit_res; |
2635 | if (!list_empty_careful(&log->l_writeq)) { | ||
2636 | struct xlog_ticket *ntic; | ||
2637 | |||
2638 | spin_lock(&log->l_grant_write_lock); | ||
2639 | free_bytes = xlog_space_left(log, &log->l_grant_write_head); | ||
2640 | list_for_each_entry(ntic, &log->l_writeq, t_queue) { | ||
2641 | ASSERT(ntic->t_flags & XLOG_TIC_PERM_RESERV); | ||
2642 | |||
2643 | if (free_bytes < ntic->t_unit_res) | ||
2644 | break; | ||
2645 | free_bytes -= ntic->t_unit_res; | ||
2646 | wake_up(&ntic->t_wait); | ||
2647 | } | ||
2648 | |||
2649 | if (ntic != list_first_entry(&log->l_writeq, | ||
2650 | struct xlog_ticket, t_queue)) { | ||
2651 | if (list_empty(&tic->t_queue)) | ||
2652 | list_add_tail(&tic->t_queue, &log->l_writeq); | ||
2653 | trace_xfs_log_regrant_write_sleep1(log, tic); | ||
2654 | |||
2655 | xlog_grant_push_ail(log, need_bytes); | ||
2656 | |||
2657 | XFS_STATS_INC(xs_sleep_logspace); | ||
2658 | xlog_wait(&tic->t_wait, &log->l_grant_write_lock); | ||
2659 | trace_xfs_log_regrant_write_wake1(log, tic); | ||
2660 | } else | ||
2661 | spin_unlock(&log->l_grant_write_lock); | ||
2662 | } | ||
2663 | |||
2664 | redo: | ||
2665 | if (XLOG_FORCED_SHUTDOWN(log)) | ||
2666 | goto error_return_unlocked; | ||
2667 | |||
2668 | free_bytes = xlog_space_left(log, &log->l_grant_write_head); | 2694 | free_bytes = xlog_space_left(log, &log->l_grant_write_head); |
2669 | if (free_bytes < need_bytes) { | 2695 | if (!list_empty_careful(&log->l_writeq)) { |
2670 | spin_lock(&log->l_grant_write_lock); | 2696 | spin_lock(&log->l_grant_write_lock); |
2671 | if (list_empty(&tic->t_queue)) | 2697 | if (!xlog_writeq_wake(log, &free_bytes) || |
2672 | list_add_tail(&tic->t_queue, &log->l_writeq); | 2698 | free_bytes < need_bytes) |
2673 | 2699 | error = xlog_writeq_wait(log, tic, need_bytes); | |
2674 | if (XLOG_FORCED_SHUTDOWN(log)) | 2700 | spin_unlock(&log->l_grant_write_lock); |
2675 | goto error_return; | 2701 | } else if (free_bytes < need_bytes) { |
2676 | |||
2677 | xlog_grant_push_ail(log, need_bytes); | ||
2678 | |||
2679 | XFS_STATS_INC(xs_sleep_logspace); | ||
2680 | trace_xfs_log_regrant_write_sleep2(log, tic); | ||
2681 | xlog_wait(&tic->t_wait, &log->l_grant_write_lock); | ||
2682 | |||
2683 | trace_xfs_log_regrant_write_wake2(log, tic); | ||
2684 | goto redo; | ||
2685 | } | ||
2686 | |||
2687 | if (!list_empty(&tic->t_queue)) { | ||
2688 | spin_lock(&log->l_grant_write_lock); | 2702 | spin_lock(&log->l_grant_write_lock); |
2689 | list_del_init(&tic->t_queue); | 2703 | error = xlog_writeq_wait(log, tic, need_bytes); |
2690 | spin_unlock(&log->l_grant_write_lock); | 2704 | spin_unlock(&log->l_grant_write_lock); |
2691 | } | 2705 | } |
2692 | 2706 | ||
2693 | /* we've got enough space */ | 2707 | if (error) |
2708 | return error; | ||
2709 | |||
2694 | xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); | 2710 | xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); |
2695 | trace_xfs_log_regrant_write_exit(log, tic); | 2711 | trace_xfs_log_regrant_write_exit(log, tic); |
2696 | xlog_verify_grant_tail(log); | 2712 | xlog_verify_grant_tail(log); |
2697 | return 0; | 2713 | return 0; |
2698 | 2714 | } | |
2699 | |||
2700 | error_return_unlocked: | ||
2701 | spin_lock(&log->l_grant_write_lock); | ||
2702 | error_return: | ||
2703 | list_del_init(&tic->t_queue); | ||
2704 | spin_unlock(&log->l_grant_write_lock); | ||
2705 | trace_xfs_log_regrant_write_error(log, tic); | ||
2706 | |||
2707 | /* | ||
2708 | * If we are failing, make sure the ticket doesn't have any | ||
2709 | * current reservations. We don't want to add this back when | ||
2710 | * the ticket/transaction gets cancelled. | ||
2711 | */ | ||
2712 | tic->t_curr_res = 0; | ||
2713 | tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */ | ||
2714 | return XFS_ERROR(EIO); | ||
2715 | } /* xlog_regrant_write_log_space */ | ||
2716 | |||
2717 | 2715 | ||
2718 | /* The first cnt-1 times through here we don't need to | 2716 | /* The first cnt-1 times through here we don't need to |
2719 | * move the grant write head because the permanent | 2717 | * move the grant write head because the permanent |
diff --git a/fs/xfs/xfs_sync.c b/fs/xfs/xfs_sync.c index aa3dc1a4d53d..be5c51d8f757 100644 --- a/fs/xfs/xfs_sync.c +++ b/fs/xfs/xfs_sync.c | |||
@@ -770,6 +770,17 @@ restart: | |||
770 | if (!xfs_iflock_nowait(ip)) { | 770 | if (!xfs_iflock_nowait(ip)) { |
771 | if (!(sync_mode & SYNC_WAIT)) | 771 | if (!(sync_mode & SYNC_WAIT)) |
772 | goto out; | 772 | goto out; |
773 | |||
774 | /* | ||
775 | * If we only have a single dirty inode in a cluster there is | ||
776 | * a fair chance that the AIL push may have pushed it into | ||
777 | * the buffer, but xfsbufd won't touch it until 30 seconds | ||
778 | * from now, and thus we will lock up here. | ||
779 | * | ||
780 | * Promote the inode buffer to the front of the delwri list | ||
781 | * and wake up xfsbufd now. | ||
782 | */ | ||
783 | xfs_promote_inode(ip); | ||
773 | xfs_iflock(ip); | 784 | xfs_iflock(ip); |
774 | } | 785 | } |
775 | 786 | ||
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index f1d2802b2f07..494035798873 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h | |||
@@ -834,18 +834,14 @@ DEFINE_LOGGRANT_EVENT(xfs_log_umount_write); | |||
834 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_enter); | 834 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_enter); |
835 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_exit); | 835 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_exit); |
836 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_error); | 836 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_error); |
837 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep1); | 837 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep); |
838 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake1); | 838 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake); |
839 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep2); | ||
840 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake2); | ||
841 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake_up); | 839 | DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake_up); |
842 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_enter); | 840 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_enter); |
843 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_exit); | 841 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_exit); |
844 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_error); | 842 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_error); |
845 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep1); | 843 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep); |
846 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake1); | 844 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake); |
847 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep2); | ||
848 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake2); | ||
849 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake_up); | 845 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake_up); |
850 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_enter); | 846 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_enter); |
851 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_exit); | 847 | DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_exit); |