diff options
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 */ |