summaryrefslogtreecommitdiffstats
path: root/fs/nilfs2
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 13:26:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 13:26:23 -0400
commita0e881b7c189fa2bd76c024dbff91e79511c971d (patch)
tree0c801918565b08921d21aceee5b326f64d998f5f /fs/nilfs2
parenteff0d13f3823f35d70228cd151d2a2c89288ff32 (diff)
parentdbc6e0222d79e78925fe20733844a796a4b72cf9 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull second vfs pile from Al Viro: "The stuff in there: fsfreeze deadlock fixes by Jan (essentially, the deadlock reproduced by xfstests 068), symlink and hardlink restriction patches, plus assorted cleanups and fixes. Note that another fsfreeze deadlock (emergency thaw one) is *not* dealt with - the series by Fernando conflicts a lot with Jan's, breaks userland ABI (FIFREEZE semantics gets changed) and trades the deadlock for massive vfsmount leak; this is going to be handled next cycle. There probably will be another pull request, but that stuff won't be in it." Fix up trivial conflicts due to unrelated changes next to each other in drivers/{staging/gdm72xx/usb_boot.c, usb/gadget/storage_common.c} * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (54 commits) delousing target_core_file a bit Documentation: Correct s_umount state for freeze_fs/unfreeze_fs fs: Remove old freezing mechanism ext2: Implement freezing btrfs: Convert to new freezing mechanism nilfs2: Convert to new freezing mechanism ntfs: Convert to new freezing mechanism fuse: Convert to new freezing mechanism gfs2: Convert to new freezing mechanism ocfs2: Convert to new freezing mechanism xfs: Convert to new freezing code ext4: Convert to new freezing mechanism fs: Protect write paths by sb_start_write - sb_end_write fs: Skip atime update on frozen filesystem fs: Add freezing handling to mnt_want_write() / mnt_drop_write() fs: Improve filesystem freezing handling switch the protection of percpu_counter list to spinlock nfsd: Push mnt_want_write() outside of i_mutex btrfs: Push mnt_want_write() outside of i_mutex fat: Push mnt_want_write() outside of i_mutex ...
Diffstat (limited to 'fs/nilfs2')
-rw-r--r--fs/nilfs2/file.c18
-rw-r--r--fs/nilfs2/ioctl.c2
-rw-r--r--fs/nilfs2/segment.c5
3 files changed, 15 insertions, 10 deletions
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
index 62cebc8e1a1f..a4d56ac02e6c 100644
--- a/fs/nilfs2/file.c
+++ b/fs/nilfs2/file.c
@@ -69,16 +69,18 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
69 struct page *page = vmf->page; 69 struct page *page = vmf->page;
70 struct inode *inode = vma->vm_file->f_dentry->d_inode; 70 struct inode *inode = vma->vm_file->f_dentry->d_inode;
71 struct nilfs_transaction_info ti; 71 struct nilfs_transaction_info ti;
72 int ret; 72 int ret = 0;
73 73
74 if (unlikely(nilfs_near_disk_full(inode->i_sb->s_fs_info))) 74 if (unlikely(nilfs_near_disk_full(inode->i_sb->s_fs_info)))
75 return VM_FAULT_SIGBUS; /* -ENOSPC */ 75 return VM_FAULT_SIGBUS; /* -ENOSPC */
76 76
77 sb_start_pagefault(inode->i_sb);
77 lock_page(page); 78 lock_page(page);
78 if (page->mapping != inode->i_mapping || 79 if (page->mapping != inode->i_mapping ||
79 page_offset(page) >= i_size_read(inode) || !PageUptodate(page)) { 80 page_offset(page) >= i_size_read(inode) || !PageUptodate(page)) {
80 unlock_page(page); 81 unlock_page(page);
81 return VM_FAULT_NOPAGE; /* make the VM retry the fault */ 82 ret = -EFAULT; /* make the VM retry the fault */
83 goto out;
82 } 84 }
83 85
84 /* 86 /*
@@ -112,19 +114,21 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
112 ret = nilfs_transaction_begin(inode->i_sb, &ti, 1); 114 ret = nilfs_transaction_begin(inode->i_sb, &ti, 1);
113 /* never returns -ENOMEM, but may return -ENOSPC */ 115 /* never returns -ENOMEM, but may return -ENOSPC */
114 if (unlikely(ret)) 116 if (unlikely(ret))
115 return VM_FAULT_SIGBUS; 117 goto out;
116 118
117 ret = block_page_mkwrite(vma, vmf, nilfs_get_block); 119 ret = __block_page_mkwrite(vma, vmf, nilfs_get_block);
118 if (ret != VM_FAULT_LOCKED) { 120 if (ret) {
119 nilfs_transaction_abort(inode->i_sb); 121 nilfs_transaction_abort(inode->i_sb);
120 return ret; 122 goto out;
121 } 123 }
122 nilfs_set_file_dirty(inode, 1 << (PAGE_SHIFT - inode->i_blkbits)); 124 nilfs_set_file_dirty(inode, 1 << (PAGE_SHIFT - inode->i_blkbits));
123 nilfs_transaction_commit(inode->i_sb); 125 nilfs_transaction_commit(inode->i_sb);
124 126
125 mapped: 127 mapped:
126 wait_on_page_writeback(page); 128 wait_on_page_writeback(page);
127 return VM_FAULT_LOCKED; 129 out:
130 sb_end_pagefault(inode->i_sb);
131 return block_page_mkwrite_return(ret);
128} 132}
129 133
130static const struct vm_operations_struct nilfs_file_vm_ops = { 134static const struct vm_operations_struct nilfs_file_vm_ops = {
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
index 0b6387c67e6c..fdb180769485 100644
--- a/fs/nilfs2/ioctl.c
+++ b/fs/nilfs2/ioctl.c
@@ -660,8 +660,6 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
660 goto out_free; 660 goto out_free;
661 } 661 }
662 662
663 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
664
665 ret = nilfs_ioctl_move_blocks(inode->i_sb, &argv[0], kbufs[0]); 663 ret = nilfs_ioctl_move_blocks(inode->i_sb, &argv[0], kbufs[0]);
666 if (ret < 0) 664 if (ret < 0)
667 printk(KERN_ERR "NILFS: GC failed during preparation: " 665 printk(KERN_ERR "NILFS: GC failed during preparation: "
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 88e11fb346b6..a5752a589932 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -189,7 +189,7 @@ int nilfs_transaction_begin(struct super_block *sb,
189 if (ret > 0) 189 if (ret > 0)
190 return 0; 190 return 0;
191 191
192 vfs_check_frozen(sb, SB_FREEZE_WRITE); 192 sb_start_intwrite(sb);
193 193
194 nilfs = sb->s_fs_info; 194 nilfs = sb->s_fs_info;
195 down_read(&nilfs->ns_segctor_sem); 195 down_read(&nilfs->ns_segctor_sem);
@@ -205,6 +205,7 @@ int nilfs_transaction_begin(struct super_block *sb,
205 current->journal_info = ti->ti_save; 205 current->journal_info = ti->ti_save;
206 if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC) 206 if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC)
207 kmem_cache_free(nilfs_transaction_cachep, ti); 207 kmem_cache_free(nilfs_transaction_cachep, ti);
208 sb_end_intwrite(sb);
208 return ret; 209 return ret;
209} 210}
210 211
@@ -246,6 +247,7 @@ int nilfs_transaction_commit(struct super_block *sb)
246 err = nilfs_construct_segment(sb); 247 err = nilfs_construct_segment(sb);
247 if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC) 248 if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC)
248 kmem_cache_free(nilfs_transaction_cachep, ti); 249 kmem_cache_free(nilfs_transaction_cachep, ti);
250 sb_end_intwrite(sb);
249 return err; 251 return err;
250} 252}
251 253
@@ -264,6 +266,7 @@ void nilfs_transaction_abort(struct super_block *sb)
264 current->journal_info = ti->ti_save; 266 current->journal_info = ti->ti_save;
265 if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC) 267 if (ti->ti_flags & NILFS_TI_DYNAMIC_ALLOC)
266 kmem_cache_free(nilfs_transaction_cachep, ti); 268 kmem_cache_free(nilfs_transaction_cachep, ti);
269 sb_end_intwrite(sb);
267} 270}
268 271
269void nilfs_relax_pressure_in_lock(struct super_block *sb) 272void nilfs_relax_pressure_in_lock(struct super_block *sb)