History

mm: prevent concurrent unmap_mapping_range() on the same inode

Michael Leun reported that running parallel opens on a fuse filesystem can trigger a "kernel BUG at mm/truncate.c:475" Gurudas Pai reported the same bug on NFS. The reason is, unmap_mapping_range() is not prepared for more than one concurrent invocation per inode. For example: thread1: going through a big range, stops in the middle of a vma and stores the restart address in vm_truncate_count. thread2: comes in with a small (e.g. single page) unmap request on the same vma, somewhere before restart_address, finds that the vma was already unmapped up to the restart address and happily returns without doing anything. Another scenario would be two big unmap requests, both having to restart the unmapping and each one setting vm_truncate_count to its own value. This could go on forever without any of them being able to finish. Truncate and hole punching already serialize with i_mutex. Other callers of unmap_mapping_range() do not, and it's difficult to get i_mutex protection for all callers. In particular ->d_revalidate(), which calls invalidate_inode_pages2_range() in fuse, may be called with or without i_mutex. This patch adds a new mutex to 'struct address_space' to prevent running multiple concurrent unmap_mapping_range() on the same mapping. [ We'll hopefully get rid of all this with the upcoming mm preemptibility series by Peter Zijlstra, the "mm: Remove i_mmap_mutex lockbreak" patch in particular. But that is for 2.6.39 ]

Miklos Szeredi committed 15 years ago

Commit 2aa15891 parent 78794b210 files · +23 −38Browse files

Unified · Split

10 files
  1. fs/gfs2/main.c +1 −8
  2. fs/inode.c +15 −7
  3. fs/nilfs2/btnode.c +0 −5
  4. fs/nilfs2/btnode.h +0 −1
  5. fs/nilfs2/mdt.c +2 −2
  6. fs/nilfs2/page.c +0 −13
  7. fs/nilfs2/page.h +0 −1
  8. fs/nilfs2/super.c +1 −1
  9. include/linux/fs.h +2 −0
  10. mm/memory.c +2 −0
fs/gfs2/main.c+1−8
@@ -59,14 +59,7 @@ static void gfs2_init_gl_aspace_once(void *foo) · 58 unmodified lines
5959 struct address_space *mapping = (struct address_space *)(gl + 1);
6060
6161 gfs2_init_glock_once(gl);
62− memset(mapping, 0, sizeof(*mapping));
63− INIT_RADIX_TREE(&mapping->page_tree, GFP_ATOMIC);
64− spin_lock_init(&mapping->tree_lock);
65− spin_lock_init(&mapping->i_mmap_lock);
66− INIT_LIST_HEAD(&mapping->private_list);
67− spin_lock_init(&mapping->private_lock);
68− INIT_RAW_PRIO_TREE_ROOT(&mapping->i_mmap);
69− INIT_LIST_HEAD(&mapping->i_mmap_nonlinear);
62+ address_space_init_once(mapping);
7063 }
7164
7265 /**
fs/inode.c+15−7
@@ -295,6 +295,20 @@ static void destroy_inode(struct inode *inode) · 294 unmodified lines
295295 call_rcu(&inode->i_rcu, i_callback);
296296 }
297297
298+void address_space_init_once(struct address_space *mapping)
299+{
300+ memset(mapping, 0, sizeof(*mapping));
301+ INIT_RADIX_TREE(&mapping->page_tree, GFP_ATOMIC);
302+ spin_lock_init(&mapping->tree_lock);
303+ spin_lock_init(&mapping->i_mmap_lock);
304+ INIT_LIST_HEAD(&mapping->private_list);
305+ spin_lock_init(&mapping->private_lock);
306+ INIT_RAW_PRIO_TREE_ROOT(&mapping->i_mmap);
307+ INIT_LIST_HEAD(&mapping->i_mmap_nonlinear);
308+ mutex_init(&mapping->unmap_mutex);
309+}
310+EXPORT_SYMBOL(address_space_init_once);
311+
298312 /*
299313 * These are initializations that only need to be done
300314 * once, because the fields are idempotent across use
@@ -308,13 +322,7 @@ void inode_init_once(struct inode *inode) · 7 unmodified lines
308322 INIT_LIST_HEAD(&inode->i_devices);
309323 INIT_LIST_HEAD(&inode->i_wb_list);
310324 INIT_LIST_HEAD(&inode->i_lru);
311− INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC);
312− spin_lock_init(&inode->i_data.tree_lock);
313− spin_lock_init(&inode->i_data.i_mmap_lock);
314− INIT_LIST_HEAD(&inode->i_data.private_list);
315− spin_lock_init(&inode->i_data.private_lock);
316− INIT_RAW_PRIO_TREE_ROOT(&inode->i_data.i_mmap);
317− INIT_LIST_HEAD(&inode->i_data.i_mmap_nonlinear);
325+ address_space_init_once(&inode->i_data);
318326 i_size_ordered_init(inode);
319327 #ifdef CONFIG_FSNOTIFY
320328 INIT_HLIST_HEAD(&inode->i_fsnotify_marks);
fs/nilfs2/btnode.c+0−5
@@ -35,11 +35,6 @@ · 34 unmodified lines
3535 #include "btnode.h"
3636
3737
38−void nilfs_btnode_cache_init_once(struct address_space *btnc)
39−{
40− nilfs_mapping_init_once(btnc);
41−}
42−
4338 static const struct address_space_operations def_btnode_aops = {
4439 .sync_page = block_sync_page,
4540 };
fs/nilfs2/btnode.h+0−1
@@ -37,7 +37,6 @@ struct nilfs_btnode_chkey_ctxt { · 36 unmodified lines
3737 struct buffer_head *newbh;
3838 };
3939
40−void nilfs_btnode_cache_init_once(struct address_space *);
4140 void nilfs_btnode_cache_init(struct address_space *, struct backing_dev_info *);
4241 void nilfs_btnode_cache_clear(struct address_space *);
4342 struct buffer_head *nilfs_btnode_create_block(struct address_space *btnc,
fs/nilfs2/mdt.c+2−2
@@ -454,9 +454,9 @@ int nilfs_mdt_setup_shadow_map(struct inode *inode, · 453 unmodified lines
454454 struct backing_dev_info *bdi = inode->i_sb->s_bdi;
455455
456456 INIT_LIST_HEAD(&shadow->frozen_buffers);
457− nilfs_mapping_init_once(&shadow->frozen_data);
457+ address_space_init_once(&shadow->frozen_data);
458458 nilfs_mapping_init(&shadow->frozen_data, bdi, &shadow_map_aops);
459− nilfs_mapping_init_once(&shadow->frozen_btnodes);
459+ address_space_init_once(&shadow->frozen_btnodes);
460460 nilfs_mapping_init(&shadow->frozen_btnodes, bdi, &shadow_map_aops);
461461 mi->mi_shadow = shadow;
462462 return 0;
fs/nilfs2/page.c+0−13
@@ -492,19 +492,6 @@ unsigned nilfs_page_count_clean_buffers(struct page *page, · 491 unmodified lines
492492 return nc;
493493 }
494494
495−void nilfs_mapping_init_once(struct address_space *mapping)
496−{
497− memset(mapping, 0, sizeof(*mapping));
498− INIT_RADIX_TREE(&mapping->page_tree, GFP_ATOMIC);
499− spin_lock_init(&mapping->tree_lock);
500− INIT_LIST_HEAD(&mapping->private_list);
501− spin_lock_init(&mapping->private_lock);
502−
503− spin_lock_init(&mapping->i_mmap_lock);
504− INIT_RAW_PRIO_TREE_ROOT(&mapping->i_mmap);
505− INIT_LIST_HEAD(&mapping->i_mmap_nonlinear);
506−}
507−
508495 void nilfs_mapping_init(struct address_space *mapping,
509496 struct backing_dev_info *bdi,
510497 const struct address_space_operations *aops)
fs/nilfs2/page.h+0−1
@@ -61,7 +61,6 @@ void nilfs_free_private_page(struct page *); · 60 unmodified lines
6161 int nilfs_copy_dirty_pages(struct address_space *, struct address_space *);
6262 void nilfs_copy_back_pages(struct address_space *, struct address_space *);
6363 void nilfs_clear_dirty_pages(struct address_space *);
64−void nilfs_mapping_init_once(struct address_space *mapping);
6564 void nilfs_mapping_init(struct address_space *mapping,
6665 struct backing_dev_info *bdi,
6766 const struct address_space_operations *aops);
fs/nilfs2/super.c+1−1
@@ -1279,7 +1279,7 @@ static void nilfs_inode_init_once(void *obj) · 1278 unmodified lines
12791279 #ifdef CONFIG_NILFS_XATTR
12801280 init_rwsem(&ii->xattr_sem);
12811281 #endif
1282− nilfs_btnode_cache_init_once(&ii->i_btnode_cache);
1282+ address_space_init_once(&ii->i_btnode_cache);
12831283 ii->i_bmap = &ii->i_bmap_data;
12841284 inode_init_once(&ii->vfs_inode);
12851285 }
include/linux/fs.h+2−0
@@ -649,6 +649,7 @@ struct address_space { · 648 unmodified lines
649649 spinlock_t private_lock; /* for use by the address_space */
650650 struct list_head private_list; /* ditto */
651651 struct address_space *assoc_mapping; /* ditto */
652+ struct mutex unmap_mutex; /* to protect unmapping */
652653 } __attribute__((aligned(sizeof(long))));
653654 /*
654655 * On most architectures that alignment is already the case; but
@@ -2225,6 +2226,7 @@ extern loff_t vfs_llseek(struct file *file, loff_t offset, int origin); · 1570 unmodified lines
22252226
22262227 extern int inode_init_always(struct super_block *, struct inode *);
22272228 extern void inode_init_once(struct inode *);
2229+extern void address_space_init_once(struct address_space *mapping);
22282230 extern void ihold(struct inode * inode);
22292231 extern void iput(struct inode *);
22302232 extern struct inode * igrab(struct inode *);
mm/memory.c+2−0
@@ -2648,6 +2648,7 @@ void unmap_mapping_range(struct address_space *mapping, · 2647 unmodified lines
26482648 details.last_index = ULONG_MAX;
26492649 details.i_mmap_lock = &mapping->i_mmap_lock;
26502650
2651+ mutex_lock(&mapping->unmap_mutex);
26512652 spin_lock(&mapping->i_mmap_lock);
26522653
26532654 /* Protect against endless unmapping loops */
@@ -2664,6 +2665,7 @@ void unmap_mapping_range(struct address_space *mapping, · 10 unmodified lines
26642665 if (unlikely(!list_empty(&mapping->i_mmap_nonlinear)))
26652666 unmap_mapping_range_list(&mapping->i_mmap_nonlinear, &details);
26662667 spin_unlock(&mapping->i_mmap_lock);
2668+ mutex_unlock(&mapping->unmap_mutex);
26672669 }
26682670 EXPORT_SYMBOL(unmap_mapping_range);
26692671