ocfs2: Convert to new freezing mechanism
authorJan Kara <jack@suse.cz>
Tue, 12 Jun 2012 14:20:40 +0000 (16:20 +0200)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 31 Jul 2012 05:45:49 +0000 (09:45 +0400)
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>
fs/ocfs2/file.c
fs/ocfs2/ioctl.c
fs/ocfs2/journal.c
fs/ocfs2/mmap.c

index 7602783d7f41c9a01827f16446da43e036e6a7cb..46a1f6d7510405bf14a0dbc837d2585cfd64e75d 100644 (file)
@@ -1971,6 +1971,7 @@ int ocfs2_change_file_space(struct file *file, unsigned int cmd,
 {
        struct inode *inode = file->f_path.dentry->d_inode;
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+       int ret;
 
        if ((cmd == OCFS2_IOC_RESVSP || cmd == OCFS2_IOC_RESVSP64) &&
            !ocfs2_writes_unwritten_extents(osb))
@@ -1985,7 +1986,12 @@ int ocfs2_change_file_space(struct file *file, unsigned int cmd,
        if (!(file->f_mode & FMODE_WRITE))
                return -EBADF;
 
-       return __ocfs2_change_file_space(file, inode, file->f_pos, cmd, sr, 0);
+       ret = mnt_want_write_file(file);
+       if (ret)
+               return ret;
+       ret = __ocfs2_change_file_space(file, inode, file->f_pos, cmd, sr, 0);
+       mnt_drop_write_file(file);
+       return ret;
 }
 
 static 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,
        if (iocb->ki_left == 0)
                return 0;
 
-       vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
+       sb_start_write(inode->i_sb);
 
        appending = file->f_flags & O_APPEND ? 1 : 0;
        direct_io = file->f_flags & O_DIRECT ? 1 : 0;
@@ -2436,6 +2442,7 @@ out_sems:
                ocfs2_iocb_clear_sem_locked(iocb);
 
        mutex_unlock(&inode->i_mutex);
+       sb_end_write(inode->i_sb);
 
        if (written)
                ret = written;
index d96f7f81d8dd3257f49bb02885db296af22881cb..f20edcbfe700c83a12bb90b697535ea7a4435e98 100644 (file)
@@ -928,7 +928,12 @@ long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                if (get_user(new_clusters, (int __user *)arg))
                        return -EFAULT;
 
-               return ocfs2_group_extend(inode, new_clusters);
+               status = mnt_want_write_file(filp);
+               if (status)
+                       return status;
+               status = ocfs2_group_extend(inode, new_clusters);
+               mnt_drop_write_file(filp);
+               return status;
        case OCFS2_IOC_GROUP_ADD:
        case OCFS2_IOC_GROUP_ADD64:
                if (!capable(CAP_SYS_RESOURCE))
@@ -937,7 +942,12 @@ long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                if (copy_from_user(&input, (int __user *) arg, sizeof(input)))
                        return -EFAULT;
 
-               return ocfs2_group_add(inode, &input);
+               status = mnt_want_write_file(filp);
+               if (status)
+                       return status;
+               status = ocfs2_group_add(inode, &input);
+               mnt_drop_write_file(filp);
+               return status;
        case OCFS2_IOC_REFLINK:
                if (copy_from_user(&args, argp, sizeof(args)))
                        return -EFAULT;
index 0a42ae96dca7d4a0f662505e0e51206895ce4156..2dd36af79e262f8de2051525e1baf8585786cba8 100644 (file)
@@ -355,11 +355,14 @@ handle_t *ocfs2_start_trans(struct ocfs2_super *osb, int max_buffs)
        if (journal_current_handle())
                return jbd2_journal_start(journal, max_buffs);
 
+       sb_start_intwrite(osb->sb);
+
        down_read(&osb->journal->j_trans_barrier);
 
        handle = jbd2_journal_start(journal, max_buffs);
        if (IS_ERR(handle)) {
                up_read(&osb->journal->j_trans_barrier);
+               sb_end_intwrite(osb->sb);
 
                mlog_errno(PTR_ERR(handle));
 
@@ -388,8 +391,10 @@ int ocfs2_commit_trans(struct ocfs2_super *osb,
        if (ret < 0)
                mlog_errno(ret);
 
-       if (!nested)
+       if (!nested) {
                up_read(&journal->j_trans_barrier);
+               sb_end_intwrite(osb->sb);
+       }
 
        return ret;
 }
index 9cd41083e99123eca1c48085fb39809e6b906b40..d150372fd81da7967eb3a8f3d2a3b0d9c8c41c82 100644 (file)
@@ -136,6 +136,7 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
        sigset_t oldset;
        int ret;
 
+       sb_start_pagefault(inode->i_sb);
        ocfs2_block_signals(&oldset);
 
        /*
@@ -165,6 +166,7 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 
 out:
        ocfs2_unblock_signals(&oldset);
+       sb_end_pagefault(inode->i_sb);
        return ret;
 }