diff options
| -rw-r--r-- | fs/ocfs2/inode.c | 14 | ||||
| -rw-r--r-- | fs/ocfs2/mmap.c | 48 | ||||
| -rw-r--r-- | fs/ocfs2/super.c | 20 | ||||
| -rw-r--r-- | fs/ocfs2/super.h | 7 |
4 files changed, 39 insertions, 50 deletions
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 9ee13f70da57..b7650ccd76d0 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
| @@ -957,7 +957,7 @@ static void ocfs2_cleanup_delete_inode(struct inode *inode, | |||
| 957 | void ocfs2_delete_inode(struct inode *inode) | 957 | void ocfs2_delete_inode(struct inode *inode) |
| 958 | { | 958 | { |
| 959 | int wipe, status; | 959 | int wipe, status; |
| 960 | sigset_t blocked, oldset; | 960 | sigset_t oldset; |
| 961 | struct buffer_head *di_bh = NULL; | 961 | struct buffer_head *di_bh = NULL; |
| 962 | 962 | ||
| 963 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); | 963 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); |
| @@ -984,13 +984,7 @@ void ocfs2_delete_inode(struct inode *inode) | |||
| 984 | * messaging paths may return us -ERESTARTSYS. Which would | 984 | * messaging paths may return us -ERESTARTSYS. Which would |
| 985 | * cause us to exit early, resulting in inodes being orphaned | 985 | * cause us to exit early, resulting in inodes being orphaned |
| 986 | * forever. */ | 986 | * forever. */ |
| 987 | sigfillset(&blocked); | 987 | ocfs2_block_signals(&oldset); |
| 988 | status = sigprocmask(SIG_BLOCK, &blocked, &oldset); | ||
| 989 | if (status < 0) { | ||
| 990 | mlog_errno(status); | ||
| 991 | ocfs2_cleanup_delete_inode(inode, 1); | ||
| 992 | goto bail; | ||
| 993 | } | ||
| 994 | 988 | ||
| 995 | /* | 989 | /* |
| 996 | * Synchronize us against ocfs2_get_dentry. We take this in | 990 | * Synchronize us against ocfs2_get_dentry. We take this in |
| @@ -1064,9 +1058,7 @@ bail_unlock_nfs_sync: | |||
| 1064 | ocfs2_nfs_sync_unlock(OCFS2_SB(inode->i_sb), 0); | 1058 | ocfs2_nfs_sync_unlock(OCFS2_SB(inode->i_sb), 0); |
| 1065 | 1059 | ||
| 1066 | bail_unblock: | 1060 | bail_unblock: |
| 1067 | status = sigprocmask(SIG_SETMASK, &oldset, NULL); | 1061 | ocfs2_unblock_signals(&oldset); |
| 1068 | if (status < 0) | ||
| 1069 | mlog_errno(status); | ||
| 1070 | bail: | 1062 | bail: |
| 1071 | clear_inode(inode); | 1063 | clear_inode(inode); |
| 1072 | mlog_exit_void(); | 1064 | mlog_exit_void(); |
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c index 39737613424a..a61809f8eab5 100644 --- a/fs/ocfs2/mmap.c +++ b/fs/ocfs2/mmap.c | |||
| @@ -42,44 +42,20 @@ | |||
| 42 | #include "file.h" | 42 | #include "file.h" |
| 43 | #include "inode.h" | 43 | #include "inode.h" |
| 44 | #include "mmap.h" | 44 | #include "mmap.h" |
| 45 | #include "super.h" | ||
| 45 | 46 | ||
| 46 | static inline int ocfs2_vm_op_block_sigs(sigset_t *blocked, sigset_t *oldset) | ||
| 47 | { | ||
| 48 | /* The best way to deal with signals in the vm path is | ||
| 49 | * to block them upfront, rather than allowing the | ||
| 50 | * locking paths to return -ERESTARTSYS. */ | ||
| 51 | sigfillset(blocked); | ||
| 52 | |||
| 53 | /* We should technically never get a bad return value | ||
| 54 | * from sigprocmask */ | ||
| 55 | return sigprocmask(SIG_BLOCK, blocked, oldset); | ||
| 56 | } | ||
| 57 | |||
| 58 | static inline int ocfs2_vm_op_unblock_sigs(sigset_t *oldset) | ||
| 59 | { | ||
| 60 | return sigprocmask(SIG_SETMASK, oldset, NULL); | ||
| 61 | } | ||
| 62 | 47 | ||
| 63 | static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf) | 48 | static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf) |
| 64 | { | 49 | { |
| 65 | sigset_t blocked, oldset; | 50 | sigset_t oldset; |
| 66 | int error, ret; | 51 | int ret; |
| 67 | 52 | ||
| 68 | mlog_entry("(area=%p, page offset=%lu)\n", area, vmf->pgoff); | 53 | mlog_entry("(area=%p, page offset=%lu)\n", area, vmf->pgoff); |
| 69 | 54 | ||
| 70 | error = ocfs2_vm_op_block_sigs(&blocked, &oldset); | 55 | ocfs2_block_signals(&oldset); |
| 71 | if (error < 0) { | ||
| 72 | mlog_errno(error); | ||
| 73 | ret = VM_FAULT_SIGBUS; | ||
| 74 | goto out; | ||
| 75 | } | ||
| 76 | |||
| 77 | ret = filemap_fault(area, vmf); | 56 | ret = filemap_fault(area, vmf); |
| 57 | ocfs2_unblock_signals(&oldset); | ||
| 78 | 58 | ||
| 79 | error = ocfs2_vm_op_unblock_sigs(&oldset); | ||
| 80 | if (error < 0) | ||
| 81 | mlog_errno(error); | ||
| 82 | out: | ||
| 83 | mlog_exit_ptr(vmf->page); | 59 | mlog_exit_ptr(vmf->page); |
| 84 | return ret; | 60 | return ret; |
| 85 | } | 61 | } |
| @@ -159,14 +135,10 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 159 | struct page *page = vmf->page; | 135 | struct page *page = vmf->page; |
| 160 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; | 136 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; |
| 161 | struct buffer_head *di_bh = NULL; | 137 | struct buffer_head *di_bh = NULL; |
| 162 | sigset_t blocked, oldset; | 138 | sigset_t oldset; |
| 163 | int ret, ret2; | 139 | int ret; |
| 164 | 140 | ||
| 165 | ret = ocfs2_vm_op_block_sigs(&blocked, &oldset); | 141 | ocfs2_block_signals(&oldset); |
| 166 | if (ret < 0) { | ||
| 167 | mlog_errno(ret); | ||
| 168 | return ret; | ||
| 169 | } | ||
| 170 | 142 | ||
| 171 | /* | 143 | /* |
| 172 | * The cluster locks taken will block a truncate from another | 144 | * The cluster locks taken will block a truncate from another |
| @@ -194,9 +166,7 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 194 | ocfs2_inode_unlock(inode, 1); | 166 | ocfs2_inode_unlock(inode, 1); |
| 195 | 167 | ||
| 196 | out: | 168 | out: |
| 197 | ret2 = ocfs2_vm_op_unblock_sigs(&oldset); | 169 | ocfs2_unblock_signals(&oldset); |
| 198 | if (ret2 < 0) | ||
| 199 | mlog_errno(ret2); | ||
| 200 | if (ret) | 170 | if (ret) |
| 201 | ret = VM_FAULT_SIGBUS; | 171 | ret = VM_FAULT_SIGBUS; |
| 202 | return ret; | 172 | return ret; |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 12c2203a62fe..cf6d87b57450 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
| @@ -2560,5 +2560,25 @@ void __ocfs2_abort(struct super_block* sb, | |||
| 2560 | ocfs2_handle_error(sb); | 2560 | ocfs2_handle_error(sb); |
| 2561 | } | 2561 | } |
| 2562 | 2562 | ||
| 2563 | /* | ||
| 2564 | * Void signal blockers, because in-kernel sigprocmask() only fails | ||
| 2565 | * when SIG_* is wrong. | ||
| 2566 | */ | ||
| 2567 | void ocfs2_block_signals(sigset_t *oldset) | ||
| 2568 | { | ||
| 2569 | int rc; | ||
| 2570 | sigset_t blocked; | ||
| 2571 | |||
| 2572 | sigfillset(&blocked); | ||
| 2573 | rc = sigprocmask(SIG_BLOCK, &blocked, oldset); | ||
| 2574 | BUG_ON(rc); | ||
| 2575 | } | ||
| 2576 | |||
| 2577 | void ocfs2_unblock_signals(sigset_t *oldset) | ||
| 2578 | { | ||
| 2579 | int rc = sigprocmask(SIG_SETMASK, oldset, NULL); | ||
| 2580 | BUG_ON(rc); | ||
| 2581 | } | ||
| 2582 | |||
| 2563 | module_init(ocfs2_init); | 2583 | module_init(ocfs2_init); |
| 2564 | module_exit(ocfs2_exit); | 2584 | module_exit(ocfs2_exit); |
diff --git a/fs/ocfs2/super.h b/fs/ocfs2/super.h index 783f5270f2a1..40c7de084c10 100644 --- a/fs/ocfs2/super.h +++ b/fs/ocfs2/super.h | |||
| @@ -45,4 +45,11 @@ void __ocfs2_abort(struct super_block *sb, | |||
| 45 | 45 | ||
| 46 | #define ocfs2_abort(sb, fmt, args...) __ocfs2_abort(sb, __PRETTY_FUNCTION__, fmt, ##args) | 46 | #define ocfs2_abort(sb, fmt, args...) __ocfs2_abort(sb, __PRETTY_FUNCTION__, fmt, ##args) |
| 47 | 47 | ||
| 48 | /* | ||
| 49 | * Void signal blockers, because in-kernel sigprocmask() only fails | ||
| 50 | * when SIG_* is wrong. | ||
| 51 | */ | ||
| 52 | void ocfs2_block_signals(sigset_t *oldset); | ||
| 53 | void ocfs2_unblock_signals(sigset_t *oldset); | ||
| 54 | |||
| 48 | #endif /* OCFS2_SUPER_H */ | 55 | #endif /* OCFS2_SUPER_H */ |
