aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-06-12 10:20:40 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-07-31 01:45:49 -0400
commitfef6925cd4c6b564ecff477e07a0fca987542223 (patch)
tree2791b2d287819453b830ad60c316d4f19fcaeead
parentd9457dc056249913a7abe8b71dc09e427e590e35 (diff)
ocfs2: Convert to new freezing mechanism
Protect ocfs2_page_mkwrite() and ocfs2_file_aio_write() using the new freeze protection. We also protect several ioctl entry points which were missing the protection. Finally, we add freeze protection to the journaling mechanism so that iput() of unlinked inode cannot modify a frozen filesystem. CC: Mark Fasheh <mfasheh@suse.com> CC: Joel Becker <jlbec@evilplan.org> CC: ocfs2-devel@oss.oracle.com Acked-by: Joel Becker <jlbec@evilplan.org> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/ocfs2/file.c11
-rw-r--r--fs/ocfs2/ioctl.c14
-rw-r--r--fs/ocfs2/journal.c7
-rw-r--r--fs/ocfs2/mmap.c2
4 files changed, 29 insertions, 5 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 7602783d7f41..46a1f6d75104 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1971,6 +1971,7 @@ int ocfs2_change_file_space(struct file *file, unsigned int cmd,
1971{ 1971{
1972 struct inode *inode = file->f_path.dentry->d_inode; 1972 struct inode *inode = file->f_path.dentry->d_inode;
1973 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 1973 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
1974 int ret;
1974 1975
1975 if ((cmd == OCFS2_IOC_RESVSP || cmd == OCFS2_IOC_RESVSP64) && 1976 if ((cmd == OCFS2_IOC_RESVSP || cmd == OCFS2_IOC_RESVSP64) &&
1976 !ocfs2_writes_unwritten_extents(osb)) 1977 !ocfs2_writes_unwritten_extents(osb))
@@ -1985,7 +1986,12 @@ int ocfs2_change_file_space(struct file *file, unsigned int cmd,
1985 if (!(file->f_mode & FMODE_WRITE)) 1986 if (!(file->f_mode & FMODE_WRITE))
1986 return -EBADF; 1987 return -EBADF;
1987 1988
1988 return __ocfs2_change_file_space(file, inode, file->f_pos, cmd, sr, 0); 1989 ret = mnt_want_write_file(file);
1990 if (ret)
1991 return ret;
1992 ret = __ocfs2_change_file_space(file, inode, file->f_pos, cmd, sr, 0);
1993 mnt_drop_write_file(file);
1994 return ret;
1989} 1995}
1990 1996
1991static long ocfs2_fallocate(struct file *file, int mode, loff_t offset, 1997static long ocfs2_fallocate(struct file *file, int mode, loff_t offset,
@@ -2261,7 +2267,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
2261 if (iocb->ki_left == 0) 2267 if (iocb->ki_left == 0)
2262 return 0; 2268 return 0;
2263 2269
2264 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); 2270 sb_start_write(inode->i_sb);
2265 2271
2266 appending = file->f_flags & O_APPEND ? 1 : 0; 2272 appending = file->f_flags & O_APPEND ? 1 : 0;
2267 direct_io = file->f_flags & O_DIRECT ? 1 : 0; 2273 direct_io = file->f_flags & O_DIRECT ? 1 : 0;
@@ -2436,6 +2442,7 @@ out_sems:
2436 ocfs2_iocb_clear_sem_locked(iocb); 2442 ocfs2_iocb_clear_sem_locked(iocb);
2437 2443
2438 mutex_unlock(&inode->i_mutex); 2444 mutex_unlock(&inode->i_mutex);
2445 sb_end_write(inode->i_sb);
2439 2446
2440 if (written) 2447 if (written)
2441 ret = written; 2448 ret = written;
diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c
index d96f7f81d8dd..f20edcbfe700 100644
--- a/fs/ocfs2/ioctl.c
+++ b/fs/ocfs2/ioctl.c
@@ -928,7 +928,12 @@ long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
928 if (get_user(new_clusters, (int __user *)arg)) 928 if (get_user(new_clusters, (int __user *)arg))
929 return -EFAULT; 929 return -EFAULT;
930 930
931 return ocfs2_group_extend(inode, new_clusters); 931 status = mnt_want_write_file(filp);
932 if (status)
933 return status;
934 status = ocfs2_group_extend(inode, new_clusters);
935 mnt_drop_write_file(filp);
936 return status;
932 case OCFS2_IOC_GROUP_ADD: 937 case OCFS2_IOC_GROUP_ADD:
933 case OCFS2_IOC_GROUP_ADD64: 938 case OCFS2_IOC_GROUP_ADD64:
934 if (!capable(CAP_SYS_RESOURCE)) 939 if (!capable(CAP_SYS_RESOURCE))
@@ -937,7 +942,12 @@ long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
937 if (copy_from_user(&input, (int __user *) arg, sizeof(input))) 942 if (copy_from_user(&input, (int __user *) arg, sizeof(input)))
938 return -EFAULT; 943 return -EFAULT;
939 944
940 return ocfs2_group_add(inode, &input); 945 status = mnt_want_write_file(filp);
946 if (status)
947 return status;
948 status = ocfs2_group_add(inode, &input);
949 mnt_drop_write_file(filp);
950 return status;
941 case OCFS2_IOC_REFLINK: 951 case OCFS2_IOC_REFLINK:
942 if (copy_from_user(&args, argp, sizeof(args))) 952 if (copy_from_user(&args, argp, sizeof(args)))
943 return -EFAULT; 953 return -EFAULT;
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 0a42ae96dca7..2dd36af79e26 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -355,11 +355,14 @@ handle_t *ocfs2_start_trans(struct ocfs2_super *osb, int max_buffs)
355 if (journal_current_handle()) 355 if (journal_current_handle())
356 return jbd2_journal_start(journal, max_buffs); 356 return jbd2_journal_start(journal, max_buffs);
357 357
358 sb_start_intwrite(osb->sb);
359
358 down_read(&osb->journal->j_trans_barrier); 360 down_read(&osb->journal->j_trans_barrier);
359 361
360 handle = jbd2_journal_start(journal, max_buffs); 362 handle = jbd2_journal_start(journal, max_buffs);
361 if (IS_ERR(handle)) { 363 if (IS_ERR(handle)) {
362 up_read(&osb->journal->j_trans_barrier); 364 up_read(&osb->journal->j_trans_barrier);
365 sb_end_intwrite(osb->sb);
363 366
364 mlog_errno(PTR_ERR(handle)); 367 mlog_errno(PTR_ERR(handle));
365 368
@@ -388,8 +391,10 @@ int ocfs2_commit_trans(struct ocfs2_super *osb,
388 if (ret < 0) 391 if (ret < 0)
389 mlog_errno(ret); 392 mlog_errno(ret);
390 393
391 if (!nested) 394 if (!nested) {
392 up_read(&journal->j_trans_barrier); 395 up_read(&journal->j_trans_barrier);
396 sb_end_intwrite(osb->sb);
397 }
393 398
394 return ret; 399 return ret;
395} 400}
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index 9cd41083e991..d150372fd81d 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -136,6 +136,7 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
136 sigset_t oldset; 136 sigset_t oldset;
137 int ret; 137 int ret;
138 138
139 sb_start_pagefault(inode->i_sb);
139 ocfs2_block_signals(&oldset); 140 ocfs2_block_signals(&oldset);
140 141
141 /* 142 /*
@@ -165,6 +166,7 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
165 166
166out: 167out:
167 ocfs2_unblock_signals(&oldset); 168 ocfs2_unblock_signals(&oldset);
169 sb_end_pagefault(inode->i_sb);
168 return ret; 170 return ret;
169} 171}
170 172