aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2012-05-23 14:13:11 -0400
committerJosef Bacik <josef@redhat.com>2012-05-30 10:23:36 -0400
commit72ac3c0d7921f943d92d1ef42a549fb52e56817d (patch)
treec8825a2b3848f201a2b67b3a2ec0aaf9669f9ed3 /fs/btrfs
parentcd023e7b17fe86c530475da210b3348421c40e5f (diff)
Btrfs: convert the inode bit field to use the actual bit operations
Miao pointed this out while I was working on an orphan problem that messing with a bitfield where different ranges are protected by different locks doesn't work out right. Turns out we've been doing this forever where we have different parts of the bit field protected by either no lock at all or different locks which could cause all sorts of weird problems including the issue I was hitting. So instead make a runtime_flags thing that we use the normal bit operations on that are all atomic so we can keep having our no/different locking for the different flags and then make force_compress it's own thing so it can be treated normally. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/btrfs_inode.h30
-rw-r--r--fs/btrfs/delayed-inode.c4
-rw-r--r--fs/btrfs/disk-io.c3
-rw-r--r--fs/btrfs/extent-tree.c11
-rw-r--r--fs/btrfs/file.c12
-rw-r--r--fs/btrfs/inode.c28
6 files changed, 44 insertions, 44 deletions
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 3771b8543a7e..6265edb219e2 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -24,6 +24,19 @@
24#include "ordered-data.h" 24#include "ordered-data.h"
25#include "delayed-inode.h" 25#include "delayed-inode.h"
26 26
27/*
28 * ordered_data_close is set by truncate when a file that used
29 * to have good data has been truncated to zero. When it is set
30 * the btrfs file release call will add this inode to the
31 * ordered operations list so that we make sure to flush out any
32 * new data the application may have written before commit.
33 */
34#define BTRFS_INODE_ORDERED_DATA_CLOSE 0
35#define BTRFS_INODE_ORPHAN_META_RESERVED 1
36#define BTRFS_INODE_DUMMY 2
37#define BTRFS_INODE_IN_DEFRAG 3
38#define BTRFS_INODE_DELALLOC_META_RESERVED 4
39
27/* in memory btrfs inode */ 40/* in memory btrfs inode */
28struct btrfs_inode { 41struct btrfs_inode {
29 /* which subvolume this inode belongs to */ 42 /* which subvolume this inode belongs to */
@@ -78,6 +91,8 @@ struct btrfs_inode {
78 /* the space_info for where this inode's data allocations are done */ 91 /* the space_info for where this inode's data allocations are done */
79 struct btrfs_space_info *space_info; 92 struct btrfs_space_info *space_info;
80 93
94 unsigned long runtime_flags;
95
81 /* full 64 bit generation number, struct vfs_inode doesn't have a big 96 /* full 64 bit generation number, struct vfs_inode doesn't have a big
82 * enough field for this. 97 * enough field for this.
83 */ 98 */
@@ -142,22 +157,9 @@ struct btrfs_inode {
142 unsigned reserved_extents; 157 unsigned reserved_extents;
143 158
144 /* 159 /*
145 * ordered_data_close is set by truncate when a file that used
146 * to have good data has been truncated to zero. When it is set
147 * the btrfs file release call will add this inode to the
148 * ordered operations list so that we make sure to flush out any
149 * new data the application may have written before commit.
150 */
151 unsigned ordered_data_close:1;
152 unsigned orphan_meta_reserved:1;
153 unsigned dummy_inode:1;
154 unsigned in_defrag:1;
155 unsigned delalloc_meta_reserved:1;
156
157 /*
158 * always compress this one file 160 * always compress this one file
159 */ 161 */
160 unsigned force_compress:4; 162 unsigned force_compress;
161 163
162 struct btrfs_delayed_node *delayed_node; 164 struct btrfs_delayed_node *delayed_node;
163 165
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
index bcd40c7109fa..c18d0442ae6d 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -669,8 +669,8 @@ static int btrfs_delayed_inode_reserve_metadata(
669 return ret; 669 return ret;
670 } else if (src_rsv == &root->fs_info->delalloc_block_rsv) { 670 } else if (src_rsv == &root->fs_info->delalloc_block_rsv) {
671 spin_lock(&BTRFS_I(inode)->lock); 671 spin_lock(&BTRFS_I(inode)->lock);
672 if (BTRFS_I(inode)->delalloc_meta_reserved) { 672 if (test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED,
673 BTRFS_I(inode)->delalloc_meta_reserved = 0; 673 &BTRFS_I(inode)->runtime_flags)) {
674 spin_unlock(&BTRFS_I(inode)->lock); 674 spin_unlock(&BTRFS_I(inode)->lock);
675 release = true; 675 release = true;
676 goto migrate; 676 goto migrate;
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 19f5b450f405..0cf8ef2b5b1a 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2001,7 +2001,8 @@ int open_ctree(struct super_block *sb,
2001 BTRFS_I(fs_info->btree_inode)->root = tree_root; 2001 BTRFS_I(fs_info->btree_inode)->root = tree_root;
2002 memset(&BTRFS_I(fs_info->btree_inode)->location, 0, 2002 memset(&BTRFS_I(fs_info->btree_inode)->location, 0,
2003 sizeof(struct btrfs_key)); 2003 sizeof(struct btrfs_key));
2004 BTRFS_I(fs_info->btree_inode)->dummy_inode = 1; 2004 set_bit(BTRFS_INODE_DUMMY,
2005 &BTRFS_I(fs_info->btree_inode)->runtime_flags);
2005 insert_inode_hash(fs_info->btree_inode); 2006 insert_inode_hash(fs_info->btree_inode);
2006 2007
2007 spin_lock_init(&fs_info->block_group_cache_lock); 2008 spin_lock_init(&fs_info->block_group_cache_lock);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 59ae191d4f93..1902726fa70a 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4355,10 +4355,9 @@ static unsigned drop_outstanding_extent(struct inode *inode)
4355 BTRFS_I(inode)->outstanding_extents--; 4355 BTRFS_I(inode)->outstanding_extents--;
4356 4356
4357 if (BTRFS_I(inode)->outstanding_extents == 0 && 4357 if (BTRFS_I(inode)->outstanding_extents == 0 &&
4358 BTRFS_I(inode)->delalloc_meta_reserved) { 4358 test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED,
4359 &BTRFS_I(inode)->runtime_flags))
4359 drop_inode_space = 1; 4360 drop_inode_space = 1;
4360 BTRFS_I(inode)->delalloc_meta_reserved = 0;
4361 }
4362 4361
4363 /* 4362 /*
4364 * If we have more or the same amount of outsanding extents than we have 4363 * If we have more or the same amount of outsanding extents than we have
@@ -4465,7 +4464,8 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
4465 * Add an item to reserve for updating the inode when we complete the 4464 * Add an item to reserve for updating the inode when we complete the
4466 * delalloc io. 4465 * delalloc io.
4467 */ 4466 */
4468 if (!BTRFS_I(inode)->delalloc_meta_reserved) { 4467 if (!test_bit(BTRFS_INODE_DELALLOC_META_RESERVED,
4468 &BTRFS_I(inode)->runtime_flags)) {
4469 nr_extents++; 4469 nr_extents++;
4470 extra_reserve = 1; 4470 extra_reserve = 1;
4471 } 4471 }
@@ -4511,7 +4511,8 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
4511 4511
4512 spin_lock(&BTRFS_I(inode)->lock); 4512 spin_lock(&BTRFS_I(inode)->lock);
4513 if (extra_reserve) { 4513 if (extra_reserve) {
4514 BTRFS_I(inode)->delalloc_meta_reserved = 1; 4514 set_bit(BTRFS_INODE_DELALLOC_META_RESERVED,
4515 &BTRFS_I(inode)->runtime_flags);
4515 nr_extents--; 4516 nr_extents--;
4516 } 4517 }
4517 BTRFS_I(inode)->reserved_extents += nr_extents; 4518 BTRFS_I(inode)->reserved_extents += nr_extents;
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index cfc0ab915d03..c9005f216975 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -103,7 +103,7 @@ static void __btrfs_add_inode_defrag(struct inode *inode,
103 goto exists; 103 goto exists;
104 } 104 }
105 } 105 }
106 BTRFS_I(inode)->in_defrag = 1; 106 set_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags);
107 rb_link_node(&defrag->rb_node, parent, p); 107 rb_link_node(&defrag->rb_node, parent, p);
108 rb_insert_color(&defrag->rb_node, &root->fs_info->defrag_inodes); 108 rb_insert_color(&defrag->rb_node, &root->fs_info->defrag_inodes);
109 return; 109 return;
@@ -131,7 +131,7 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
131 if (btrfs_fs_closing(root->fs_info)) 131 if (btrfs_fs_closing(root->fs_info))
132 return 0; 132 return 0;
133 133
134 if (BTRFS_I(inode)->in_defrag) 134 if (test_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags))
135 return 0; 135 return 0;
136 136
137 if (trans) 137 if (trans)
@@ -148,7 +148,7 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
148 defrag->root = root->root_key.objectid; 148 defrag->root = root->root_key.objectid;
149 149
150 spin_lock(&root->fs_info->defrag_inodes_lock); 150 spin_lock(&root->fs_info->defrag_inodes_lock);
151 if (!BTRFS_I(inode)->in_defrag) 151 if (!test_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags))
152 __btrfs_add_inode_defrag(inode, defrag); 152 __btrfs_add_inode_defrag(inode, defrag);
153 else 153 else
154 kfree(defrag); 154 kfree(defrag);
@@ -252,7 +252,7 @@ int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info)
252 goto next; 252 goto next;
253 253
254 /* do a chunk of defrag */ 254 /* do a chunk of defrag */
255 BTRFS_I(inode)->in_defrag = 0; 255 clear_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags);
256 range.start = defrag->last_offset; 256 range.start = defrag->last_offset;
257 num_defrag = btrfs_defrag_file(inode, NULL, &range, defrag->transid, 257 num_defrag = btrfs_defrag_file(inode, NULL, &range, defrag->transid,
258 defrag_batch); 258 defrag_batch);
@@ -1465,8 +1465,8 @@ int btrfs_release_file(struct inode *inode, struct file *filp)
1465 * flush down new bytes that may have been written if the 1465 * flush down new bytes that may have been written if the
1466 * application were using truncate to replace a file in place. 1466 * application were using truncate to replace a file in place.
1467 */ 1467 */
1468 if (BTRFS_I(inode)->ordered_data_close) { 1468 if (test_and_clear_bit(BTRFS_INODE_ORDERED_DATA_CLOSE,
1469 BTRFS_I(inode)->ordered_data_close = 0; 1469 &BTRFS_I(inode)->runtime_flags)) {
1470 btrfs_add_ordered_operation(NULL, BTRFS_I(inode)->root, inode); 1470 btrfs_add_ordered_operation(NULL, BTRFS_I(inode)->root, inode);
1471 if (inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT) 1471 if (inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT)
1472 filemap_flush(inode->i_mapping); 1472 filemap_flush(inode->i_mapping);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 9a1b96fd672a..91ad63901756 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2182,10 +2182,9 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode)
2182 insert = 1; 2182 insert = 1;
2183 } 2183 }
2184 2184
2185 if (!BTRFS_I(inode)->orphan_meta_reserved) { 2185 if (!test_and_set_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
2186 BTRFS_I(inode)->orphan_meta_reserved = 1; 2186 &BTRFS_I(inode)->runtime_flags))
2187 reserve = 1; 2187 reserve = 1;
2188 }
2189 spin_unlock(&root->orphan_lock); 2188 spin_unlock(&root->orphan_lock);
2190 2189
2191 /* grab metadata reservation from transaction handle */ 2190 /* grab metadata reservation from transaction handle */
@@ -2233,10 +2232,9 @@ int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode)
2233 delete_item = 1; 2232 delete_item = 1;
2234 } 2233 }
2235 2234
2236 if (BTRFS_I(inode)->orphan_meta_reserved) { 2235 if (test_and_clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
2237 BTRFS_I(inode)->orphan_meta_reserved = 0; 2236 &BTRFS_I(inode)->runtime_flags))
2238 release_rsv = 1; 2237 release_rsv = 1;
2239 }
2240 spin_unlock(&root->orphan_lock); 2238 spin_unlock(&root->orphan_lock);
2241 2239
2242 if (trans && delete_item) { 2240 if (trans && delete_item) {
@@ -3642,7 +3640,8 @@ static int btrfs_setsize(struct inode *inode, loff_t newsize)
3642 * any new writes get down to disk quickly. 3640 * any new writes get down to disk quickly.
3643 */ 3641 */
3644 if (newsize == 0) 3642 if (newsize == 0)
3645 BTRFS_I(inode)->ordered_data_close = 1; 3643 set_bit(BTRFS_INODE_ORDERED_DATA_CLOSE,
3644 &BTRFS_I(inode)->runtime_flags);
3646 3645
3647 /* we don't support swapfiles, so vmtruncate shouldn't fail */ 3646 /* we don't support swapfiles, so vmtruncate shouldn't fail */
3648 truncate_setsize(inode, newsize); 3647 truncate_setsize(inode, newsize);
@@ -4102,7 +4101,7 @@ static struct inode *new_simple_dir(struct super_block *s,
4102 4101
4103 BTRFS_I(inode)->root = root; 4102 BTRFS_I(inode)->root = root;
4104 memcpy(&BTRFS_I(inode)->location, key, sizeof(*key)); 4103 memcpy(&BTRFS_I(inode)->location, key, sizeof(*key));
4105 BTRFS_I(inode)->dummy_inode = 1; 4104 set_bit(BTRFS_INODE_DUMMY, &BTRFS_I(inode)->runtime_flags);
4106 4105
4107 inode->i_ino = BTRFS_EMPTY_SUBVOL_DIR_OBJECTID; 4106 inode->i_ino = BTRFS_EMPTY_SUBVOL_DIR_OBJECTID;
4108 inode->i_op = &btrfs_dir_ro_inode_operations; 4107 inode->i_op = &btrfs_dir_ro_inode_operations;
@@ -4406,7 +4405,7 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc)
4406 int ret = 0; 4405 int ret = 0;
4407 bool nolock = false; 4406 bool nolock = false;
4408 4407
4409 if (BTRFS_I(inode)->dummy_inode) 4408 if (test_bit(BTRFS_INODE_DUMMY, &BTRFS_I(inode)->runtime_flags))
4410 return 0; 4409 return 0;
4411 4410
4412 if (btrfs_fs_closing(root->fs_info) && btrfs_is_free_space_inode(root, inode)) 4411 if (btrfs_fs_closing(root->fs_info) && btrfs_is_free_space_inode(root, inode))
@@ -4439,7 +4438,7 @@ int btrfs_dirty_inode(struct inode *inode)
4439 struct btrfs_trans_handle *trans; 4438 struct btrfs_trans_handle *trans;
4440 int ret; 4439 int ret;
4441 4440
4442 if (BTRFS_I(inode)->dummy_inode) 4441 if (test_bit(BTRFS_INODE_DUMMY, &BTRFS_I(inode)->runtime_flags))
4443 return 0; 4442 return 0;
4444 4443
4445 trans = btrfs_join_transaction(root); 4444 trans = btrfs_join_transaction(root);
@@ -6752,7 +6751,8 @@ static int btrfs_truncate(struct inode *inode)
6752 * using truncate to replace the contents of the file will 6751 * using truncate to replace the contents of the file will
6753 * end up with a zero length file after a crash. 6752 * end up with a zero length file after a crash.
6754 */ 6753 */
6755 if (inode->i_size == 0 && BTRFS_I(inode)->ordered_data_close) 6754 if (inode->i_size == 0 && test_bit(BTRFS_INODE_ORDERED_DATA_CLOSE,
6755 &BTRFS_I(inode)->runtime_flags))
6756 btrfs_add_ordered_operation(trans, root, inode); 6756 btrfs_add_ordered_operation(trans, root, inode);
6757 6757
6758 while (1) { 6758 while (1) {
@@ -6889,11 +6889,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
6889 ei->outstanding_extents = 0; 6889 ei->outstanding_extents = 0;
6890 ei->reserved_extents = 0; 6890 ei->reserved_extents = 0;
6891 6891
6892 ei->ordered_data_close = 0; 6892 ei->runtime_flags = 0;
6893 ei->orphan_meta_reserved = 0;
6894 ei->dummy_inode = 0;
6895 ei->in_defrag = 0;
6896 ei->delalloc_meta_reserved = 0;
6897 ei->force_compress = BTRFS_COMPRESS_NONE; 6893 ei->force_compress = BTRFS_COMPRESS_NONE;
6898 6894
6899 ei->delayed_node = NULL; 6895 ei->delayed_node = NULL;