History

Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable

* git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: Btrfs: Clear space_info full when adding new devices Btrfs: Fix locking around adding new space_info

Linus Torvalds committed 17 years ago

Commit fe2fd6c2 parents a8e7d49 913d9523 files · +59 −3Browse files

Unified · Split

3 files
  1. fs/btrfs/ctree.h +9 −0
  2. fs/btrfs/extent-tree.c +42 −3
  3. fs/btrfs/volumes.c +8 −0
fs/btrfs/ctree.h+9−0
@@ -784,7 +784,14 @@ struct btrfs_fs_info { · 783 unmodified lines
784 struct list_head dirty_cowonly_roots;784 struct list_head dirty_cowonly_roots;
785 785
786 struct btrfs_fs_devices *fs_devices;786 struct btrfs_fs_devices *fs_devices;
787
788 /*
789 * the space_info list is almost entirely read only. It only changes
790 * when we add a new raid type to the FS, and that happens
791 * very rarely. RCU is used to protect it.
792 */
787 struct list_head space_info;793 struct list_head space_info;
794
788 spinlock_t delalloc_lock;795 spinlock_t delalloc_lock;
789 spinlock_t new_trans_lock;796 spinlock_t new_trans_lock;
790 u64 delalloc_bytes;797 u64 delalloc_bytes;
@@ -1797,6 +1804,8 @@ int btrfs_cleanup_reloc_trees(struct btrfs_root *root); · 1006 unmodified lines
1797int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len);1804int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len);
1798u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags);1805u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags);
1799void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde);1806void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde);
1807void btrfs_clear_space_info_full(struct btrfs_fs_info *info);
1808
1800int btrfs_check_metadata_free_space(struct btrfs_root *root);1809int btrfs_check_metadata_free_space(struct btrfs_root *root);
1801int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,1810int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
1802 u64 bytes);1811 u64 bytes);
fs/btrfs/extent-tree.c+42−3
@@ -20,6 +20,7 @@ · 19 unmodified lines
20#include <linux/writeback.h>20#include <linux/writeback.h>
21#include <linux/blkdev.h>21#include <linux/blkdev.h>
22#include <linux/sort.h>22#include <linux/sort.h>
23#include <linux/rcupdate.h>
23#include "compat.h"24#include "compat.h"
24#include "hash.h"25#include "hash.h"
25#include "crc32c.h"26#include "crc32c.h"
@@ -330,13 +331,33 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, · 304 unmodified lines
330{331{
331 struct list_head *head = &info->space_info;332 struct list_head *head = &info->space_info;
332 struct btrfs_space_info *found;333 struct btrfs_space_info *found;
333 list_for_each_entry(found, head, list) {334
334 if (found->flags == flags)335 rcu_read_lock();
336 list_for_each_entry_rcu(found, head, list) {
337 if (found->flags == flags) {
338 rcu_read_unlock();
335 return found;339 return found;
340 }
336 }341 }
342 rcu_read_unlock();
337 return NULL;343 return NULL;
338}344}
339 345
346/*
347 * after adding space to the filesystem, we need to clear the full flags
348 * on all the space infos.
349 */
350void btrfs_clear_space_info_full(struct btrfs_fs_info *info)
351{
352 struct list_head *head = &info->space_info;
353 struct btrfs_space_info *found;
354
355 rcu_read_lock();
356 list_for_each_entry_rcu(found, head, list)
357 found->full = 0;
358 rcu_read_unlock();
359}
360
340static u64 div_factor(u64 num, int factor)361static u64 div_factor(u64 num, int factor)
341{362{
342 if (factor == 10)363 if (factor == 10)
@@ -1903,7 +1924,6 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, · 1560 unmodified lines
1903 if (!found)1924 if (!found)
1904 return -ENOMEM;1925 return -ENOMEM;
1905 1926
1906 list_add(&found->list, &info->space_info);
1907 INIT_LIST_HEAD(&found->block_groups);1927 INIT_LIST_HEAD(&found->block_groups);
1908 init_rwsem(&found->groups_sem);1928 init_rwsem(&found->groups_sem);
1909 spin_lock_init(&found->lock);1929 spin_lock_init(&found->lock);
@@ -1917,6 +1937,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, · 7 unmodified lines
1917 found->full = 0;1937 found->full = 0;
1918 found->force_alloc = 0;1938 found->force_alloc = 0;
1919 *space_info = found;1939 *space_info = found;
1940 list_add_rcu(&found->list, &info->space_info);
1920 return 0;1941 return 0;
1921}1942}
1922 1943
@@ -6320,6 +6341,7 @@ out: · 4397 unmodified lines
6320int btrfs_free_block_groups(struct btrfs_fs_info *info)6341int btrfs_free_block_groups(struct btrfs_fs_info *info)
6321{6342{
6322 struct btrfs_block_group_cache *block_group;6343 struct btrfs_block_group_cache *block_group;
6344 struct btrfs_space_info *space_info;
6323 struct rb_node *n;6345 struct rb_node *n;
6324 6346
6325 spin_lock(&info->block_group_cache_lock);6347 spin_lock(&info->block_group_cache_lock);
@@ -6341,6 +6363,23 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) · 15 unmodified lines
6341 spin_lock(&info->block_group_cache_lock);6363 spin_lock(&info->block_group_cache_lock);
6342 }6364 }
6343 spin_unlock(&info->block_group_cache_lock);6365 spin_unlock(&info->block_group_cache_lock);
6366
6367 /* now that all the block groups are freed, go through and
6368 * free all the space_info structs. This is only called during
6369 * the final stages of unmount, and so we know nobody is
6370 * using them. We call synchronize_rcu() once before we start,
6371 * just to be on the safe side.
6372 */
6373 synchronize_rcu();
6374
6375 while(!list_empty(&info->space_info)) {
6376 space_info = list_entry(info->space_info.next,
6377 struct btrfs_space_info,
6378 list);
6379
6380 list_del(&space_info->list);
6381 kfree(space_info);
6382 }
6344 return 0;6383 return 0;
6345}6384}
6346 6385
fs/btrfs/volumes.c+8−0
@@ -1374,6 +1374,12 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) · 1373 unmodified lines
1374 ret = btrfs_add_device(trans, root, device);1374 ret = btrfs_add_device(trans, root, device);
1375 }1375 }
1376 1376
1377 /*
1378 * we've got more storage, clear any full flags on the space
1379 * infos
1380 */
1381 btrfs_clear_space_info_full(root->fs_info);
1382
1377 unlock_chunks(root);1383 unlock_chunks(root);
1378 btrfs_commit_transaction(trans, root);1384 btrfs_commit_transaction(trans, root);
1379 1385
@@ -1459,6 +1465,8 @@ static int __btrfs_grow_device(struct btrfs_trans_handle *trans, · 79 unmodified lines
1459 device->fs_devices->total_rw_bytes += diff;1465 device->fs_devices->total_rw_bytes += diff;
1460 1466
1461 device->total_bytes = new_size;1467 device->total_bytes = new_size;
1468 btrfs_clear_space_info_full(device->dev_root->fs_info);
1469
1462 return btrfs_update_device(trans, device);1470 return btrfs_update_device(trans, device);
1463}1471}
1464 1472