aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/inode.c14
-rw-r--r--fs/ocfs2/mmap.c48
-rw-r--r--fs/ocfs2/super.c20
-rw-r--r--fs/ocfs2/super.h7
4 files changed, 39 insertions, 50 deletions
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 9ee13f70da5..b7650ccd76d 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -957,7 +957,7 @@ static void ocfs2_cleanup_delete_inode(struct inode *inode,
957void ocfs2_delete_inode(struct inode *inode) 957void 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
1066bail_unblock: 1060bail_unblock:
1067 status = sigprocmask(SIG_SETMASK, &oldset, NULL); 1061 ocfs2_unblock_signals(&oldset);
1068 if (status < 0)
1069 mlog_errno(status);
1070bail: 1062bail:
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 39737613424..a61809f8eab 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
46static 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
58static inline int ocfs2_vm_op_unblock_sigs(sigset_t *oldset)
59{
60 return sigprocmask(SIG_SETMASK, oldset, NULL);
61}
62 47
63static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf) 48static 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);
82out:
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
196out: 168out:
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 12c2203a62f..cf6d87b5745 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 */
2567void 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
2577void ocfs2_unblock_signals(sigset_t *oldset)
2578{
2579 int rc = sigprocmask(SIG_SETMASK, oldset, NULL);
2580 BUG_ON(rc);
2581}
2582
2563module_init(ocfs2_init); 2583module_init(ocfs2_init);
2564module_exit(ocfs2_exit); 2584module_exit(ocfs2_exit);
diff --git a/fs/ocfs2/super.h b/fs/ocfs2/super.h
index 783f5270f2a..40c7de084c1 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 */
52void ocfs2_block_signals(sigset_t *oldset);
53void ocfs2_unblock_signals(sigset_t *oldset);
54
48#endif /* OCFS2_SUPER_H */ 55#endif /* OCFS2_SUPER_H */