diff options
| -rw-r--r-- | fs/nilfs2/file.c | 18 | ||||
| -rw-r--r-- | fs/nilfs2/ioctl.c | 2 | ||||
| -rw-r--r-- | fs/nilfs2/segment.c | 5 |
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 | ||
| 130 | static const struct vm_operations_struct nilfs_file_vm_ops = { | 134 | static const struct vm_operations_struct nilfs_file_vm_ops = { |
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index 06658caa18bd..08f27968a7a9 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 | ||
| 269 | void nilfs_relax_pressure_in_lock(struct super_block *sb) | 272 | void nilfs_relax_pressure_in_lock(struct super_block *sb) |
