Commit 4d5e74bc0aec3f54b7e429d77b7c35de042c507d

Authored by Chris Mason
1 parent 2da98f003f

Btrfs: Fix data=ordered vs wait_on_inode deadlock on older kernels

Using ilookup5 during data=ordered writeback could deadlock on I_LOCK.  This
saves a pointer to the inode instead.

Signed-off-by: Chris Mason <chris.mason@oracle.com>

Showing 3 changed files with 27 additions and 21 deletions Side-by-side Diff

fs/btrfs/ordered-data.c
... ... @@ -25,6 +25,7 @@
25 25 struct tree_entry {
26 26 u64 root_objectid;
27 27 u64 objectid;
  28 + struct inode *inode;
28 29 struct rb_node rb_node;
29 30 };
30 31  
... ... @@ -144,6 +145,7 @@
144 145 write_lock(&tree->lock);
145 146 entry->objectid = inode->i_ino;
146 147 entry->root_objectid = root_objectid;
  148 + entry->inode = inode;
147 149  
148 150 node = tree_insert(&tree->tree, root_objectid,
149 151 inode->i_ino, &entry->rb_node);
... ... @@ -159,7 +161,8 @@
159 161 }
160 162  
161 163 int btrfs_find_first_ordered_inode(struct btrfs_ordered_inode_tree *tree,
162   - u64 *root_objectid, u64 *objectid)
  164 + u64 *root_objectid, u64 *objectid,
  165 + struct inode **inode)
163 166 {
164 167 struct tree_entry *entry;
165 168 struct rb_node *node;
166 169  
... ... @@ -184,13 +187,16 @@
184 187 }
185 188  
186 189 *root_objectid = entry->root_objectid;
  190 + *inode = entry->inode;
  191 + atomic_inc(&entry->inode->i_count);
187 192 *objectid = entry->objectid;
188 193 write_unlock(&tree->lock);
189 194 return 1;
190 195 }
191 196  
192 197 int btrfs_find_del_first_ordered_inode(struct btrfs_ordered_inode_tree *tree,
193   - u64 *root_objectid, u64 *objectid)
  198 + u64 *root_objectid, u64 *objectid,
  199 + struct inode **inode)
194 200 {
195 201 struct tree_entry *entry;
196 202 struct rb_node *node;
... ... @@ -216,6 +222,8 @@
216 222  
217 223 *root_objectid = entry->root_objectid;
218 224 *objectid = entry->objectid;
  225 + *inode = entry->inode;
  226 + atomic_inc(&entry->inode->i_count);
219 227 rb_erase(node, &tree->tree);
220 228 write_unlock(&tree->lock);
221 229 kfree(entry);
fs/btrfs/ordered-data.h
... ... @@ -33,9 +33,11 @@
33 33  
34 34 int btrfs_add_ordered_inode(struct inode *inode);
35 35 int btrfs_find_del_first_ordered_inode(struct btrfs_ordered_inode_tree *tree,
36   - u64 *root_objectid, u64 *objectid);
  36 + u64 *root_objectid, u64 *objectid,
  37 + struct inode **inode);
37 38 int btrfs_find_first_ordered_inode(struct btrfs_ordered_inode_tree *tree,
38   - u64 *root_objectid, u64 *objectid);
  39 + u64 *root_objectid, u64 *objectid,
  40 + struct inode **inode);
39 41 int btrfs_del_ordered_inode(struct inode *inode);
40 42 #endif
fs/btrfs/transaction.c
... ... @@ -490,19 +490,17 @@
490 490 while(1) {
491 491 ret = btrfs_find_first_ordered_inode(
492 492 &cur_trans->ordered_inode_tree,
493   - &root_objectid, &objectid);
  493 + &root_objectid, &objectid, &inode);
494 494 if (!ret)
495 495 break;
496 496  
497 497 mutex_unlock(&root->fs_info->trans_mutex);
498 498 mutex_unlock(&root->fs_info->fs_mutex);
499   - inode = btrfs_ilookup(root->fs_info->sb, objectid,
500   - root_objectid);
501   - if (inode) {
502   - if (S_ISREG(inode->i_mode))
503   - filemap_fdatawrite(inode->i_mapping);
504   - iput(inode);
505   - }
  499 +
  500 + if (S_ISREG(inode->i_mode))
  501 + filemap_fdatawrite(inode->i_mapping);
  502 + iput(inode);
  503 +
506 504 mutex_lock(&root->fs_info->fs_mutex);
507 505 mutex_lock(&root->fs_info->trans_mutex);
508 506 }
509 507  
... ... @@ -511,19 +509,17 @@
511 509 objectid = 0;
512 510 ret = btrfs_find_del_first_ordered_inode(
513 511 &cur_trans->ordered_inode_tree,
514   - &root_objectid, &objectid);
  512 + &root_objectid, &objectid, &inode);
515 513 if (!ret)
516 514 break;
517 515 mutex_unlock(&root->fs_info->trans_mutex);
518 516 mutex_unlock(&root->fs_info->fs_mutex);
519   - inode = btrfs_ilookup(root->fs_info->sb, objectid,
520   - root_objectid);
521   - if (inode) {
522   - if (S_ISREG(inode->i_mode))
523   - filemap_write_and_wait(inode->i_mapping);
524   - atomic_dec(&inode->i_count);
525   - iput(inode);
526   - }
  517 +
  518 + if (S_ISREG(inode->i_mode))
  519 + filemap_write_and_wait(inode->i_mapping);
  520 + atomic_dec(&inode->i_count);
  521 + iput(inode);
  522 +
527 523 mutex_lock(&root->fs_info->fs_mutex);
528 524 mutex_lock(&root->fs_info->trans_mutex);
529 525 }