aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/disk-io.c9
-rw-r--r--fs/btrfs/extent-tree.c248
-rw-r--r--fs/btrfs/free-space-cache.c57
-rw-r--r--fs/btrfs/super.c13
-rw-r--r--fs/btrfs/transaction.c2
-rw-r--r--fs/btrfs/transaction.h2
-rw-r--r--fs/btrfs/volumes.c63
-rw-r--r--fs/btrfs/volumes.h3
9 files changed, 342 insertions, 58 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index d4042c89d29b..938efe33be80 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -3431,6 +3431,8 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
3431 struct btrfs_root *root, u64 group_start, 3431 struct btrfs_root *root, u64 group_start,
3432 struct extent_map *em); 3432 struct extent_map *em);
3433void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info); 3433void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info);
3434void btrfs_get_block_group_trimming(struct btrfs_block_group_cache *cache);
3435void btrfs_put_block_group_trimming(struct btrfs_block_group_cache *cache);
3434void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans, 3436void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans,
3435 struct btrfs_root *root); 3437 struct btrfs_root *root);
3436u64 btrfs_get_alloc_profile(struct btrfs_root *root, int data); 3438u64 btrfs_get_alloc_profile(struct btrfs_root *root, int data);
@@ -4067,6 +4069,7 @@ __cold
4067void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, 4069void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function,
4068 unsigned int line, int errno, const char *fmt, ...); 4070 unsigned int line, int errno, const char *fmt, ...);
4069 4071
4072const char *btrfs_decode_error(int errno);
4070 4073
4071__cold 4074__cold
4072void __btrfs_abort_transaction(struct btrfs_trans_handle *trans, 4075void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 230546b45474..cc15514b4a76 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3761,6 +3761,15 @@ void close_ctree(struct btrfs_root *root)
3761 cancel_work_sync(&fs_info->async_reclaim_work); 3761 cancel_work_sync(&fs_info->async_reclaim_work);
3762 3762
3763 if (!(fs_info->sb->s_flags & MS_RDONLY)) { 3763 if (!(fs_info->sb->s_flags & MS_RDONLY)) {
3764 /*
3765 * If the cleaner thread is stopped and there are
3766 * block groups queued for removal, the deletion will be
3767 * skipped when we quit the cleaner thread.
3768 */
3769 mutex_lock(&root->fs_info->cleaner_mutex);
3770 btrfs_delete_unused_bgs(root->fs_info);
3771 mutex_unlock(&root->fs_info->cleaner_mutex);
3772
3764 ret = btrfs_commit_super(root); 3773 ret = btrfs_commit_super(root);
3765 if (ret) 3774 if (ret)
3766 btrfs_err(fs_info, "commit super ret %d", ret); 3775 btrfs_err(fs_info, "commit super ret %d", ret);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 59d59d98bca1..5411f0ab5683 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1882,10 +1882,77 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans,
1882 return ret; 1882 return ret;
1883} 1883}
1884 1884
1885static int btrfs_issue_discard(struct block_device *bdev, 1885#define in_range(b, first, len) ((b) >= (first) && (b) < (first) + (len))
1886 u64 start, u64 len) 1886static int btrfs_issue_discard(struct block_device *bdev, u64 start, u64 len,
1887 u64 *discarded_bytes)
1887{ 1888{
1888 return blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_NOFS, 0); 1889 int j, ret = 0;
1890 u64 bytes_left, end;
1891 u64 aligned_start = ALIGN(start, 1 << 9);
1892
1893 if (WARN_ON(start != aligned_start)) {
1894 len -= aligned_start - start;
1895 len = round_down(len, 1 << 9);
1896 start = aligned_start;
1897 }
1898
1899 *discarded_bytes = 0;
1900
1901 if (!len)
1902 return 0;
1903
1904 end = start + len;
1905 bytes_left = len;
1906
1907 /* Skip any superblocks on this device. */
1908 for (j = 0; j < BTRFS_SUPER_MIRROR_MAX; j++) {
1909 u64 sb_start = btrfs_sb_offset(j);
1910 u64 sb_end = sb_start + BTRFS_SUPER_INFO_SIZE;
1911 u64 size = sb_start - start;
1912
1913 if (!in_range(sb_start, start, bytes_left) &&
1914 !in_range(sb_end, start, bytes_left) &&
1915 !in_range(start, sb_start, BTRFS_SUPER_INFO_SIZE))
1916 continue;
1917
1918 /*
1919 * Superblock spans beginning of range. Adjust start and
1920 * try again.
1921 */
1922 if (sb_start <= start) {
1923 start += sb_end - start;
1924 if (start > end) {
1925 bytes_left = 0;
1926 break;
1927 }
1928 bytes_left = end - start;
1929 continue;
1930 }
1931
1932 if (size) {
1933 ret = blkdev_issue_discard(bdev, start >> 9, size >> 9,
1934 GFP_NOFS, 0);
1935 if (!ret)
1936 *discarded_bytes += size;
1937 else if (ret != -EOPNOTSUPP)
1938 return ret;
1939 }
1940
1941 start = sb_end;
1942 if (start > end) {
1943 bytes_left = 0;
1944 break;
1945 }
1946 bytes_left = end - start;
1947 }
1948
1949 if (bytes_left) {
1950 ret = blkdev_issue_discard(bdev, start >> 9, bytes_left >> 9,
1951 GFP_NOFS, 0);
1952 if (!ret)
1953 *discarded_bytes += bytes_left;
1954 }
1955 return ret;
1889} 1956}
1890 1957
1891int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, 1958int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
@@ -1906,14 +1973,16 @@ int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
1906 1973
1907 1974
1908 for (i = 0; i < bbio->num_stripes; i++, stripe++) { 1975 for (i = 0; i < bbio->num_stripes; i++, stripe++) {
1976 u64 bytes;
1909 if (!stripe->dev->can_discard) 1977 if (!stripe->dev->can_discard)
1910 continue; 1978 continue;
1911 1979
1912 ret = btrfs_issue_discard(stripe->dev->bdev, 1980 ret = btrfs_issue_discard(stripe->dev->bdev,
1913 stripe->physical, 1981 stripe->physical,
1914 stripe->length); 1982 stripe->length,
1983 &bytes);
1915 if (!ret) 1984 if (!ret)
1916 discarded_bytes += stripe->length; 1985 discarded_bytes += bytes;
1917 else if (ret != -EOPNOTSUPP) 1986 else if (ret != -EOPNOTSUPP)
1918 break; /* Logic errors or -ENOMEM, or -EIO but I don't know how that could happen JDM */ 1987 break; /* Logic errors or -ENOMEM, or -EIO but I don't know how that could happen JDM */
1919 1988
@@ -6061,20 +6130,19 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
6061 struct btrfs_root *root) 6130 struct btrfs_root *root)
6062{ 6131{
6063 struct btrfs_fs_info *fs_info = root->fs_info; 6132 struct btrfs_fs_info *fs_info = root->fs_info;
6133 struct btrfs_block_group_cache *block_group, *tmp;
6134 struct list_head *deleted_bgs;
6064 struct extent_io_tree *unpin; 6135 struct extent_io_tree *unpin;
6065 u64 start; 6136 u64 start;
6066 u64 end; 6137 u64 end;
6067 int ret; 6138 int ret;
6068 6139
6069 if (trans->aborted)
6070 return 0;
6071
6072 if (fs_info->pinned_extents == &fs_info->freed_extents[0]) 6140 if (fs_info->pinned_extents == &fs_info->freed_extents[0])
6073 unpin = &fs_info->freed_extents[1]; 6141 unpin = &fs_info->freed_extents[1];
6074 else 6142 else
6075 unpin = &fs_info->freed_extents[0]; 6143 unpin = &fs_info->freed_extents[0];
6076 6144
6077 while (1) { 6145 while (!trans->aborted) {
6078 mutex_lock(&fs_info->unused_bg_unpin_mutex); 6146 mutex_lock(&fs_info->unused_bg_unpin_mutex);
6079 ret = find_first_extent_bit(unpin, 0, &start, &end, 6147 ret = find_first_extent_bit(unpin, 0, &start, &end,
6080 EXTENT_DIRTY, NULL); 6148 EXTENT_DIRTY, NULL);
@@ -6093,6 +6161,34 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
6093 cond_resched(); 6161 cond_resched();
6094 } 6162 }
6095 6163
6164 /*
6165 * Transaction is finished. We don't need the lock anymore. We
6166 * do need to clean up the block groups in case of a transaction
6167 * abort.
6168 */
6169 deleted_bgs = &trans->transaction->deleted_bgs;
6170 list_for_each_entry_safe(block_group, tmp, deleted_bgs, bg_list) {
6171 u64 trimmed = 0;
6172
6173 ret = -EROFS;
6174 if (!trans->aborted)
6175 ret = btrfs_discard_extent(root,
6176 block_group->key.objectid,
6177 block_group->key.offset,
6178 &trimmed);
6179
6180 list_del_init(&block_group->bg_list);
6181 btrfs_put_block_group_trimming(block_group);
6182 btrfs_put_block_group(block_group);
6183
6184 if (ret) {
6185 const char *errstr = btrfs_decode_error(ret);
6186 btrfs_warn(fs_info,
6187 "Discard failed while removing blockgroup: errno=%d %s\n",
6188 ret, errstr);
6189 }
6190 }
6191
6096 return 0; 6192 return 0;
6097} 6193}
6098 6194
@@ -9830,6 +9926,11 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
9830 * currently running transaction might finish and a new one start, 9926 * currently running transaction might finish and a new one start,
9831 * allowing for new block groups to be created that can reuse the same 9927 * allowing for new block groups to be created that can reuse the same
9832 * physical device locations unless we take this special care. 9928 * physical device locations unless we take this special care.
9929 *
9930 * There may also be an implicit trim operation if the file system
9931 * is mounted with -odiscard. The same protections must remain
9932 * in place until the extents have been discarded completely when
9933 * the transaction commit has completed.
9833 */ 9934 */
9834 remove_em = (atomic_read(&block_group->trimming) == 0); 9935 remove_em = (atomic_read(&block_group->trimming) == 0);
9835 /* 9936 /*
@@ -9904,6 +10005,7 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
9904 spin_lock(&fs_info->unused_bgs_lock); 10005 spin_lock(&fs_info->unused_bgs_lock);
9905 while (!list_empty(&fs_info->unused_bgs)) { 10006 while (!list_empty(&fs_info->unused_bgs)) {
9906 u64 start, end; 10007 u64 start, end;
10008 int trimming;
9907 10009
9908 block_group = list_first_entry(&fs_info->unused_bgs, 10010 block_group = list_first_entry(&fs_info->unused_bgs,
9909 struct btrfs_block_group_cache, 10011 struct btrfs_block_group_cache,
@@ -10003,12 +10105,39 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
10003 spin_unlock(&block_group->lock); 10105 spin_unlock(&block_group->lock);
10004 spin_unlock(&space_info->lock); 10106 spin_unlock(&space_info->lock);
10005 10107
10108 /* DISCARD can flip during remount */
10109 trimming = btrfs_test_opt(root, DISCARD);
10110
10111 /* Implicit trim during transaction commit. */
10112 if (trimming)
10113 btrfs_get_block_group_trimming(block_group);
10114
10006 /* 10115 /*
10007 * Btrfs_remove_chunk will abort the transaction if things go 10116 * Btrfs_remove_chunk will abort the transaction if things go
10008 * horribly wrong. 10117 * horribly wrong.
10009 */ 10118 */
10010 ret = btrfs_remove_chunk(trans, root, 10119 ret = btrfs_remove_chunk(trans, root,
10011 block_group->key.objectid); 10120 block_group->key.objectid);
10121
10122 if (ret) {
10123 if (trimming)
10124 btrfs_put_block_group_trimming(block_group);
10125 goto end_trans;
10126 }
10127
10128 /*
10129 * If we're not mounted with -odiscard, we can just forget
10130 * about this block group. Otherwise we'll need to wait
10131 * until transaction commit to do the actual discard.
10132 */
10133 if (trimming) {
10134 WARN_ON(!list_empty(&block_group->bg_list));
10135 spin_lock(&trans->transaction->deleted_bgs_lock);
10136 list_move(&block_group->bg_list,
10137 &trans->transaction->deleted_bgs);
10138 spin_unlock(&trans->transaction->deleted_bgs_lock);
10139 btrfs_get_block_group(block_group);
10140 }
10012end_trans: 10141end_trans:
10013 btrfs_end_transaction(trans, root); 10142 btrfs_end_transaction(trans, root);
10014next: 10143next:
@@ -10062,10 +10191,99 @@ int btrfs_error_unpin_extent_range(struct btrfs_root *root, u64 start, u64 end)
10062 return unpin_extent_range(root, start, end, false); 10191 return unpin_extent_range(root, start, end, false);
10063} 10192}
10064 10193
10194/*
10195 * It used to be that old block groups would be left around forever.
10196 * Iterating over them would be enough to trim unused space. Since we
10197 * now automatically remove them, we also need to iterate over unallocated
10198 * space.
10199 *
10200 * We don't want a transaction for this since the discard may take a
10201 * substantial amount of time. We don't require that a transaction be
10202 * running, but we do need to take a running transaction into account
10203 * to ensure that we're not discarding chunks that were released in
10204 * the current transaction.
10205 *
10206 * Holding the chunks lock will prevent other threads from allocating
10207 * or releasing chunks, but it won't prevent a running transaction
10208 * from committing and releasing the memory that the pending chunks
10209 * list head uses. For that, we need to take a reference to the
10210 * transaction.
10211 */
10212static int btrfs_trim_free_extents(struct btrfs_device *device,
10213 u64 minlen, u64 *trimmed)
10214{
10215 u64 start = 0, len = 0;
10216 int ret;
10217
10218 *trimmed = 0;
10219
10220 /* Not writeable = nothing to do. */
10221 if (!device->writeable)
10222 return 0;
10223
10224 /* No free space = nothing to do. */
10225 if (device->total_bytes <= device->bytes_used)
10226 return 0;
10227
10228 ret = 0;
10229
10230 while (1) {
10231 struct btrfs_fs_info *fs_info = device->dev_root->fs_info;
10232 struct btrfs_transaction *trans;
10233 u64 bytes;
10234
10235 ret = mutex_lock_interruptible(&fs_info->chunk_mutex);
10236 if (ret)
10237 return ret;
10238
10239 down_read(&fs_info->commit_root_sem);
10240
10241 spin_lock(&fs_info->trans_lock);
10242 trans = fs_info->running_transaction;
10243 if (trans)
10244 atomic_inc(&trans->use_count);
10245 spin_unlock(&fs_info->trans_lock);
10246
10247 ret = find_free_dev_extent_start(trans, device, minlen, start,
10248 &start, &len);
10249 if (trans)
10250 btrfs_put_transaction(trans);
10251
10252 if (ret) {
10253 up_read(&fs_info->commit_root_sem);
10254 mutex_unlock(&fs_info->chunk_mutex);
10255 if (ret == -ENOSPC)
10256 ret = 0;
10257 break;
10258 }
10259
10260 ret = btrfs_issue_discard(device->bdev, start, len, &bytes);
10261 up_read(&fs_info->commit_root_sem);
10262 mutex_unlock(&fs_info->chunk_mutex);
10263
10264 if (ret)
10265 break;
10266
10267 start += len;
10268 *trimmed += bytes;
10269
10270 if (fatal_signal_pending(current)) {
10271 ret = -ERESTARTSYS;
10272 break;
10273 }
10274
10275 cond_resched();
10276 }
10277
10278 return ret;
10279}
10280
10065int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) 10281int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range)
10066{ 10282{
10067 struct btrfs_fs_info *fs_info = root->fs_info; 10283 struct btrfs_fs_info *fs_info = root->fs_info;
10068 struct btrfs_block_group_cache *cache = NULL; 10284 struct btrfs_block_group_cache *cache = NULL;
10285 struct btrfs_device *device;
10286 struct list_head *devices;
10069 u64 group_trimmed; 10287 u64 group_trimmed;
10070 u64 start; 10288 u64 start;
10071 u64 end; 10289 u64 end;
@@ -10120,6 +10338,18 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range)
10120 cache = next_block_group(fs_info->tree_root, cache); 10338 cache = next_block_group(fs_info->tree_root, cache);
10121 } 10339 }
10122 10340
10341 mutex_lock(&root->fs_info->fs_devices->device_list_mutex);
10342 devices = &root->fs_info->fs_devices->alloc_list;
10343 list_for_each_entry(device, devices, dev_alloc_list) {
10344 ret = btrfs_trim_free_extents(device, range->minlen,
10345 &group_trimmed);
10346 if (ret)
10347 break;
10348
10349 trimmed += group_trimmed;
10350 }
10351 mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
10352
10123 range->len = trimmed; 10353 range->len = trimmed;
10124 return ret; 10354 return ret;
10125} 10355}
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index fb5a6b1c62a6..abe3a66bd3ba 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -3272,35 +3272,23 @@ next:
3272 return ret; 3272 return ret;
3273} 3273}
3274 3274
3275int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group, 3275void btrfs_get_block_group_trimming(struct btrfs_block_group_cache *cache)
3276 u64 *trimmed, u64 start, u64 end, u64 minlen)
3277{ 3276{
3278 int ret; 3277 atomic_inc(&cache->trimming);
3278}
3279 3279
3280 *trimmed = 0; 3280void btrfs_put_block_group_trimming(struct btrfs_block_group_cache *block_group)
3281{
3282 struct extent_map_tree *em_tree;
3283 struct extent_map *em;
3284 bool cleanup;
3281 3285
3282 spin_lock(&block_group->lock); 3286 spin_lock(&block_group->lock);
3283 if (block_group->removed) { 3287 cleanup = (atomic_dec_and_test(&block_group->trimming) &&
3284 spin_unlock(&block_group->lock); 3288 block_group->removed);
3285 return 0;
3286 }
3287 atomic_inc(&block_group->trimming);
3288 spin_unlock(&block_group->lock); 3289 spin_unlock(&block_group->lock);
3289 3290
3290 ret = trim_no_bitmap(block_group, trimmed, start, end, minlen); 3291 if (cleanup) {
3291 if (ret)
3292 goto out;
3293
3294 ret = trim_bitmaps(block_group, trimmed, start, end, minlen);
3295out:
3296 spin_lock(&block_group->lock);
3297 if (atomic_dec_and_test(&block_group->trimming) &&
3298 block_group->removed) {
3299 struct extent_map_tree *em_tree;
3300 struct extent_map *em;
3301
3302 spin_unlock(&block_group->lock);
3303
3304 lock_chunks(block_group->fs_info->chunk_root); 3292 lock_chunks(block_group->fs_info->chunk_root);
3305 em_tree = &block_group->fs_info->mapping_tree.map_tree; 3293 em_tree = &block_group->fs_info->mapping_tree.map_tree;
3306 write_lock(&em_tree->lock); 3294 write_lock(&em_tree->lock);
@@ -3324,10 +3312,31 @@ out:
3324 * this block group have left 1 entry each one. Free them. 3312 * this block group have left 1 entry each one. Free them.
3325 */ 3313 */
3326 __btrfs_remove_free_space_cache(block_group->free_space_ctl); 3314 __btrfs_remove_free_space_cache(block_group->free_space_ctl);
3327 } else { 3315 }
3316}
3317
3318int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group,
3319 u64 *trimmed, u64 start, u64 end, u64 minlen)
3320{
3321 int ret;
3322
3323 *trimmed = 0;
3324
3325 spin_lock(&block_group->lock);
3326 if (block_group->removed) {
3328 spin_unlock(&block_group->lock); 3327 spin_unlock(&block_group->lock);
3328 return 0;
3329 } 3329 }
3330 btrfs_get_block_group_trimming(block_group);
3331 spin_unlock(&block_group->lock);
3332
3333 ret = trim_no_bitmap(block_group, trimmed, start, end, minlen);
3334 if (ret)
3335 goto out;
3330 3336
3337 ret = trim_bitmaps(block_group, trimmed, start, end, minlen);
3338out:
3339 btrfs_put_block_group_trimming(block_group);
3331 return ret; 3340 return ret;
3332} 3341}
3333 3342
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index d366dd4664d0..c389c13f0f38 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -69,7 +69,7 @@ static struct file_system_type btrfs_fs_type;
69 69
70static int btrfs_remount(struct super_block *sb, int *flags, char *data); 70static int btrfs_remount(struct super_block *sb, int *flags, char *data);
71 71
72static const char *btrfs_decode_error(int errno) 72const char *btrfs_decode_error(int errno)
73{ 73{
74 char *errstr = "unknown"; 74 char *errstr = "unknown";
75 75
@@ -1651,6 +1651,17 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
1651 1651
1652 sb->s_flags |= MS_RDONLY; 1652 sb->s_flags |= MS_RDONLY;
1653 1653
1654 /*
1655 * Setting MS_RDONLY will put the cleaner thread to
1656 * sleep at the next loop if it's already active.
1657 * If it's already asleep, we'll leave unused block
1658 * groups on disk until we're mounted read-write again
1659 * unless we clean them up here.
1660 */
1661 mutex_lock(&root->fs_info->cleaner_mutex);
1662 btrfs_delete_unused_bgs(fs_info);
1663 mutex_unlock(&root->fs_info->cleaner_mutex);
1664
1654 btrfs_dev_replace_suspend_for_unmount(fs_info); 1665 btrfs_dev_replace_suspend_for_unmount(fs_info);
1655 btrfs_scrub_cancel(fs_info); 1666 btrfs_scrub_cancel(fs_info);
1656 btrfs_pause_balance(fs_info); 1667 btrfs_pause_balance(fs_info);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 91f44c9f7ebc..20267d47dbcd 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -258,6 +258,8 @@ loop:
258 mutex_init(&cur_trans->cache_write_mutex); 258 mutex_init(&cur_trans->cache_write_mutex);
259 cur_trans->num_dirty_bgs = 0; 259 cur_trans->num_dirty_bgs = 0;
260 spin_lock_init(&cur_trans->dirty_bgs_lock); 260 spin_lock_init(&cur_trans->dirty_bgs_lock);
261 INIT_LIST_HEAD(&cur_trans->deleted_bgs);
262 spin_lock_init(&cur_trans->deleted_bgs_lock);
261 list_add_tail(&cur_trans->list, &fs_info->trans_list); 263 list_add_tail(&cur_trans->list, &fs_info->trans_list);
262 extent_io_tree_init(&cur_trans->dirty_pages, 264 extent_io_tree_init(&cur_trans->dirty_pages,
263 fs_info->btree_inode->i_mapping); 265 fs_info->btree_inode->i_mapping);
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
index eb09c2067fa8..edc2fbc262d7 100644
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -74,6 +74,8 @@ struct btrfs_transaction {
74 */ 74 */
75 struct mutex cache_write_mutex; 75 struct mutex cache_write_mutex;
76 spinlock_t dirty_bgs_lock; 76 spinlock_t dirty_bgs_lock;
77 struct list_head deleted_bgs;
78 spinlock_t deleted_bgs_lock;
77 struct btrfs_delayed_ref_root delayed_refs; 79 struct btrfs_delayed_ref_root delayed_refs;
78 int aborted; 80 int aborted;
79 int dirty_bg_run; 81 int dirty_bg_run;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 88e2fe931bde..7c84a8122c37 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1116,15 +1116,18 @@ out:
1116 return ret; 1116 return ret;
1117} 1117}
1118 1118
1119static int contains_pending_extent(struct btrfs_trans_handle *trans, 1119static int contains_pending_extent(struct btrfs_transaction *transaction,
1120 struct btrfs_device *device, 1120 struct btrfs_device *device,
1121 u64 *start, u64 len) 1121 u64 *start, u64 len)
1122{ 1122{
1123 struct btrfs_fs_info *fs_info = device->dev_root->fs_info;
1123 struct extent_map *em; 1124 struct extent_map *em;
1124 struct list_head *search_list = &trans->transaction->pending_chunks; 1125 struct list_head *search_list = &fs_info->pinned_chunks;
1125 int ret = 0; 1126 int ret = 0;
1126 u64 physical_start = *start; 1127 u64 physical_start = *start;
1127 1128
1129 if (transaction)
1130 search_list = &transaction->pending_chunks;
1128again: 1131again:
1129 list_for_each_entry(em, search_list, list) { 1132 list_for_each_entry(em, search_list, list) {
1130 struct map_lookup *map; 1133 struct map_lookup *map;
@@ -1159,8 +1162,8 @@ again:
1159 } 1162 }
1160 } 1163 }
1161 } 1164 }
1162 if (search_list == &trans->transaction->pending_chunks) { 1165 if (search_list != &fs_info->pinned_chunks) {
1163 search_list = &trans->root->fs_info->pinned_chunks; 1166 search_list = &fs_info->pinned_chunks;
1164 goto again; 1167 goto again;
1165 } 1168 }
1166 1169
@@ -1169,12 +1172,13 @@ again:
1169 1172
1170 1173
1171/* 1174/*
1172 * find_free_dev_extent - find free space in the specified device 1175 * find_free_dev_extent_start - find free space in the specified device
1173 * @device: the device which we search the free space in 1176 * @device: the device which we search the free space in
1174 * @num_bytes: the size of the free space that we need 1177 * @num_bytes: the size of the free space that we need
1175 * @start: store the start of the free space. 1178 * @search_start: the position from which to begin the search
1176 * @len: the size of the free space. that we find, or the size of the max 1179 * @start: store the start of the free space.
1177 * free space if we don't find suitable free space 1180 * @len: the size of the free space. that we find, or the size
1181 * of the max free space if we don't find suitable free space
1178 * 1182 *
1179 * this uses a pretty simple search, the expectation is that it is 1183 * this uses a pretty simple search, the expectation is that it is
1180 * called very infrequently and that a given device has a small number 1184 * called very infrequently and that a given device has a small number
@@ -1188,9 +1192,9 @@ again:
1188 * But if we don't find suitable free space, it is used to store the size of 1192 * But if we don't find suitable free space, it is used to store the size of
1189 * the max free space. 1193 * the max free space.
1190 */ 1194 */
1191int find_free_dev_extent(struct btrfs_trans_handle *trans, 1195int find_free_dev_extent_start(struct btrfs_transaction *transaction,
1192 struct btrfs_device *device, u64 num_bytes, 1196 struct btrfs_device *device, u64 num_bytes,
1193 u64 *start, u64 *len) 1197 u64 search_start, u64 *start, u64 *len)
1194{ 1198{
1195 struct btrfs_key key; 1199 struct btrfs_key key;
1196 struct btrfs_root *root = device->dev_root; 1200 struct btrfs_root *root = device->dev_root;
@@ -1200,19 +1204,11 @@ int find_free_dev_extent(struct btrfs_trans_handle *trans,
1200 u64 max_hole_start; 1204 u64 max_hole_start;
1201 u64 max_hole_size; 1205 u64 max_hole_size;
1202 u64 extent_end; 1206 u64 extent_end;
1203 u64 search_start;
1204 u64 search_end = device->total_bytes; 1207 u64 search_end = device->total_bytes;
1205 int ret; 1208 int ret;
1206 int slot; 1209 int slot;
1207 struct extent_buffer *l; 1210 struct extent_buffer *l;
1208 1211
1209 /* FIXME use last free of some kind */
1210
1211 /* we don't want to overwrite the superblock on the drive,
1212 * so we make sure to start at an offset of at least 1MB
1213 */
1214 search_start = max(root->fs_info->alloc_start, 1024ull * 1024);
1215
1216 path = btrfs_alloc_path(); 1212 path = btrfs_alloc_path();
1217 if (!path) 1213 if (!path)
1218 return -ENOMEM; 1214 return -ENOMEM;
@@ -1273,7 +1269,7 @@ again:
1273 * Have to check before we set max_hole_start, otherwise 1269 * Have to check before we set max_hole_start, otherwise
1274 * we could end up sending back this offset anyway. 1270 * we could end up sending back this offset anyway.
1275 */ 1271 */
1276 if (contains_pending_extent(trans, device, 1272 if (contains_pending_extent(transaction, device,
1277 &search_start, 1273 &search_start,
1278 hole_size)) { 1274 hole_size)) {
1279 if (key.offset >= search_start) { 1275 if (key.offset >= search_start) {
@@ -1322,7 +1318,7 @@ next:
1322 if (search_end > search_start) { 1318 if (search_end > search_start) {
1323 hole_size = search_end - search_start; 1319 hole_size = search_end - search_start;
1324 1320
1325 if (contains_pending_extent(trans, device, &search_start, 1321 if (contains_pending_extent(transaction, device, &search_start,
1326 hole_size)) { 1322 hole_size)) {
1327 btrfs_release_path(path); 1323 btrfs_release_path(path);
1328 goto again; 1324 goto again;
@@ -1348,6 +1344,24 @@ out:
1348 return ret; 1344 return ret;
1349} 1345}
1350 1346
1347int find_free_dev_extent(struct btrfs_trans_handle *trans,
1348 struct btrfs_device *device, u64 num_bytes,
1349 u64 *start, u64 *len)
1350{
1351 struct btrfs_root *root = device->dev_root;
1352 u64 search_start;
1353
1354 /* FIXME use last free of some kind */
1355
1356 /*
1357 * we don't want to overwrite the superblock on the drive,
1358 * so we make sure to start at an offset of at least 1MB
1359 */
1360 search_start = max(root->fs_info->alloc_start, 1024ull * 1024);
1361 return find_free_dev_extent_start(trans->transaction, device,
1362 num_bytes, search_start, start, len);
1363}
1364
1351static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans, 1365static int btrfs_free_dev_extent(struct btrfs_trans_handle *trans,
1352 struct btrfs_device *device, 1366 struct btrfs_device *device,
1353 u64 start, u64 *dev_extent_len) 1367 u64 start, u64 *dev_extent_len)
@@ -4196,7 +4210,8 @@ again:
4196 u64 start = new_size; 4210 u64 start = new_size;
4197 u64 len = old_size - new_size; 4211 u64 len = old_size - new_size;
4198 4212
4199 if (contains_pending_extent(trans, device, &start, len)) { 4213 if (contains_pending_extent(trans->transaction, device,
4214 &start, len)) {
4200 unlock_chunks(root); 4215 unlock_chunks(root);
4201 checked_pending_chunks = true; 4216 checked_pending_chunks = true;
4202 failed = 0; 4217 failed = 0;
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 95842a909e7f..2ca784a14e84 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -453,6 +453,9 @@ int btrfs_cancel_balance(struct btrfs_fs_info *fs_info);
453int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info); 453int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info);
454int btrfs_check_uuid_tree(struct btrfs_fs_info *fs_info); 454int btrfs_check_uuid_tree(struct btrfs_fs_info *fs_info);
455int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset); 455int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset);
456int find_free_dev_extent_start(struct btrfs_transaction *transaction,
457 struct btrfs_device *device, u64 num_bytes,
458 u64 search_start, u64 *start, u64 *max_avail);
456int find_free_dev_extent(struct btrfs_trans_handle *trans, 459int find_free_dev_extent(struct btrfs_trans_handle *trans,
457 struct btrfs_device *device, u64 num_bytes, 460 struct btrfs_device *device, u64 num_bytes,
458 u64 *start, u64 *max_avail); 461 u64 *start, u64 *max_avail);