diff options
author | Joel Becker <joel.becker@oracle.com> | 2009-09-02 20:17:36 -0400 |
---|---|---|
committer | Joel Becker <joel.becker@oracle.com> | 2010-05-10 14:50:10 -0400 |
commit | e4b963f10e9026c83419b5c25b93a0350413cf16 (patch) | |
tree | d162595c9f79626d040cb28c84e53fd8b7fe50ff /fs/ocfs2 | |
parent | 0467ae954d1843de65e7cf8f706f88fe65cd8418 (diff) |
ocfs2: Wrap signal blocking in void functions.
ocfs2 sometimes needs to block signals around dlm operations, but it
currently does it with sigprocmask(). Even worse, it's checking the
error code of sigprocmask(). The in-kernel sigprocmask() can only error
if you get the SIG_* argument wrong. We don't.
Wrap the sigprocmask() calls with ocfs2_[un]block_signals(). These
functions are void, but they will BUG() if somehow sigprocmask() returns
an error.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2')
-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 */ |