aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
authorYan, Zheng <zheng.yan@oracle.com>2010-05-16 10:48:46 -0400
committerChris Mason <chris.mason@oracle.com>2010-05-25 10:34:50 -0400
commita22285a6a32390195235171b89d157ed1a1fe932 (patch)
tree3fabc88a029e1af4f2fdcc708e7b62ef3cf3703a /fs/btrfs/transaction.c
parentf0486c68e4bd9a06a5904d3eeb3a0d73a83befb8 (diff)
Btrfs: Integrate metadata reservation with start_transaction
Besides simplify the code, this change makes sure all metadata reservation for normal metadata operations are released after committing transaction. Changes since V1: Add code that check if unlink and rmdir will free space. Add ENOSPC handling for clone ioctl. Signed-off-by: Yan Zheng <zheng.yan@oracle.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c131
1 files changed, 90 insertions, 41 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 21ad37c05199..2616491a5c5b 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -165,53 +165,89 @@ enum btrfs_trans_type {
165 TRANS_USERSPACE, 165 TRANS_USERSPACE,
166}; 166};
167 167
168static int may_wait_transaction(struct btrfs_root *root, int type)
169{
170 if (!root->fs_info->log_root_recovering &&
171 ((type == TRANS_START && !root->fs_info->open_ioctl_trans) ||
172 type == TRANS_USERSPACE))
173 return 1;
174 return 0;
175}
176
168static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, 177static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
169 int num_blocks, int type) 178 u64 num_items, int type)
170{ 179{
171 struct btrfs_trans_handle *h = 180 struct btrfs_trans_handle *h;
172 kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS); 181 struct btrfs_transaction *cur_trans;
182 int retries = 0;
173 int ret; 183 int ret;
184again:
185 h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
186 if (!h)
187 return ERR_PTR(-ENOMEM);
174 188
175 mutex_lock(&root->fs_info->trans_mutex); 189 mutex_lock(&root->fs_info->trans_mutex);
176 if (!root->fs_info->log_root_recovering && 190 if (may_wait_transaction(root, type))
177 ((type == TRANS_START && !root->fs_info->open_ioctl_trans) ||
178 type == TRANS_USERSPACE))
179 wait_current_trans(root); 191 wait_current_trans(root);
192
180 ret = join_transaction(root); 193 ret = join_transaction(root);
181 BUG_ON(ret); 194 BUG_ON(ret);
182 195
183 h->transid = root->fs_info->running_transaction->transid; 196 cur_trans = root->fs_info->running_transaction;
184 h->transaction = root->fs_info->running_transaction; 197 cur_trans->use_count++;
185 h->blocks_reserved = num_blocks; 198 mutex_unlock(&root->fs_info->trans_mutex);
199
200 h->transid = cur_trans->transid;
201 h->transaction = cur_trans;
186 h->blocks_used = 0; 202 h->blocks_used = 0;
187 h->block_group = 0; 203 h->block_group = 0;
204 h->bytes_reserved = 0;
188 h->delayed_ref_updates = 0; 205 h->delayed_ref_updates = 0;
189 h->block_rsv = NULL; 206 h->block_rsv = NULL;
190 207
191 if (!current->journal_info && type != TRANS_USERSPACE) 208 smp_mb();
192 current->journal_info = h; 209 if (cur_trans->blocked && may_wait_transaction(root, type)) {
210 btrfs_commit_transaction(h, root);
211 goto again;
212 }
213
214 if (num_items > 0) {
215 ret = btrfs_trans_reserve_metadata(h, root, num_items,
216 &retries);
217 if (ret == -EAGAIN) {
218 btrfs_commit_transaction(h, root);
219 goto again;
220 }
221 if (ret < 0) {
222 btrfs_end_transaction(h, root);
223 return ERR_PTR(ret);
224 }
225 }
193 226
194 root->fs_info->running_transaction->use_count++; 227 mutex_lock(&root->fs_info->trans_mutex);
195 record_root_in_trans(h, root); 228 record_root_in_trans(h, root);
196 mutex_unlock(&root->fs_info->trans_mutex); 229 mutex_unlock(&root->fs_info->trans_mutex);
230
231 if (!current->journal_info && type != TRANS_USERSPACE)
232 current->journal_info = h;
197 return h; 233 return h;
198} 234}
199 235
200struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, 236struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
201 int num_blocks) 237 int num_items)
202{ 238{
203 return start_transaction(root, num_blocks, TRANS_START); 239 return start_transaction(root, num_items, TRANS_START);
204} 240}
205struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root, 241struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root,
206 int num_blocks) 242 int num_blocks)
207{ 243{
208 return start_transaction(root, num_blocks, TRANS_JOIN); 244 return start_transaction(root, 0, TRANS_JOIN);
209} 245}
210 246
211struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r, 247struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r,
212 int num_blocks) 248 int num_blocks)
213{ 249{
214 return start_transaction(r, num_blocks, TRANS_USERSPACE); 250 return start_transaction(r, 0, TRANS_USERSPACE);
215} 251}
216 252
217/* wait for a transaction commit to be fully complete */ 253/* wait for a transaction commit to be fully complete */
@@ -312,6 +348,8 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
312 count++; 348 count++;
313 } 349 }
314 350
351 btrfs_trans_release_metadata(trans, root);
352
315 mutex_lock(&info->trans_mutex); 353 mutex_lock(&info->trans_mutex);
316 cur_trans = info->running_transaction; 354 cur_trans = info->running_transaction;
317 WARN_ON(cur_trans != trans->transaction); 355 WARN_ON(cur_trans != trans->transaction);
@@ -757,47 +795,49 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
757 struct btrfs_root *root = pending->root; 795 struct btrfs_root *root = pending->root;
758 struct btrfs_root *parent_root; 796 struct btrfs_root *parent_root;
759 struct inode *parent_inode; 797 struct inode *parent_inode;
798 struct dentry *dentry;
760 struct extent_buffer *tmp; 799 struct extent_buffer *tmp;
761 struct extent_buffer *old; 800 struct extent_buffer *old;
762 int ret; 801 int ret;
763 u64 objectid;
764 int namelen;
765 u64 index = 0; 802 u64 index = 0;
766 803 u64 objectid;
767 parent_inode = pending->dentry->d_parent->d_inode;
768 parent_root = BTRFS_I(parent_inode)->root;
769 804
770 new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); 805 new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
771 if (!new_root_item) { 806 if (!new_root_item) {
772 ret = -ENOMEM; 807 pending->error = -ENOMEM;
773 goto fail; 808 goto fail;
774 } 809 }
810
775 ret = btrfs_find_free_objectid(trans, tree_root, 0, &objectid); 811 ret = btrfs_find_free_objectid(trans, tree_root, 0, &objectid);
776 if (ret) 812 if (ret) {
813 pending->error = ret;
777 goto fail; 814 goto fail;
815 }
778 816
779 key.objectid = objectid; 817 key.objectid = objectid;
780 /* record when the snapshot was created in key.offset */ 818 key.offset = (u64)-1;
781 key.offset = trans->transid; 819 key.type = BTRFS_ROOT_ITEM_KEY;
782 btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
783 820
784 memcpy(&pending->root_key, &key, sizeof(key)); 821 trans->block_rsv = &pending->block_rsv;
785 pending->root_key.offset = (u64)-1;
786 822
823 dentry = pending->dentry;
824 parent_inode = dentry->d_parent->d_inode;
825 parent_root = BTRFS_I(parent_inode)->root;
787 record_root_in_trans(trans, parent_root); 826 record_root_in_trans(trans, parent_root);
827
788 /* 828 /*
789 * insert the directory item 829 * insert the directory item
790 */ 830 */
791 namelen = strlen(pending->name);
792 ret = btrfs_set_inode_index(parent_inode, &index); 831 ret = btrfs_set_inode_index(parent_inode, &index);
793 BUG_ON(ret); 832 BUG_ON(ret);
794 ret = btrfs_insert_dir_item(trans, parent_root, 833 ret = btrfs_insert_dir_item(trans, parent_root,
795 pending->name, namelen, 834 dentry->d_name.name, dentry->d_name.len,
796 parent_inode->i_ino, 835 parent_inode->i_ino, &key,
797 &pending->root_key, BTRFS_FT_DIR, index); 836 BTRFS_FT_DIR, index);
798 BUG_ON(ret); 837 BUG_ON(ret);
799 838
800 btrfs_i_size_write(parent_inode, parent_inode->i_size + namelen * 2); 839 btrfs_i_size_write(parent_inode, parent_inode->i_size +
840 dentry->d_name.len * 2);
801 ret = btrfs_update_inode(trans, parent_root, parent_inode); 841 ret = btrfs_update_inode(trans, parent_root, parent_inode);
802 BUG_ON(ret); 842 BUG_ON(ret);
803 843
@@ -814,22 +854,29 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
814 free_extent_buffer(old); 854 free_extent_buffer(old);
815 855
816 btrfs_set_root_node(new_root_item, tmp); 856 btrfs_set_root_node(new_root_item, tmp);
817 ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, 857 /* record when the snapshot was created in key.offset */
818 new_root_item); 858 key.offset = trans->transid;
819 BUG_ON(ret); 859 ret = btrfs_insert_root(trans, tree_root, &key, new_root_item);
820 btrfs_tree_unlock(tmp); 860 btrfs_tree_unlock(tmp);
821 free_extent_buffer(tmp); 861 free_extent_buffer(tmp);
862 BUG_ON(ret);
822 863
823 ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root, 864 /*
824 pending->root_key.objectid, 865 * insert root back/forward references
866 */
867 ret = btrfs_add_root_ref(trans, tree_root, objectid,
825 parent_root->root_key.objectid, 868 parent_root->root_key.objectid,
826 parent_inode->i_ino, index, pending->name, 869 parent_inode->i_ino, index,
827 namelen); 870 dentry->d_name.name, dentry->d_name.len);
828 BUG_ON(ret); 871 BUG_ON(ret);
829 872
873 key.offset = (u64)-1;
874 pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key);
875 BUG_ON(IS_ERR(pending->snap));
830fail: 876fail:
831 kfree(new_root_item); 877 kfree(new_root_item);
832 return ret; 878 btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1);
879 return 0;
833} 880}
834 881
835/* 882/*
@@ -898,6 +945,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
898 ret = btrfs_run_delayed_refs(trans, root, 0); 945 ret = btrfs_run_delayed_refs(trans, root, 0);
899 BUG_ON(ret); 946 BUG_ON(ret);
900 947
948 btrfs_trans_release_metadata(trans, root);
949
901 cur_trans = trans->transaction; 950 cur_trans = trans->transaction;
902 /* 951 /*
903 * set the flushing flag so procs in this transaction have to 952 * set the flushing flag so procs in this transaction have to